@artinstack/migrator 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,159 @@
1
+ // src/lib/content-asset-urls.ts
2
+ import * as cheerio from "cheerio";
3
+ var IMAGE_EXTENSIONS = "jpe?g|png|gif|webp|avif|svg";
4
+ var IMAGE_EXTENSION_PATTERN = new RegExp(String.raw`\.(?:${IMAGE_EXTENSIONS})\b`, "i");
5
+ var QUOTED_IMAGE_PATH = String.raw`[^"']+\.(?:${IMAGE_EXTENSIONS})(?:\?[^"'#]*)?(?:#.*)?`;
6
+ var SHORTCODE_IMAGE_PARAM_PATTERN = new RegExp(
7
+ String.raw`\b(?:image|bg_image|background_image|url)\s*=\s*["'](${QUOTED_IMAGE_PATH})["']`,
8
+ "gi"
9
+ );
10
+ var BARE_SRC_PARAM_PATTERN = new RegExp(
11
+ String.raw`\bsrc\s*=\s*["'](${QUOTED_IMAGE_PATH})["']`,
12
+ "gi"
13
+ );
14
+ var DATA_BG_IMAGE_PATTERN = /\bdata-bg-image\s*=\s*["']([^"']+)["']/gi;
15
+ var BACKGROUND_IMAGE_URL_PATTERN = /background(?:-image)?\s*:[^;]*?url\s*\(\s*(['"]?)([^'")]+)\1\s*\)/gi;
16
+ var HERO_URL_PARAM_PATTERN = new RegExp(
17
+ String.raw`\b(?:bg_image|background_image)\s*=\s*["'](${QUOTED_IMAGE_PATH})["']`,
18
+ "gi"
19
+ );
20
+ var INLINE_IMAGE_PARAM_PATTERN = new RegExp(
21
+ String.raw`\bimage\s*=\s*["'](${QUOTED_IMAGE_PATH})["']`,
22
+ "gi"
23
+ );
24
+ var IMG_TAG_SRC_PATTERN = /<img\b[^>]*\bsrc\s*=\s*["']([^"']+)["']/gi;
25
+ function ingestLikelyImageUrl(urls, raw) {
26
+ const normalized = normalizeAssetUrl(raw ?? "");
27
+ if (normalized && isLikelyImageUrl(normalized)) {
28
+ urls.add(normalized);
29
+ }
30
+ }
31
+ function extractImgTagSrcs(content) {
32
+ if (!content.trim()) return [];
33
+ const $ = cheerio.load(content, { xml: false });
34
+ const srcs = [];
35
+ $("img[src]").each((_, el) => {
36
+ const src = $(el).attr("src")?.trim();
37
+ if (src) srcs.push(src);
38
+ });
39
+ return srcs;
40
+ }
41
+ function hasImageExtension(value) {
42
+ const withoutHash = value.split("#", 1)[0] ?? value;
43
+ const withoutQuery = withoutHash.split("?", 1)[0] ?? withoutHash;
44
+ return IMAGE_EXTENSION_PATTERN.test(withoutQuery);
45
+ }
46
+ function extractDataBgImageUrls(content) {
47
+ const urls = [];
48
+ for (const match of content.matchAll(DATA_BG_IMAGE_PATTERN)) {
49
+ const raw = match[1]?.trim();
50
+ if (raw) urls.push(raw);
51
+ }
52
+ return urls;
53
+ }
54
+ function extractCssBackgroundImageUrls(content) {
55
+ const urls = [];
56
+ for (const match of content.matchAll(BACKGROUND_IMAGE_URL_PATTERN)) {
57
+ const raw = match[2]?.trim();
58
+ if (raw) urls.push(raw);
59
+ }
60
+ return urls;
61
+ }
62
+ function discoverRawImgSrcs(content) {
63
+ return extractImgTagSrcs(content).filter((src) => !src.startsWith("data:"));
64
+ }
65
+ function normalizeAssetUrl(raw) {
66
+ const trimmed = raw.trim();
67
+ if (!trimmed || trimmed.startsWith("data:")) return void 0;
68
+ if (trimmed.startsWith("//")) return `https:${trimmed}`;
69
+ return trimmed;
70
+ }
71
+ function isLikelyImageUrl(url) {
72
+ if (!url || url.startsWith("data:")) return false;
73
+ if (url.startsWith("/")) {
74
+ return hasImageExtension(url);
75
+ }
76
+ if (!/^https?:\/\//i.test(url)) return false;
77
+ try {
78
+ const { pathname } = new URL(url);
79
+ if (hasImageExtension(pathname)) return true;
80
+ } catch {
81
+ }
82
+ return hasImageExtension(url);
83
+ }
84
+ function pushFeaturedCandidate(candidates, raw, index, tier) {
85
+ const normalized = normalizeAssetUrl(raw ?? "");
86
+ if (!normalized || !isLikelyImageUrl(normalized)) return;
87
+ candidates.push({ url: normalized, index, tier });
88
+ }
89
+ function collectFeaturedAssetCandidates(content) {
90
+ const candidates = [];
91
+ for (const match of content.matchAll(DATA_BG_IMAGE_PATTERN)) {
92
+ pushFeaturedCandidate(candidates, match[1], match.index ?? 0, 0);
93
+ }
94
+ for (const match of content.matchAll(BACKGROUND_IMAGE_URL_PATTERN)) {
95
+ pushFeaturedCandidate(candidates, match[2], match.index ?? 0, 0);
96
+ }
97
+ for (const match of content.matchAll(HERO_URL_PARAM_PATTERN)) {
98
+ pushFeaturedCandidate(candidates, match[1], match.index ?? 0, 0);
99
+ }
100
+ for (const match of content.matchAll(IMG_TAG_SRC_PATTERN)) {
101
+ pushFeaturedCandidate(candidates, match[1], match.index ?? 0, 1);
102
+ }
103
+ for (const match of content.matchAll(INLINE_IMAGE_PARAM_PATTERN)) {
104
+ pushFeaturedCandidate(candidates, match[1], match.index ?? 0, 1);
105
+ }
106
+ return candidates;
107
+ }
108
+ function discoverFeaturedAssetCandidateUrls(content) {
109
+ if (!content.trim()) return [];
110
+ const ranked = [...collectFeaturedAssetCandidates(content)].sort((left, right) => {
111
+ if (left.tier !== right.tier) return left.tier - right.tier;
112
+ return left.index - right.index;
113
+ });
114
+ const urls = [];
115
+ const seen = /* @__PURE__ */ new Set();
116
+ for (const candidate of ranked) {
117
+ if (seen.has(candidate.url)) continue;
118
+ seen.add(candidate.url);
119
+ urls.push(candidate.url);
120
+ }
121
+ return urls;
122
+ }
123
+ function resolveFeaturedContentAssetUrl(content) {
124
+ return discoverFeaturedAssetCandidateUrls(content)[0];
125
+ }
126
+ function discoverContentAssetUrls(content) {
127
+ if (!content.trim()) return [];
128
+ const urls = /* @__PURE__ */ new Set();
129
+ for (const raw of extractImgTagSrcs(content)) {
130
+ ingestLikelyImageUrl(urls, raw);
131
+ }
132
+ for (const match of content.matchAll(SHORTCODE_IMAGE_PARAM_PATTERN)) {
133
+ ingestLikelyImageUrl(urls, match[1]);
134
+ }
135
+ for (const match of content.matchAll(BARE_SRC_PARAM_PATTERN)) {
136
+ ingestLikelyImageUrl(urls, match[1]);
137
+ }
138
+ for (const raw of extractDataBgImageUrls(content)) {
139
+ ingestLikelyImageUrl(urls, raw);
140
+ }
141
+ for (const raw of extractCssBackgroundImageUrls(content)) {
142
+ ingestLikelyImageUrl(urls, raw);
143
+ }
144
+ return [...urls];
145
+ }
146
+ function extractInlineImageSrcs(content) {
147
+ return discoverContentAssetUrls(content);
148
+ }
149
+
150
+ export {
151
+ discoverRawImgSrcs,
152
+ normalizeAssetUrl,
153
+ isLikelyImageUrl,
154
+ discoverFeaturedAssetCandidateUrls,
155
+ resolveFeaturedContentAssetUrl,
156
+ discoverContentAssetUrls,
157
+ extractInlineImageSrcs
158
+ };
159
+ //# sourceMappingURL=chunk-XYP3VYDH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/content-asset-urls.ts"],"sourcesContent":["import * as cheerio from \"cheerio\";\n\nconst IMAGE_EXTENSIONS = \"jpe?g|png|gif|webp|avif|svg\";\n/** Image file extension in a path or URL (allows trailing `?query` / `#hash`). */\nconst IMAGE_EXTENSION_PATTERN = new RegExp(String.raw`\\.(?:${IMAGE_EXTENSIONS})\\b`, \"i\");\n\n/** Captured value must contain an image extension — skips `url=\"…/about\"`, `<iframe src=\"…youtube…\">`, etc. */\nconst QUOTED_IMAGE_PATH = String.raw`[^\"']+\\.(?:${IMAGE_EXTENSIONS})(?:\\?[^\"'#]*)?(?:#.*)?`;\n\nconst SHORTCODE_IMAGE_PARAM_PATTERN = new RegExp(\n String.raw`\\b(?:image|bg_image|background_image|url)\\s*=\\s*[\"'](${QUOTED_IMAGE_PATH})[\"']`,\n \"gi\",\n);\n\n/** Bare `src=\"…jpg\"` outside `<img>` (shortcode fragments); `<img src>` handled by cheerio. */\nconst BARE_SRC_PARAM_PATTERN = new RegExp(\n String.raw`\\bsrc\\s*=\\s*[\"'](${QUOTED_IMAGE_PATH})[\"']`,\n \"gi\",\n);\n\nconst DATA_BG_IMAGE_PATTERN = /\\bdata-bg-image\\s*=\\s*[\"']([^\"']+)[\"']/gi;\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\nconst HERO_URL_PARAM_PATTERN = new RegExp(\n String.raw`\\b(?:bg_image|background_image)\\s*=\\s*[\"'](${QUOTED_IMAGE_PATH})[\"']`,\n \"gi\",\n);\n\nconst INLINE_IMAGE_PARAM_PATTERN = new RegExp(\n String.raw`\\bimage\\s*=\\s*[\"'](${QUOTED_IMAGE_PATH})[\"']`,\n \"gi\",\n);\n\nconst IMG_TAG_SRC_PATTERN = /<img\\b[^>]*\\bsrc\\s*=\\s*[\"']([^\"']+)[\"']/gi;\n\ninterface FeaturedAssetCandidate {\n url: string;\n index: number;\n tier: 0 | 1;\n}\n\nfunction ingestLikelyImageUrl(urls: Set<string>, raw: string | undefined): void {\n const normalized = normalizeAssetUrl(raw ?? \"\");\n if (normalized && isLikelyImageUrl(normalized)) {\n urls.add(normalized);\n }\n}\n\nfunction extractImgTagSrcs(content: string): string[] {\n if (!content.trim()) return [];\n const $ = cheerio.load(content, { xml: false });\n const srcs: string[] = [];\n $(\"img[src]\").each((_, el) => {\n const src = $(el).attr(\"src\")?.trim();\n if (src) srcs.push(src);\n });\n return srcs;\n}\n\nfunction hasImageExtension(value: string): boolean {\n const withoutHash = value.split(\"#\", 1)[0] ?? value;\n const withoutQuery = withoutHash.split(\"?\", 1)[0] ?? withoutHash;\n return IMAGE_EXTENSION_PATTERN.test(withoutQuery);\n}\n\nfunction extractDataBgImageUrls(content: string): string[] {\n const urls: string[] = [];\n for (const match of content.matchAll(DATA_BG_IMAGE_PATTERN)) {\n const raw = match[1]?.trim();\n if (raw) urls.push(raw);\n }\n return urls;\n}\n\nfunction extractCssBackgroundImageUrls(content: string): string[] {\n const urls: string[] = [];\n for (const match of content.matchAll(BACKGROUND_IMAGE_URL_PATTERN)) {\n const raw = match[2]?.trim();\n if (raw) urls.push(raw);\n }\n return urls;\n}\n\n/** All `<img src>` values (including those not ingested as vault assets). */\nexport function discoverRawImgSrcs(content: string): string[] {\n return extractImgTagSrcs(content).filter((src) => !src.startsWith(\"data:\"));\n}\n\n/** Normalize protocol-relative and trim; skip data URIs. */\nexport function normalizeAssetUrl(raw: string): string | undefined {\n const trimmed = raw.trim();\n if (!trimmed || trimmed.startsWith(\"data:\")) return undefined;\n if (trimmed.startsWith(\"//\")) return `https:${trimmed}`;\n return trimmed;\n}\n\n/** Heuristic: URL likely points at a raster/vector image asset, not a page link. */\nexport function isLikelyImageUrl(url: string): boolean {\n if (!url || url.startsWith(\"data:\")) return false;\n\n if (url.startsWith(\"/\")) {\n return hasImageExtension(url);\n }\n\n if (!/^https?:\\/\\//i.test(url)) return false;\n\n try {\n const { pathname } = new URL(url);\n if (hasImageExtension(pathname)) return true;\n } catch {\n // fall through — malformed absolute URL\n }\n\n return hasImageExtension(url);\n}\n\nfunction pushFeaturedCandidate(\n candidates: FeaturedAssetCandidate[],\n raw: string | undefined,\n index: number,\n tier: 0 | 1,\n): void {\n const normalized = normalizeAssetUrl(raw ?? \"\");\n if (!normalized || !isLikelyImageUrl(normalized)) return;\n candidates.push({ url: normalized, index, tier });\n}\n\nfunction collectFeaturedAssetCandidates(content: string): FeaturedAssetCandidate[] {\n const candidates: FeaturedAssetCandidate[] = [];\n\n for (const match of content.matchAll(DATA_BG_IMAGE_PATTERN)) {\n pushFeaturedCandidate(candidates, match[1], match.index ?? 0, 0);\n }\n for (const match of content.matchAll(BACKGROUND_IMAGE_URL_PATTERN)) {\n pushFeaturedCandidate(candidates, match[2], match.index ?? 0, 0);\n }\n for (const match of content.matchAll(HERO_URL_PARAM_PATTERN)) {\n pushFeaturedCandidate(candidates, match[1], match.index ?? 0, 0);\n }\n for (const match of content.matchAll(IMG_TAG_SRC_PATTERN)) {\n pushFeaturedCandidate(candidates, match[1], match.index ?? 0, 1);\n }\n for (const match of content.matchAll(INLINE_IMAGE_PARAM_PATTERN)) {\n pushFeaturedCandidate(candidates, match[1], match.index ?? 0, 1);\n }\n\n return candidates;\n}\n\n/**\n * Ordered featured-image candidates when `_thumbnail_id` is missing — heroes\n * (`data-bg-image`, CSS backgrounds, `bg_image=`) before inline assets; within\n * each tier, first in document order wins. Filename tokens (`_w`, `_2048`, …)\n * are not interpreted as quality signals.\n */\nexport function discoverFeaturedAssetCandidateUrls(content: string): string[] {\n if (!content.trim()) return [];\n\n const ranked = [...collectFeaturedAssetCandidates(content)].sort((left, right) => {\n if (left.tier !== right.tier) return left.tier - right.tier;\n return left.index - right.index;\n });\n\n const urls: string[] = [];\n const seen = new Set<string>();\n for (const candidate of ranked) {\n if (seen.has(candidate.url)) continue;\n seen.add(candidate.url);\n urls.push(candidate.url);\n }\n return urls;\n}\n\n/** Best featured-image URL from post/page HTML when attachment id is unavailable. */\nexport function resolveFeaturedContentAssetUrl(content: string): string | undefined {\n return discoverFeaturedAssetCandidateUrls(content)[0];\n}\n\n/**\n * Generic content-discovery pass: collect image URLs from HTML `<img>` tags,\n * section hero markers (`data-bg-image`), inline CSS backgrounds, and common\n * shortcode/builder attributes (`src=`, `image=`, `bg_image=`, …) without\n * parsing builder-specific structure (Tatsu, Elementor, etc.).\n */\nexport function discoverContentAssetUrls(content: string): string[] {\n if (!content.trim()) return [];\n\n const urls = new Set<string>();\n\n for (const raw of extractImgTagSrcs(content)) {\n ingestLikelyImageUrl(urls, raw);\n }\n\n for (const match of content.matchAll(SHORTCODE_IMAGE_PARAM_PATTERN)) {\n ingestLikelyImageUrl(urls, match[1]);\n }\n\n for (const match of content.matchAll(BARE_SRC_PARAM_PATTERN)) {\n ingestLikelyImageUrl(urls, match[1]);\n }\n\n for (const raw of extractDataBgImageUrls(content)) {\n ingestLikelyImageUrl(urls, raw);\n }\n\n for (const raw of extractCssBackgroundImageUrls(content)) {\n ingestLikelyImageUrl(urls, raw);\n }\n\n return [...urls];\n}\n\n/** @deprecated Use discoverContentAssetUrls — kept for call-site clarity during transition. */\nexport function extractInlineImageSrcs(content: string): string[] {\n return discoverContentAssetUrls(content);\n}\n"],"mappings":"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","names":[]}
package/dist/cli/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  createWpContentGatewayRewrite,
4
4
  getAdapter
5
- } from "../chunk-XUBCG3IA.js";
5
+ } from "../chunk-KF7G7DM6.js";
6
6
  import {
7
7
  analyzeConflicts,
8
8
  buildMigrationReport,
@@ -17,12 +17,12 @@ import {
17
17
  runMigration,
18
18
  staleUrlsFromEstimate,
19
19
  writeFilesystemExport
20
- } from "../chunk-YLFVYPB3.js";
20
+ } from "../chunk-MDSY3FEZ.js";
21
21
  import {
22
22
  collectEntities
23
23
  } from "../chunk-HI7JHWZU.js";
24
- import "../chunk-S7TRWILI.js";
25
- import "../chunk-2PNSVE5Y.js";
24
+ import "../chunk-BOYB6XRA.js";
25
+ import "../chunk-XYP3VYDH.js";
26
26
 
27
27
  // src/cli/index.ts
28
28
  import { writeFile } from "fs/promises";
@@ -0,0 +1,177 @@
1
+ import { z } from 'zod';
2
+ import { l as ValidationResult } from './types-DWOP8Dcy.js';
3
+ import './rewrite-inline-images-Bq16bJA5.js';
4
+
5
+ /**
6
+ * Map normalized upload URLs (and pathnames) → normalizer `sourceId`.
7
+ * Attachment ids are WXR `post_id` strings; inline discoveries use `url:{src}`.
8
+ */
9
+ declare function buildMigrationMediaUrlIndex(entries: Iterable<{
10
+ sourceUrl: string;
11
+ sourceId: string;
12
+ }>): Map<string, string>;
13
+ declare function resolveMigrationMediaSourceId(src: string, urlIndex: Map<string, string>): string | undefined;
14
+
15
+ type LayoutKind = "section" | "row" | "column";
16
+ /** Map OSS-2 `data-layout` markers to Grapes component types (host may override). */
17
+ interface LayoutTypeMap {
18
+ section?: string;
19
+ row?: string;
20
+ column?: string;
21
+ }
22
+ interface HtmlToGrapesOptions {
23
+ /** Map source class names to Grapes component types. */
24
+ componentMap?: Record<string, string>;
25
+ /** Map HTML tag names to Grapes component types (e.g. `h2` → `heading`). */
26
+ tagMap?: Record<string, string>;
27
+ /** Map `data-layout` section/row/column markers to Grapes component types. */
28
+ layoutTypeMap?: LayoutTypeMap;
29
+ }
30
+ interface GrapesStyleRule {
31
+ selectors: string[];
32
+ style: Record<string, string>;
33
+ }
34
+ interface GrapesComponent {
35
+ type: string;
36
+ tagName?: string;
37
+ attributes?: Record<string, string>;
38
+ classes?: string[];
39
+ components?: GrapesComponent[];
40
+ content?: string;
41
+ void?: boolean;
42
+ }
43
+ interface GrapesProjectSnapshot {
44
+ content: GrapesComponent[];
45
+ styles: GrapesStyleRule[];
46
+ contentHtml?: string;
47
+ contentCss?: string;
48
+ }
49
+
50
+ /** Cheerio HTML walk → Grapes `content` + root `styles`. */
51
+ declare function htmlToGrapes(html: string, options?: HtmlToGrapesOptions): GrapesProjectSnapshot;
52
+
53
+ /** ProseMirror / Tiptap mark (inline formatting). */
54
+ interface TiptapMark {
55
+ type: string;
56
+ attrs?: Record<string, string>;
57
+ }
58
+ /** ProseMirror / Tiptap node — text nodes use `text`; others use `content`. */
59
+ interface TiptapNode {
60
+ type: string;
61
+ attrs?: Record<string, unknown>;
62
+ content?: TiptapNode[];
63
+ marks?: TiptapMark[];
64
+ text?: string;
65
+ }
66
+ /** Root Tiptap document (`content_json` shape). */
67
+ interface TiptapDoc {
68
+ type: "doc";
69
+ content: TiptapNode[];
70
+ }
71
+ interface HtmlToTiptapOptions {
72
+ /**
73
+ * Unwrap OSS-2 `data-layout` scaffolding (section/row/column divs) into prose blocks.
74
+ * @default true
75
+ */
76
+ unwrapLayoutMarkers?: boolean;
77
+ }
78
+
79
+ /** Cheerio HTML walk → Tiptap / ProseMirror `doc` JSON for blog `content_json`. */
80
+ declare function htmlToTiptap(html: string, options?: HtmlToTiptapOptions): TiptapDoc;
81
+
82
+ /** Parse `<style>` blocks and class rules into Grapes root `styles[]`. */
83
+ declare function cssToStyles(css: string): GrapesStyleRule[];
84
+
85
+ declare const grapesStyleRuleSchema: z.ZodObject<{
86
+ selectors: z.ZodArray<z.ZodString, "many">;
87
+ style: z.ZodRecord<z.ZodString, z.ZodString>;
88
+ }, "strip", z.ZodTypeAny, {
89
+ style: Record<string, string>;
90
+ selectors: string[];
91
+ }, {
92
+ style: Record<string, string>;
93
+ selectors: string[];
94
+ }>;
95
+ declare const grapesComponentSchema: z.ZodType<GrapesComponent>;
96
+ declare const grapesProjectSnapshotSchema: z.ZodObject<{
97
+ content: z.ZodArray<z.ZodType<GrapesComponent, z.ZodTypeDef, GrapesComponent>, "many">;
98
+ styles: z.ZodArray<z.ZodObject<{
99
+ selectors: z.ZodArray<z.ZodString, "many">;
100
+ style: z.ZodRecord<z.ZodString, z.ZodString>;
101
+ }, "strip", z.ZodTypeAny, {
102
+ style: Record<string, string>;
103
+ selectors: string[];
104
+ }, {
105
+ style: Record<string, string>;
106
+ selectors: string[];
107
+ }>, "many">;
108
+ contentHtml: z.ZodOptional<z.ZodString>;
109
+ contentCss: z.ZodOptional<z.ZodString>;
110
+ }, "strip", z.ZodTypeAny, {
111
+ content: GrapesComponent[];
112
+ styles: {
113
+ style: Record<string, string>;
114
+ selectors: string[];
115
+ }[];
116
+ contentHtml?: string | undefined;
117
+ contentCss?: string | undefined;
118
+ }, {
119
+ content: GrapesComponent[];
120
+ styles: {
121
+ style: Record<string, string>;
122
+ selectors: string[];
123
+ }[];
124
+ contentHtml?: string | undefined;
125
+ contentCss?: string | undefined;
126
+ }>;
127
+ interface ValidateGrapesProjectSnapshotOptions {
128
+ /** When set, every component `type` in the tree must be in this allowlist. */
129
+ allowedComponentTypes?: string[];
130
+ }
131
+ /**
132
+ * Opt-in structural check for a Grapes project snapshot (not a full Grapes editor project file).
133
+ * Does not validate host-specific component registries unless `allowedComponentTypes` is passed.
134
+ */
135
+ declare function validateGrapesProjectSnapshot(snapshot: unknown, options?: ValidateGrapesProjectSnapshotOptions): ValidationResult;
136
+
137
+ declare const tiptapMarkSchema: z.ZodObject<{
138
+ type: z.ZodString;
139
+ attrs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
140
+ }, "strip", z.ZodTypeAny, {
141
+ type: string;
142
+ attrs?: Record<string, string> | undefined;
143
+ }, {
144
+ type: string;
145
+ attrs?: Record<string, string> | undefined;
146
+ }>;
147
+ declare const tiptapNodeSchema: z.ZodType<TiptapNode>;
148
+ declare const tiptapDocSchema: z.ZodObject<{
149
+ type: z.ZodLiteral<"doc">;
150
+ content: z.ZodArray<z.ZodType<TiptapNode, z.ZodTypeDef, TiptapNode>, "many">;
151
+ }, "strip", z.ZodTypeAny, {
152
+ type: "doc";
153
+ content: TiptapNode[];
154
+ }, {
155
+ type: "doc";
156
+ content: TiptapNode[];
157
+ }>;
158
+ interface ValidateTiptapDocOptions {
159
+ /** When set, every node `type` in the tree must be in this allowlist. */
160
+ allowedNodeTypes?: string[];
161
+ /** When set, every mark `type` must be in this allowlist. */
162
+ allowedMarkTypes?: string[];
163
+ }
164
+ /** Opt-in structural check for a Tiptap / ProseMirror document. */
165
+ declare function validateTiptapDoc(doc: unknown, options?: ValidateTiptapDocOptions): ValidationResult;
166
+
167
+ interface ExpandMigrationMediaRefsResult {
168
+ html: string;
169
+ unresolved: string[];
170
+ }
171
+ /**
172
+ * Expand OSS-14 `artinstack-migration://asset/…` refs to host CDN URLs.
173
+ * Lookup (`migration_entities` → `publicUrl`) is host-supplied via `resolvePublicUrl`.
174
+ */
175
+ declare function expandMigrationMediaRefs(html: string, resolvePublicUrl: (sourceId: string) => string | undefined): ExpandMigrationMediaRefsResult;
176
+
177
+ export { type ExpandMigrationMediaRefsResult as E, type GrapesComponent as G, type HtmlToGrapesOptions as H, type LayoutKind as L, type TiptapDoc as T, type ValidateGrapesProjectSnapshotOptions as V, type GrapesProjectSnapshot as a, type GrapesStyleRule as b, type HtmlToTiptapOptions as c, type LayoutTypeMap as d, type TiptapMark as e, type TiptapNode as f, type ValidateTiptapDocOptions as g, buildMigrationMediaUrlIndex as h, cssToStyles as i, expandMigrationMediaRefs as j, grapesComponentSchema as k, grapesProjectSnapshotSchema as l, grapesStyleRuleSchema as m, htmlToGrapes as n, htmlToTiptap as o, tiptapMarkSchema as p, tiptapNodeSchema as q, resolveMigrationMediaSourceId as r, validateTiptapDoc as s, tiptapDocSchema as t, validateGrapesProjectSnapshot as v };
package/dist/index.d.ts CHANGED
@@ -3,9 +3,9 @@ export { A as AdapterContext, E as EntityKey, h as EntityType, i as MigrationCur
3
3
  export { EntityState, MigrationCheckpoint, TrackedEntity, buildPortfolioMediaLinks, isTerminalState, normalizedAssetExifSchema, normalizedAssetSchema, normalizedCategorySchema, normalizedEntitySchema, normalizedPageSchema, normalizedPortfolioSchema, normalizedPostSchema, normalizedTagSchema, shouldProcessEntity, sourceMetadataSchema, validateNormalizedAsset, validateNormalizedCategory, validateNormalizedEntity, validateNormalizedPage, validateNormalizedPortfolio, validateNormalizedPost, validateNormalizedTag } from './normalizer/index.js';
4
4
  export { B as BundleCounts, E as EntityBundle, b as bundleCounts, c as collectEntities, e as emptyBundle } from './bundle-uAAHehbv.js';
5
5
  export { ConflictReport, DryRunOptions, DryRunResult, FALLBACK_ASSET_BYTES, FilesystemMigrationSink, MIGRATION_WRITE_STAGES, MigrationRedirect, MigrationReport, MigrationRunMode, MigrationRunOptions, MigrationRunResult, MigrationSink, MigrationWriteStage, StorageEstimate, UploadAssetInput, UploadAssetResult, WriteFilesystemOptions, analyzeConflicts, buildMigrationReport, buildRedirectMap, bundleToCombinedJson, createFilesystemMigrationSink, detectRedirectLoops, emptyConflictReport, estimateStorage, hasBlockingConflicts, hasWarnings, portfolioMediaMatchesBundle, runDryRun, runMigration, runMigrationFromBundle, staleUrlsFromEstimate, writeFilesystemExport } from './sinks/index.js';
6
- export { R as RewriteInlineImageRef, a as RewriteInlineImagesOptions, b as RewriteInlineImagesResult, U as UploadedAssetRef, r as rewriteInlineImages } from './rewrite-inline-images-BckVKPbh.js';
7
- export { GrapesComponent, GrapesProjectSnapshot, GrapesStyleRule, HtmlToGrapesOptions, HtmlToTiptapOptions, LayoutKind, LayoutTypeMap, TiptapDoc, TiptapMark, TiptapNode, ValidateGrapesProjectSnapshotOptions, ValidateTiptapDocOptions, cssToStyles, grapesComponentSchema, grapesProjectSnapshotSchema, grapesStyleRuleSchema, htmlToGrapes, htmlToTiptap, tiptapDocSchema, tiptapMarkSchema, tiptapNodeSchema, validateGrapesProjectSnapshot, validateTiptapDoc } from './transformers/index.js';
8
- export { discoverContentAssetUrls, discoverRawImgSrcs, extractInlineImageSrcs, isLikelyImageUrl, normalizeAssetUrl } from './lib/index.js';
6
+ export { R as RewriteInlineImageRef, a as RewriteInlineImagesOptions, b as RewriteInlineImagesResult, S as StampMigrationMediaRefsOptions, U as UploadedAssetRef, r as rewriteInlineImages, s as stampMigrationMediaRefs } from './rewrite-inline-images-Bq16bJA5.js';
7
+ export { E as ExpandMigrationMediaRefsResult, G as GrapesComponent, a as GrapesProjectSnapshot, b as GrapesStyleRule, H as HtmlToGrapesOptions, c as HtmlToTiptapOptions, L as LayoutKind, d as LayoutTypeMap, T as TiptapDoc, e as TiptapMark, f as TiptapNode, V as ValidateGrapesProjectSnapshotOptions, g as ValidateTiptapDocOptions, h as buildMigrationMediaUrlIndex, i as cssToStyles, j as expandMigrationMediaRefs, k as grapesComponentSchema, l as grapesProjectSnapshotSchema, m as grapesStyleRuleSchema, n as htmlToGrapes, o as htmlToTiptap, r as resolveMigrationMediaSourceId, t as tiptapDocSchema, p as tiptapMarkSchema, q as tiptapNodeSchema, v as validateGrapesProjectSnapshot, s as validateTiptapDoc } from './index-Dp6nqBqe.js';
8
+ export { discoverContentAssetUrls, discoverFeaturedAssetCandidateUrls, discoverRawImgSrcs, extractInlineImageSrcs, isLikelyImageUrl, normalizeAssetUrl, resolveFeaturedContentAssetUrl } from './lib/index.js';
9
9
  import { z } from 'zod';
10
10
  import 'node:stream';
11
11
 
@@ -521,4 +521,16 @@ declare const wixAdapter: MigrationAdapter;
521
521
 
522
522
  declare function getAdapter(platform: MigrationPlatform): MigrationAdapter;
523
523
 
524
- export { MigrationAdapter, MigrationPlatform, type OriginUrlRewriteConfig, type OriginUrlRewriteRule, SMUGMUG_API_BASE, SMUGMUG_OAUTH_ENDPOINTS, SQUARESPACE_JSON_FORMAT, SmugMugApiClient, type SmugMugClientOptions, type SmugMugCredentials, type SquarespaceClientOptions, type SquarespaceCollectTarget, SquarespaceCollectionClient, WixCollectionClient, WixPageSnapshotCollector, buildJsonPrettyUrl, buildSmugMugAuthorizationHeader, createWpContentGatewayRewrite, getAdapter, mapJsonPrettyWire, readSmugMugCredentialsFromEnv, rewriteOriginUrlsInText, signSmugMugOAuthRequest, smugMugCredentialsSchema, smugmugAdapter, squarespaceAdapter, wixAdapter, wordpressAdapter };
524
+ /** Pseudo-URL scheme for portable migration asset pointers (not WordPress shortcodes). */
525
+ declare const MIGRATION_MEDIA_REF_SCHEME = "artinstack-migration://asset/";
526
+ /** Build `artinstack-migration://asset/{sourceId}` (percent-encodes the normalizer source id). */
527
+ declare function formatMigrationMediaRef(sourceAssetId: string): string;
528
+ declare function isMigrationMediaRef(value: string): boolean;
529
+ /** Parse a migration media ref back to the normalizer `sourceId`, or `undefined` if not a ref. */
530
+ declare function parseMigrationMediaRef(value: string): string | undefined;
531
+ /** Default `replaceWith` for `rewriteInlineImages` / `stampMigrationMediaRefs` (OSS-14). */
532
+ declare function createMigrationMediaRefReplaceWith(): (ref: {
533
+ sourceAssetId?: string;
534
+ }) => string;
535
+
536
+ export { MIGRATION_MEDIA_REF_SCHEME, MigrationAdapter, MigrationPlatform, type OriginUrlRewriteConfig, type OriginUrlRewriteRule, SMUGMUG_API_BASE, SMUGMUG_OAUTH_ENDPOINTS, SQUARESPACE_JSON_FORMAT, SmugMugApiClient, type SmugMugClientOptions, type SmugMugCredentials, type SquarespaceClientOptions, type SquarespaceCollectTarget, SquarespaceCollectionClient, WixCollectionClient, WixPageSnapshotCollector, buildJsonPrettyUrl, buildSmugMugAuthorizationHeader, createMigrationMediaRefReplaceWith, createWpContentGatewayRewrite, formatMigrationMediaRef, getAdapter, isMigrationMediaRef, mapJsonPrettyWire, parseMigrationMediaRef, readSmugMugCredentialsFromEnv, rewriteOriginUrlsInText, signSmugMugOAuthRequest, smugMugCredentialsSchema, smugmugAdapter, squarespaceAdapter, wixAdapter, wordpressAdapter };
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  squarespaceAdapter,
16
16
  wixAdapter,
17
17
  wordpressAdapter
18
- } from "./chunk-XUBCG3IA.js";
18
+ } from "./chunk-KF7G7DM6.js";
19
19
  import {
20
20
  normalizedAssetExifSchema,
21
21
  normalizedAssetSchema,
@@ -58,7 +58,7 @@ import {
58
58
  runMigrationFromBundle,
59
59
  staleUrlsFromEstimate,
60
60
  writeFilesystemExport
61
- } from "./chunk-YLFVYPB3.js";
61
+ } from "./chunk-MDSY3FEZ.js";
62
62
  import {
63
63
  buildPortfolioMediaLinks,
64
64
  bundleCounts,
@@ -70,6 +70,7 @@ import {
70
70
  } from "./chunk-HI7JHWZU.js";
71
71
  import {
72
72
  cssToStyles,
73
+ expandMigrationMediaRefs,
73
74
  grapesComponentSchema,
74
75
  grapesProjectSnapshotSchema,
75
76
  grapesStyleRuleSchema,
@@ -80,20 +81,31 @@ import {
80
81
  tiptapNodeSchema,
81
82
  validateGrapesProjectSnapshot,
82
83
  validateTiptapDoc
83
- } from "./chunk-CIOYDRY5.js";
84
+ } from "./chunk-S4XYG4SM.js";
84
85
  import {
85
- rewriteInlineImages
86
- } from "./chunk-S7TRWILI.js";
86
+ MIGRATION_MEDIA_REF_SCHEME,
87
+ buildMigrationMediaUrlIndex,
88
+ createMigrationMediaRefReplaceWith,
89
+ formatMigrationMediaRef,
90
+ isMigrationMediaRef,
91
+ parseMigrationMediaRef,
92
+ resolveMigrationMediaSourceId,
93
+ rewriteInlineImages,
94
+ stampMigrationMediaRefs
95
+ } from "./chunk-BOYB6XRA.js";
87
96
  import {
88
97
  discoverContentAssetUrls,
98
+ discoverFeaturedAssetCandidateUrls,
89
99
  discoverRawImgSrcs,
90
100
  extractInlineImageSrcs,
91
101
  isLikelyImageUrl,
92
- normalizeAssetUrl
93
- } from "./chunk-2PNSVE5Y.js";
102
+ normalizeAssetUrl,
103
+ resolveFeaturedContentAssetUrl
104
+ } from "./chunk-XYP3VYDH.js";
94
105
  export {
95
106
  FALLBACK_ASSET_BYTES,
96
107
  FilesystemMigrationSink,
108
+ MIGRATION_MEDIA_REF_SCHEME,
97
109
  MIGRATION_WRITE_STAGES,
98
110
  SMUGMUG_API_BASE,
99
111
  SMUGMUG_OAUTH_ENDPOINTS,
@@ -104,6 +116,7 @@ export {
104
116
  WixPageSnapshotCollector,
105
117
  analyzeConflicts,
106
118
  buildJsonPrettyUrl,
119
+ buildMigrationMediaUrlIndex,
107
120
  buildMigrationReport,
108
121
  buildPortfolioMediaLinks,
109
122
  buildRedirectMap,
@@ -112,16 +125,20 @@ export {
112
125
  bundleToCombinedJson,
113
126
  collectEntities,
114
127
  createFilesystemMigrationSink,
128
+ createMigrationMediaRefReplaceWith,
115
129
  createWpContentGatewayRewrite,
116
130
  cssToStyles,
117
131
  detectRedirectLoops,
118
132
  discoverContentAssetUrls,
133
+ discoverFeaturedAssetCandidateUrls,
119
134
  discoverRawImgSrcs,
120
135
  emptyBundle,
121
136
  emptyConflictReport,
122
137
  entityKey,
123
138
  estimateStorage,
139
+ expandMigrationMediaRefs,
124
140
  extractInlineImageSrcs,
141
+ formatMigrationMediaRef,
125
142
  getAdapter,
126
143
  grapesComponentSchema,
127
144
  grapesProjectSnapshotSchema,
@@ -131,6 +148,7 @@ export {
131
148
  htmlToGrapes,
132
149
  htmlToTiptap,
133
150
  isLikelyImageUrl,
151
+ isMigrationMediaRef,
134
152
  isTerminalState,
135
153
  mapJsonPrettyWire,
136
154
  normalizeAssetUrl,
@@ -142,8 +160,11 @@ export {
142
160
  normalizedPortfolioSchema,
143
161
  normalizedPostSchema,
144
162
  normalizedTagSchema,
163
+ parseMigrationMediaRef,
145
164
  portfolioMediaMatchesBundle,
146
165
  readSmugMugCredentialsFromEnv,
166
+ resolveFeaturedContentAssetUrl,
167
+ resolveMigrationMediaSourceId,
147
168
  rewriteInlineImages,
148
169
  rewriteOriginUrlsInText,
149
170
  runDryRun,
@@ -156,6 +177,7 @@ export {
156
177
  sourceMetadataSchema,
157
178
  squarespaceAdapter,
158
179
  staleUrlsFromEstimate,
180
+ stampMigrationMediaRefs,
159
181
  tiptapDocSchema,
160
182
  tiptapMarkSchema,
161
183
  tiptapNodeSchema,
@@ -5,12 +5,22 @@ declare function normalizeAssetUrl(raw: string): string | undefined;
5
5
  /** Heuristic: URL likely points at a raster/vector image asset, not a page link. */
6
6
  declare function isLikelyImageUrl(url: string): boolean;
7
7
  /**
8
- * Generic content-discovery pass: collect image URLs from HTML `<img>` tags and
9
- * common shortcode/builder attributes (`src=`, `image=`, `url=`) without parsing
10
- * builder-specific structure (Tatsu, Elementor, etc.).
8
+ * Ordered featured-image candidates when `_thumbnail_id` is missing heroes
9
+ * (`data-bg-image`, CSS backgrounds, `bg_image=`) before inline assets; within
10
+ * each tier, first in document order wins. Filename tokens (`_w`, `_2048`, )
11
+ * are not interpreted as quality signals.
12
+ */
13
+ declare function discoverFeaturedAssetCandidateUrls(content: string): string[];
14
+ /** Best featured-image URL from post/page HTML when attachment id is unavailable. */
15
+ declare function resolveFeaturedContentAssetUrl(content: string): string | undefined;
16
+ /**
17
+ * Generic content-discovery pass: collect image URLs from HTML `<img>` tags,
18
+ * section hero markers (`data-bg-image`), inline CSS backgrounds, and common
19
+ * shortcode/builder attributes (`src=`, `image=`, `bg_image=`, …) without
20
+ * parsing builder-specific structure (Tatsu, Elementor, etc.).
11
21
  */
12
22
  declare function discoverContentAssetUrls(content: string): string[];
13
23
  /** @deprecated Use discoverContentAssetUrls — kept for call-site clarity during transition. */
14
24
  declare function extractInlineImageSrcs(content: string): string[];
15
25
 
16
- export { discoverContentAssetUrls, discoverRawImgSrcs, extractInlineImageSrcs, isLikelyImageUrl, normalizeAssetUrl };
26
+ export { discoverContentAssetUrls, discoverFeaturedAssetCandidateUrls, discoverRawImgSrcs, extractInlineImageSrcs, isLikelyImageUrl, normalizeAssetUrl, resolveFeaturedContentAssetUrl };
package/dist/lib/index.js CHANGED
@@ -1,15 +1,19 @@
1
1
  import {
2
2
  discoverContentAssetUrls,
3
+ discoverFeaturedAssetCandidateUrls,
3
4
  discoverRawImgSrcs,
4
5
  extractInlineImageSrcs,
5
6
  isLikelyImageUrl,
6
- normalizeAssetUrl
7
- } from "../chunk-2PNSVE5Y.js";
7
+ normalizeAssetUrl,
8
+ resolveFeaturedContentAssetUrl
9
+ } from "../chunk-XYP3VYDH.js";
8
10
  export {
9
11
  discoverContentAssetUrls,
12
+ discoverFeaturedAssetCandidateUrls,
10
13
  discoverRawImgSrcs,
11
14
  extractInlineImageSrcs,
12
15
  isLikelyImageUrl,
13
- normalizeAssetUrl
16
+ normalizeAssetUrl,
17
+ resolveFeaturedContentAssetUrl
14
18
  };
15
19
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,41 @@
1
+ interface RewriteInlineImageRef {
2
+ originalSrc: string;
3
+ sourceAssetId?: string;
4
+ }
5
+ interface UploadedAssetRef {
6
+ targetId: string;
7
+ publicUrl?: string;
8
+ }
9
+ interface RewriteInlineImagesOptions {
10
+ resolveAsset: (src: string) => RewriteInlineImageRef | undefined;
11
+ /**
12
+ * Replace a resolved source id with a migration ref or CDN URL.
13
+ * When omitted, defaults to OSS-14 `artinstack-migration://asset/…` refs.
14
+ */
15
+ replaceWith?: (ref: RewriteInlineImageRef, uploaded?: UploadedAssetRef) => string;
16
+ /**
17
+ * When true, skip URLs that cannot be matched to an uploaded vault target.
18
+ * Default: false when using migration refs; true when a custom `replaceWith` is supplied.
19
+ */
20
+ requireUploaded?: boolean;
21
+ }
22
+ interface RewriteInlineImagesResult {
23
+ html: string;
24
+ referencedSources: string[];
25
+ unresolved: string[];
26
+ }
27
+ /** Rewrite `<img src>` / `srcset`, `data-bg-image`, and inline CSS backgrounds using uploaded asset targets. */
28
+ declare function rewriteInlineImages(html: string, options: RewriteInlineImagesOptions, uploadedBySourceId: Map<string, UploadedAssetRef>): RewriteInlineImagesResult;
29
+ interface StampMigrationMediaRefsOptions {
30
+ /** Pre-built url/pathname → sourceId map (from attachments + inline assets). */
31
+ urlToSourceId: Map<string, string>;
32
+ replaceWith?: RewriteInlineImagesOptions["replaceWith"];
33
+ requireUploaded?: boolean;
34
+ }
35
+ /**
36
+ * OSS-14 — replace resolved `wp-content/uploads` URLs with `artinstack-migration://asset/…`
37
+ * refs. Does not invent refs for unknown URLs (left unchanged + listed in `unresolved`).
38
+ */
39
+ declare function stampMigrationMediaRefs(html: string, options: StampMigrationMediaRefsOptions): RewriteInlineImagesResult;
40
+
41
+ export { type RewriteInlineImageRef as R, type StampMigrationMediaRefsOptions as S, type UploadedAssetRef as U, type RewriteInlineImagesOptions as a, type RewriteInlineImagesResult as b, rewriteInlineImages as r, stampMigrationMediaRefs as s };
@@ -1,7 +1,7 @@
1
1
  import { d as NormalizedCategory, e as NormalizedTag, b as NormalizedAsset, c as NormalizedPortfolio, N as NormalizedPost, a as NormalizedPage, P as PortfolioMediaLink, E as EntityKey, f as NormalizedEntity, g as MigrationPlatform, M as MigrationAdapter } from '../types-DWOP8Dcy.js';
2
2
  import { Readable } from 'node:stream';
3
- import { a as RewriteInlineImagesOptions } from '../rewrite-inline-images-BckVKPbh.js';
4
- export { b as RewriteInlineImagesResult, r as rewriteInlineImages } from '../rewrite-inline-images-BckVKPbh.js';
3
+ import { a as RewriteInlineImagesOptions } from '../rewrite-inline-images-Bq16bJA5.js';
4
+ export { b as RewriteInlineImagesResult, r as rewriteInlineImages } from '../rewrite-inline-images-Bq16bJA5.js';
5
5
  import { E as EntityBundle } from '../bundle-uAAHehbv.js';
6
6
 
7
7
  interface CreatePostResult {
@@ -18,12 +18,12 @@ import {
18
18
  runMigrationFromBundle,
19
19
  staleUrlsFromEstimate,
20
20
  writeFilesystemExport
21
- } from "../chunk-YLFVYPB3.js";
21
+ } from "../chunk-MDSY3FEZ.js";
22
22
  import "../chunk-HI7JHWZU.js";
23
23
  import {
24
24
  rewriteInlineImages
25
- } from "../chunk-S7TRWILI.js";
26
- import "../chunk-2PNSVE5Y.js";
25
+ } from "../chunk-BOYB6XRA.js";
26
+ import "../chunk-XYP3VYDH.js";
27
27
  export {
28
28
  FALLBACK_ASSET_BYTES,
29
29
  FilesystemMigrationSink,