@artinstack/migrator 0.1.7 → 0.1.9

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.
Files changed (41) hide show
  1. package/README.md +2 -1
  2. package/dist/{bundle-uAAHehbv.d.ts → bundle-B3XS20r_.d.ts} +1 -1
  3. package/dist/{chunk-BOYB6XRA.js → chunk-BONZ3U3I.js} +11 -62
  4. package/dist/chunk-BONZ3U3I.js.map +1 -0
  5. package/dist/chunk-EJTWYEAX.js +1 -0
  6. package/dist/chunk-EJTWYEAX.js.map +1 -0
  7. package/dist/{chunk-KF7G7DM6.js → chunk-FB3MMCHY.js} +315 -84
  8. package/dist/chunk-FB3MMCHY.js.map +1 -0
  9. package/dist/{chunk-HI7JHWZU.js → chunk-KTQGOM45.js} +1 -1
  10. package/dist/chunk-KTQGOM45.js.map +1 -0
  11. package/dist/{chunk-MDSY3FEZ.js → chunk-PPT5RIZ4.js} +83 -39
  12. package/dist/chunk-PPT5RIZ4.js.map +1 -0
  13. package/dist/{chunk-XYP3VYDH.js → chunk-S4GMDRGX.js} +149 -6
  14. package/dist/chunk-S4GMDRGX.js.map +1 -0
  15. package/dist/{chunk-S4XYG4SM.js → chunk-S4SUJT2D.js} +36 -2
  16. package/dist/chunk-S4SUJT2D.js.map +1 -0
  17. package/dist/chunk-XRCF73DA.js +24 -0
  18. package/dist/chunk-XRCF73DA.js.map +1 -0
  19. package/dist/cli/index.js +8 -6
  20. package/dist/cli/index.js.map +1 -1
  21. package/dist/index.d.ts +9 -33
  22. package/dist/index.js +31 -16
  23. package/dist/lib/index.d.ts +7 -25
  24. package/dist/lib/index.js +34 -3
  25. package/dist/media-urls-u49RCyPn.d.ts +88 -0
  26. package/dist/normalizer/index.d.ts +4 -4
  27. package/dist/normalizer/index.js +1 -1
  28. package/dist/{rewrite-inline-images-Bq16bJA5.d.ts → rewrite-inline-images-BsgSquzV.d.ts} +4 -0
  29. package/dist/sinks/index.d.ts +21 -5
  30. package/dist/sinks/index.js +7 -4
  31. package/dist/transformers/index.d.ts +170 -4
  32. package/dist/transformers/index.js +5 -4
  33. package/dist/{types-DWOP8Dcy.d.ts → types-Ce4r6zqt.d.ts} +4 -0
  34. package/package.json +1 -1
  35. package/dist/chunk-BOYB6XRA.js.map +0 -1
  36. package/dist/chunk-HI7JHWZU.js.map +0 -1
  37. package/dist/chunk-KF7G7DM6.js.map +0 -1
  38. package/dist/chunk-MDSY3FEZ.js.map +0 -1
  39. package/dist/chunk-S4XYG4SM.js.map +0 -1
  40. package/dist/chunk-XYP3VYDH.js.map +0 -1
  41. package/dist/index-Dp6nqBqe.d.ts +0 -177
@@ -1,48 +1,29 @@
1
1
  import {
2
2
  SquarespaceCollectionClient,
3
3
  WORDPRESS_BUILDER_REGISTRY,
4
+ WORDPRESS_WIDGET_REGISTRY,
5
+ WP_WIDGET_PLACEHOLDER,
4
6
  enumerateSquarespaceEntities,
5
- linkToPath,
6
- sanitizeSlug,
7
7
  summarizeSquarespaceExport,
8
8
  validateSquarespaceExportFile
9
- } from "./chunk-MDSY3FEZ.js";
9
+ } from "./chunk-PPT5RIZ4.js";
10
10
  import {
11
- buildMigrationMediaUrlIndex,
12
11
  stampMigrationMediaRefs
13
- } from "./chunk-BOYB6XRA.js";
12
+ } from "./chunk-BONZ3U3I.js";
13
+ import {
14
+ linkToPath,
15
+ sanitizeSlug
16
+ } from "./chunk-XRCF73DA.js";
14
17
  import {
18
+ buildContentMediaUrlIndex,
19
+ canonicalizeInlineAssetUrl,
15
20
  discoverContentAssetUrls,
21
+ discoverContentAssets,
16
22
  normalizeAssetUrl,
17
- resolveFeaturedContentAssetUrl
18
- } from "./chunk-XYP3VYDH.js";
19
-
20
- // src/lib/origin-url-rewrite.ts
21
- function rewriteOriginUrlsInText(text, config) {
22
- if (!text || config.rules.length === 0) return text;
23
- let result = text;
24
- for (const rule of config.rules) {
25
- if (typeof rule.match === "string") {
26
- if (!rule.match) continue;
27
- result = result.split(rule.match).join(rule.replace);
28
- continue;
29
- }
30
- result = result.replace(rule.match, rule.replace);
31
- }
32
- return result;
33
- }
34
- function createWpContentGatewayRewrite(gatewayBase, publicOrigin) {
35
- const normalizedGateway = gatewayBase.replace(/\/$/, "");
36
- const normalizedPublic = publicOrigin.replace(/\/$/, "");
37
- return {
38
- rules: [
39
- {
40
- match: `${normalizedGateway}/wp-content/`,
41
- replace: `${normalizedPublic}/wp-content/`
42
- }
43
- ]
44
- };
45
- }
23
+ parseMigrationMediaRef,
24
+ resolveFeaturedContentAssetUrl,
25
+ rewriteOriginUrlsInText
26
+ } from "./chunk-S4GMDRGX.js";
46
27
 
47
28
  // src/parsers/wordpress/parse-wxr.ts
48
29
  import { readFile } from "fs/promises";
@@ -316,16 +297,221 @@ function stripLegacyTokens(content, tokens) {
316
297
  function detectThemes(content, registry) {
317
298
  return registry.filter((theme) => theme.detect.test(content));
318
299
  }
300
+ function extractBareOrQuotedParam(params, name) {
301
+ const quoted = extractQuotedParam(params, name);
302
+ if (quoted) return quoted;
303
+ const pattern = new RegExp(`\\b${escapeRegExp(name)}\\s*=\\s*([^\\s"'\\]]+)`, "i");
304
+ const match = pattern.exec(params);
305
+ return match?.[1]?.trim() || void 0;
306
+ }
307
+ function emitWidgetStub(widget, attrs, tag = "div") {
308
+ const parts = [`data-wp-widget="${escapeLayoutAttr(widget)}"`];
309
+ for (const [key, value] of Object.entries(attrs)) {
310
+ if (value) parts.push(`${key}="${escapeLayoutAttr(value)}"`);
311
+ }
312
+ return `<${tag} ${parts.join(" ")}>${WP_WIDGET_PLACEHOLDER}</${tag}>`;
313
+ }
314
+ function normalizeVideoEmbedUrl(raw) {
315
+ const trimmed = raw.trim();
316
+ if (!trimmed || trimmed.startsWith("data:")) return void 0;
317
+ try {
318
+ const url = new URL(trimmed.startsWith("//") ? `https:${trimmed}` : trimmed);
319
+ const host = url.hostname.replace(/^www\./, "").replace(/^m\./, "");
320
+ if (host === "youtu.be") {
321
+ const id = url.pathname.split("/").filter(Boolean)[0];
322
+ if (id) {
323
+ return { provider: "youtube", embedUrl: `https://www.youtube-nocookie.com/embed/${id}` };
324
+ }
325
+ }
326
+ if (host === "youtube.com" || host === "youtube-nocookie.com") {
327
+ const embedMatch = url.pathname.match(/\/embed\/([^/?#]+)/);
328
+ if (embedMatch?.[1]) {
329
+ const start = url.searchParams.get("start");
330
+ const suffix = start ? `?start=${start}` : "";
331
+ return {
332
+ provider: "youtube",
333
+ embedUrl: `https://www.youtube-nocookie.com/embed/${embedMatch[1]}${suffix}`
334
+ };
335
+ }
336
+ const videoId = url.searchParams.get("v");
337
+ if (videoId) {
338
+ const t = url.searchParams.get("t") ?? url.searchParams.get("start");
339
+ const startSeconds = t?.endsWith("s") ? t.slice(0, -1) : t;
340
+ const suffix = startSeconds ? `?start=${startSeconds}` : "";
341
+ return {
342
+ provider: "youtube",
343
+ embedUrl: `https://www.youtube-nocookie.com/embed/${videoId}${suffix}`
344
+ };
345
+ }
346
+ }
347
+ if (host === "vimeo.com") {
348
+ const segments = url.pathname.split("/").filter(Boolean);
349
+ const id = segments[segments.length - 1];
350
+ if (id && /^\d+$/.test(id)) {
351
+ return { provider: "vimeo", embedUrl: `https://player.vimeo.com/video/${id}` };
352
+ }
353
+ }
354
+ if (host === "player.vimeo.com") {
355
+ const match = url.pathname.match(/\/video\/(\d+)/);
356
+ if (match?.[1]) {
357
+ return { provider: "vimeo", embedUrl: `https://player.vimeo.com/video/${match[1]}` };
358
+ }
359
+ }
360
+ } catch {
361
+ return void 0;
362
+ }
363
+ return void 0;
364
+ }
365
+ function emitVideoWidgetFromParams(params, inner) {
366
+ const url = extractShortcodeParam(params, ["url", "src", "video", "link", "youtube_url", "vimeo_url"]) ?? inner.trim().match(/^https?:\/\/\S+/)?.[0];
367
+ if (!url) {
368
+ return emitWidgetStub("video", { "data-video-provider": "external" });
369
+ }
370
+ const normalized = normalizeVideoEmbedUrl(url);
371
+ if (normalized) {
372
+ return emitWidgetStub("video", {
373
+ "data-video-provider": normalized.provider,
374
+ "data-embed-url": normalized.embedUrl
375
+ });
376
+ }
377
+ if (/\.(mp4|webm|ogg)(\?|#|$)/i.test(url)) {
378
+ return emitHtmlTag("video", url);
379
+ }
380
+ return emitWidgetStub("video", {
381
+ "data-video-provider": "external",
382
+ "data-embed-url": url
383
+ });
384
+ }
385
+ function flattenMapShortcodes(content, widgetRegistry) {
386
+ let html = content;
387
+ for (const prefix of widgetRegistry.mapShortcodePrefixes) {
388
+ const pattern = new RegExp(
389
+ `\\[${escapeRegExp(prefix)}\\b([^\\]]*)\\]\\s*(?:\\[\\/${escapeRegExp(prefix)}\\b[^\\]]*\\])?`,
390
+ "gi"
391
+ );
392
+ html = html.replace(pattern, (_, params) => {
393
+ const embedUrl = extractShortcodeParam(params, ["embed_url", "url", "src", "map_url"]);
394
+ const query = extractBareOrQuotedParam(params, "address") ?? extractBareOrQuotedParam(params, "q");
395
+ return emitWidgetStub("map", {
396
+ ...embedUrl?.includes("google.com/maps") ? { "data-embed-url": embedUrl } : {},
397
+ ...query && !embedUrl ? { "data-wp-map-query": query } : {}
398
+ });
399
+ });
400
+ }
401
+ return html;
402
+ }
403
+ function flattenContactFormShortcodes(content, widgetRegistry) {
404
+ let html = content;
405
+ for (const rule of widgetRegistry.contactFormRules) {
406
+ const pattern = new RegExp(
407
+ `\\[${escapeRegExp(rule.tag)}\\b([^\\]]*)\\]\\s*(?:\\[\\/${escapeRegExp(rule.tag)}\\b[^\\]]*\\])?`,
408
+ "gi"
409
+ );
410
+ html = html.replace(pattern, (_, params) => {
411
+ const id = extractBareOrQuotedParam(params, rule.idParam);
412
+ return emitWidgetStub(
413
+ "contact-form",
414
+ {
415
+ "data-wp-form-source": rule.source,
416
+ ...id ? { "data-wp-form-id": id } : {}
417
+ },
418
+ "section"
419
+ );
420
+ });
421
+ }
422
+ return html;
423
+ }
424
+ function emitInlineGalleryFromIds(idList) {
425
+ const images = idList.map((id) => `<img data-wp-attachment-id="${escapeLayoutAttr(id)}" alt="" />`).join("");
426
+ return `<figure data-wp-inline-gallery>${images}</figure>`;
427
+ }
428
+ function parseGalleryAttachmentIds(params) {
429
+ const ids = extractBareOrQuotedParam(params, "ids");
430
+ const idList = ids?.split(",").map((part) => part.trim()).filter((part) => /^\d+$/.test(part));
431
+ return idList?.length ? idList : void 0;
432
+ }
433
+ function flattenIdGalleryShortcode(content, tag) {
434
+ const escaped = escapeRegExp(tag);
435
+ const pattern = new RegExp(`\\[${escaped}\\b([^\\]]*)\\](?:\\s*\\[\\/${escaped}\\])?`, "gi");
436
+ return content.replace(pattern, (fullMatch, params) => {
437
+ const idList = parseGalleryAttachmentIds(params);
438
+ if (idList?.length) {
439
+ return emitInlineGalleryFromIds(idList);
440
+ }
441
+ return fullMatch;
442
+ });
443
+ }
444
+ function flattenGalleryShortcodes(content, widgetRegistry) {
445
+ const tag = escapeRegExp(widgetRegistry.galleryShortcode);
446
+ const pattern = new RegExp(`\\[${tag}\\b([^\\]]*)\\](?:\\s*\\[\\/${tag}\\])?`, "gi");
447
+ return content.replace(pattern, (_, params) => {
448
+ const idList = parseGalleryAttachmentIds(params);
449
+ if (idList?.length) {
450
+ return emitInlineGalleryFromIds(idList);
451
+ }
452
+ const category = extractBareOrQuotedParam(params, "category") ?? extractBareOrQuotedParam(params, "type");
453
+ return emitWidgetStub("portfolio", {
454
+ "data-wp-gallery-dynamic": "1",
455
+ ...category ? { "data-wp-portfolio-category": category } : {}
456
+ });
457
+ });
458
+ }
459
+ function flattenIdBasedGalleryShortcodes(content, widgetRegistry) {
460
+ let html = content;
461
+ for (const tag of widgetRegistry.idGalleryShortcodes) {
462
+ html = flattenIdGalleryShortcode(html, tag);
463
+ }
464
+ return html;
465
+ }
466
+ function flattenPortfolioShortcodes(content, widgetRegistry) {
467
+ const tag = escapeRegExp(widgetRegistry.portfolioShortcode);
468
+ const pattern = new RegExp(`\\[${tag}\\b([^\\]]*)\\](?:\\s*\\[\\/${tag}\\])?`, "gi");
469
+ return content.replace(pattern, (_, params) => {
470
+ const category = extractBareOrQuotedParam(params, "category");
471
+ const slug = extractBareOrQuotedParam(params, "slug");
472
+ return emitWidgetStub("portfolio", {
473
+ ...category ? { "data-wp-portfolio-category": category } : {},
474
+ ...slug ? { "data-wp-portfolio-slug": slug } : {}
475
+ });
476
+ });
477
+ }
478
+ function flattenVideoShortcodes(content, widgetRegistry) {
479
+ let html = content;
480
+ for (const prefix of widgetRegistry.videoShortcodePrefixes) {
481
+ const wrapped = new RegExp(
482
+ `\\[${escapeRegExp(prefix)}\\b([^\\]]*)\\]([\\s\\S]*?)\\[\\/${escapeRegExp(prefix)}\\b[^\\]]*\\]`,
483
+ "gi"
484
+ );
485
+ html = html.replace(
486
+ wrapped,
487
+ (_, params, inner) => emitVideoWidgetFromParams(params, inner)
488
+ );
489
+ const selfClosing = new RegExp(
490
+ `\\[${escapeRegExp(prefix)}\\b([^\\]]*)\\]`,
491
+ "gi"
492
+ );
493
+ html = html.replace(selfClosing, (_, params) => emitVideoWidgetFromParams(params, ""));
494
+ }
495
+ return html;
496
+ }
497
+ function flattenWordPressWidgets(content, widgetRegistry = WORDPRESS_WIDGET_REGISTRY) {
498
+ let html = content;
499
+ html = flattenGalleryShortcodes(html, widgetRegistry);
500
+ html = flattenIdBasedGalleryShortcodes(html, widgetRegistry);
501
+ html = flattenPortfolioShortcodes(html, widgetRegistry);
502
+ html = flattenMapShortcodes(html, widgetRegistry);
503
+ html = flattenContactFormShortcodes(html, widgetRegistry);
504
+ html = flattenVideoShortcodes(html, widgetRegistry);
505
+ return html;
506
+ }
319
507
  function flattenWordPressBuilders(content, options = {}) {
320
508
  if (!content.trim()) {
321
509
  return { html: content, detectedThemes: [] };
322
510
  }
323
511
  const registry = options.registry ?? WORDPRESS_BUILDER_REGISTRY;
324
512
  const themes = detectThemes(content, registry);
325
- if (themes.length === 0) {
326
- return { html: content, detectedThemes: [] };
327
- }
328
- let html = content;
513
+ const widgetRegistry = options.widgetRegistry ?? WORDPRESS_WIDGET_REGISTRY;
514
+ let html = flattenWordPressWidgets(content, widgetRegistry);
329
515
  for (const theme of themes) {
330
516
  for (const rule of theme.wrapperRules ?? []) {
331
517
  html = convertWrapperRule(html, rule);
@@ -361,6 +547,7 @@ function flattenWordPressBuilders(content, options = {}) {
361
547
 
362
548
  // src/parsers/wordpress/parse-wxr.ts
363
549
  var PLATFORM = "wordpress";
550
+ var DEFAULT_WORDPRESS_PORTFOLIO_CPT_SLUGS = ["portfolio"];
364
551
  var WOOCOMMERCE_STUB_PAGE_SLUGS = /* @__PURE__ */ new Set(["cart", "checkout", "my-account"]);
365
552
  var WOOCOMMERCE_STUB_SHORTCODE = /^\[woocommerce_(?:cart|checkout|my_account)\]\s*$/i;
366
553
  function isWooCommerceStubPage(slug, contentHtml) {
@@ -400,15 +587,29 @@ function getContentEncoded(item) {
400
587
  }
401
588
  return textValue(item.encoded);
402
589
  }
403
- function sourceMeta(id, link, exportedAt) {
590
+ function sourceMeta(id, link, exportedAt, postType) {
404
591
  return {
405
592
  platform: PLATFORM,
406
593
  id,
407
594
  url: link || void 0,
408
595
  path: linkToPath(link),
409
- exportedAt
596
+ exportedAt,
597
+ ...postType ? { postType } : {}
410
598
  };
411
599
  }
600
+ function resolvePortfolioCptSlugs(options) {
601
+ const slugs = options.portfolioCptSlugs ?? DEFAULT_WORDPRESS_PORTFOLIO_CPT_SLUGS;
602
+ return new Set(slugs.map((slug) => slug.toLowerCase()));
603
+ }
604
+ function portfolioCptSourceId(postId) {
605
+ return `portfolio:${postId}`;
606
+ }
607
+ function isPortfolioCptPostType(postType, portfolioCptSlugs) {
608
+ return portfolioCptSlugs.has(postType.toLowerCase());
609
+ }
610
+ function countWxrPortfolioCptItems(items, portfolioCptSlugs = new Set(DEFAULT_WORDPRESS_PORTFOLIO_CPT_SLUGS)) {
611
+ return items.filter((item) => isPortfolioCptPostType(textValue(item.post_type), portfolioCptSlugs)).length;
612
+ }
412
613
  function getExcerpt(item) {
413
614
  const excerpt = item.excerpt;
414
615
  if (!excerpt) return "";
@@ -439,11 +640,11 @@ function buildAttachmentIndex(items, originUrlRewrite) {
439
640
  for (const item of items) {
440
641
  if (textValue(item.post_type) !== "attachment") continue;
441
642
  const id = textValue(item.post_id);
442
- let url = textValue(item.attachment_url) || textValue(item.link);
443
- if (!id || !url) continue;
444
- if (originUrlRewrite) {
445
- url = rewriteOriginUrlsInText(url, originUrlRewrite);
446
- }
643
+ const rawUrl = textValue(item.attachment_url) || textValue(item.link);
644
+ if (!id || !rawUrl) continue;
645
+ const canonical = canonicalizeInlineAssetUrl(rawUrl, originUrlRewrite);
646
+ if (!canonical) continue;
647
+ const url = canonical.canonicalUrl;
447
648
  const filename = basename(new URL(url, "http://local.invalid").pathname) || `attachment-${id}`;
448
649
  index.set(id, {
449
650
  sourceUrl: url,
@@ -502,29 +703,45 @@ function collectTaxonomies(items) {
502
703
  }
503
704
  return { categories, tags };
504
705
  }
505
- function collectInlineAssets(html, attachmentIndex, seenUrls, exportedAt) {
706
+ function collectInlineAssets(html, attachmentIndex, seenUrls, seenAttachmentIds, exportedAt, originUrlRewrite) {
506
707
  const assets = [];
507
- for (const src of discoverContentAssetUrls(html)) {
508
- if (seenUrls.has(src)) continue;
509
- seenUrls.add(src);
708
+ const discovery = discoverContentAssets(html);
709
+ for (const discovered of discovery.urls) {
710
+ const canonical = canonicalizeInlineAssetUrl(discovered, originUrlRewrite);
711
+ if (!canonical) continue;
712
+ if (seenUrls.has(canonical.canonicalUrl)) continue;
713
+ seenUrls.add(canonical.canonicalUrl);
510
714
  let filename;
511
715
  try {
512
- filename = basename(new URL(src, "http://local.invalid").pathname) || "inline-asset";
716
+ filename = basename(new URL(canonical.canonicalUrl, "http://local.invalid").pathname) || "inline-asset";
513
717
  } catch {
514
718
  filename = "inline-asset";
515
719
  }
516
720
  assets.push({
517
721
  type: "asset",
518
- source: sourceMeta(`url:${src}`, src, exportedAt),
519
- sourceId: `url:${src}`,
520
- sourceUrl: src,
722
+ source: sourceMeta(canonical.sourceId, canonical.canonicalUrl, exportedAt),
723
+ sourceId: canonical.sourceId,
724
+ sourceUrl: canonical.canonicalUrl,
521
725
  filename,
522
726
  mimeType: guessMime(filename)
523
727
  });
524
728
  }
525
- for (const [id, entry] of attachmentIndex) {
729
+ for (const attachmentId of discovery.unresolvedAttachmentIds) {
730
+ if (seenAttachmentIds.has(attachmentId)) continue;
731
+ seenAttachmentIds.add(attachmentId);
732
+ const entry = attachmentIndex.get(attachmentId);
733
+ if (!entry) continue;
526
734
  if (seenUrls.has(entry.sourceUrl)) continue;
527
- void id;
735
+ seenUrls.add(entry.sourceUrl);
736
+ assets.push({
737
+ type: "asset",
738
+ source: sourceMeta(attachmentId, entry.sourceUrl, exportedAt),
739
+ sourceId: attachmentId,
740
+ sourceUrl: entry.sourceUrl,
741
+ filename: entry.filename,
742
+ mimeType: entry.mimeType ?? guessMime(entry.filename),
743
+ caption: entry.title
744
+ });
528
745
  }
529
746
  return assets;
530
747
  }
@@ -538,12 +755,15 @@ function preprocessContent(rawHtml, options) {
538
755
  }
539
756
  return html;
540
757
  }
541
- function resolveFeaturedAssetSourceId(thumbnailId, attachmentIndex, contentHtml) {
758
+ function resolveFeaturedAssetSourceId(thumbnailId, attachmentIndex, contentHtml, originUrlRewrite) {
542
759
  if (thumbnailId && attachmentIndex.has(thumbnailId)) {
543
760
  return thumbnailId;
544
761
  }
545
762
  const featuredUrl = resolveFeaturedContentAssetUrl(contentHtml);
546
- return featuredUrl ? `url:${featuredUrl}` : void 0;
763
+ if (!featuredUrl) return void 0;
764
+ const fromRef = parseMigrationMediaRef(featuredUrl);
765
+ if (fromRef) return fromRef;
766
+ return canonicalizeInlineAssetUrl(featuredUrl, originUrlRewrite)?.sourceId;
547
767
  }
548
768
  function maybeRewriteUrl(url, config) {
549
769
  if (!url) return void 0;
@@ -557,12 +777,6 @@ async function* enumerateWxrEntities(options) {
557
777
  const { categories, tags } = collectTaxonomies(items);
558
778
  const seenAssetUrls = /* @__PURE__ */ new Set();
559
779
  const emittedAttachmentIds = /* @__PURE__ */ new Set();
560
- const attachmentUrlIndex = buildMigrationMediaUrlIndex(
561
- [...attachmentIndex.entries()].map(([sourceId, entry]) => ({
562
- sourceId,
563
- sourceUrl: entry.sourceUrl
564
- }))
565
- );
566
780
  for (const category of categories.values()) {
567
781
  yield category;
568
782
  }
@@ -582,33 +796,49 @@ async function* enumerateWxrEntities(options) {
582
796
  caption: entry.title
583
797
  };
584
798
  }
799
+ const portfolioCptSlugs = resolvePortfolioCptSlugs(options);
585
800
  for (const item of items) {
586
801
  const postType = textValue(item.post_type);
587
- if (postType !== "post" && postType !== "page") continue;
802
+ const isPost = postType === "post";
803
+ const isPage = postType === "page";
804
+ const isPortfolioCpt = isPortfolioCptPostType(postType, portfolioCptSlugs);
805
+ if (!isPost && !isPage && !isPortfolioCpt) continue;
588
806
  const id = textValue(item.post_id);
589
807
  const link = maybeRewriteUrl(textValue(item.link), options.originUrlRewrite);
590
808
  const slug = sanitizeSlug(textValue(item.post_name) || textValue(item.title) || id);
591
809
  let contentHtml = preprocessContent(getContentEncoded(item), options);
592
- if (postType === "page" && options.skipWooCommerceStubPages !== false && isWooCommerceStubPage(slug, contentHtml)) {
810
+ if (isPage && options.skipWooCommerceStubPages !== false && isWooCommerceStubPage(slug, contentHtml)) {
593
811
  continue;
594
812
  }
595
813
  const inlineAssets = collectInlineAssets(
596
814
  contentHtml,
597
815
  attachmentIndex,
598
816
  seenAssetUrls,
599
- options.exportedAt
817
+ emittedAttachmentIds,
818
+ options.exportedAt,
819
+ options.originUrlRewrite
600
820
  );
601
821
  for (const asset of inlineAssets) {
602
822
  yield asset;
603
823
  }
604
824
  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;
825
+ const urlIndex = buildContentMediaUrlIndex(
826
+ [
827
+ ...[...attachmentIndex.entries()].map(([sourceId, entry]) => ({
828
+ sourceId,
829
+ sourceUrl: entry.sourceUrl
830
+ })),
831
+ ...inlineAssets.map((asset) => ({
832
+ sourceId: asset.sourceId,
833
+ sourceUrl: asset.sourceUrl
834
+ }))
835
+ ],
836
+ options.originUrlRewrite
837
+ );
838
+ contentHtml = stampMigrationMediaRefs(contentHtml, {
839
+ urlToSourceId: urlIndex,
840
+ originUrlRewrite: options.originUrlRewrite
841
+ }).html;
612
842
  }
613
843
  const categorySlugs = [];
614
844
  const tagSlugs = [];
@@ -619,12 +849,13 @@ async function* enumerateWxrEntities(options) {
619
849
  if (domain === "category") categorySlugs.push(nicename);
620
850
  if (domain === "post_tag") tagSlugs.push(nicename);
621
851
  }
622
- if (postType === "post") {
852
+ if (isPost) {
623
853
  const thumbnailId = getPostMeta(item, "_thumbnail_id");
624
854
  const featuredAssetSourceId = resolveFeaturedAssetSourceId(
625
855
  thumbnailId,
626
856
  attachmentIndex,
627
- contentHtml
857
+ contentHtml,
858
+ options.originUrlRewrite
628
859
  );
629
860
  const post = {
630
861
  type: "post",
@@ -643,11 +874,12 @@ async function* enumerateWxrEntities(options) {
643
874
  };
644
875
  yield post;
645
876
  } else {
646
- const isHomePage = getPostMeta(item, "_wp_show_on_front") === "1" || getPostMeta(item, "page_on_front") === "1";
877
+ const isHomePage = !isPortfolioCpt && (getPostMeta(item, "_wp_show_on_front") === "1" || getPostMeta(item, "page_on_front") === "1");
878
+ const pageSourceId = isPortfolioCpt ? portfolioCptSourceId(id) : id;
647
879
  const page = {
648
880
  type: "page",
649
- source: sourceMeta(id, link, options.exportedAt),
650
- sourceId: id,
881
+ source: sourceMeta(pageSourceId, link, options.exportedAt, isPortfolioCpt ? postType : void 0),
882
+ sourceId: pageSourceId,
651
883
  title: textValue(item.title) || slug,
652
884
  slug,
653
885
  contentHtml,
@@ -679,7 +911,7 @@ async function validateWxrFile(filePath) {
679
911
  posts: items.filter((i) => textValue(i.post_type) === "post").length,
680
912
  pages: items.filter((i) => textValue(i.post_type) === "page").length,
681
913
  assets: items.filter((i) => textValue(i.post_type) === "attachment").length,
682
- portfolios: 0,
914
+ portfolioCpt: countWxrPortfolioCptItems(items),
683
915
  categories: 0,
684
916
  tags: 0
685
917
  };
@@ -700,11 +932,12 @@ function resolveWxrOptions(input) {
700
932
  filePath: String(obj.path),
701
933
  originUrlRewrite: obj.originUrlRewrite,
702
934
  flattenBuilders: obj.flattenBuilders,
703
- skipWooCommerceStubPages: obj.skipWooCommerceStubPages
935
+ skipWooCommerceStubPages: obj.skipWooCommerceStubPages,
936
+ portfolioCptSlugs: obj.portfolioCptSlugs
704
937
  };
705
938
  }
706
939
  throw new Error(
707
- "WordPress adapter requires input path (string or { path, originUrlRewrite?, flattenBuilders?, skipWooCommerceStubPages? })"
940
+ "WordPress adapter requires input path (string or { path, originUrlRewrite?, flattenBuilders?, skipWooCommerceStubPages?, portfolioCptSlugs? })"
708
941
  );
709
942
  }
710
943
  var wordpressAdapter = {
@@ -2680,8 +2913,6 @@ function getAdapter(platform) {
2680
2913
  }
2681
2914
 
2682
2915
  export {
2683
- rewriteOriginUrlsInText,
2684
- createWpContentGatewayRewrite,
2685
2916
  wordpressAdapter,
2686
2917
  SMUGMUG_API_BASE,
2687
2918
  SMUGMUG_OAUTH_ENDPOINTS,
@@ -2697,4 +2928,4 @@ export {
2697
2928
  wixAdapter,
2698
2929
  getAdapter
2699
2930
  };
2700
- //# sourceMappingURL=chunk-KF7G7DM6.js.map
2931
+ //# sourceMappingURL=chunk-FB3MMCHY.js.map