@jant/core 0.3.45 → 0.3.46

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.
@@ -437,6 +437,18 @@ function isAbsoluteUrl(value) {
437
437
  return typeof value === "string" && /^https?:\/\//i.test(value);
438
438
  }
439
439
 
440
+ /**
441
+ * True when `url` points to a different location than the import target —
442
+ * i.e. has a scheme (`https://`, `data:`) or is protocol-relative (`//cdn…`).
443
+ * False for relative paths (`/media/x`, `./x`, `x`), which always belong to
444
+ * the source site and must be rehosted. Used to filter the body-fallback
445
+ * upload when `--skip-remote-media` is set.
446
+ */
447
+ function isAbsoluteImportUrl(value) {
448
+ if (typeof value !== "string") return false;
449
+ return /^([a-z][a-z0-9+.\-]*:|\/\/)/i.test(value);
450
+ }
451
+
440
452
  /**
441
453
  * Resolve a `media:` entry's `src` or `poster` reference to a local disk
442
454
  * path when the export bundled the bytes under `static/`. Absolute URLs
@@ -641,19 +653,7 @@ async function buildImportedAttachments(
641
653
  target,
642
654
  siteConfig,
643
655
  sourceRootDir,
644
- options = {},
645
656
  ) {
646
- if (
647
- sourceRootDir &&
648
- typeof sourceRootDir === "object" &&
649
- !Array.isArray(sourceRootDir) &&
650
- options &&
651
- Object.keys(options).length === 0
652
- ) {
653
- options = sourceRootDir;
654
- sourceRootDir = null;
655
- }
656
-
657
657
  const attachments = [];
658
658
  let uploaded = 0;
659
659
 
@@ -668,10 +668,6 @@ async function buildImportedAttachments(
668
668
  continue;
669
669
  }
670
670
 
671
- if (options.skipUploads) {
672
- continue;
673
- }
674
-
675
671
  const normalized = await normalizeMediaSpec(
676
672
  spec,
677
673
  siteConfig,
@@ -1976,6 +1972,7 @@ function buildPostPayloadFromBundle(bundle, options) {
1976
1972
  }
1977
1973
 
1978
1974
  export const __test__ = {
1975
+ isAbsoluteImportUrl,
1979
1976
  resolveImportUrl,
1980
1977
  readMediaSpecAsset,
1981
1978
  normalizeMediaSpec,
@@ -2009,7 +2006,7 @@ export async function run(argv) {
2009
2006
  token: { type: "string" },
2010
2007
  path: { type: "string", default: "." },
2011
2008
  "dry-run": { type: "boolean", default: false },
2012
- "skip-media": { type: "boolean", default: false },
2009
+ "skip-remote-media": { type: "boolean", default: false },
2013
2010
  help: { type: "boolean", short: "h" },
2014
2011
  },
2015
2012
  });
@@ -2034,7 +2031,7 @@ export async function run(argv) {
2034
2031
  );
2035
2032
  console.log(" --dry-run Parse and validate without making API calls");
2036
2033
  console.log(
2037
- " --skip-media Skip remote media download/upload (embedded text attachments still import)",
2034
+ " --skip-remote-media Skip uploading absolute-URL images found in body (relative paths and declared media still import)",
2038
2035
  );
2039
2036
  console.log("");
2040
2037
  console.log(
@@ -2066,7 +2063,7 @@ export async function run(argv) {
2066
2063
 
2067
2064
  const apiUrl = values.url?.replace(/\/$/, "");
2068
2065
  const dryRun = values["dry-run"];
2069
- const skipMedia = values["skip-media"];
2066
+ const skipRemoteMedia = values["skip-remote-media"];
2070
2067
  const target = dryRun
2071
2068
  ? null
2072
2069
  : values.url
@@ -2149,7 +2146,7 @@ export async function run(argv) {
2149
2146
  `[dry-run] Would replace navigation with ${importedNav.items.length} items`,
2150
2147
  );
2151
2148
  }
2152
- if (avatarImport && !skipMedia) {
2149
+ if (avatarImport) {
2153
2150
  if (avatarImport.mode === "remove") {
2154
2151
  console.log("[dry-run] Would remove existing site avatar");
2155
2152
  } else {
@@ -2204,7 +2201,7 @@ export async function run(argv) {
2204
2201
  }
2205
2202
  }
2206
2203
 
2207
- if (avatarImport && !skipMedia) {
2204
+ if (avatarImport) {
2208
2205
  try {
2209
2206
  await target.syncSiteAvatar(
2210
2207
  avatarImport.mode === "set" ? avatarImport : null,
@@ -2349,7 +2346,7 @@ export async function run(argv) {
2349
2346
  }
2350
2347
 
2351
2348
  const rootResourceIds = [];
2352
- if (!skipMedia && !dryRun && rootResourceSpecs.length > 0) {
2349
+ if (!dryRun && rootResourceSpecs.length > 0) {
2353
2350
  const result = await uploadBundleResources(rootResourceSpecs, target);
2354
2351
  mediaUploaded += result.uploaded;
2355
2352
  if (result.urlMap.size > 0) {
@@ -2360,8 +2357,13 @@ export async function run(argv) {
2360
2357
 
2361
2358
  // Fallback: rewrite any leftover in-body image URLs (covers hand-
2362
2359
  // authored Hugo content where the exporter didn't declare resources).
2363
- if (!skipMedia && !dryRun) {
2364
- const imageMedia = findImageUrls(rootBody).map((src) => ({ src }));
2360
+ // `--skip-remote-media` filters out absolute URLs here so we only
2361
+ // rehost relative paths (the source site's own files).
2362
+ if (!dryRun) {
2363
+ const fallbackUrls = findImageUrls(rootBody).filter(
2364
+ (url) => !skipRemoteMedia || !isAbsoluteImportUrl(url),
2365
+ );
2366
+ const imageMedia = fallbackUrls.map((src) => ({ src }));
2365
2367
  const uploadResult = await uploadMediaList(
2366
2368
  imageMedia,
2367
2369
  target,
@@ -2380,7 +2382,6 @@ export async function run(argv) {
2380
2382
  target,
2381
2383
  siteConfig,
2382
2384
  sourceRootDir,
2383
- { skipUploads: skipMedia },
2384
2385
  );
2385
2386
  importedAttachments = attachmentResult.attachments;
2386
2387
  mediaUploaded += attachmentResult.uploaded;
@@ -2396,7 +2397,7 @@ export async function run(argv) {
2396
2397
  // These reference a `.md` artifact that holds the full body; the
2397
2398
  // normalizer fetches the bytes (local disk first, then remote URL)
2398
2399
  // and decodes them.
2399
- if (!skipMedia && !dryRun) {
2400
+ if (!dryRun) {
2400
2401
  for (const textEntry of rootTextAttachmentEntries) {
2401
2402
  const textAttachment = await normalizeTextAttachmentSpec(
2402
2403
  textEntry,
@@ -2496,7 +2497,7 @@ export async function run(argv) {
2496
2497
  }
2497
2498
 
2498
2499
  const replyResourceIds = [];
2499
- if (!skipMedia && replyResourceSpecs.length > 0) {
2500
+ if (replyResourceSpecs.length > 0) {
2500
2501
  const result = await uploadBundleResources(
2501
2502
  replyResourceSpecs,
2502
2503
  target,
@@ -2508,8 +2509,11 @@ export async function run(argv) {
2508
2509
  replyResourceIds.push(...result.mediaIds);
2509
2510
  }
2510
2511
 
2511
- if (!skipMedia) {
2512
- const imageMedia = findImageUrls(replyBody).map((src) => ({ src }));
2512
+ {
2513
+ const fallbackUrls = findImageUrls(replyBody).filter(
2514
+ (url) => !skipRemoteMedia || !isAbsoluteImportUrl(url),
2515
+ );
2516
+ const imageMedia = fallbackUrls.map((src) => ({ src }));
2513
2517
  const uploadResult = await uploadMediaList(
2514
2518
  imageMedia,
2515
2519
  target,
@@ -2527,7 +2531,6 @@ export async function run(argv) {
2527
2531
  target,
2528
2532
  siteConfig,
2529
2533
  sourceRootDir,
2530
- { skipUploads: skipMedia },
2531
2534
  );
2532
2535
  replyAttachments = attachmentResult.attachments;
2533
2536
  mediaUploaded += attachmentResult.uploaded;
@@ -2535,15 +2538,13 @@ export async function run(argv) {
2535
2538
  replyAttachments.push({ type: "media", mediaId });
2536
2539
  }
2537
2540
 
2538
- if (!skipMedia) {
2539
- for (const textEntry of replyTextAttachmentEntries) {
2540
- const textAttachment = await normalizeTextAttachmentSpec(
2541
- textEntry,
2542
- siteConfig,
2543
- sourceRootDir,
2544
- );
2545
- if (textAttachment) replyAttachments.push(textAttachment);
2546
- }
2541
+ for (const textEntry of replyTextAttachmentEntries) {
2542
+ const textAttachment = await normalizeTextAttachmentSpec(
2543
+ textEntry,
2544
+ siteConfig,
2545
+ sourceRootDir,
2546
+ );
2547
+ if (textAttachment) replyAttachments.push(textAttachment);
2547
2548
  }
2548
2549
 
2549
2550
  const replyMemberships = resolveCollectionMemberships(
@@ -1,5 +1,5 @@
1
1
  import "./url-umUptr5z.js";
2
- import { t as createApp } from "./app-C-L7wL6o.js";
2
+ import { t as createApp } from "./app-DB-P66E5.js";
3
3
  import "./github-sync-CQ1x271f.js";
4
4
  import "./env-CgaH9Mut.js";
5
5
  export { createApp };
@@ -3352,9 +3352,9 @@ function normalizeThemeColorForMeta(color) {
3352
3352
  * internal paths (e.g. `/_assets/client-HASH.js`) embedded by the Worker build
3353
3353
  * from the Vite client manifest. Used only in production (IS_VITE_DEV=false).
3354
3354
  */ var IS_VITE_DEV = typeof __JANT_DEV__ !== "undefined" && __JANT_DEV__ === true;
3355
- var CORE_VERSION = "0.3.45-63de2a28e1b65691";
3355
+ var CORE_VERSION = "0.3.46-4c46f967df638082";
3356
3356
  var CLIENT_JS_FILE = "/_assets/client-dSfWfMe9.js";
3357
- var CLIENT_AUTH_JS_FILE = "/_assets/client-auth-Dcon89Av.js";
3357
+ var CLIENT_AUTH_JS_FILE = "/_assets/client-auth-BLCUje4M.js";
3358
3358
  var CLIENT_CSS_FILE = "/_assets/client-DDs6NzB3.css";
3359
3359
  var CLIENT_CJK_CSS_FILE = "/_assets/client-cjk-B7Z0snDu.css";
3360
3360
  var CLIENT_CJK_TC_CSS_FILE = "/_assets/client-cjk-tc-BesJYrb2.css";
@@ -3673,7 +3673,7 @@ var IconSprite = () => {
3673
3673
  const cjkSerifFont = appConfig?.cjkSerifFont ?? "off";
3674
3674
  const cjkStylesheetPath = cjkSerifFont === "zh-Hans" ? IS_VITE_DEV ? assetPath("/src/style-cjk.css") : toPublicAssetPath(CLIENT_CJK_CSS_FILE, assetBasePath) : cjkSerifFont === "zh-Hant" ? IS_VITE_DEV ? assetPath("/src/style-cjk-tc.css") : toPublicAssetPath(CLIENT_CJK_TC_CSS_FILE, assetBasePath) : cjkSerifFont === "ja" ? IS_VITE_DEV ? assetPath("/src/style-cjk-jp.css") : toPublicAssetPath(CLIENT_CJK_JP_CSS_FILE, assetBasePath) : cjkSerifFont === "ko" ? IS_VITE_DEV ? assetPath("/src/style-cjk-kr.css") : toPublicAssetPath(CLIENT_CJK_KR_CSS_FILE, assetBasePath) : null;
3675
3675
  const clientScriptPath = IS_VITE_DEV ? resolvedClientBundle === "full" ? assetPath("/src/client-auth.ts") : assetPath("/src/client.ts") : toPublicAssetPath(resolvedClientBundle === "full" ? CLIENT_AUTH_JS_FILE : CLIENT_JS_FILE, assetBasePath);
3676
- const faviconAssetVersion = resolvedFaviconVersion || "0.3.45-63de2a28e1b65691";
3676
+ const faviconAssetVersion = resolvedFaviconVersion || "0.3.46-4c46f967df638082";
3677
3677
  const resolvedFaviconHref = faviconHref ?? (faviconAssetVersion ? toPublicPath(`/favicon.ico?v=${faviconAssetVersion}`, sitePathPrefix) : toPublicPath("/favicon.ico", sitePathPrefix));
3678
3678
  const resolvedAppleTouchHref = appleTouchHref ?? (faviconAssetVersion ? toPublicPath(`/apple-touch-icon.png?v=${faviconAssetVersion}`, sitePathPrefix) : toPublicPath("/apple-touch-icon.png", sitePathPrefix));
3679
3679
  const socialImageHref = resolvedSocialImagePath && (isFullUrl(resolvedSocialImagePath) || resolvedSocialImagePath.startsWith("//") ? resolvedSocialImagePath : toAbsoluteSiteUrl(resolvedSocialImagePath, appConfig?.siteUrl || "", sitePathPrefix));
@@ -10172,7 +10172,7 @@ var PaginatedPageHeader = ({ title, currentPage = 1, totalPages, description, ic
10172
10172
  class: "py-8 text-muted-foreground",
10173
10173
  children: [i18n._({ id: "Q/uoSA" }), !isAuthenticated && /* @__PURE__ */ jsxDEV$1(Fragment$1, { children: [" ", /* @__PURE__ */ jsxDEV$1("a", {
10174
10174
  href: signinUrl,
10175
- class: "underline-offset-2 hover:underline",
10175
+ class: "underline underline-offset-2",
10176
10176
  children: i18n._({ id: "nfU386" })
10177
10177
  })] })]
10178
10178
  })
@@ -146,7 +146,7 @@
146
146
  "name": "url"
147
147
  },
148
148
  "src/client-auth.ts": {
149
- "file": "_assets/client-auth-Dcon89Av.js",
149
+ "file": "_assets/client-auth-BLCUje4M.js",
150
150
  "name": "client-auth",
151
151
  "src": "src/client-auth.ts",
152
152
  "isEntry": true,