@artinstack/migrator 0.1.12 → 0.1.14
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 +32 -1
- package/dist/{bundle-CysqqLij.d.ts → bundle-BgoXkWMy.d.ts} +1 -1
- package/dist/{chunk-MUFGDYGI.js → chunk-373TTCG7.js} +11 -1
- package/dist/chunk-373TTCG7.js.map +1 -0
- package/dist/{chunk-VRRYN6NS.js → chunk-5TRCJONX.js} +3 -3
- package/dist/{chunk-QFJXNEXG.js → chunk-HUSXCKPI.js} +4 -2
- package/dist/{chunk-QFJXNEXG.js.map → chunk-HUSXCKPI.js.map} +1 -1
- package/dist/{chunk-PFUXPS7A.js → chunk-PD5AZX3B.js} +1 -1
- package/dist/chunk-PD5AZX3B.js.map +1 -0
- package/dist/{chunk-J7EUSPEA.js → chunk-S55525RD.js} +312 -44
- package/dist/chunk-S55525RD.js.map +1 -0
- package/dist/{chunk-WCAHVNWW.js → chunk-X4TJQWZF.js} +13 -3
- package/dist/chunk-X4TJQWZF.js.map +1 -0
- package/dist/{chunk-Q44KGFIH.js → chunk-ZKIAIP3B.js} +79 -8
- package/dist/chunk-ZKIAIP3B.js.map +1 -0
- package/dist/cli/index.js +5 -5
- package/dist/index.d.ts +3 -3
- package/dist/index.js +7 -7
- package/dist/normalizer/index.d.ts +100 -4
- package/dist/normalizer/index.js +2 -2
- package/dist/sinks/index.d.ts +2 -2
- package/dist/sinks/index.js +3 -3
- package/dist/transformers/index.d.ts +1 -1
- package/dist/transformers/index.js +3 -3
- package/dist/{types-CLNmloya.d.ts → types-Bicgdp4Z.d.ts} +13 -1
- package/package.json +1 -1
- package/dist/chunk-J7EUSPEA.js.map +0 -1
- package/dist/chunk-MUFGDYGI.js.map +0 -1
- package/dist/chunk-PFUXPS7A.js.map +0 -1
- package/dist/chunk-Q44KGFIH.js.map +0 -1
- package/dist/chunk-WCAHVNWW.js.map +0 -1
- /package/dist/{chunk-VRRYN6NS.js.map → chunk-5TRCJONX.js.map} +0 -0
package/README.md
CHANGED
|
@@ -41,6 +41,36 @@ pnpm link --global # optional: artinstack-migrate on PATH
|
|
|
41
41
|
|
|
42
42
|
Requires **Node.js 20+**.
|
|
43
43
|
|
|
44
|
+
## Supported input formats
|
|
45
|
+
|
|
46
|
+
The `@artinstack/migrator` is a pure **content schema and layout migrator**, not a full-site systems restoration tool.
|
|
47
|
+
|
|
48
|
+
### Unsupported formats
|
|
49
|
+
|
|
50
|
+
These files contain runtime theme binaries, core PHP files, and raw database dumps. They **cannot** be fed directly into the migrator:
|
|
51
|
+
|
|
52
|
+
- **All-in-One WP Migration** (`.wpress`)
|
|
53
|
+
- **Duplicator / UpdraftPlus** backups (`.zip`, `.tar.gz`)
|
|
54
|
+
|
|
55
|
+
### Supported formats (by platform)
|
|
56
|
+
|
|
57
|
+
| Platform | Accepted input |
|
|
58
|
+
|----------|----------------|
|
|
59
|
+
| **WordPress** | **WXR (XML)** — Tools → Export in wp-admin |
|
|
60
|
+
| **Wix** | Blog RSS/Atom, REST export, static HTML snapshots |
|
|
61
|
+
| **Squarespace** | json-pretty export |
|
|
62
|
+
| **SmugMug** | API crawl or export JSON |
|
|
63
|
+
|
|
64
|
+
### Recommended workflow (`.wpress` → WXR)
|
|
65
|
+
|
|
66
|
+
If your client or source site only provided an All-in-One WP Migration (`.wpress`) file:
|
|
67
|
+
|
|
68
|
+
1. **Restore** — Spin up a temporary local WordPress instance (e.g. LocalWP) and restore the `.wpress` file.
|
|
69
|
+
2. **Export** — Inside the restored WP dashboard, go to **Tools → Export**, select **All content** (or specific pages/posts), and download the **WXR (XML)** file.
|
|
70
|
+
3. **Migrate** — Feed the resulting WXR file into `artinstack-migrate wordpress …`.
|
|
71
|
+
|
|
72
|
+
See [architecture.md § Supported input formats](./docs/architecture.md#supported-input-formats) for the full `.wpress` assessment.
|
|
73
|
+
|
|
44
74
|
## CLI
|
|
45
75
|
|
|
46
76
|
```bash
|
|
@@ -158,9 +188,10 @@ pnpm dev # watch build
|
|
|
158
188
|
| WordPress builder flattening + origin URL rewrite (pre-DTO) | Yes | Optional same config on adapter input |
|
|
159
189
|
| Stamp `artinstack-migration://asset/…` refs in content HTML | Yes | No |
|
|
160
190
|
| Expand refs → CDN URLs at persist | Exported helper | Call site + DB lookup |
|
|
191
|
+
| Page `layoutHints` (e.g. theme hero slider alias) | Yes — on `NormalizedPage` when meta references chrome outside body | Rebuild slider / hero at import |
|
|
161
192
|
| CLI + filesystem JSON export | Yes | No |
|
|
162
193
|
| `MigrationSink` interface | Yes | Implementation |
|
|
163
|
-
|
|
|
194
|
+
| Map `data-wp-widget` stubs → platform blocks; populate slider heroes from hints | No | Yes |
|
|
164
195
|
| Jobs, worker, credentials, UI | No | Yes |
|
|
165
196
|
|
|
166
197
|
## License
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NormalizedPost, a as NormalizedPage, b as NormalizedAsset, c as NormalizedPortfolio, d as NormalizedCategory, e as NormalizedTag, f as NormalizedEntity } from './types-
|
|
1
|
+
import { N as NormalizedPost, a as NormalizedPage, b as NormalizedAsset, c as NormalizedPortfolio, d as NormalizedCategory, e as NormalizedTag, f as NormalizedEntity } from './types-Bicgdp4Z.js';
|
|
2
2
|
|
|
3
3
|
interface EntityBundle {
|
|
4
4
|
posts: NormalizedPost[];
|
|
@@ -26,6 +26,15 @@ var normalizedPostSchema = z.object({
|
|
|
26
26
|
seoTitle: z.string().optional(),
|
|
27
27
|
seoDescription: z.string().optional()
|
|
28
28
|
});
|
|
29
|
+
var pageHeroSliderHintSchema = z.object({
|
|
30
|
+
plugin: z.enum(["revslider", "masterslider"]),
|
|
31
|
+
alias: z.string().min(1),
|
|
32
|
+
slidertitle: z.string().optional(),
|
|
33
|
+
source: z.enum(["meta-shortcode", "meta-slider-field", "tatsu-json"]).optional()
|
|
34
|
+
});
|
|
35
|
+
var pageLayoutHintsSchema = z.object({
|
|
36
|
+
heroSlider: pageHeroSliderHintSchema.optional()
|
|
37
|
+
});
|
|
29
38
|
var normalizedPageSchema = z.object({
|
|
30
39
|
type: z.literal("page"),
|
|
31
40
|
source: sourceMetadataSchema,
|
|
@@ -36,6 +45,7 @@ var normalizedPageSchema = z.object({
|
|
|
36
45
|
contentCss: z.string().optional(),
|
|
37
46
|
isHomePage: z.boolean().optional(),
|
|
38
47
|
isPortfolioPage: z.boolean().optional(),
|
|
48
|
+
layoutHints: pageLayoutHintsSchema.optional(),
|
|
39
49
|
status: publishStatusSchema,
|
|
40
50
|
seoTitle: z.string().optional(),
|
|
41
51
|
seoDescription: z.string().optional()
|
|
@@ -145,4 +155,4 @@ export {
|
|
|
145
155
|
validateNormalizedTag,
|
|
146
156
|
validateNormalizedEntity
|
|
147
157
|
};
|
|
148
|
-
//# sourceMappingURL=chunk-
|
|
158
|
+
//# sourceMappingURL=chunk-373TTCG7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/normalizer/validate.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport type { ValidationIssue, ValidationResult } from \"./types.js\";\n\nconst migrationPlatformSchema = z.enum([\"wordpress\", \"smugmug\", \"squarespace\", \"wix\"]);\nconst publishStatusSchema = z.enum([\"draft\", \"published\", \"archived\"]);\n\nexport const sourceMetadataSchema = z.object({\n platform: migrationPlatformSchema,\n id: z.string().min(1),\n url: z.string().optional(),\n path: z.string().optional(),\n exportedAt: z.string().optional(),\n});\n\nexport const normalizedPostSchema = z.object({\n type: z.literal(\"post\"),\n source: sourceMetadataSchema,\n sourceId: z.string().min(1),\n title: z.string().min(1),\n slug: z.string().min(1),\n excerpt: z.string().optional(),\n contentHtml: z.string(),\n publishedAt: z.string().optional(),\n status: publishStatusSchema,\n categorySlugs: z.array(z.string().min(1)).optional(),\n tagSlugs: z.array(z.string().min(1)).optional(),\n sourceFeaturedMediaId: z.string().optional(),\n featuredAssetSourceId: z.string().optional(),\n seoTitle: z.string().optional(),\n seoDescription: z.string().optional(),\n});\n\nconst pageHeroSliderHintSchema = z.object({\n plugin: z.enum([\"revslider\", \"masterslider\"]),\n alias: z.string().min(1),\n slidertitle: z.string().optional(),\n source: z.enum([\"meta-shortcode\", \"meta-slider-field\", \"tatsu-json\"]).optional(),\n});\n\nconst pageLayoutHintsSchema = z.object({\n heroSlider: pageHeroSliderHintSchema.optional(),\n});\n\nexport const normalizedPageSchema = z.object({\n type: z.literal(\"page\"),\n source: sourceMetadataSchema,\n sourceId: z.string().min(1),\n title: z.string().min(1),\n slug: z.string().min(1),\n contentHtml: z.string(),\n contentCss: z.string().optional(),\n isHomePage: z.boolean().optional(),\n isPortfolioPage: z.boolean().optional(),\n layoutHints: pageLayoutHintsSchema.optional(),\n status: publishStatusSchema,\n seoTitle: z.string().optional(),\n seoDescription: z.string().optional(),\n});\n\nexport const normalizedAssetExifSchema = z.object({\n iso: z.number().optional(),\n aperture: z.number().optional(),\n shutter: z.string().optional(),\n focalLength: z.number().optional(),\n});\n\nexport const normalizedAssetSchema = z.object({\n type: z.literal(\"asset\"),\n source: sourceMetadataSchema,\n sourceId: z.string().min(1),\n sourceUrl: z.string().min(1),\n filename: z.string().min(1),\n mimeType: z.string().optional(),\n caption: z.string().optional(),\n altText: z.string().optional(),\n keywords: z.array(z.string()).optional(),\n exif: normalizedAssetExifSchema.optional(),\n portfolioSourceId: z.string().optional(),\n sort: z.number().optional(),\n});\n\nexport const normalizedPortfolioSchema = z.object({\n type: z.literal(\"portfolio\"),\n source: sourceMetadataSchema,\n sourceId: z.string().min(1),\n title: z.string().min(1),\n slug: z.string().min(1),\n description: z.string().optional(),\n parentSourceId: z.string().optional(),\n});\n\nexport const normalizedCategorySchema = z.object({\n type: z.literal(\"category\"),\n source: sourceMetadataSchema,\n sourceId: z.string().min(1),\n name: z.string().min(1),\n slug: z.string().min(1),\n});\n\nexport const normalizedTagSchema = z.object({\n type: z.literal(\"tag\"),\n source: sourceMetadataSchema,\n sourceId: z.string().min(1),\n name: z.string().min(1),\n slug: z.string().min(1),\n});\n\nexport const normalizedEntitySchema = z.discriminatedUnion(\"type\", [\n normalizedPostSchema,\n normalizedPageSchema,\n normalizedAssetSchema,\n normalizedPortfolioSchema,\n normalizedCategorySchema,\n normalizedTagSchema,\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 parseToValidationResult(schema: z.ZodTypeAny, value: unknown): ValidationResult {\n const result = schema.safeParse(value);\n if (result.success) {\n return { ok: true, issues: [] };\n }\n return { ok: false, issues: zodIssuesToValidationIssues(result.error.issues) };\n}\n\n/** Opt-in structural check for a normalized post DTO (no cross-entity FK validation). */\nexport function validateNormalizedPost(post: unknown): ValidationResult {\n return parseToValidationResult(normalizedPostSchema, post);\n}\n\n/** Opt-in structural check for a normalized page DTO (no cross-entity FK validation). */\nexport function validateNormalizedPage(page: unknown): ValidationResult {\n return parseToValidationResult(normalizedPageSchema, page);\n}\n\n/** Opt-in structural check for a normalized asset DTO. */\nexport function validateNormalizedAsset(asset: unknown): ValidationResult {\n return parseToValidationResult(normalizedAssetSchema, asset);\n}\n\n/** Opt-in structural check for a normalized portfolio DTO. */\nexport function validateNormalizedPortfolio(portfolio: unknown): ValidationResult {\n return parseToValidationResult(normalizedPortfolioSchema, portfolio);\n}\n\n/** Opt-in structural check for a normalized category DTO. */\nexport function validateNormalizedCategory(category: unknown): ValidationResult {\n return parseToValidationResult(normalizedCategorySchema, category);\n}\n\n/** Opt-in structural check for a normalized tag DTO. */\nexport function validateNormalizedTag(tag: unknown): ValidationResult {\n return parseToValidationResult(normalizedTagSchema, tag);\n}\n\n/** Opt-in structural check for any normalized entity discriminated by `type`. */\nexport function validateNormalizedEntity(entity: unknown): ValidationResult {\n return parseToValidationResult(normalizedEntitySchema, entity);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
emptyBundle,
|
|
6
6
|
entityKey,
|
|
7
7
|
shouldProcessEntity
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-PD5AZX3B.js";
|
|
9
9
|
import {
|
|
10
10
|
UNRESOLVABLE_SHORTCODE_PREFIXES,
|
|
11
11
|
rewriteInlineImages
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-HUSXCKPI.js";
|
|
13
13
|
import {
|
|
14
14
|
linkToPath,
|
|
15
15
|
sanitizeSlug
|
|
@@ -1565,4 +1565,4 @@ export {
|
|
|
1565
1565
|
resolveAdapterImportSummary,
|
|
1566
1566
|
runDryRun
|
|
1567
1567
|
};
|
|
1568
|
-
//# sourceMappingURL=chunk-
|
|
1568
|
+
//# sourceMappingURL=chunk-5TRCJONX.js.map
|
|
@@ -202,6 +202,9 @@ var WORDPRESS_WIDGET_REGISTRY = {
|
|
|
202
202
|
],
|
|
203
203
|
portfolioShortcode: "portfolio",
|
|
204
204
|
blogShortcodeTags: ["blog", "recent_posts"],
|
|
205
|
+
testimonialsWrapperTags: ["testimonials"],
|
|
206
|
+
testimonialItemTag: "testimonial",
|
|
207
|
+
sliderShortcodeTags: ["rev_slider", "masterslider"],
|
|
205
208
|
galleryShortcode: "gallery",
|
|
206
209
|
idGalleryShortcodes: ["oshine_gallery", "vc_gallery", "nggallery"]
|
|
207
210
|
};
|
|
@@ -333,7 +336,6 @@ var WORDPRESS_BUILDER_REGISTRY = [
|
|
|
333
336
|
],
|
|
334
337
|
wrapperRules: [
|
|
335
338
|
{ shortcodePrefix: "grid_content" },
|
|
336
|
-
{ shortcodePrefix: "testimonial", urlParams: ["author_image"] },
|
|
337
339
|
{ shortcodePrefix: "blox_text" }
|
|
338
340
|
],
|
|
339
341
|
urlRules: [
|
|
@@ -352,4 +354,4 @@ export {
|
|
|
352
354
|
UNRESOLVABLE_SHORTCODE_PREFIXES,
|
|
353
355
|
WORDPRESS_BUILDER_REGISTRY
|
|
354
356
|
};
|
|
355
|
-
//# sourceMappingURL=chunk-
|
|
357
|
+
//# sourceMappingURL=chunk-HUSXCKPI.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/transformers/rewrite-inline-images.ts","../src/parsers/wordpress/builders/registry.ts"],"sourcesContent":["import * as cheerio from \"cheerio\";\n\nimport {\n buildMigrationMediaUrlIndex,\n createMigrationMediaRefReplaceWith,\n isMigrationMediaRef,\n normalizeAssetUrl,\n resolveMigrationMediaSourceId,\n type OriginUrlRewriteConfig,\n} from \"../lib/media-urls.js\";\n\nexport interface RewriteInlineImageRef {\n originalSrc: string;\n sourceAssetId?: string;\n}\n\nexport interface UploadedAssetRef {\n targetId: string;\n publicUrl?: string;\n}\n\nexport interface RewriteInlineImagesOptions {\n resolveAsset: (src: string) => RewriteInlineImageRef | undefined;\n /**\n * Replace a resolved source id with a migration ref or CDN URL.\n * When omitted, defaults to OSS-14 `artinstack-migration://asset/…` refs.\n */\n replaceWith?: (ref: RewriteInlineImageRef, uploaded?: UploadedAssetRef) => string;\n /**\n * When true, skip URLs that cannot be matched to an uploaded vault target.\n * Default: false when using migration refs; true when a custom `replaceWith` is supplied.\n */\n requireUploaded?: boolean;\n}\n\nexport interface RewriteInlineImagesResult {\n html: string;\n referencedSources: 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 resolveRewriteOptions(\n options: RewriteInlineImagesOptions,\n): Required<Pick<RewriteInlineImagesOptions, \"replaceWith\" | \"requireUploaded\">> {\n const replaceWith = options.replaceWith ?? createMigrationMediaRefReplaceWith();\n const requireUploaded = options.requireUploaded ?? Boolean(options.replaceWith);\n return { replaceWith, requireUploaded };\n}\n\nfunction tryRewriteUrl(\n src: string,\n options: RewriteInlineImagesOptions,\n uploadedBySourceId: Map<string, UploadedAssetRef>,\n referencedSources: Set<string>,\n unresolved: Set<string>,\n): string | undefined {\n const normalized = normalizeAssetUrl(src);\n if (!normalized) return undefined;\n\n if (isMigrationMediaRef(normalized)) {\n referencedSources.add(normalized);\n return normalized;\n }\n\n referencedSources.add(normalized);\n const ref = options.resolveAsset(normalized);\n if (!ref?.sourceAssetId) {\n unresolved.add(normalized);\n return undefined;\n }\n\n const { replaceWith, requireUploaded } = resolveRewriteOptions(options);\n const uploaded = uploadedBySourceId.get(ref.sourceAssetId);\n if (requireUploaded && !uploaded) {\n unresolved.add(normalized);\n return undefined;\n }\n\n return replaceWith(ref, uploaded);\n}\n\nfunction rewriteBackgroundUrlsInStyle(\n style: string,\n options: RewriteInlineImagesOptions,\n uploadedBySourceId: Map<string, UploadedAssetRef>,\n referencedSources: Set<string>,\n unresolved: Set<string>,\n): string {\n return style.replace(BACKGROUND_IMAGE_URL_PATTERN, (full, quote: string, rawUrl: string) => {\n const replaced = tryRewriteUrl(rawUrl.trim(), options, uploadedBySourceId, referencedSources, unresolved);\n if (!replaced) return full;\n\n const urlCall = quote\n ? `url(${quote}${replaced}${quote})`\n : `url(${replaced})`;\n return full.replace(/url\\s*\\(\\s*(['\"]?)([^'\")]+)\\1\\s*\\)/i, urlCall);\n });\n}\n\nfunction rewriteSrcset(\n srcset: string,\n options: RewriteInlineImagesOptions,\n uploadedBySourceId: Map<string, UploadedAssetRef>,\n referencedSources: Set<string>,\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 replaced = tryRewriteUrl(urlPart ?? \"\", options, uploadedBySourceId, referencedSources, unresolved);\n if (!replaced) return entry;\n return descriptor ? `${replaced} ${descriptor}` : replaced;\n })\n .join(\", \");\n}\n\n/** Rewrite `<img src>` / `srcset`, `data-bg-image`, and inline CSS backgrounds using uploaded asset targets. */\nexport function rewriteInlineImages(\n html: string,\n options: RewriteInlineImagesOptions,\n uploadedBySourceId: Map<string, UploadedAssetRef>,\n): RewriteInlineImagesResult {\n if (!html.trim()) {\n return { html, referencedSources: [], unresolved: [] };\n }\n\n const $ = cheerio.load(html, { xml: false });\n const referencedSources = new Set<string>();\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 && !src.startsWith(\"data:\")) {\n const replaced = tryRewriteUrl(src, options, uploadedBySourceId, referencedSources, unresolved);\n if (replaced) img.attr(\"src\", replaced);\n }\n\n const srcset = img.attr(\"srcset\")?.trim();\n if (srcset) {\n img.attr(\"srcset\", rewriteSrcset(srcset, options, uploadedBySourceId, referencedSources, 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 || bgImage.startsWith(\"data:\")) return;\n const replaced = tryRewriteUrl(bgImage, options, uploadedBySourceId, referencedSources, unresolved);\n if (replaced) node.attr(\"data-bg-image\", replaced);\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 = rewriteBackgroundUrlsInStyle(\n style,\n options,\n uploadedBySourceId,\n referencedSources,\n unresolved,\n );\n if (rewritten !== style) node.attr(\"style\", rewritten);\n });\n\n return {\n html: $.root().html() ?? html,\n referencedSources: [...referencedSources],\n unresolved: [...unresolved],\n };\n}\n\nexport interface StampMigrationMediaRefsOptions {\n /** Pre-built url/pathname → sourceId map (from attachments + inline assets). */\n urlToSourceId: Map<string, string>;\n /** Canonicalize lookup keys during stamp (OSS-15). */\n originUrlRewrite?: OriginUrlRewriteConfig;\n replaceWith?: RewriteInlineImagesOptions[\"replaceWith\"];\n requireUploaded?: boolean;\n}\n\n/**\n * OSS-14 — replace resolved `wp-content/uploads` URLs with `artinstack-migration://asset/…`\n * refs. Does not invent refs for unknown URLs (left unchanged + listed in `unresolved`).\n */\nexport function stampMigrationMediaRefs(\n html: string,\n options: StampMigrationMediaRefsOptions,\n): RewriteInlineImagesResult {\n return rewriteInlineImages(\n html,\n {\n resolveAsset: (src) => {\n const sourceAssetId = resolveMigrationMediaSourceId(\n src,\n options.urlToSourceId,\n options.originUrlRewrite,\n );\n if (!sourceAssetId) return undefined;\n return { originalSrc: src, sourceAssetId };\n },\n replaceWith: options.replaceWith,\n requireUploaded: options.requireUploaded ?? false,\n },\n new Map(),\n );\n}\n\n/** Build a url index from attachment rows and/or normalized assets. */\nexport { buildMigrationMediaUrlIndex };\n","export type BuilderHtmlTag = \"img\" | \"video\" | \"iframe\";\nexport type TextHtmlTag = \"p\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\";\n\n/** Bucket 1 — shortcodes with asset URL params → standard HTML. */\nexport interface BuilderUrlRule {\n shortcodePrefix: string;\n urlParams: string[];\n tag: BuilderHtmlTag;\n}\n\n/** Bucket 1 — shortcodes with text params → semantic HTML. */\nexport interface BuilderTextRule {\n shortcodePrefix: string;\n fields: { param: string; tag: TextHtmlTag }[];\n}\n\n/** Bucket 1 — shortcodes with inner HTML (+ optional image param). */\nexport interface BuilderWrapperRule {\n shortcodePrefix: string;\n urlParams?: string[];\n}\n\n/** Bucket 1 — image-based icon modules (`icon_image` param) → linked `<img>`. */\nexport interface BuilderIconImageRule {\n shortcodePrefix: string;\n imageParam: string;\n hrefParam?: string;\n}\n\n/** Bucket 1 — dynamic embeds replaced with a static migration placeholder. */\nexport interface BuilderPlaceholderRule {\n shortcodePrefix: string;\n html: string;\n}\n\n/** Profile A — prefixed namespace tokens (Tatsu, Divi, WPBakery, …). */\nexport interface PrefixedLayoutMap {\n kind: \"prefixed\";\n sectionRegex: RegExp;\n sectionCloseRegex: RegExp;\n rowRegex: RegExp;\n rowCloseRegex: RegExp;\n columnRegex: RegExp;\n columnCloseRegex: RegExp;\n bgParamName?: string;\n colsParamName?: string;\n}\n\n/** Profile B — legacy Blox fractional column tokens (`one_third`, `one_half`, …). */\nexport interface FractionalLayoutMap {\n kind: \"fractional\";\n sectionRegex: RegExp;\n sectionCloseRegex: RegExp;\n rowRegex: RegExp;\n rowCloseRegex: RegExp;\n columnTokens: string[];\n columnOpenRegexes: RegExp[];\n columnCloseRegexes: RegExp[];\n columnWidths: Record<string, string>;\n bgParamName?: string;\n}\n\n/** Profile C — multiple tokens per layout role (Blox prefixed, WPBakery inner columns, …). */\nexport interface ExtendedPrefixedLayoutLevel {\n role: \"section\" | \"row\" | \"column\";\n tokens: string[];\n bgParamName?: string;\n colsParamName?: string;\n widthParamName?: string;\n}\n\nexport interface ExtendedPrefixedLayoutMap {\n kind: \"extended-prefixed\";\n levels: ExtendedPrefixedLayoutLevel[];\n}\n\nexport type StructuralLayoutMap =\n | PrefixedLayoutMap\n | FractionalLayoutMap\n | ExtendedPrefixedLayoutMap;\n\nfunction layoutEscapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction shortcodeOpenRegex(token: string): RegExp {\n return new RegExp(`\\\\[${layoutEscapeRegExp(token)}\\\\b([^\\\\]]*)\\\\]`, \"gi\");\n}\n\nfunction shortcodeCloseRegex(token: string): RegExp {\n return new RegExp(`\\\\[\\\\/${layoutEscapeRegExp(token)}\\\\b[^\\\\]]*\\\\]`, \"gi\");\n}\n\nconst FRACTIONAL_COLUMN_WIDTHS: Record<string, string> = {\n one_col: \"100%\",\n one_half: \"50%\",\n one_third: \"33.33%\",\n two_third: \"66.67%\",\n two_thirds: \"66.67%\",\n one_fourth: \"25%\",\n three_fourth: \"75%\",\n three_fourths: \"75%\",\n};\n\nexport function parseFractionalColumnWidth(token: string): string | undefined {\n return FRACTIONAL_COLUMN_WIDTHS[token];\n}\n\n/** Profile A — section/row/column share a static namespace prefix. */\nexport function prefixedLayoutMap(config: {\n section: string;\n row: string;\n column: string;\n bgParamName?: string;\n colsParamName?: string;\n}): PrefixedLayoutMap {\n return {\n kind: \"prefixed\",\n sectionRegex: shortcodeOpenRegex(config.section),\n sectionCloseRegex: shortcodeCloseRegex(config.section),\n rowRegex: shortcodeOpenRegex(config.row),\n rowCloseRegex: shortcodeCloseRegex(config.row),\n columnRegex: shortcodeOpenRegex(config.column),\n columnCloseRegex: shortcodeCloseRegex(config.column),\n bgParamName: config.bgParamName,\n colsParamName: config.colsParamName,\n };\n}\n\n/** Profile B — legacy Blox/Oshine mathematical column shortcodes. */\n/** Profile C — map several shortcode names per section/row/column role (longest token first). */\nexport function extendedPrefixedLayoutMap(\n levels: ExtendedPrefixedLayoutLevel[],\n): ExtendedPrefixedLayoutMap {\n return { kind: \"extended-prefixed\", levels };\n}\n\nexport function fractionalLayoutMap(config: {\n section: string;\n row: string;\n columns: string[];\n bgParamName?: string;\n}): FractionalLayoutMap {\n const columnWidths: Record<string, string> = {};\n for (const token of config.columns) {\n const width = parseFractionalColumnWidth(token);\n if (width) columnWidths[token] = width;\n }\n\n return {\n kind: \"fractional\",\n sectionRegex: shortcodeOpenRegex(config.section),\n sectionCloseRegex: shortcodeCloseRegex(config.section),\n rowRegex: shortcodeOpenRegex(config.row),\n rowCloseRegex: shortcodeCloseRegex(config.row),\n columnTokens: config.columns,\n columnOpenRegexes: config.columns.map(shortcodeOpenRegex),\n columnCloseRegexes: config.columns.map(shortcodeCloseRegex),\n columnWidths,\n bgParamName: config.bgParamName,\n };\n}\n\n/** Per builder-family registry entry — declarative map executed by the flatten engine. */\nexport interface BuilderThemeConfig {\n id: string;\n detect: RegExp;\n layoutMap?: StructuralLayoutMap;\n /** Additional layout maps applied after `layoutMap` (e.g. Blox prefixed + legacy fractional). */\n layoutMaps?: StructuralLayoutMap[];\n urlRules?: BuilderUrlRule[];\n textRules?: BuilderTextRule[];\n wrapperRules?: BuilderWrapperRule[];\n iconImageRules?: BuilderIconImageRule[];\n placeholderRules?: BuilderPlaceholderRule[];\n scaffoldingPrefixes?: string[];\n legacyScaffoldingTokens?: string[];\n}\n\n/** @deprecated Alias — families not themes. */\nexport type BuilderFamilyConfig = BuilderThemeConfig;\n\n// ---------------------------------------------------------------------------\n// Widget registry (OSS-12 / OSS-16) — cross-builder; not BuilderThemeConfig\n// ---------------------------------------------------------------------------\n\n/** Keeps empty widget stubs from collapsing during cheerio text sweeps. */\nexport const WP_WIDGET_PLACEHOLDER = \"\\u200B\";\n\nexport interface WordPressContactFormWidgetRule {\n /** Shortcode tag name (e.g. `contact-form-7`). */\n tag: string;\n /** Value for `data-wp-form-source`. */\n source: string;\n /** Attribute holding the form id (e.g. `id`). */\n idParam: string;\n}\n\n/** Declarative widget tables consumed by `flattenWordPressWidgets()` in flatten.ts. */\nexport interface WordPressWidgetRegistry {\n mapShortcodePrefixes: readonly string[];\n contactFormRules: readonly WordPressContactFormWidgetRule[];\n videoShortcodePrefixes: readonly string[];\n /** Core / plugin portfolio dynamic shortcode tag. */\n portfolioShortcode: string;\n /** Builder blog roll modules (Tatsu/Oshine `[blog]`, etc.). */\n blogShortcodeTags: readonly string[];\n /** WordPress core gallery shortcode tag (`ids=` split handled in engine). */\n galleryShortcode: string;\n /** Builder/plugin gallery shortcodes with explicit `ids=` attachment lists (OSS-12). */\n idGalleryShortcodes: readonly string[];\n}\n\nexport const WORDPRESS_WIDGET_REGISTRY: WordPressWidgetRegistry = {\n mapShortcodePrefixes: [\n \"blox_gmap\",\n \"tatsu_gmap\",\n \"tatsu_map\",\n \"et_pb_map\",\n \"vc_gmaps\",\n \"vc_map\",\n ],\n contactFormRules: [\n { tag: \"contact-form-7\", source: \"contact-form-7\", idParam: \"id\" },\n { tag: \"contact_form\", source: \"contact-form-7\", idParam: \"id\" },\n { tag: \"gravityform\", source: \"gravityforms\", idParam: \"id\" },\n { tag: \"ninja_form\", source: \"ninja-forms\", idParam: \"id\" },\n { tag: \"wpforms\", source: \"wpforms\", idParam: \"id\" },\n ],\n videoShortcodePrefixes: [\n \"youtube\",\n \"vimeo\",\n \"embed\",\n \"tatsu_video\",\n \"et_pb_video\",\n \"vc_video\",\n ],\n portfolioShortcode: \"portfolio\",\n blogShortcodeTags: [\"blog\", \"recent_posts\"],\n galleryShortcode: \"gallery\",\n idGalleryShortcodes: [\"oshine_gallery\", \"vc_gallery\", \"nggallery\"],\n};\n\n/** Shortcodes that cannot become static HTML — reported in conflicts, never stripped. */\nexport const UNRESOLVABLE_SHORTCODE_PREFIXES = [\n \"woocommerce_cart\",\n \"woocommerce_checkout\",\n \"woocommerce_my_account\",\n] as const;\n\nexport const WORDPRESS_BUILDER_REGISTRY: BuilderThemeConfig[] = [\n {\n id: \"tatsu\",\n detect: /\\[(?:\\/)?tatsu_/i,\n layoutMap: prefixedLayoutMap({\n section: \"tatsu_section\",\n row: \"tatsu_row\",\n column: \"tatsu_column\",\n bgParamName: \"bg_image\",\n colsParamName: \"layout\",\n }),\n wrapperRules: [\n { shortcodePrefix: \"tatsu_text\" },\n { shortcodePrefix: \"tatsu_inline_text\" },\n { shortcodePrefix: \"tatsu_text_with_shortcodes\" },\n { shortcodePrefix: \"tatsu_icon_group\" },\n ],\n urlRules: [\n { shortcodePrefix: \"tatsu_image\", urlParams: [\"image\", \"url\", \"src\"], tag: \"img\" },\n { shortcodePrefix: \"tatsu_single_image\", urlParams: [\"image\", \"url\", \"src\"], tag: \"img\" },\n ],\n iconImageRules: [\n { shortcodePrefix: \"tatsu_icon\", imageParam: \"icon_image\", hrefParam: \"href\" },\n ],\n scaffoldingPrefixes: [\"tatsu_\"],\n },\n {\n id: \"divi\",\n detect: /\\[(?:\\/)?et_pb_/i,\n layoutMap: prefixedLayoutMap({\n section: \"et_pb_section\",\n row: \"et_pb_row\",\n column: \"et_pb_column\",\n bgParamName: \"background_image\",\n }),\n urlRules: [{ shortcodePrefix: \"et_pb_image\", urlParams: [\"src\", \"url\"], tag: \"img\" }],\n scaffoldingPrefixes: [\"et_pb_\"],\n },\n {\n id: \"wpbakery\",\n detect: /\\[(?:\\/)?vc_/i,\n layoutMap: extendedPrefixedLayoutMap([\n { role: \"section\", tokens: [\"vc_section\"], bgParamName: \"bg_image\" },\n { role: \"row\", tokens: [\"vc_row\"], colsParamName: \"layout\" },\n { role: \"column\", tokens: [\"vc_column_inner\", \"vc_column\"], widthParamName: \"width\" },\n ]),\n urlRules: [\n { shortcodePrefix: \"vc_single_image\", urlParams: [\"image\", \"src\", \"url\"], tag: \"img\" },\n ],\n scaffoldingPrefixes: [\"vc_\"],\n },\n {\n id: \"fusion\",\n detect: /\\[(?:\\/)?fusion_/i,\n layoutMap: prefixedLayoutMap({\n section: \"fusion_builder_container\",\n row: \"fusion_builder_row\",\n column: \"fusion_builder_column\",\n bgParamName: \"background_image\",\n }),\n scaffoldingPrefixes: [\"fusion_\"],\n },\n {\n id: \"beaver\",\n detect: /\\[(?:\\/)?fl_(?:row|col|builder)/i,\n layoutMap: extendedPrefixedLayoutMap([\n { role: \"row\", tokens: [\"fl_row\"] },\n { role: \"column\", tokens: [\"fl_col\"] },\n ]),\n scaffoldingPrefixes: [\"fl_\"],\n },\n {\n id: \"elementor\",\n detect: /\\[(?:\\/)?elementor[-_]/i,\n urlRules: [\n { shortcodePrefix: \"elementor-widget\", urlParams: [\"url\", \"src\", \"image\"], tag: \"img\" },\n ],\n scaffoldingPrefixes: [\"elementor_\"],\n },\n {\n id: \"oshine\",\n detect:\n /\\[(?:special_sub_title|special_heading5|blox_\\w+|grid_content|grids|testimonial\\b|portfolio\\b|recent_posts\\b|animate_icon\\w*|section\\b|row\\b|one_col|one_third|one_half|one_fourth|two_third|three_fourth|text\\b)/i,\n layoutMap: fractionalLayoutMap({\n section: \"section\",\n row: \"row\",\n columns: [\n \"one_col\",\n \"one_third\",\n \"two_third\",\n \"two_thirds\",\n \"one_half\",\n \"one_fourth\",\n \"three_fourth\",\n \"three_fourths\",\n ],\n bgParamName: \"bg_image\",\n }),\n layoutMaps: [\n extendedPrefixedLayoutMap([\n { role: \"section\", tokens: [\"blox_row\"], bgParamName: \"bg_image\" },\n { role: \"row\", tokens: [\"blox_row_inner\"], colsParamName: \"columns\" },\n {\n role: \"column\",\n tokens: [\"blox_column_inner\", \"blox_column\"],\n widthParamName: \"width\",\n },\n ]),\n ],\n textRules: [\n {\n shortcodePrefix: \"special_sub_title\",\n fields: [{ param: \"title_content\", tag: \"p\" }],\n },\n {\n shortcodePrefix: \"special_heading5\",\n fields: [\n { param: \"title_content\", tag: \"h2\" },\n { param: \"caption_content\", tag: \"h4\" },\n ],\n },\n ],\n wrapperRules: [\n { shortcodePrefix: \"grid_content\" },\n { shortcodePrefix: \"testimonial\", urlParams: [\"author_image\"] },\n { shortcodePrefix: \"blox_text\" },\n ],\n urlRules: [\n { shortcodePrefix: \"blox_image\", urlParams: [\"image\", \"img\", \"src\", \"url\"], tag: \"img\" },\n ],\n scaffoldingPrefixes: [\"blox_\", \"animate_icon\"],\n legacyScaffoldingTokens: [\"text\", \"icon\", \"linebreak\", \"grids\", \"testimonials\"],\n },\n];\n\n/** @deprecated Use urlRules on BuilderThemeConfig — kept for type migration clarity. */\nexport type BuilderContentRule = BuilderUrlRule;\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/transformers/rewrite-inline-images.ts","../src/parsers/wordpress/builders/registry.ts"],"sourcesContent":["import * as cheerio from \"cheerio\";\n\nimport {\n buildMigrationMediaUrlIndex,\n createMigrationMediaRefReplaceWith,\n isMigrationMediaRef,\n normalizeAssetUrl,\n resolveMigrationMediaSourceId,\n type OriginUrlRewriteConfig,\n} from \"../lib/media-urls.js\";\n\nexport interface RewriteInlineImageRef {\n originalSrc: string;\n sourceAssetId?: string;\n}\n\nexport interface UploadedAssetRef {\n targetId: string;\n publicUrl?: string;\n}\n\nexport interface RewriteInlineImagesOptions {\n resolveAsset: (src: string) => RewriteInlineImageRef | undefined;\n /**\n * Replace a resolved source id with a migration ref or CDN URL.\n * When omitted, defaults to OSS-14 `artinstack-migration://asset/…` refs.\n */\n replaceWith?: (ref: RewriteInlineImageRef, uploaded?: UploadedAssetRef) => string;\n /**\n * When true, skip URLs that cannot be matched to an uploaded vault target.\n * Default: false when using migration refs; true when a custom `replaceWith` is supplied.\n */\n requireUploaded?: boolean;\n}\n\nexport interface RewriteInlineImagesResult {\n html: string;\n referencedSources: 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 resolveRewriteOptions(\n options: RewriteInlineImagesOptions,\n): Required<Pick<RewriteInlineImagesOptions, \"replaceWith\" | \"requireUploaded\">> {\n const replaceWith = options.replaceWith ?? createMigrationMediaRefReplaceWith();\n const requireUploaded = options.requireUploaded ?? Boolean(options.replaceWith);\n return { replaceWith, requireUploaded };\n}\n\nfunction tryRewriteUrl(\n src: string,\n options: RewriteInlineImagesOptions,\n uploadedBySourceId: Map<string, UploadedAssetRef>,\n referencedSources: Set<string>,\n unresolved: Set<string>,\n): string | undefined {\n const normalized = normalizeAssetUrl(src);\n if (!normalized) return undefined;\n\n if (isMigrationMediaRef(normalized)) {\n referencedSources.add(normalized);\n return normalized;\n }\n\n referencedSources.add(normalized);\n const ref = options.resolveAsset(normalized);\n if (!ref?.sourceAssetId) {\n unresolved.add(normalized);\n return undefined;\n }\n\n const { replaceWith, requireUploaded } = resolveRewriteOptions(options);\n const uploaded = uploadedBySourceId.get(ref.sourceAssetId);\n if (requireUploaded && !uploaded) {\n unresolved.add(normalized);\n return undefined;\n }\n\n return replaceWith(ref, uploaded);\n}\n\nfunction rewriteBackgroundUrlsInStyle(\n style: string,\n options: RewriteInlineImagesOptions,\n uploadedBySourceId: Map<string, UploadedAssetRef>,\n referencedSources: Set<string>,\n unresolved: Set<string>,\n): string {\n return style.replace(BACKGROUND_IMAGE_URL_PATTERN, (full, quote: string, rawUrl: string) => {\n const replaced = tryRewriteUrl(rawUrl.trim(), options, uploadedBySourceId, referencedSources, unresolved);\n if (!replaced) return full;\n\n const urlCall = quote\n ? `url(${quote}${replaced}${quote})`\n : `url(${replaced})`;\n return full.replace(/url\\s*\\(\\s*(['\"]?)([^'\")]+)\\1\\s*\\)/i, urlCall);\n });\n}\n\nfunction rewriteSrcset(\n srcset: string,\n options: RewriteInlineImagesOptions,\n uploadedBySourceId: Map<string, UploadedAssetRef>,\n referencedSources: Set<string>,\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 replaced = tryRewriteUrl(urlPart ?? \"\", options, uploadedBySourceId, referencedSources, unresolved);\n if (!replaced) return entry;\n return descriptor ? `${replaced} ${descriptor}` : replaced;\n })\n .join(\", \");\n}\n\n/** Rewrite `<img src>` / `srcset`, `data-bg-image`, and inline CSS backgrounds using uploaded asset targets. */\nexport function rewriteInlineImages(\n html: string,\n options: RewriteInlineImagesOptions,\n uploadedBySourceId: Map<string, UploadedAssetRef>,\n): RewriteInlineImagesResult {\n if (!html.trim()) {\n return { html, referencedSources: [], unresolved: [] };\n }\n\n const $ = cheerio.load(html, { xml: false });\n const referencedSources = new Set<string>();\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 && !src.startsWith(\"data:\")) {\n const replaced = tryRewriteUrl(src, options, uploadedBySourceId, referencedSources, unresolved);\n if (replaced) img.attr(\"src\", replaced);\n }\n\n const srcset = img.attr(\"srcset\")?.trim();\n if (srcset) {\n img.attr(\"srcset\", rewriteSrcset(srcset, options, uploadedBySourceId, referencedSources, 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 || bgImage.startsWith(\"data:\")) return;\n const replaced = tryRewriteUrl(bgImage, options, uploadedBySourceId, referencedSources, unresolved);\n if (replaced) node.attr(\"data-bg-image\", replaced);\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 = rewriteBackgroundUrlsInStyle(\n style,\n options,\n uploadedBySourceId,\n referencedSources,\n unresolved,\n );\n if (rewritten !== style) node.attr(\"style\", rewritten);\n });\n\n return {\n html: $.root().html() ?? html,\n referencedSources: [...referencedSources],\n unresolved: [...unresolved],\n };\n}\n\nexport interface StampMigrationMediaRefsOptions {\n /** Pre-built url/pathname → sourceId map (from attachments + inline assets). */\n urlToSourceId: Map<string, string>;\n /** Canonicalize lookup keys during stamp (OSS-15). */\n originUrlRewrite?: OriginUrlRewriteConfig;\n replaceWith?: RewriteInlineImagesOptions[\"replaceWith\"];\n requireUploaded?: boolean;\n}\n\n/**\n * OSS-14 — replace resolved `wp-content/uploads` URLs with `artinstack-migration://asset/…`\n * refs. Does not invent refs for unknown URLs (left unchanged + listed in `unresolved`).\n */\nexport function stampMigrationMediaRefs(\n html: string,\n options: StampMigrationMediaRefsOptions,\n): RewriteInlineImagesResult {\n return rewriteInlineImages(\n html,\n {\n resolveAsset: (src) => {\n const sourceAssetId = resolveMigrationMediaSourceId(\n src,\n options.urlToSourceId,\n options.originUrlRewrite,\n );\n if (!sourceAssetId) return undefined;\n return { originalSrc: src, sourceAssetId };\n },\n replaceWith: options.replaceWith,\n requireUploaded: options.requireUploaded ?? false,\n },\n new Map(),\n );\n}\n\n/** Build a url index from attachment rows and/or normalized assets. */\nexport { buildMigrationMediaUrlIndex };\n","export type BuilderHtmlTag = \"img\" | \"video\" | \"iframe\";\nexport type TextHtmlTag = \"p\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\";\n\n/** Bucket 1 — shortcodes with asset URL params → standard HTML. */\nexport interface BuilderUrlRule {\n shortcodePrefix: string;\n urlParams: string[];\n tag: BuilderHtmlTag;\n}\n\n/** Bucket 1 — shortcodes with text params → semantic HTML. */\nexport interface BuilderTextRule {\n shortcodePrefix: string;\n fields: { param: string; tag: TextHtmlTag }[];\n}\n\n/** Bucket 1 — shortcodes with inner HTML (+ optional image param). */\nexport interface BuilderWrapperRule {\n shortcodePrefix: string;\n urlParams?: string[];\n}\n\n/** Bucket 1 — image-based icon modules (`icon_image` param) → linked `<img>`. */\nexport interface BuilderIconImageRule {\n shortcodePrefix: string;\n imageParam: string;\n hrefParam?: string;\n}\n\n/** Bucket 1 — dynamic embeds replaced with a static migration placeholder. */\nexport interface BuilderPlaceholderRule {\n shortcodePrefix: string;\n html: string;\n}\n\n/** Profile A — prefixed namespace tokens (Tatsu, Divi, WPBakery, …). */\nexport interface PrefixedLayoutMap {\n kind: \"prefixed\";\n sectionRegex: RegExp;\n sectionCloseRegex: RegExp;\n rowRegex: RegExp;\n rowCloseRegex: RegExp;\n columnRegex: RegExp;\n columnCloseRegex: RegExp;\n bgParamName?: string;\n colsParamName?: string;\n}\n\n/** Profile B — legacy Blox fractional column tokens (`one_third`, `one_half`, …). */\nexport interface FractionalLayoutMap {\n kind: \"fractional\";\n sectionRegex: RegExp;\n sectionCloseRegex: RegExp;\n rowRegex: RegExp;\n rowCloseRegex: RegExp;\n columnTokens: string[];\n columnOpenRegexes: RegExp[];\n columnCloseRegexes: RegExp[];\n columnWidths: Record<string, string>;\n bgParamName?: string;\n}\n\n/** Profile C — multiple tokens per layout role (Blox prefixed, WPBakery inner columns, …). */\nexport interface ExtendedPrefixedLayoutLevel {\n role: \"section\" | \"row\" | \"column\";\n tokens: string[];\n bgParamName?: string;\n colsParamName?: string;\n widthParamName?: string;\n}\n\nexport interface ExtendedPrefixedLayoutMap {\n kind: \"extended-prefixed\";\n levels: ExtendedPrefixedLayoutLevel[];\n}\n\nexport type StructuralLayoutMap =\n | PrefixedLayoutMap\n | FractionalLayoutMap\n | ExtendedPrefixedLayoutMap;\n\nfunction layoutEscapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction shortcodeOpenRegex(token: string): RegExp {\n return new RegExp(`\\\\[${layoutEscapeRegExp(token)}\\\\b([^\\\\]]*)\\\\]`, \"gi\");\n}\n\nfunction shortcodeCloseRegex(token: string): RegExp {\n return new RegExp(`\\\\[\\\\/${layoutEscapeRegExp(token)}\\\\b[^\\\\]]*\\\\]`, \"gi\");\n}\n\nconst FRACTIONAL_COLUMN_WIDTHS: Record<string, string> = {\n one_col: \"100%\",\n one_half: \"50%\",\n one_third: \"33.33%\",\n two_third: \"66.67%\",\n two_thirds: \"66.67%\",\n one_fourth: \"25%\",\n three_fourth: \"75%\",\n three_fourths: \"75%\",\n};\n\nexport function parseFractionalColumnWidth(token: string): string | undefined {\n return FRACTIONAL_COLUMN_WIDTHS[token];\n}\n\n/** Profile A — section/row/column share a static namespace prefix. */\nexport function prefixedLayoutMap(config: {\n section: string;\n row: string;\n column: string;\n bgParamName?: string;\n colsParamName?: string;\n}): PrefixedLayoutMap {\n return {\n kind: \"prefixed\",\n sectionRegex: shortcodeOpenRegex(config.section),\n sectionCloseRegex: shortcodeCloseRegex(config.section),\n rowRegex: shortcodeOpenRegex(config.row),\n rowCloseRegex: shortcodeCloseRegex(config.row),\n columnRegex: shortcodeOpenRegex(config.column),\n columnCloseRegex: shortcodeCloseRegex(config.column),\n bgParamName: config.bgParamName,\n colsParamName: config.colsParamName,\n };\n}\n\n/** Profile B — legacy Blox/Oshine mathematical column shortcodes. */\n/** Profile C — map several shortcode names per section/row/column role (longest token first). */\nexport function extendedPrefixedLayoutMap(\n levels: ExtendedPrefixedLayoutLevel[],\n): ExtendedPrefixedLayoutMap {\n return { kind: \"extended-prefixed\", levels };\n}\n\nexport function fractionalLayoutMap(config: {\n section: string;\n row: string;\n columns: string[];\n bgParamName?: string;\n}): FractionalLayoutMap {\n const columnWidths: Record<string, string> = {};\n for (const token of config.columns) {\n const width = parseFractionalColumnWidth(token);\n if (width) columnWidths[token] = width;\n }\n\n return {\n kind: \"fractional\",\n sectionRegex: shortcodeOpenRegex(config.section),\n sectionCloseRegex: shortcodeCloseRegex(config.section),\n rowRegex: shortcodeOpenRegex(config.row),\n rowCloseRegex: shortcodeCloseRegex(config.row),\n columnTokens: config.columns,\n columnOpenRegexes: config.columns.map(shortcodeOpenRegex),\n columnCloseRegexes: config.columns.map(shortcodeCloseRegex),\n columnWidths,\n bgParamName: config.bgParamName,\n };\n}\n\n/** Per builder-family registry entry — declarative map executed by the flatten engine. */\nexport interface BuilderThemeConfig {\n id: string;\n detect: RegExp;\n layoutMap?: StructuralLayoutMap;\n /** Additional layout maps applied after `layoutMap` (e.g. Blox prefixed + legacy fractional). */\n layoutMaps?: StructuralLayoutMap[];\n urlRules?: BuilderUrlRule[];\n textRules?: BuilderTextRule[];\n wrapperRules?: BuilderWrapperRule[];\n iconImageRules?: BuilderIconImageRule[];\n placeholderRules?: BuilderPlaceholderRule[];\n scaffoldingPrefixes?: string[];\n legacyScaffoldingTokens?: string[];\n}\n\n/** @deprecated Alias — families not themes. */\nexport type BuilderFamilyConfig = BuilderThemeConfig;\n\n// ---------------------------------------------------------------------------\n// Widget registry (OSS-12 / OSS-16) — cross-builder; not BuilderThemeConfig\n// ---------------------------------------------------------------------------\n\n/** Keeps empty widget stubs from collapsing during cheerio text sweeps. */\nexport const WP_WIDGET_PLACEHOLDER = \"\\u200B\";\n\nexport interface WordPressContactFormWidgetRule {\n /** Shortcode tag name (e.g. `contact-form-7`). */\n tag: string;\n /** Value for `data-wp-form-source`. */\n source: string;\n /** Attribute holding the form id (e.g. `id`). */\n idParam: string;\n}\n\n/** Declarative widget tables consumed by `flattenWordPressWidgets()` in flatten.ts. */\nexport interface WordPressWidgetRegistry {\n mapShortcodePrefixes: readonly string[];\n contactFormRules: readonly WordPressContactFormWidgetRule[];\n videoShortcodePrefixes: readonly string[];\n /** Core / plugin portfolio dynamic shortcode tag. */\n portfolioShortcode: string;\n /** Builder blog roll modules (Tatsu/Oshine `[blog]`, etc.). */\n blogShortcodeTags: readonly string[];\n /** Testimonials carousel/list wrapper shortcodes (Oshine `[testimonials]`, etc.). */\n testimonialsWrapperTags: readonly string[];\n /** Inner testimonial item shortcode tag. */\n testimonialItemTag: string;\n /** In-body RevSlider / MasterSlider shortcodes → slider widget stub (alias only). */\n sliderShortcodeTags: readonly string[];\n /** WordPress core gallery shortcode tag (`ids=` split handled in engine). */\n galleryShortcode: string;\n /** Builder/plugin gallery shortcodes with explicit `ids=` attachment lists (OSS-12). */\n idGalleryShortcodes: readonly string[];\n}\n\nexport const WORDPRESS_WIDGET_REGISTRY: WordPressWidgetRegistry = {\n mapShortcodePrefixes: [\n \"blox_gmap\",\n \"tatsu_gmap\",\n \"tatsu_map\",\n \"et_pb_map\",\n \"vc_gmaps\",\n \"vc_map\",\n ],\n contactFormRules: [\n { tag: \"contact-form-7\", source: \"contact-form-7\", idParam: \"id\" },\n { tag: \"contact_form\", source: \"contact-form-7\", idParam: \"id\" },\n { tag: \"gravityform\", source: \"gravityforms\", idParam: \"id\" },\n { tag: \"ninja_form\", source: \"ninja-forms\", idParam: \"id\" },\n { tag: \"wpforms\", source: \"wpforms\", idParam: \"id\" },\n ],\n videoShortcodePrefixes: [\n \"youtube\",\n \"vimeo\",\n \"embed\",\n \"tatsu_video\",\n \"et_pb_video\",\n \"vc_video\",\n ],\n portfolioShortcode: \"portfolio\",\n blogShortcodeTags: [\"blog\", \"recent_posts\"],\n testimonialsWrapperTags: [\"testimonials\"],\n testimonialItemTag: \"testimonial\",\n sliderShortcodeTags: [\"rev_slider\", \"masterslider\"],\n galleryShortcode: \"gallery\",\n idGalleryShortcodes: [\"oshine_gallery\", \"vc_gallery\", \"nggallery\"],\n};\n\n/** Shortcodes that cannot become static HTML — reported in conflicts, never stripped. */\nexport const UNRESOLVABLE_SHORTCODE_PREFIXES = [\n \"woocommerce_cart\",\n \"woocommerce_checkout\",\n \"woocommerce_my_account\",\n] as const;\n\nexport const WORDPRESS_BUILDER_REGISTRY: BuilderThemeConfig[] = [\n {\n id: \"tatsu\",\n detect: /\\[(?:\\/)?tatsu_/i,\n layoutMap: prefixedLayoutMap({\n section: \"tatsu_section\",\n row: \"tatsu_row\",\n column: \"tatsu_column\",\n bgParamName: \"bg_image\",\n colsParamName: \"layout\",\n }),\n wrapperRules: [\n { shortcodePrefix: \"tatsu_text\" },\n { shortcodePrefix: \"tatsu_inline_text\" },\n { shortcodePrefix: \"tatsu_text_with_shortcodes\" },\n { shortcodePrefix: \"tatsu_icon_group\" },\n ],\n urlRules: [\n { shortcodePrefix: \"tatsu_image\", urlParams: [\"image\", \"url\", \"src\"], tag: \"img\" },\n { shortcodePrefix: \"tatsu_single_image\", urlParams: [\"image\", \"url\", \"src\"], tag: \"img\" },\n ],\n iconImageRules: [\n { shortcodePrefix: \"tatsu_icon\", imageParam: \"icon_image\", hrefParam: \"href\" },\n ],\n scaffoldingPrefixes: [\"tatsu_\"],\n },\n {\n id: \"divi\",\n detect: /\\[(?:\\/)?et_pb_/i,\n layoutMap: prefixedLayoutMap({\n section: \"et_pb_section\",\n row: \"et_pb_row\",\n column: \"et_pb_column\",\n bgParamName: \"background_image\",\n }),\n urlRules: [{ shortcodePrefix: \"et_pb_image\", urlParams: [\"src\", \"url\"], tag: \"img\" }],\n scaffoldingPrefixes: [\"et_pb_\"],\n },\n {\n id: \"wpbakery\",\n detect: /\\[(?:\\/)?vc_/i,\n layoutMap: extendedPrefixedLayoutMap([\n { role: \"section\", tokens: [\"vc_section\"], bgParamName: \"bg_image\" },\n { role: \"row\", tokens: [\"vc_row\"], colsParamName: \"layout\" },\n { role: \"column\", tokens: [\"vc_column_inner\", \"vc_column\"], widthParamName: \"width\" },\n ]),\n urlRules: [\n { shortcodePrefix: \"vc_single_image\", urlParams: [\"image\", \"src\", \"url\"], tag: \"img\" },\n ],\n scaffoldingPrefixes: [\"vc_\"],\n },\n {\n id: \"fusion\",\n detect: /\\[(?:\\/)?fusion_/i,\n layoutMap: prefixedLayoutMap({\n section: \"fusion_builder_container\",\n row: \"fusion_builder_row\",\n column: \"fusion_builder_column\",\n bgParamName: \"background_image\",\n }),\n scaffoldingPrefixes: [\"fusion_\"],\n },\n {\n id: \"beaver\",\n detect: /\\[(?:\\/)?fl_(?:row|col|builder)/i,\n layoutMap: extendedPrefixedLayoutMap([\n { role: \"row\", tokens: [\"fl_row\"] },\n { role: \"column\", tokens: [\"fl_col\"] },\n ]),\n scaffoldingPrefixes: [\"fl_\"],\n },\n {\n id: \"elementor\",\n detect: /\\[(?:\\/)?elementor[-_]/i,\n urlRules: [\n { shortcodePrefix: \"elementor-widget\", urlParams: [\"url\", \"src\", \"image\"], tag: \"img\" },\n ],\n scaffoldingPrefixes: [\"elementor_\"],\n },\n {\n id: \"oshine\",\n detect:\n /\\[(?:special_sub_title|special_heading5|blox_\\w+|grid_content|grids|testimonial\\b|portfolio\\b|recent_posts\\b|animate_icon\\w*|section\\b|row\\b|one_col|one_third|one_half|one_fourth|two_third|three_fourth|text\\b)/i,\n layoutMap: fractionalLayoutMap({\n section: \"section\",\n row: \"row\",\n columns: [\n \"one_col\",\n \"one_third\",\n \"two_third\",\n \"two_thirds\",\n \"one_half\",\n \"one_fourth\",\n \"three_fourth\",\n \"three_fourths\",\n ],\n bgParamName: \"bg_image\",\n }),\n layoutMaps: [\n extendedPrefixedLayoutMap([\n { role: \"section\", tokens: [\"blox_row\"], bgParamName: \"bg_image\" },\n { role: \"row\", tokens: [\"blox_row_inner\"], colsParamName: \"columns\" },\n {\n role: \"column\",\n tokens: [\"blox_column_inner\", \"blox_column\"],\n widthParamName: \"width\",\n },\n ]),\n ],\n textRules: [\n {\n shortcodePrefix: \"special_sub_title\",\n fields: [{ param: \"title_content\", tag: \"p\" }],\n },\n {\n shortcodePrefix: \"special_heading5\",\n fields: [\n { param: \"title_content\", tag: \"h2\" },\n { param: \"caption_content\", tag: \"h4\" },\n ],\n },\n ],\n wrapperRules: [\n { shortcodePrefix: \"grid_content\" },\n { shortcodePrefix: \"blox_text\" },\n ],\n urlRules: [\n { shortcodePrefix: \"blox_image\", urlParams: [\"image\", \"img\", \"src\", \"url\"], tag: \"img\" },\n ],\n scaffoldingPrefixes: [\"blox_\", \"animate_icon\"],\n legacyScaffoldingTokens: [\"text\", \"icon\", \"linebreak\", \"grids\", \"testimonials\"],\n },\n];\n\n/** @deprecated Use urlRules on BuilderThemeConfig — kept for type migration clarity. */\nexport type BuilderContentRule = BuilderUrlRule;\n"],"mappings":";;;;;;;;AAAA,YAAY,aAAa;AA0CzB,IAAM,+BACJ;AAEF,SAAS,sBACP,SAC+E;AAC/E,QAAM,cAAc,QAAQ,eAAe,mCAAmC;AAC9E,QAAM,kBAAkB,QAAQ,mBAAmB,QAAQ,QAAQ,WAAW;AAC9E,SAAO,EAAE,aAAa,gBAAgB;AACxC;AAEA,SAAS,cACP,KACA,SACA,oBACA,mBACA,YACoB;AACpB,QAAM,aAAa,kBAAkB,GAAG;AACxC,MAAI,CAAC,WAAY,QAAO;AAExB,MAAI,oBAAoB,UAAU,GAAG;AACnC,sBAAkB,IAAI,UAAU;AAChC,WAAO;AAAA,EACT;AAEA,oBAAkB,IAAI,UAAU;AAChC,QAAM,MAAM,QAAQ,aAAa,UAAU;AAC3C,MAAI,CAAC,KAAK,eAAe;AACvB,eAAW,IAAI,UAAU;AACzB,WAAO;AAAA,EACT;AAEA,QAAM,EAAE,aAAa,gBAAgB,IAAI,sBAAsB,OAAO;AACtE,QAAM,WAAW,mBAAmB,IAAI,IAAI,aAAa;AACzD,MAAI,mBAAmB,CAAC,UAAU;AAChC,eAAW,IAAI,UAAU;AACzB,WAAO;AAAA,EACT;AAEA,SAAO,YAAY,KAAK,QAAQ;AAClC;AAEA,SAAS,6BACP,OACA,SACA,oBACA,mBACA,YACQ;AACR,SAAO,MAAM,QAAQ,8BAA8B,CAAC,MAAM,OAAe,WAAmB;AAC1F,UAAM,WAAW,cAAc,OAAO,KAAK,GAAG,SAAS,oBAAoB,mBAAmB,UAAU;AACxG,QAAI,CAAC,SAAU,QAAO;AAEtB,UAAM,UAAU,QACZ,OAAO,KAAK,GAAG,QAAQ,GAAG,KAAK,MAC/B,OAAO,QAAQ;AACnB,WAAO,KAAK,QAAQ,uCAAuC,OAAO;AAAA,EACpE,CAAC;AACH;AAEA,SAAS,cACP,QACA,SACA,oBACA,mBACA,YACQ;AACR,SAAO,OACJ,MAAM,GAAG,EACT,IAAI,CAAC,UAAU;AACd,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,CAAC,SAAS,UAAU,IAAI,QAAQ,MAAM,OAAO,CAAC;AACpD,UAAM,WAAW,cAAc,WAAW,IAAI,SAAS,oBAAoB,mBAAmB,UAAU;AACxG,QAAI,CAAC,SAAU,QAAO;AACtB,WAAO,aAAa,GAAG,QAAQ,IAAI,UAAU,KAAK;AAAA,EACpD,CAAC,EACA,KAAK,IAAI;AACd;AAGO,SAAS,oBACd,MACA,SACA,oBAC2B;AAC3B,MAAI,CAAC,KAAK,KAAK,GAAG;AAChB,WAAO,EAAE,MAAM,mBAAmB,CAAC,GAAG,YAAY,CAAC,EAAE;AAAA,EACvD;AAEA,QAAM,IAAY,aAAK,MAAM,EAAE,KAAK,MAAM,CAAC;AAC3C,QAAM,oBAAoB,oBAAI,IAAY;AAC1C,QAAM,aAAa,oBAAI,IAAY;AAEnC,IAAE,KAAK,EAAE,KAAK,CAAC,GAAG,YAAY;AAC5B,UAAM,MAAM,EAAE,OAAO;AACrB,UAAM,MAAM,IAAI,KAAK,KAAK,GAAG,KAAK;AAClC,QAAI,OAAO,CAAC,IAAI,WAAW,OAAO,GAAG;AACnC,YAAM,WAAW,cAAc,KAAK,SAAS,oBAAoB,mBAAmB,UAAU;AAC9F,UAAI,SAAU,KAAI,KAAK,OAAO,QAAQ;AAAA,IACxC;AAEA,UAAM,SAAS,IAAI,KAAK,QAAQ,GAAG,KAAK;AACxC,QAAI,QAAQ;AACV,UAAI,KAAK,UAAU,cAAc,QAAQ,SAAS,oBAAoB,mBAAmB,UAAU,CAAC;AAAA,IACtG;AAAA,EACF,CAAC;AAED,IAAE,iBAAiB,EAAE,KAAK,CAAC,GAAG,YAAY;AACxC,UAAM,OAAO,EAAE,OAAO;AACtB,UAAM,UAAU,KAAK,KAAK,eAAe,GAAG,KAAK;AACjD,QAAI,CAAC,WAAW,QAAQ,WAAW,OAAO,EAAG;AAC7C,UAAM,WAAW,cAAc,SAAS,SAAS,oBAAoB,mBAAmB,UAAU;AAClG,QAAI,SAAU,MAAK,KAAK,iBAAiB,QAAQ;AAAA,EACnD,CAAC;AAED,IAAE,SAAS,EAAE,KAAK,CAAC,GAAG,YAAY;AAChC,UAAM,OAAO,EAAE,OAAO;AACtB,UAAM,QAAQ,KAAK,KAAK,OAAO;AAC/B,QAAI,CAAC,OAAO,SAAS,YAAY,EAAG;AACpC,UAAM,YAAY;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,cAAc,MAAO,MAAK,KAAK,SAAS,SAAS;AAAA,EACvD,CAAC;AAED,SAAO;AAAA,IACL,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK;AAAA,IACzB,mBAAmB,CAAC,GAAG,iBAAiB;AAAA,IACxC,YAAY,CAAC,GAAG,UAAU;AAAA,EAC5B;AACF;AAeO,SAAS,wBACd,MACA,SAC2B;AAC3B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,cAAc,CAAC,QAAQ;AACrB,cAAM,gBAAgB;AAAA,UACpB;AAAA,UACA,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV;AACA,YAAI,CAAC,cAAe,QAAO;AAC3B,eAAO,EAAE,aAAa,KAAK,cAAc;AAAA,MAC3C;AAAA,MACA,aAAa,QAAQ;AAAA,MACrB,iBAAiB,QAAQ,mBAAmB;AAAA,IAC9C;AAAA,IACA,oBAAI,IAAI;AAAA,EACV;AACF;;;ACrIA,SAAS,mBAAmB,OAAuB;AACjD,SAAO,MAAM,QAAQ,uBAAuB,MAAM;AACpD;AAEA,SAAS,mBAAmB,OAAuB;AACjD,SAAO,IAAI,OAAO,MAAM,mBAAmB,KAAK,CAAC,mBAAmB,IAAI;AAC1E;AAEA,SAAS,oBAAoB,OAAuB;AAClD,SAAO,IAAI,OAAO,SAAS,mBAAmB,KAAK,CAAC,iBAAiB,IAAI;AAC3E;AAEA,IAAM,2BAAmD;AAAA,EACvD,SAAS;AAAA,EACT,UAAU;AAAA,EACV,WAAW;AAAA,EACX,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,eAAe;AACjB;AAEO,SAAS,2BAA2B,OAAmC;AAC5E,SAAO,yBAAyB,KAAK;AACvC;AAGO,SAAS,kBAAkB,QAMZ;AACpB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,cAAc,mBAAmB,OAAO,OAAO;AAAA,IAC/C,mBAAmB,oBAAoB,OAAO,OAAO;AAAA,IACrD,UAAU,mBAAmB,OAAO,GAAG;AAAA,IACvC,eAAe,oBAAoB,OAAO,GAAG;AAAA,IAC7C,aAAa,mBAAmB,OAAO,MAAM;AAAA,IAC7C,kBAAkB,oBAAoB,OAAO,MAAM;AAAA,IACnD,aAAa,OAAO;AAAA,IACpB,eAAe,OAAO;AAAA,EACxB;AACF;AAIO,SAAS,0BACd,QAC2B;AAC3B,SAAO,EAAE,MAAM,qBAAqB,OAAO;AAC7C;AAEO,SAAS,oBAAoB,QAKZ;AACtB,QAAM,eAAuC,CAAC;AAC9C,aAAW,SAAS,OAAO,SAAS;AAClC,UAAM,QAAQ,2BAA2B,KAAK;AAC9C,QAAI,MAAO,cAAa,KAAK,IAAI;AAAA,EACnC;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,cAAc,mBAAmB,OAAO,OAAO;AAAA,IAC/C,mBAAmB,oBAAoB,OAAO,OAAO;AAAA,IACrD,UAAU,mBAAmB,OAAO,GAAG;AAAA,IACvC,eAAe,oBAAoB,OAAO,GAAG;AAAA,IAC7C,cAAc,OAAO;AAAA,IACrB,mBAAmB,OAAO,QAAQ,IAAI,kBAAkB;AAAA,IACxD,oBAAoB,OAAO,QAAQ,IAAI,mBAAmB;AAAA,IAC1D;AAAA,IACA,aAAa,OAAO;AAAA,EACtB;AACF;AA0BO,IAAM,wBAAwB;AAgC9B,IAAM,4BAAqD;AAAA,EAChE,sBAAsB;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,kBAAkB;AAAA,IAChB,EAAE,KAAK,kBAAkB,QAAQ,kBAAkB,SAAS,KAAK;AAAA,IACjE,EAAE,KAAK,gBAAgB,QAAQ,kBAAkB,SAAS,KAAK;AAAA,IAC/D,EAAE,KAAK,eAAe,QAAQ,gBAAgB,SAAS,KAAK;AAAA,IAC5D,EAAE,KAAK,cAAc,QAAQ,eAAe,SAAS,KAAK;AAAA,IAC1D,EAAE,KAAK,WAAW,QAAQ,WAAW,SAAS,KAAK;AAAA,EACrD;AAAA,EACA,wBAAwB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,oBAAoB;AAAA,EACpB,mBAAmB,CAAC,QAAQ,cAAc;AAAA,EAC1C,yBAAyB,CAAC,cAAc;AAAA,EACxC,oBAAoB;AAAA,EACpB,qBAAqB,CAAC,cAAc,cAAc;AAAA,EAClD,kBAAkB;AAAA,EAClB,qBAAqB,CAAC,kBAAkB,cAAc,WAAW;AACnE;AAGO,IAAM,kCAAkC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,6BAAmD;AAAA,EAC9D;AAAA,IACE,IAAI;AAAA,IACJ,QAAQ;AAAA,IACR,WAAW,kBAAkB;AAAA,MAC3B,SAAS;AAAA,MACT,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,eAAe;AAAA,IACjB,CAAC;AAAA,IACD,cAAc;AAAA,MACZ,EAAE,iBAAiB,aAAa;AAAA,MAChC,EAAE,iBAAiB,oBAAoB;AAAA,MACvC,EAAE,iBAAiB,6BAA6B;AAAA,MAChD,EAAE,iBAAiB,mBAAmB;AAAA,IACxC;AAAA,IACA,UAAU;AAAA,MACR,EAAE,iBAAiB,eAAe,WAAW,CAAC,SAAS,OAAO,KAAK,GAAG,KAAK,MAAM;AAAA,MACjF,EAAE,iBAAiB,sBAAsB,WAAW,CAAC,SAAS,OAAO,KAAK,GAAG,KAAK,MAAM;AAAA,IAC1F;AAAA,IACA,gBAAgB;AAAA,MACd,EAAE,iBAAiB,cAAc,YAAY,cAAc,WAAW,OAAO;AAAA,IAC/E;AAAA,IACA,qBAAqB,CAAC,QAAQ;AAAA,EAChC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,QAAQ;AAAA,IACR,WAAW,kBAAkB;AAAA,MAC3B,SAAS;AAAA,MACT,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,aAAa;AAAA,IACf,CAAC;AAAA,IACD,UAAU,CAAC,EAAE,iBAAiB,eAAe,WAAW,CAAC,OAAO,KAAK,GAAG,KAAK,MAAM,CAAC;AAAA,IACpF,qBAAqB,CAAC,QAAQ;AAAA,EAChC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,QAAQ;AAAA,IACR,WAAW,0BAA0B;AAAA,MACnC,EAAE,MAAM,WAAW,QAAQ,CAAC,YAAY,GAAG,aAAa,WAAW;AAAA,MACnE,EAAE,MAAM,OAAO,QAAQ,CAAC,QAAQ,GAAG,eAAe,SAAS;AAAA,MAC3D,EAAE,MAAM,UAAU,QAAQ,CAAC,mBAAmB,WAAW,GAAG,gBAAgB,QAAQ;AAAA,IACtF,CAAC;AAAA,IACD,UAAU;AAAA,MACR,EAAE,iBAAiB,mBAAmB,WAAW,CAAC,SAAS,OAAO,KAAK,GAAG,KAAK,MAAM;AAAA,IACvF;AAAA,IACA,qBAAqB,CAAC,KAAK;AAAA,EAC7B;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,QAAQ;AAAA,IACR,WAAW,kBAAkB;AAAA,MAC3B,SAAS;AAAA,MACT,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,aAAa;AAAA,IACf,CAAC;AAAA,IACD,qBAAqB,CAAC,SAAS;AAAA,EACjC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,QAAQ;AAAA,IACR,WAAW,0BAA0B;AAAA,MACnC,EAAE,MAAM,OAAO,QAAQ,CAAC,QAAQ,EAAE;AAAA,MAClC,EAAE,MAAM,UAAU,QAAQ,CAAC,QAAQ,EAAE;AAAA,IACvC,CAAC;AAAA,IACD,qBAAqB,CAAC,KAAK;AAAA,EAC7B;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,QAAQ;AAAA,IACR,UAAU;AAAA,MACR,EAAE,iBAAiB,oBAAoB,WAAW,CAAC,OAAO,OAAO,OAAO,GAAG,KAAK,MAAM;AAAA,IACxF;AAAA,IACA,qBAAqB,CAAC,YAAY;AAAA,EACpC;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,QACE;AAAA,IACF,WAAW,oBAAoB;AAAA,MAC7B,SAAS;AAAA,MACT,KAAK;AAAA,MACL,SAAS;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,aAAa;AAAA,IACf,CAAC;AAAA,IACD,YAAY;AAAA,MACV,0BAA0B;AAAA,QACxB,EAAE,MAAM,WAAW,QAAQ,CAAC,UAAU,GAAG,aAAa,WAAW;AAAA,QACjE,EAAE,MAAM,OAAO,QAAQ,CAAC,gBAAgB,GAAG,eAAe,UAAU;AAAA,QACpE;AAAA,UACE,MAAM;AAAA,UACN,QAAQ,CAAC,qBAAqB,aAAa;AAAA,UAC3C,gBAAgB;AAAA,QAClB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,WAAW;AAAA,MACT;AAAA,QACE,iBAAiB;AAAA,QACjB,QAAQ,CAAC,EAAE,OAAO,iBAAiB,KAAK,IAAI,CAAC;AAAA,MAC/C;AAAA,MACA;AAAA,QACE,iBAAiB;AAAA,QACjB,QAAQ;AAAA,UACN,EAAE,OAAO,iBAAiB,KAAK,KAAK;AAAA,UACpC,EAAE,OAAO,mBAAmB,KAAK,KAAK;AAAA,QACxC;AAAA,MACF;AAAA,IACF;AAAA,IACA,cAAc;AAAA,MACZ,EAAE,iBAAiB,eAAe;AAAA,MAClC,EAAE,iBAAiB,YAAY;AAAA,IACjC;AAAA,IACA,UAAU;AAAA,MACR,EAAE,iBAAiB,cAAc,WAAW,CAAC,SAAS,OAAO,OAAO,KAAK,GAAG,KAAK,MAAM;AAAA,IACzF;AAAA,IACA,qBAAqB,CAAC,SAAS,cAAc;AAAA,IAC7C,yBAAyB,CAAC,QAAQ,QAAQ,aAAa,SAAS,cAAc;AAAA,EAChF;AACF;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/normalizer/types.ts","../src/normalizer/idempotency.ts","../src/normalizer/bundle.ts","../src/normalizer/portfolio-media.ts"],"sourcesContent":["export type MigrationPlatform = \"wordpress\" | \"smugmug\" | \"squarespace\" | \"wix\";\n\nexport type EntityType = \"post\" | \"page\" | \"asset\" | \"portfolio\" | \"category\" | \"tag\";\n\nexport type PublishStatus = \"draft\" | \"published\" | \"archived\";\n\nexport interface SourceMetadata {\n platform: MigrationPlatform;\n id: string;\n url?: string;\n path?: string;\n exportedAt?: string;\n /** WordPress `post_type` when the DTO shape differs (e.g. portfolio CPT emitted as `page`). */\n postType?: string;\n}\n\n/** Canonical post DTO — raw HTML; sanitize at host sink. */\nexport interface NormalizedPost {\n type: \"post\";\n source: SourceMetadata;\n sourceId: string;\n title: string;\n slug: string;\n excerpt?: string;\n contentHtml: string;\n publishedAt?: string;\n status: PublishStatus;\n categorySlugs?: string[];\n tagSlugs?: string[];\n /** WordPress attachment id before two-pass resolution. */\n sourceFeaturedMediaId?: string;\n featuredAssetSourceId?: string;\n seoTitle?: string;\n seoDescription?: string;\n}\n\n/** RevSlider / MasterSlider reference from theme hero meta (OSS-27) — alias only, no slide payloads in WXR. */\nexport interface PageHeroSliderHint {\n plugin: \"revslider\" | \"masterslider\";\n alias: string;\n slidertitle?: string;\n source?: \"meta-shortcode\" | \"meta-slider-field\" | \"tatsu-json\";\n}\n\n/** Non-body layout signals for host promotion (theme chrome, hero slots, …). */\nexport interface PageLayoutHints {\n heroSlider?: PageHeroSliderHint;\n}\n\n/** Canonical page DTO — raw HTML snapshot. */\nexport interface NormalizedPage {\n type: \"page\";\n source: SourceMetadata;\n sourceId: string;\n title: string;\n slug: string;\n contentHtml: string;\n contentCss?: string;\n isHomePage?: boolean;\n /** Site portfolio listing shell (distinct from portfolio CPT singles). */\n isPortfolioPage?: boolean;\n layoutHints?: PageLayoutHints;\n status: PublishStatus;\n seoTitle?: string;\n seoDescription?: string;\n}\n\n/** EXIF fields preserved from SmugMug / camera metadata when present. */\nexport interface NormalizedAssetExif {\n iso?: number;\n aperture?: number;\n shutter?: string;\n focalLength?: number;\n}\n\n/** Remote asset to stream into the host sink. */\nexport interface NormalizedAsset {\n type: \"asset\";\n source: SourceMetadata;\n sourceId: string;\n sourceUrl: string;\n filename: string;\n mimeType?: string;\n caption?: string;\n altText?: string;\n keywords?: string[];\n exif?: NormalizedAssetExif;\n portfolioSourceId?: string;\n sort?: number;\n}\n\n/** M2M index: portfolio ↔ asset membership and sort order. */\nexport interface PortfolioMediaLink {\n portfolioSourceId: string;\n assetSourceId: string;\n sort: number;\n}\n\nexport interface NormalizedPortfolio {\n type: \"portfolio\";\n source: SourceMetadata;\n sourceId: string;\n title: string;\n slug: string;\n description?: string;\n parentSourceId?: string;\n}\n\nexport interface NormalizedCategory {\n type: \"category\";\n source: SourceMetadata;\n sourceId: string;\n name: string;\n slug: string;\n}\n\nexport interface NormalizedTag {\n type: \"tag\";\n source: SourceMetadata;\n sourceId: string;\n name: string;\n slug: string;\n}\n\nexport type NormalizedEntity =\n | NormalizedPost\n | NormalizedPage\n | NormalizedAsset\n | NormalizedPortfolio\n | NormalizedCategory\n | NormalizedTag;\n\nexport interface ValidationIssue {\n code: string;\n message: string;\n path?: string;\n}\n\nexport interface ValidationResult {\n ok: boolean;\n issues: ValidationIssue[];\n summary?: {\n posts?: number;\n pages?: number;\n assets?: number;\n portfolios?: number;\n /** WordPress `post_type=portfolio` (and configured CPT slugs) in raw WXR. */\n portfolioCpt?: number;\n categories?: number;\n tags?: number;\n /** WXR rows the parser would emit (OSS-19). */\n importableItemCount?: number;\n unsupportedOnly?: boolean;\n skippedPostTypes?: Record<string, number>;\n };\n}\n\nexport interface WxrImportSummary {\n importableItemCount: number;\n unsupportedOnly: boolean;\n skippedPostTypes: Record<string, number>;\n skippedWooCommerceStubPages?: number;\n}\n\nexport interface AdapterContext {\n input: unknown;\n cursor?: MigrationCursor;\n}\n\nexport interface MigrationAdapter {\n platform: MigrationPlatform;\n validateInput(input: unknown): ValidationResult | Promise<ValidationResult>;\n enumerateEntities(ctx: AdapterContext): AsyncIterable<NormalizedEntity>;\n /** Platform-specific import accounting (e.g. WordPress skipped `post_type`s). */\n getImportSummary?(input: unknown): Promise<WxrImportSummary | undefined>;\n}\n\nexport interface MigrationCursor {\n lastEntityKey?: EntityKey;\n state?: Record<string, unknown>;\n}\n\nexport interface EntityKey {\n platform: MigrationPlatform;\n entityType: EntityType;\n sourceId: string;\n}\n\nexport function entityKey(entity: NormalizedEntity, platform: MigrationPlatform): EntityKey {\n return {\n platform,\n entityType: entity.type,\n sourceId: entity.sourceId,\n };\n}\n","import type { EntityKey, MigrationCursor } from \"./types.js\";\n\n/** Portable entity state for resume / idempotency (not Directus field names). */\nexport type EntityState = \"pending\" | \"done\" | \"failed\" | \"skipped\";\n\nexport interface TrackedEntity extends EntityKey {\n state: EntityState;\n targetId?: string;\n errorMessage?: string;\n}\n\nexport interface MigrationCheckpoint {\n jobId: string;\n cursor: MigrationCursor;\n entities: TrackedEntity[];\n updatedAt: string;\n}\n\nexport function isTerminalState(state: EntityState): boolean {\n return state === \"done\" || state === \"skipped\";\n}\n\nexport function shouldProcessEntity(\n key: EntityKey,\n entities: TrackedEntity[],\n): boolean {\n const existing = entities.find(\n (e) =>\n e.platform === key.platform &&\n e.entityType === key.entityType &&\n e.sourceId === key.sourceId,\n );\n return !existing || !isTerminalState(existing.state);\n}\n","import type {\n NormalizedAsset,\n NormalizedCategory,\n NormalizedEntity,\n NormalizedPage,\n NormalizedPortfolio,\n NormalizedPost,\n NormalizedTag,\n} from \"./types.js\";\n\nexport interface EntityBundle {\n posts: NormalizedPost[];\n pages: NormalizedPage[];\n media: NormalizedAsset[];\n portfolios: NormalizedPortfolio[];\n categories: NormalizedCategory[];\n tags: NormalizedTag[];\n}\n\nexport function emptyBundle(): EntityBundle {\n return {\n posts: [],\n pages: [],\n media: [],\n portfolios: [],\n categories: [],\n tags: [],\n };\n}\n\nexport async function collectEntities(\n entities: AsyncIterable<NormalizedEntity>,\n): Promise<EntityBundle> {\n const bundle = emptyBundle();\n\n for await (const entity of entities) {\n switch (entity.type) {\n case \"post\":\n bundle.posts.push(entity);\n break;\n case \"page\":\n bundle.pages.push(entity);\n break;\n case \"asset\":\n bundle.media.push(entity);\n break;\n case \"portfolio\":\n bundle.portfolios.push(entity);\n break;\n case \"category\":\n bundle.categories.push(entity);\n break;\n case \"tag\":\n bundle.tags.push(entity);\n break;\n default: {\n const _exhaustive: never = entity;\n throw new Error(`Unknown entity type: ${(_exhaustive as NormalizedEntity).type}`);\n }\n }\n }\n\n return bundle;\n}\n\nexport interface BundleCounts {\n posts: number;\n pages: number;\n assets: number;\n portfolios: number;\n categories: number;\n tags: number;\n}\n\nexport function bundleCounts(bundle: EntityBundle): BundleCounts {\n return {\n posts: bundle.posts.length,\n pages: bundle.pages.length,\n assets: bundle.media.length,\n portfolios: bundle.portfolios.length,\n categories: bundle.categories.length,\n tags: bundle.tags.length,\n };\n}\n","import type { EntityBundle } from \"./bundle.js\";\nimport type { PortfolioMediaLink } from \"./types.js\";\n\n/** Derive portfolio↔asset M2M rows from assets carrying `portfolioSourceId`. */\nexport function buildPortfolioMediaLinks(bundle: EntityBundle): PortfolioMediaLink[] {\n const links: PortfolioMediaLink[] = [];\n\n for (const asset of bundle.media) {\n if (!asset.portfolioSourceId) continue;\n links.push({\n portfolioSourceId: asset.portfolioSourceId,\n assetSourceId: asset.sourceId,\n sort: asset.sort ?? 0,\n });\n }\n\n links.sort((a, b) => {\n if (a.portfolioSourceId !== b.portfolioSourceId) {\n return a.portfolioSourceId.localeCompare(b.portfolioSourceId);\n }\n return a.sort - b.sort || a.assetSourceId.localeCompare(b.assetSourceId);\n });\n\n return links;\n}\n"],"mappings":";AA4LO,SAAS,UAAU,QAA0B,UAAwC;AAC1F,SAAO;AAAA,IACL;AAAA,IACA,YAAY,OAAO;AAAA,IACnB,UAAU,OAAO;AAAA,EACnB;AACF;;;AChLO,SAAS,gBAAgB,OAA6B;AAC3D,SAAO,UAAU,UAAU,UAAU;AACvC;AAEO,SAAS,oBACd,KACA,UACS;AACT,QAAM,WAAW,SAAS;AAAA,IACxB,CAAC,MACC,EAAE,aAAa,IAAI,YACnB,EAAE,eAAe,IAAI,cACrB,EAAE,aAAa,IAAI;AAAA,EACvB;AACA,SAAO,CAAC,YAAY,CAAC,gBAAgB,SAAS,KAAK;AACrD;;;ACdO,SAAS,cAA4B;AAC1C,SAAO;AAAA,IACL,OAAO,CAAC;AAAA,IACR,OAAO,CAAC;AAAA,IACR,OAAO,CAAC;AAAA,IACR,YAAY,CAAC;AAAA,IACb,YAAY,CAAC;AAAA,IACb,MAAM,CAAC;AAAA,EACT;AACF;AAEA,eAAsB,gBACpB,UACuB;AACvB,QAAM,SAAS,YAAY;AAE3B,mBAAiB,UAAU,UAAU;AACnC,YAAQ,OAAO,MAAM;AAAA,MACnB,KAAK;AACH,eAAO,MAAM,KAAK,MAAM;AACxB;AAAA,MACF,KAAK;AACH,eAAO,MAAM,KAAK,MAAM;AACxB;AAAA,MACF,KAAK;AACH,eAAO,MAAM,KAAK,MAAM;AACxB;AAAA,MACF,KAAK;AACH,eAAO,WAAW,KAAK,MAAM;AAC7B;AAAA,MACF,KAAK;AACH,eAAO,WAAW,KAAK,MAAM;AAC7B;AAAA,MACF,KAAK;AACH,eAAO,KAAK,KAAK,MAAM;AACvB;AAAA,MACF,SAAS;AACP,cAAM,cAAqB;AAC3B,cAAM,IAAI,MAAM,wBAAyB,YAAiC,IAAI,EAAE;AAAA,MAClF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAWO,SAAS,aAAa,QAAoC;AAC/D,SAAO;AAAA,IACL,OAAO,OAAO,MAAM;AAAA,IACpB,OAAO,OAAO,MAAM;AAAA,IACpB,QAAQ,OAAO,MAAM;AAAA,IACrB,YAAY,OAAO,WAAW;AAAA,IAC9B,YAAY,OAAO,WAAW;AAAA,IAC9B,MAAM,OAAO,KAAK;AAAA,EACpB;AACF;;;AC/EO,SAAS,yBAAyB,QAA4C;AACnF,QAAM,QAA8B,CAAC;AAErC,aAAW,SAAS,OAAO,OAAO;AAChC,QAAI,CAAC,MAAM,kBAAmB;AAC9B,UAAM,KAAK;AAAA,MACT,mBAAmB,MAAM;AAAA,MACzB,eAAe,MAAM;AAAA,MACrB,MAAM,MAAM,QAAQ;AAAA,IACtB,CAAC;AAAA,EACH;AAEA,QAAM,KAAK,CAAC,GAAG,MAAM;AACnB,QAAI,EAAE,sBAAsB,EAAE,mBAAmB;AAC/C,aAAO,EAAE,kBAAkB,cAAc,EAAE,iBAAiB;AAAA,IAC9D;AACA,WAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,cAAc,EAAE,aAAa;AAAA,EACzE,CAAC;AAED,SAAO;AACT;","names":[]}
|