@artinstack/migrator 0.1.6 → 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.
package/README.md CHANGED
@@ -15,7 +15,8 @@ src/
15
15
  normalizer/ Canonical DTOs + portable idempotency types
16
16
  sinks/ filesystem export, MigrationSink interface
17
17
  cli/ artinstack-migrate
18
- transformers/ HtmlToGrapes, css-to-styles, rewrite-inline-images
18
+ transformers/ HtmlToGrapes, css-to-styles, inline image rewrite, media ref expand
19
+ lib/ content-asset-urls, migration-media-ref, origin-url-rewrite
19
20
  ```
20
21
 
21
22
  ## Install
@@ -114,6 +115,31 @@ Each file contains an array of normalized DTOs (`NormalizedPost`, `NormalizedPag
114
115
 
115
116
  Per-platform export file formats and API client usage are documented in [docs/architecture.md](./docs/architecture.md).
116
117
 
118
+ ## Migration media refs
119
+
120
+ WordPress `contentHtml` is stamped with `artinstack-migration://asset/…` refs by default (not CDN URLs). Rationale, ref format, and OSS/host split: [docs/architecture.md § Migration media refs](./docs/architecture.md#migration-media-refs).
121
+
122
+ **Host — expand refs before persist** (`htmlToGrapes`, hero promotion, sink write):
123
+
124
+ ```ts
125
+ import {
126
+ expandMigrationMediaRefs,
127
+ formatMigrationMediaRef,
128
+ isMigrationMediaRef,
129
+ parseMigrationMediaRef,
130
+ rewriteInlineImages,
131
+ stampMigrationMediaRefs,
132
+ } from "@artinstack/migrator";
133
+
134
+ const { html, unresolved } = expandMigrationMediaRefs(contentHtml, (sourceId) =>
135
+ lookupPublicUrl(sourceId), // migration_entities → CDN
136
+ );
137
+ ```
138
+
139
+ **CLI / JSON export:** use `--rewrite-gateway` + `--rewrite-public` so gateway uploads normalize before refs are stamped. Unresolved upload URLs stay in HTML and appear in `conflicts.json` as `unresolvedInlineImages`.
140
+
141
+ **Tests:** `fixtures/wordpress/pages-export.test.ts` (naikonpixels pages WXR).
142
+
117
143
  ## Development
118
144
 
119
145
  ```bash
@@ -129,6 +155,8 @@ pnpm dev # watch build
129
155
  |-------|------------------------|------------------|
130
156
  | Parsers + normalizer DTOs | Yes | No |
131
157
  | WordPress builder flattening + origin URL rewrite (pre-DTO) | Yes | Optional same config on adapter input |
158
+ | Stamp `artinstack-migration://asset/…` refs in content HTML | Yes | No |
159
+ | Expand refs → CDN URLs at persist | Exported helper | Call site + DB lookup |
132
160
  | CLI + filesystem JSON export | Yes | No |
133
161
  | `MigrationSink` interface | Yes | Implementation |
134
162
  | Dynamic shortcodes (`[portfolio]`, `[recent_posts]`), forms, sanitize | No | Yes |
@@ -2,24 +2,85 @@ import {
2
2
  normalizeAssetUrl
3
3
  } from "./chunk-XYP3VYDH.js";
4
4
 
5
+ // src/lib/migration-media-ref.ts
6
+ var MIGRATION_MEDIA_REF_SCHEME = "artinstack-migration://asset/";
7
+ function formatMigrationMediaRef(sourceAssetId) {
8
+ return `${MIGRATION_MEDIA_REF_SCHEME}${encodeURIComponent(sourceAssetId)}`;
9
+ }
10
+ function isMigrationMediaRef(value) {
11
+ return value.trim().startsWith(MIGRATION_MEDIA_REF_SCHEME);
12
+ }
13
+ function parseMigrationMediaRef(value) {
14
+ const trimmed = value.trim();
15
+ if (!trimmed.startsWith(MIGRATION_MEDIA_REF_SCHEME)) return void 0;
16
+ const encoded = trimmed.slice(MIGRATION_MEDIA_REF_SCHEME.length);
17
+ if (!encoded) return void 0;
18
+ try {
19
+ return decodeURIComponent(encoded);
20
+ } catch {
21
+ return void 0;
22
+ }
23
+ }
24
+ function createMigrationMediaRefReplaceWith() {
25
+ return (ref) => {
26
+ if (!ref.sourceAssetId) return "";
27
+ return formatMigrationMediaRef(ref.sourceAssetId);
28
+ };
29
+ }
30
+
31
+ // src/lib/migration-media-url-index.ts
32
+ function urlPathname(url) {
33
+ try {
34
+ return new URL(url, "http://migration.local").pathname;
35
+ } catch {
36
+ return void 0;
37
+ }
38
+ }
39
+ function buildMigrationMediaUrlIndex(entries) {
40
+ const index = /* @__PURE__ */ new Map();
41
+ for (const entry of entries) {
42
+ index.set(entry.sourceUrl, entry.sourceId);
43
+ const normalized = normalizeAssetUrl(entry.sourceUrl);
44
+ if (normalized) index.set(normalized, entry.sourceId);
45
+ const pathname = urlPathname(entry.sourceUrl);
46
+ if (pathname) index.set(pathname, entry.sourceId);
47
+ }
48
+ return index;
49
+ }
50
+ function resolveMigrationMediaSourceId(src, urlIndex) {
51
+ const normalized = normalizeAssetUrl(src);
52
+ if (!normalized) return void 0;
53
+ return urlIndex.get(normalized) ?? urlIndex.get(src) ?? (urlPathname(normalized) ? urlIndex.get(urlPathname(normalized)) : void 0);
54
+ }
55
+
5
56
  // src/transformers/rewrite-inline-images.ts
6
57
  import * as cheerio from "cheerio";
7
58
  var BACKGROUND_IMAGE_URL_PATTERN = /background(?:-image)?\s*:[^;]*?url\s*\(\s*(['"]?)([^'")]+)\1\s*\)/gi;
59
+ function resolveRewriteOptions(options) {
60
+ const replaceWith = options.replaceWith ?? createMigrationMediaRefReplaceWith();
61
+ const requireUploaded = options.requireUploaded ?? Boolean(options.replaceWith);
62
+ return { replaceWith, requireUploaded };
63
+ }
8
64
  function tryRewriteUrl(src, options, uploadedBySourceId, referencedSources, unresolved) {
9
65
  const normalized = normalizeAssetUrl(src);
10
66
  if (!normalized) return void 0;
67
+ if (isMigrationMediaRef(normalized)) {
68
+ referencedSources.add(normalized);
69
+ return normalized;
70
+ }
11
71
  referencedSources.add(normalized);
12
72
  const ref = options.resolveAsset(normalized);
13
73
  if (!ref?.sourceAssetId) {
14
74
  unresolved.add(normalized);
15
75
  return void 0;
16
76
  }
77
+ const { replaceWith, requireUploaded } = resolveRewriteOptions(options);
17
78
  const uploaded = uploadedBySourceId.get(ref.sourceAssetId);
18
- if (!uploaded) {
79
+ if (requireUploaded && !uploaded) {
19
80
  unresolved.add(normalized);
20
81
  return void 0;
21
82
  }
22
- return options.replaceWith(ref, uploaded);
83
+ return replaceWith(ref, uploaded);
23
84
  }
24
85
  function rewriteBackgroundUrlsInStyle(style, options, uploadedBySourceId, referencedSources, unresolved) {
25
86
  return style.replace(BACKGROUND_IMAGE_URL_PATTERN, (full, quote, rawUrl) => {
@@ -84,8 +145,31 @@ function rewriteInlineImages(html, options, uploadedBySourceId) {
84
145
  unresolved: [...unresolved]
85
146
  };
86
147
  }
148
+ function stampMigrationMediaRefs(html, options) {
149
+ return rewriteInlineImages(
150
+ html,
151
+ {
152
+ resolveAsset: (src) => {
153
+ const sourceAssetId = resolveMigrationMediaSourceId(src, options.urlToSourceId);
154
+ if (!sourceAssetId) return void 0;
155
+ return { originalSrc: src, sourceAssetId };
156
+ },
157
+ replaceWith: options.replaceWith,
158
+ requireUploaded: options.requireUploaded ?? false
159
+ },
160
+ /* @__PURE__ */ new Map()
161
+ );
162
+ }
87
163
 
88
164
  export {
89
- rewriteInlineImages
165
+ MIGRATION_MEDIA_REF_SCHEME,
166
+ formatMigrationMediaRef,
167
+ isMigrationMediaRef,
168
+ parseMigrationMediaRef,
169
+ createMigrationMediaRefReplaceWith,
170
+ buildMigrationMediaUrlIndex,
171
+ resolveMigrationMediaSourceId,
172
+ rewriteInlineImages,
173
+ stampMigrationMediaRefs
90
174
  };
91
- //# sourceMappingURL=chunk-EXYXTAZM.js.map
175
+ //# sourceMappingURL=chunk-BOYB6XRA.js.map
@@ -0,0 +1 @@
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":[]}
@@ -6,7 +6,11 @@ import {
6
6
  sanitizeSlug,
7
7
  summarizeSquarespaceExport,
8
8
  validateSquarespaceExportFile
9
- } from "./chunk-IPYHS5R2.js";
9
+ } from "./chunk-MDSY3FEZ.js";
10
+ import {
11
+ buildMigrationMediaUrlIndex,
12
+ stampMigrationMediaRefs
13
+ } from "./chunk-BOYB6XRA.js";
10
14
  import {
11
15
  discoverContentAssetUrls,
12
16
  normalizeAssetUrl,
@@ -553,6 +557,12 @@ async function* enumerateWxrEntities(options) {
553
557
  const { categories, tags } = collectTaxonomies(items);
554
558
  const seenAssetUrls = /* @__PURE__ */ new Set();
555
559
  const emittedAttachmentIds = /* @__PURE__ */ new Set();
560
+ const attachmentUrlIndex = buildMigrationMediaUrlIndex(
561
+ [...attachmentIndex.entries()].map(([sourceId, entry]) => ({
562
+ sourceId,
563
+ sourceUrl: entry.sourceUrl
564
+ }))
565
+ );
556
566
  for (const category of categories.values()) {
557
567
  yield category;
558
568
  }
@@ -578,18 +588,28 @@ async function* enumerateWxrEntities(options) {
578
588
  const id = textValue(item.post_id);
579
589
  const link = maybeRewriteUrl(textValue(item.link), options.originUrlRewrite);
580
590
  const slug = sanitizeSlug(textValue(item.post_name) || textValue(item.title) || id);
581
- const contentHtml = preprocessContent(getContentEncoded(item), options);
591
+ let contentHtml = preprocessContent(getContentEncoded(item), options);
582
592
  if (postType === "page" && options.skipWooCommerceStubPages !== false && isWooCommerceStubPage(slug, contentHtml)) {
583
593
  continue;
584
594
  }
585
- for (const asset of collectInlineAssets(
595
+ const inlineAssets = collectInlineAssets(
586
596
  contentHtml,
587
597
  attachmentIndex,
588
598
  seenAssetUrls,
589
599
  options.exportedAt
590
- )) {
600
+ );
601
+ for (const asset of inlineAssets) {
591
602
  yield asset;
592
603
  }
604
+ if (options.stampMigrationMediaRefs !== false) {
605
+ const urlIndex = new Map(attachmentUrlIndex);
606
+ for (const asset of inlineAssets) {
607
+ urlIndex.set(asset.sourceUrl, asset.sourceId);
608
+ const normalized = normalizeAssetUrl(asset.sourceUrl);
609
+ if (normalized) urlIndex.set(normalized, asset.sourceId);
610
+ }
611
+ contentHtml = stampMigrationMediaRefs(contentHtml, { urlToSourceId: urlIndex }).html;
612
+ }
593
613
  const categorySlugs = [];
594
614
  const tagSlugs = [];
595
615
  for (const cat of asArray(item.category)) {
@@ -2677,4 +2697,4 @@ export {
2677
2697
  wixAdapter,
2678
2698
  getAdapter
2679
2699
  };
2680
- //# sourceMappingURL=chunk-XQVKA54A.js.map
2700
+ //# sourceMappingURL=chunk-KF7G7DM6.js.map