@artinstack/migrator 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lib/index.js CHANGED
@@ -1,19 +1,48 @@
1
+ import "../chunk-EJTWYEAX.js";
1
2
  import {
3
+ linkToPath,
4
+ sanitizeSlug
5
+ } from "../chunk-XRCF73DA.js";
6
+ import {
7
+ MIGRATION_MEDIA_REF_SCHEME,
8
+ buildContentMediaUrlIndex,
9
+ buildMigrationMediaUrlIndex,
10
+ canonicalizeInlineAssetUrl,
11
+ createMigrationMediaRefReplaceWith,
12
+ createWpContentGatewayRewrite,
2
13
  discoverContentAssetUrls,
3
14
  discoverFeaturedAssetCandidateUrls,
4
15
  discoverRawImgSrcs,
5
16
  extractInlineImageSrcs,
17
+ formatMigrationMediaRef,
6
18
  isLikelyImageUrl,
19
+ isMigrationMediaRef,
7
20
  normalizeAssetUrl,
8
- resolveFeaturedContentAssetUrl
9
- } from "../chunk-XYP3VYDH.js";
21
+ parseMigrationMediaRef,
22
+ resolveFeaturedContentAssetUrl,
23
+ resolveMigrationMediaSourceId,
24
+ rewriteOriginUrlsInText
25
+ } from "../chunk-WHGUE5FC.js";
10
26
  export {
27
+ MIGRATION_MEDIA_REF_SCHEME,
28
+ buildContentMediaUrlIndex,
29
+ buildMigrationMediaUrlIndex,
30
+ canonicalizeInlineAssetUrl,
31
+ createMigrationMediaRefReplaceWith,
32
+ createWpContentGatewayRewrite,
11
33
  discoverContentAssetUrls,
12
34
  discoverFeaturedAssetCandidateUrls,
13
35
  discoverRawImgSrcs,
14
36
  extractInlineImageSrcs,
37
+ formatMigrationMediaRef,
15
38
  isLikelyImageUrl,
39
+ isMigrationMediaRef,
40
+ linkToPath,
16
41
  normalizeAssetUrl,
17
- resolveFeaturedContentAssetUrl
42
+ parseMigrationMediaRef,
43
+ resolveFeaturedContentAssetUrl,
44
+ resolveMigrationMediaSourceId,
45
+ rewriteOriginUrlsInText,
46
+ sanitizeSlug
18
47
  };
19
48
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,74 @@
1
+ interface OriginUrlRewriteRule {
2
+ /** Literal substring or regex matched against the full text block. */
3
+ match: string | RegExp;
4
+ replace: string;
5
+ }
6
+ interface OriginUrlRewriteConfig {
7
+ rules: OriginUrlRewriteRule[];
8
+ }
9
+ /** Swap legacy gateway/staging host fragments before parse, fetch, or asset discovery. */
10
+ declare function rewriteOriginUrlsInText(text: string, config: OriginUrlRewriteConfig): string;
11
+ /** Build a rule that rewrites API-gateway `/prod/wp-content/` paths to a public origin. */
12
+ declare function createWpContentGatewayRewrite(gatewayBase: string, publicOrigin: string): OriginUrlRewriteConfig;
13
+ /** All `<img src>` values (including those not ingested as vault assets). */
14
+ declare function discoverRawImgSrcs(content: string): string[];
15
+ /** Normalize protocol-relative and trim; skip data URIs. */
16
+ declare function normalizeAssetUrl(raw: string): string | undefined;
17
+ /** Heuristic: URL likely points at a raster/vector image asset, not a page link. */
18
+ declare function isLikelyImageUrl(url: string): boolean;
19
+ /**
20
+ * Ordered featured-image candidates when `_thumbnail_id` is missing — heroes
21
+ * (`data-bg-image`, CSS backgrounds, `bg_image=`) before inline assets; within
22
+ * each tier, first in document order wins. Filename tokens (`_w`, `_2048`, …)
23
+ * are not interpreted as quality signals.
24
+ */
25
+ declare function discoverFeaturedAssetCandidateUrls(content: string): string[];
26
+ /** Best featured-image URL from post/page HTML when attachment id is unavailable. */
27
+ declare function resolveFeaturedContentAssetUrl(content: string): string | undefined;
28
+ /**
29
+ * Generic content-discovery pass: collect image URLs from HTML `<img>` tags,
30
+ * section hero markers (`data-bg-image`), inline CSS backgrounds, and common
31
+ * shortcode/builder attributes (`src=`, `image=`, `bg_image=`, …) without
32
+ * parsing builder-specific structure (Tatsu, Elementor, etc.).
33
+ */
34
+ declare function discoverContentAssetUrls(content: string): string[];
35
+ /** @deprecated Use discoverContentAssetUrls — kept for call-site clarity during transition. */
36
+ declare function extractInlineImageSrcs(content: string): string[];
37
+ /** Pseudo-URL scheme for portable migration asset pointers (not WordPress shortcodes). */
38
+ declare const MIGRATION_MEDIA_REF_SCHEME = "artinstack-migration://asset/";
39
+ /** Build `artinstack-migration://asset/{sourceId}` (percent-encodes the normalizer source id). */
40
+ declare function formatMigrationMediaRef(sourceAssetId: string): string;
41
+ declare function isMigrationMediaRef(value: string): boolean;
42
+ /** Parse a migration media ref back to the normalizer `sourceId`, or `undefined` if not a ref. */
43
+ declare function parseMigrationMediaRef(value: string): string | undefined;
44
+ /** Default `replaceWith` for `rewriteInlineImages` / `stampMigrationMediaRefs` (OSS-14). */
45
+ declare function createMigrationMediaRefReplaceWith(): (ref: {
46
+ sourceAssetId?: string;
47
+ }) => string;
48
+ interface CanonicalInlineAssetUrl {
49
+ /** Canonical absolute URL stored on `NormalizedAsset.sourceUrl`. */
50
+ canonicalUrl: string;
51
+ /** Normalizer id: `url:{canonicalUrl}`. */
52
+ sourceId: string;
53
+ }
54
+ /**
55
+ * OSS-15: one canonical key for inline `url:` assets — apply origin rewrite then
56
+ * `normalizeAssetUrl` so discovery, refs, and vault entities share the same id.
57
+ */
58
+ declare function canonicalizeInlineAssetUrl(raw: string, originUrlRewrite?: OriginUrlRewriteConfig): CanonicalInlineAssetUrl | undefined;
59
+ /**
60
+ * Map normalized upload URLs (and pathnames) → normalizer `sourceId`.
61
+ * Attachment ids are WXR `post_id` strings; inline discoveries use `url:{src}`.
62
+ */
63
+ declare function buildMigrationMediaUrlIndex(entries: Iterable<{
64
+ sourceUrl: string;
65
+ sourceId: string;
66
+ }>): Map<string, string>;
67
+ declare function resolveMigrationMediaSourceId(src: string, urlIndex: Map<string, string>, originUrlRewrite?: OriginUrlRewriteConfig): string | undefined;
68
+ /** Merge attachment + inline asset rows into one stamp/lookup index (OSS-15). */
69
+ declare function buildContentMediaUrlIndex(entries: Iterable<{
70
+ sourceUrl: string;
71
+ sourceId: string;
72
+ }>, originUrlRewrite?: OriginUrlRewriteConfig): Map<string, string>;
73
+
74
+ export { type CanonicalInlineAssetUrl as C, MIGRATION_MEDIA_REF_SCHEME as M, type OriginUrlRewriteConfig as O, type OriginUrlRewriteRule as a, buildContentMediaUrlIndex as b, buildMigrationMediaUrlIndex as c, canonicalizeInlineAssetUrl as d, createMigrationMediaRefReplaceWith as e, createWpContentGatewayRewrite as f, discoverContentAssetUrls as g, discoverFeaturedAssetCandidateUrls as h, discoverRawImgSrcs as i, extractInlineImageSrcs as j, formatMigrationMediaRef as k, isLikelyImageUrl as l, isMigrationMediaRef as m, normalizeAssetUrl as n, resolveMigrationMediaSourceId as o, parseMigrationMediaRef as p, rewriteOriginUrlsInText as q, resolveFeaturedContentAssetUrl as r };
@@ -1,3 +1,5 @@
1
+ import { O as OriginUrlRewriteConfig } from './media-urls-w46-CWUp.js';
2
+
1
3
  interface RewriteInlineImageRef {
2
4
  originalSrc: string;
3
5
  sourceAssetId?: string;
@@ -29,6 +31,8 @@ declare function rewriteInlineImages(html: string, options: RewriteInlineImagesO
29
31
  interface StampMigrationMediaRefsOptions {
30
32
  /** Pre-built url/pathname → sourceId map (from attachments + inline assets). */
31
33
  urlToSourceId: Map<string, string>;
34
+ /** Canonicalize lookup keys during stamp (OSS-15). */
35
+ originUrlRewrite?: OriginUrlRewriteConfig;
32
36
  replaceWith?: RewriteInlineImagesOptions["replaceWith"];
33
37
  requireUploaded?: boolean;
34
38
  }
@@ -1,8 +1,9 @@
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-Bq16bJA5.js';
4
- export { b as RewriteInlineImagesResult, r as rewriteInlineImages } from '../rewrite-inline-images-Bq16bJA5.js';
3
+ import { a as RewriteInlineImagesOptions } from '../rewrite-inline-images-DyxKUNs3.js';
4
+ export { b as RewriteInlineImagesResult, r as rewriteInlineImages } from '../rewrite-inline-images-DyxKUNs3.js';
5
5
  import { E as EntityBundle } from '../bundle-uAAHehbv.js';
6
+ import '../media-urls-w46-CWUp.js';
6
7
 
7
8
  interface CreatePostResult {
8
9
  targetId: string;
@@ -18,12 +18,13 @@ import {
18
18
  runMigrationFromBundle,
19
19
  staleUrlsFromEstimate,
20
20
  writeFilesystemExport
21
- } from "../chunk-MDSY3FEZ.js";
21
+ } from "../chunk-Z3L6N63Y.js";
22
22
  import "../chunk-HI7JHWZU.js";
23
23
  import {
24
24
  rewriteInlineImages
25
- } from "../chunk-BOYB6XRA.js";
26
- import "../chunk-XYP3VYDH.js";
25
+ } from "../chunk-KYNKJ4XV.js";
26
+ import "../chunk-XRCF73DA.js";
27
+ import "../chunk-WHGUE5FC.js";
27
28
  export {
28
29
  FALLBACK_ASSET_BYTES,
29
30
  FilesystemMigrationSink,
@@ -1,4 +1,170 @@
1
- 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, t as tiptapDocSchema, p as tiptapMarkSchema, q as tiptapNodeSchema, v as validateGrapesProjectSnapshot, s as validateTiptapDoc } from '../index-Dp6nqBqe.js';
2
- 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';
3
- import 'zod';
4
- import '../types-DWOP8Dcy.js';
1
+ import { z } from 'zod';
2
+ import { l as ValidationResult } from '../types-DWOP8Dcy.js';
3
+ 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-DyxKUNs3.js';
4
+ export { c as buildMigrationMediaUrlIndex } from '../media-urls-w46-CWUp.js';
5
+
6
+ type LayoutKind = "section" | "row" | "column";
7
+ /** Map OSS-2 `data-layout` markers to Grapes component types (host may override). */
8
+ interface LayoutTypeMap {
9
+ section?: string;
10
+ row?: string;
11
+ column?: string;
12
+ }
13
+ interface HtmlToGrapesOptions {
14
+ /** Map source class names to Grapes component types. */
15
+ componentMap?: Record<string, string>;
16
+ /** Map HTML tag names to Grapes component types (e.g. `h2` → `heading`). */
17
+ tagMap?: Record<string, string>;
18
+ /** Map `data-layout` section/row/column markers to Grapes component types. */
19
+ layoutTypeMap?: LayoutTypeMap;
20
+ /** Grapes type for OSS-12 `data-wp-widget` markers. Default: `wp-widget`. */
21
+ widgetComponentType?: string;
22
+ }
23
+ interface GrapesStyleRule {
24
+ selectors: string[];
25
+ style: Record<string, string>;
26
+ }
27
+ interface GrapesComponent {
28
+ type: string;
29
+ tagName?: string;
30
+ attributes?: Record<string, string>;
31
+ classes?: string[];
32
+ components?: GrapesComponent[];
33
+ content?: string;
34
+ void?: boolean;
35
+ }
36
+ interface GrapesProjectSnapshot {
37
+ content: GrapesComponent[];
38
+ styles: GrapesStyleRule[];
39
+ contentHtml?: string;
40
+ contentCss?: string;
41
+ }
42
+
43
+ /** Cheerio HTML walk → Grapes `content` + root `styles`. */
44
+ declare function htmlToGrapes(html: string, options?: HtmlToGrapesOptions): GrapesProjectSnapshot;
45
+
46
+ /** ProseMirror / Tiptap mark (inline formatting). */
47
+ interface TiptapMark {
48
+ type: string;
49
+ attrs?: Record<string, string>;
50
+ }
51
+ /** ProseMirror / Tiptap node — text nodes use `text`; others use `content`. */
52
+ interface TiptapNode {
53
+ type: string;
54
+ attrs?: Record<string, unknown>;
55
+ content?: TiptapNode[];
56
+ marks?: TiptapMark[];
57
+ text?: string;
58
+ }
59
+ /** Root Tiptap document (`content_json` shape). */
60
+ interface TiptapDoc {
61
+ type: "doc";
62
+ content: TiptapNode[];
63
+ }
64
+ interface HtmlToTiptapOptions {
65
+ /**
66
+ * Unwrap OSS-2 `data-layout` scaffolding (section/row/column divs) into prose blocks.
67
+ * @default true
68
+ */
69
+ unwrapLayoutMarkers?: boolean;
70
+ }
71
+
72
+ /** Cheerio HTML walk → Tiptap / ProseMirror `doc` JSON for blog `content_json`. */
73
+ declare function htmlToTiptap(html: string, options?: HtmlToTiptapOptions): TiptapDoc;
74
+
75
+ /** Parse `<style>` blocks and class rules into Grapes root `styles[]`. */
76
+ declare function cssToStyles(css: string): GrapesStyleRule[];
77
+
78
+ declare const grapesStyleRuleSchema: z.ZodObject<{
79
+ selectors: z.ZodArray<z.ZodString, "many">;
80
+ style: z.ZodRecord<z.ZodString, z.ZodString>;
81
+ }, "strip", z.ZodTypeAny, {
82
+ style: Record<string, string>;
83
+ selectors: string[];
84
+ }, {
85
+ style: Record<string, string>;
86
+ selectors: string[];
87
+ }>;
88
+ declare const grapesComponentSchema: z.ZodType<GrapesComponent>;
89
+ declare const grapesProjectSnapshotSchema: z.ZodObject<{
90
+ content: z.ZodArray<z.ZodType<GrapesComponent, z.ZodTypeDef, GrapesComponent>, "many">;
91
+ styles: z.ZodArray<z.ZodObject<{
92
+ selectors: z.ZodArray<z.ZodString, "many">;
93
+ style: z.ZodRecord<z.ZodString, z.ZodString>;
94
+ }, "strip", z.ZodTypeAny, {
95
+ style: Record<string, string>;
96
+ selectors: string[];
97
+ }, {
98
+ style: Record<string, string>;
99
+ selectors: string[];
100
+ }>, "many">;
101
+ contentHtml: z.ZodOptional<z.ZodString>;
102
+ contentCss: z.ZodOptional<z.ZodString>;
103
+ }, "strip", z.ZodTypeAny, {
104
+ content: GrapesComponent[];
105
+ styles: {
106
+ style: Record<string, string>;
107
+ selectors: string[];
108
+ }[];
109
+ contentHtml?: string | undefined;
110
+ contentCss?: string | undefined;
111
+ }, {
112
+ content: GrapesComponent[];
113
+ styles: {
114
+ style: Record<string, string>;
115
+ selectors: string[];
116
+ }[];
117
+ contentHtml?: string | undefined;
118
+ contentCss?: string | undefined;
119
+ }>;
120
+ interface ValidateGrapesProjectSnapshotOptions {
121
+ /** When set, every component `type` in the tree must be in this allowlist. */
122
+ allowedComponentTypes?: string[];
123
+ }
124
+ /**
125
+ * Opt-in structural check for a Grapes project snapshot (not a full Grapes editor project file).
126
+ * Does not validate host-specific component registries unless `allowedComponentTypes` is passed.
127
+ */
128
+ declare function validateGrapesProjectSnapshot(snapshot: unknown, options?: ValidateGrapesProjectSnapshotOptions): ValidationResult;
129
+
130
+ declare const tiptapMarkSchema: z.ZodObject<{
131
+ type: z.ZodString;
132
+ attrs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
133
+ }, "strip", z.ZodTypeAny, {
134
+ type: string;
135
+ attrs?: Record<string, string> | undefined;
136
+ }, {
137
+ type: string;
138
+ attrs?: Record<string, string> | undefined;
139
+ }>;
140
+ declare const tiptapNodeSchema: z.ZodType<TiptapNode>;
141
+ declare const tiptapDocSchema: z.ZodObject<{
142
+ type: z.ZodLiteral<"doc">;
143
+ content: z.ZodArray<z.ZodType<TiptapNode, z.ZodTypeDef, TiptapNode>, "many">;
144
+ }, "strip", z.ZodTypeAny, {
145
+ type: "doc";
146
+ content: TiptapNode[];
147
+ }, {
148
+ type: "doc";
149
+ content: TiptapNode[];
150
+ }>;
151
+ interface ValidateTiptapDocOptions {
152
+ /** When set, every node `type` in the tree must be in this allowlist. */
153
+ allowedNodeTypes?: string[];
154
+ /** When set, every mark `type` must be in this allowlist. */
155
+ allowedMarkTypes?: string[];
156
+ }
157
+ /** Opt-in structural check for a Tiptap / ProseMirror document. */
158
+ declare function validateTiptapDoc(doc: unknown, options?: ValidateTiptapDocOptions): ValidationResult;
159
+
160
+ interface ExpandMigrationMediaRefsResult {
161
+ html: string;
162
+ unresolved: string[];
163
+ }
164
+ /**
165
+ * Expand OSS-14 `artinstack-migration://asset/…` refs to host CDN URLs.
166
+ * Lookup (`migration_entities` → `publicUrl`) is host-supplied via `resolvePublicUrl`.
167
+ */
168
+ declare function expandMigrationMediaRefs(html: string, resolvePublicUrl: (sourceId: string) => string | undefined): ExpandMigrationMediaRefsResult;
169
+
170
+ export { type ExpandMigrationMediaRefsResult, type GrapesComponent, type GrapesProjectSnapshot, type GrapesStyleRule, type HtmlToGrapesOptions, type HtmlToTiptapOptions, type LayoutKind, type LayoutTypeMap, type TiptapDoc, type TiptapMark, type TiptapNode, type ValidateGrapesProjectSnapshotOptions, type ValidateTiptapDocOptions, cssToStyles, expandMigrationMediaRefs, grapesComponentSchema, grapesProjectSnapshotSchema, grapesStyleRuleSchema, htmlToGrapes, htmlToTiptap, tiptapDocSchema, tiptapMarkSchema, tiptapNodeSchema, validateGrapesProjectSnapshot, validateTiptapDoc };
@@ -11,13 +11,14 @@ import {
11
11
  tiptapNodeSchema,
12
12
  validateGrapesProjectSnapshot,
13
13
  validateTiptapDoc
14
- } from "../chunk-S4XYG4SM.js";
14
+ } from "../chunk-ALLFBWBO.js";
15
15
  import {
16
- buildMigrationMediaUrlIndex,
17
16
  rewriteInlineImages,
18
17
  stampMigrationMediaRefs
19
- } from "../chunk-BOYB6XRA.js";
20
- import "../chunk-XYP3VYDH.js";
18
+ } from "../chunk-KYNKJ4XV.js";
19
+ import {
20
+ buildMigrationMediaUrlIndex
21
+ } from "../chunk-WHGUE5FC.js";
21
22
  export {
22
23
  buildMigrationMediaUrlIndex,
23
24
  cssToStyles,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@artinstack/migrator",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Stateless content normalizer and migration framework — WordPress, SmugMug, Squarespace → platform-agnostic schema",
5
5
  "license": "MIT",
6
6
  "author": "ArtInStack",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/lib/migration-media-ref.ts","../src/lib/migration-media-url-index.ts","../src/transformers/rewrite-inline-images.ts"],"sourcesContent":["/** Pseudo-URL scheme for portable migration asset pointers (not WordPress shortcodes). */\nexport const MIGRATION_MEDIA_REF_SCHEME = \"artinstack-migration://asset/\";\n\n/** Build `artinstack-migration://asset/{sourceId}` (percent-encodes the normalizer source id). */\nexport function formatMigrationMediaRef(sourceAssetId: string): string {\n return `${MIGRATION_MEDIA_REF_SCHEME}${encodeURIComponent(sourceAssetId)}`;\n}\n\nexport function isMigrationMediaRef(value: string): boolean {\n return value.trim().startsWith(MIGRATION_MEDIA_REF_SCHEME);\n}\n\n/** Parse a migration media ref back to the normalizer `sourceId`, or `undefined` if not a ref. */\nexport function parseMigrationMediaRef(value: string): string | undefined {\n const trimmed = value.trim();\n if (!trimmed.startsWith(MIGRATION_MEDIA_REF_SCHEME)) return undefined;\n const encoded = trimmed.slice(MIGRATION_MEDIA_REF_SCHEME.length);\n if (!encoded) return undefined;\n try {\n return decodeURIComponent(encoded);\n } catch {\n return undefined;\n }\n}\n\n/** Default `replaceWith` for `rewriteInlineImages` / `stampMigrationMediaRefs` (OSS-14). */\nexport function createMigrationMediaRefReplaceWith(): (\n ref: { sourceAssetId?: string },\n) => string {\n return (ref) => {\n if (!ref.sourceAssetId) return \"\";\n return formatMigrationMediaRef(ref.sourceAssetId);\n };\n}\n","import { normalizeAssetUrl } from \"./content-asset-urls.js\";\n\nfunction urlPathname(url: string): string | undefined {\n try {\n return new URL(url, \"http://migration.local\").pathname;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Map normalized upload URLs (and pathnames) → normalizer `sourceId`.\n * Attachment ids are WXR `post_id` strings; inline discoveries use `url:{src}`.\n */\nexport function buildMigrationMediaUrlIndex(\n entries: Iterable<{ sourceUrl: string; sourceId: string }>,\n): Map<string, string> {\n const index = new Map<string, string>();\n\n for (const entry of entries) {\n index.set(entry.sourceUrl, entry.sourceId);\n const normalized = normalizeAssetUrl(entry.sourceUrl);\n if (normalized) index.set(normalized, entry.sourceId);\n const pathname = urlPathname(entry.sourceUrl);\n if (pathname) index.set(pathname, entry.sourceId);\n }\n\n return index;\n}\n\nexport function resolveMigrationMediaSourceId(\n src: string,\n urlIndex: Map<string, string>,\n): string | undefined {\n const normalized = normalizeAssetUrl(src);\n if (!normalized) return undefined;\n\n return (\n urlIndex.get(normalized) ??\n urlIndex.get(src) ??\n (urlPathname(normalized) ? urlIndex.get(urlPathname(normalized)!) : undefined)\n );\n}\n","import * as cheerio from \"cheerio\";\n\nimport { normalizeAssetUrl } from \"../lib/content-asset-urls.js\";\nimport {\n createMigrationMediaRefReplaceWith,\n isMigrationMediaRef,\n} from \"../lib/migration-media-ref.js\";\nimport {\n buildMigrationMediaUrlIndex,\n resolveMigrationMediaSourceId,\n} from \"../lib/migration-media-url-index.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 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(src, options.urlToSourceId);\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"],"mappings":"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","names":[]}