@ox-content/vite-plugin 2.76.0 → 2.79.0

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/index.mjs CHANGED
@@ -4,17 +4,17 @@ import { n as transformMermaidStatic, t as mermaidClientScript } from "./mermaid
4
4
  import { a as transformTabs, r as resetTabGroupCounter, t as generateTabsCSS } from "./tabs2.mjs";
5
5
  import "./pm2.mjs";
6
6
  import { n as transformYouTube, t as extractVideoId } from "./youtube2.mjs";
7
- import "./media2.mjs";
7
+ import "./media.mjs";
8
8
  import { a as fetchRepoData, i as fetchGitHubSource, l as parseGitHubLineRange, n as collectGitHubRepos, o as prefetchGitHubRepos, r as collectGitHubSources, s as prefetchGitHubSources, t as transformGitHub, u as parseGitHubPermalink } from "./github.mjs";
9
9
  import { a as transformOgp, i as prefetchOgpData, n as fetchOgpData, t as collectOgpUrls } from "./ogp2.mjs";
10
10
  import { a as normalizeVitePressFrontmatter, c as mergeThemes, i as generateVitePressMigrationConfig, l as resolveTheme, n as convertVitePressSidebar, o as defaultTheme, r as fromVitePressConfig, s as defineTheme, t as convertVitePressNav, u as themeToNapi } from "./vitepress.mjs";
11
11
  import { createRequire } from "node:module";
12
- import * as path$1 from "path";
12
+ import * as path$2 from "path";
13
13
  import { unified } from "unified";
14
14
  import rehypeParsePlugin from "rehype-parse";
15
15
  import rehypeStringifyPlugin from "rehype-stringify";
16
16
  import { createHighlighter } from "shiki";
17
- import * as path from "node:path";
17
+ import * as path$1 from "node:path";
18
18
  import { dirname, join } from "node:path";
19
19
  import * as fs from "node:fs/promises";
20
20
  import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
@@ -83,8 +83,8 @@ function stripMarkdownExtension(filePath, extensions = DEFAULT_MARKDOWN_EXTENSIO
83
83
  }
84
84
  function markdownGlobPattern(srcDir, extensions) {
85
85
  const suffixes = extensions.map((extension) => extension.replace(/^\./, ""));
86
- if (suffixes.length === 1) return path$1.join(srcDir, `**/*.${suffixes[0]}`);
87
- return path$1.join(srcDir, `**/*.{${suffixes.join(",")}}`);
86
+ if (suffixes.length === 1) return path$2.join(srcDir, `**/*.${suffixes[0]}`);
87
+ return path$2.join(srcDir, `**/*.{${suffixes.join(",")}}`);
88
88
  }
89
89
  //#endregion
90
90
  //#region src/environment.ts
@@ -342,7 +342,7 @@ async function transformAllPlugins(html, options = {}) {
342
342
  webContainer
343
343
  };
344
344
  if (Object.values(mediaOptions).some(Boolean)) {
345
- const { transformMediaEmbeds } = await import("./media.mjs");
345
+ const { transformMediaEmbeds } = await import("./media2.mjs");
346
346
  result = await transformMediaEmbeds(result, mediaOptions);
347
347
  }
348
348
  if (mermaid) {
@@ -379,7 +379,7 @@ async function transformBuiltinEmbeds(html, options) {
379
379
  webContainer: options.webContainer
380
380
  };
381
381
  if (Object.values(mediaOptions).some(Boolean)) {
382
- const { transformMediaEmbeds } = await import("./media.mjs");
382
+ const { transformMediaEmbeds } = await import("./media2.mjs");
383
383
  result = await transformMediaEmbeds(result, mediaOptions);
384
384
  }
385
385
  return result;
@@ -601,6 +601,8 @@ async function transformMarkdown(source, filePath, options, ssgOptions) {
601
601
  taskLists: options.taskLists,
602
602
  tables: options.tables,
603
603
  strikethrough: options.strikethrough,
604
+ autolinks: options.autolinks,
605
+ autolinkUrls: options.autolinks,
604
606
  frontmatter: options.frontmatter,
605
607
  tocMaxDepth: options.tocMaxDepth,
606
608
  convertMdLinks: ssgOptions?.convertMdLinks,
@@ -1028,10 +1030,10 @@ async function renderHtmlToPng(page, html, width, height, publicDir) {
1028
1030
  await route.continue();
1029
1031
  return;
1030
1032
  }
1031
- const filePath = path$1.join(publicDir, url.pathname);
1033
+ const filePath = path$2.join(publicDir, url.pathname);
1032
1034
  try {
1033
1035
  const body = await fs.readFile(filePath);
1034
- const ext = path$1.extname(filePath).toLowerCase();
1036
+ const ext = path$2.extname(filePath).toLowerCase();
1035
1037
  await route.fulfill({
1036
1038
  body,
1037
1039
  contentType: {
@@ -1228,7 +1230,7 @@ function computeCacheKey(templateSource, props, width, height) {
1228
1230
  * Returns the cached file path if found, null otherwise.
1229
1231
  */
1230
1232
  async function getCached(cacheDir, key) {
1231
- const filePath = path$1.join(cacheDir, `${key}.png`);
1233
+ const filePath = path$2.join(cacheDir, `${key}.png`);
1232
1234
  try {
1233
1235
  return await fs$2.readFile(filePath);
1234
1236
  } catch {
@@ -1240,7 +1242,7 @@ async function getCached(cacheDir, key) {
1240
1242
  */
1241
1243
  async function writeCache(cacheDir, key, png) {
1242
1244
  await fs$2.mkdir(cacheDir, { recursive: true });
1243
- const filePath = path$1.join(cacheDir, `${key}.png`);
1245
+ const filePath = path$2.join(cacheDir, `${key}.png`);
1244
1246
  await fs$2.writeFile(filePath, png);
1245
1247
  }
1246
1248
  //#endregion
@@ -1331,14 +1333,14 @@ function resolveOgImageOptions(options) {
1331
1333
  */
1332
1334
  async function resolveTemplate(options, root) {
1333
1335
  if (!options.template) return getDefaultTemplate();
1334
- const templatePath = path$1.resolve(root, options.template);
1336
+ const templatePath = path$2.resolve(root, options.template);
1335
1337
  const fs = await import("fs/promises");
1336
1338
  try {
1337
1339
  await fs.access(templatePath);
1338
1340
  } catch {
1339
1341
  throw new Error(`[ox-content:og-image] Template file not found: ${templatePath}`);
1340
1342
  }
1341
- switch (path$1.extname(templatePath).toLowerCase()) {
1343
+ switch (path$2.extname(templatePath).toLowerCase()) {
1342
1344
  case ".vue": return resolveVueTemplate(templatePath, options, root);
1343
1345
  case ".svelte": return resolveSvelteTemplate(templatePath, root);
1344
1346
  case ".tsx":
@@ -1352,9 +1354,9 @@ async function resolveTemplate(options, root) {
1352
1354
  async function resolveTsTemplate(templatePath, options, root) {
1353
1355
  const fs = await import("fs/promises");
1354
1356
  const { rolldown } = await import("rolldown");
1355
- const cacheDir = path$1.join(root, ".cache", "og-images");
1357
+ const cacheDir = path$2.join(root, ".cache", "og-images");
1356
1358
  await fs.mkdir(cacheDir, { recursive: true });
1357
- const outfile = path$1.join(cacheDir, "_template.mjs");
1359
+ const outfile = path$2.join(cacheDir, "_template.mjs");
1358
1360
  const bundle = await rolldown({
1359
1361
  input: templatePath,
1360
1362
  platform: "node"
@@ -1377,9 +1379,9 @@ async function resolveTsTemplate(templatePath, options, root) {
1377
1379
  async function resolveVueTemplate(templatePath, options, root) {
1378
1380
  const fs = await import("fs/promises");
1379
1381
  const { rolldown } = await import("rolldown");
1380
- const cacheDir = path$1.join(root, ".cache", "og-images");
1382
+ const cacheDir = path$2.join(root, ".cache", "og-images");
1381
1383
  await fs.mkdir(cacheDir, { recursive: true });
1382
- const outfile = path$1.join(cacheDir, "_template_vue.mjs");
1384
+ const outfile = path$2.join(cacheDir, "_template_vue.mjs");
1383
1385
  const bundle = await rolldown({
1384
1386
  input: templatePath,
1385
1387
  platform: "node",
@@ -1475,9 +1477,9 @@ async function getVizejsPlugin() {
1475
1477
  async function resolveSvelteTemplate(templatePath, root) {
1476
1478
  const fs = await import("fs/promises");
1477
1479
  const { rolldown } = await import("rolldown");
1478
- const cacheDir = path$1.join(root, ".cache", "og-images");
1480
+ const cacheDir = path$2.join(root, ".cache", "og-images");
1479
1481
  await fs.mkdir(cacheDir, { recursive: true });
1480
- const outfile = path$1.join(cacheDir, "_template_svelte.mjs");
1482
+ const outfile = path$2.join(cacheDir, "_template_svelte.mjs");
1481
1483
  const bundle = await rolldown({
1482
1484
  input: templatePath,
1483
1485
  platform: "node",
@@ -1533,9 +1535,9 @@ function createSvelteCompilerPlugin() {
1533
1535
  async function resolveReactTemplate(templatePath, root) {
1534
1536
  const fs = await import("fs/promises");
1535
1537
  const { rolldown } = await import("rolldown");
1536
- const cacheDir = path$1.join(root, ".cache", "og-images");
1538
+ const cacheDir = path$2.join(root, ".cache", "og-images");
1537
1539
  await fs.mkdir(cacheDir, { recursive: true });
1538
- const outfile = path$1.join(cacheDir, "_template_react.mjs");
1540
+ const outfile = path$2.join(cacheDir, "_template_react.mjs");
1539
1541
  const bundle = await rolldown({
1540
1542
  input: templatePath,
1541
1543
  platform: "node",
@@ -1585,7 +1587,7 @@ async function resolveReactTemplate(templatePath, root) {
1585
1587
  async function computeTemplateSource(options, root) {
1586
1588
  if (!options.template) return "__default__";
1587
1589
  const fs = await import("fs/promises");
1588
- const templatePath = path$1.resolve(root, options.template);
1590
+ const templatePath = path$2.resolve(root, options.template);
1589
1591
  const content = await fs.readFile(templatePath, "utf-8");
1590
1592
  return crypto.createHash("sha256").update(content).digest("hex");
1591
1593
  }
@@ -1603,7 +1605,7 @@ async function generateOgImages(pages, options, root) {
1603
1605
  if (pages.length === 0) return [];
1604
1606
  const templateFn = await resolveTemplate(options, root);
1605
1607
  const templateSource = await computeTemplateSource(options, root);
1606
- const cacheDir = path$1.join(root, ".cache", "og-images");
1608
+ const cacheDir = path$2.join(root, ".cache", "og-images");
1607
1609
  if (options.cache) {
1608
1610
  const allCached = await tryServeAllFromCache(pages, templateSource, options, cacheDir);
1609
1611
  if (allCached) return allCached;
@@ -1615,7 +1617,7 @@ async function generateOgImages(pages, options, root) {
1615
1617
  error: "Chromium not available"
1616
1618
  }));
1617
1619
  const results = [];
1618
- const publicDir = path$1.join(root, "public");
1620
+ const publicDir = path$2.join(root, "public");
1619
1621
  const concurrency = Math.max(1, options.concurrency);
1620
1622
  for (let i = 0; i < pages.length; i += concurrency) {
1621
1623
  const batch = pages.slice(i, i + concurrency);
@@ -1639,7 +1641,7 @@ async function tryServeAllFromCache(pages, templateSource, options, cacheDir) {
1639
1641
  for (const entry of pages) {
1640
1642
  const cached = await getCached(cacheDir, computeCacheKey(templateSource, entry.props, options.width, options.height));
1641
1643
  if (!cached) return null;
1642
- await fs.mkdir(path$1.dirname(entry.outputPath), { recursive: true });
1644
+ await fs.mkdir(path$2.dirname(entry.outputPath), { recursive: true });
1643
1645
  await fs.writeFile(entry.outputPath, cached);
1644
1646
  results.push({
1645
1647
  outputPath: entry.outputPath,
@@ -1657,7 +1659,7 @@ async function renderSinglePage(entry, templateFn, templateSource, options, cach
1657
1659
  if (options.cache) {
1658
1660
  const cached = await getCached(cacheDir, computeCacheKey(templateSource, entry.props, options.width, options.height));
1659
1661
  if (cached) {
1660
- await fs.mkdir(path$1.dirname(entry.outputPath), { recursive: true });
1662
+ await fs.mkdir(path$2.dirname(entry.outputPath), { recursive: true });
1661
1663
  await fs.writeFile(entry.outputPath, cached);
1662
1664
  return {
1663
1665
  outputPath: entry.outputPath,
@@ -1667,7 +1669,7 @@ async function renderSinglePage(entry, templateFn, templateSource, options, cach
1667
1669
  }
1668
1670
  const html = await templateFn(entry.props);
1669
1671
  const png = await session.renderPage(html, options.width, options.height, publicDir);
1670
- await fs.mkdir(path$1.dirname(entry.outputPath), { recursive: true });
1672
+ await fs.mkdir(path$2.dirname(entry.outputPath), { recursive: true });
1671
1673
  await fs.writeFile(entry.outputPath, png);
1672
1674
  if (options.cache) await writeCache(cacheDir, computeCacheKey(templateSource, entry.props, options.width, options.height), png);
1673
1675
  return {
@@ -2064,7 +2066,7 @@ async function generateHtmlPage(pageData, navGroups, siteName, base, ogImage, th
2064
2066
  async function externalizeSharedPageAssets(pages, outDir, base) {
2065
2067
  const optimized = (await importNapiModule()).externalizeSsgAssets(pages, outDir, base);
2066
2068
  await Promise.all(optimized.assets.map(async (asset) => {
2067
- await fs$2.mkdir(path$1.dirname(asset.outputPath), { recursive: true });
2069
+ await fs$2.mkdir(path$2.dirname(asset.outputPath), { recursive: true });
2068
2070
  await fs$2.writeFile(asset.outputPath, asset.content, "utf-8");
2069
2071
  }));
2070
2072
  return {
@@ -2125,8 +2127,8 @@ async function buildSsg(options, root) {
2125
2127
  files: [],
2126
2128
  errors: []
2127
2129
  };
2128
- const srcDir = path$1.resolve(root, options.srcDir);
2129
- const outDir = path$1.resolve(root, options.outDir);
2130
+ const srcDir = path$2.resolve(root, options.srcDir);
2131
+ const outDir = path$2.resolve(root, options.outDir);
2130
2132
  const generatedFiles = [];
2131
2133
  const errors = [];
2132
2134
  await cleanOutputDirectory(ssgOptions, outDir);
@@ -2169,7 +2171,7 @@ async function createBuildSsgContext(options, root, srcDir, outDir, markdownFile
2169
2171
  async function resolveSiteName$1(root, ssgOptions) {
2170
2172
  if (ssgOptions.siteName) return ssgOptions.siteName;
2171
2173
  try {
2172
- const pkgPath = path$1.join(root, "package.json");
2174
+ const pkgPath = path$2.join(root, "package.json");
2173
2175
  const pkg = JSON.parse(await fs$2.readFile(pkgPath, "utf-8"));
2174
2176
  return pkg.name ? formatTitle(pkg.name) : "Documentation";
2175
2177
  } catch {
@@ -2324,7 +2326,7 @@ async function writeGeneratedPages(generatedPages, context, generatedFiles) {
2324
2326
  const optimizedOutput = await externalizeSharedPageAssets(generatedPages, context.outDir, context.base);
2325
2327
  generatedFiles.push(...optimizedOutput.assets);
2326
2328
  for (const page of optimizedOutput.pages) {
2327
- await fs$2.mkdir(path$1.dirname(page.outputPath), { recursive: true });
2329
+ await fs$2.mkdir(path$2.dirname(page.outputPath), { recursive: true });
2328
2330
  await fs$2.writeFile(page.outputPath, page.html, "utf-8");
2329
2331
  generatedFiles.push(page.outputPath);
2330
2332
  }
@@ -2459,14 +2461,14 @@ async function resolveMarkdownFile(url, srcDir, extensions) {
2459
2461
  const routePath = pathname === "/" ? "" : pathname.slice(1);
2460
2462
  const directCandidates = pathname === "/" ? extensions.map((extension) => `index${extension}`) : isMarkdownFilePath(routePath, extensions) ? [routePath] : extensions.map((extension) => `${routePath}${extension}`);
2461
2463
  for (const relativePath of directCandidates) {
2462
- const filePath = path$1.join(srcDir, relativePath);
2464
+ const filePath = path$2.join(srcDir, relativePath);
2463
2465
  try {
2464
2466
  await fs$2.access(filePath);
2465
2467
  return filePath;
2466
2468
  } catch {}
2467
2469
  }
2468
2470
  for (const extension of extensions) {
2469
- const indexPath = path$1.join(srcDir, routePath, `index${extension}`);
2471
+ const indexPath = path$2.join(srcDir, routePath, `index${extension}`);
2470
2472
  try {
2471
2473
  await fs$2.access(indexPath);
2472
2474
  return indexPath;
@@ -2509,7 +2511,7 @@ function invalidatePageCache(cache, filePath) {
2509
2511
  async function resolveSiteName(options, root) {
2510
2512
  if (options.ssg.siteName) return options.ssg.siteName;
2511
2513
  try {
2512
- const pkgPath = path$1.join(root, "package.json");
2514
+ const pkgPath = path$2.join(root, "package.json");
2513
2515
  const pkg = JSON.parse(await fs$2.readFile(pkgPath, "utf-8"));
2514
2516
  if (pkg.name) return formatTitle(pkg.name);
2515
2517
  } catch {}
@@ -2519,7 +2521,7 @@ async function resolveSiteName(options, root) {
2519
2521
  * Render a single markdown page to full HTML.
2520
2522
  */
2521
2523
  async function renderPage$1(filePath, options, navGroups, siteName, base, root) {
2522
- const srcDir = path$1.resolve(root, options.srcDir);
2524
+ const srcDir = path$2.resolve(root, options.srcDir);
2523
2525
  resetTabGroupCounter();
2524
2526
  resetIslandCounter();
2525
2527
  const result = await transformMarkdown(await fs$2.readFile(filePath, "utf-8"), filePath, options, {
@@ -2571,7 +2573,7 @@ async function renderPage$1(filePath, options, navGroups, siteName, base, root)
2571
2573
  * Create the dev server middleware for SSG page serving.
2572
2574
  */
2573
2575
  function createDevServerMiddleware(options, root, cache) {
2574
- const srcDir = path$1.resolve(root, options.srcDir);
2576
+ const srcDir = path$2.resolve(root, options.srcDir);
2575
2577
  const base = options.base.endsWith("/") ? options.base : options.base + "/";
2576
2578
  return async (req, res, next) => {
2577
2579
  const url = req.url;
@@ -2639,7 +2641,7 @@ function extractTitle(content, frontmatter) {
2639
2641
  return match ? match[1].trim() : "";
2640
2642
  }
2641
2643
  function getUrlPath(filePath, srcDir, extensions) {
2642
- let rel = path$1.relative(srcDir, filePath).replace(/\\/g, "/");
2644
+ let rel = path$2.relative(srcDir, filePath).replace(/\\/g, "/");
2643
2645
  rel = stripMarkdownExtension(rel, extensions);
2644
2646
  if (rel === "index") return "/";
2645
2647
  if (rel.endsWith("/index")) rel = rel.slice(0, -6);
@@ -2679,7 +2681,7 @@ function validatePage(page, options) {
2679
2681
  return warnings;
2680
2682
  }
2681
2683
  async function collectPages(options, root) {
2682
- const srcDir = path$1.resolve(root, options.srcDir);
2684
+ const srcDir = path$2.resolve(root, options.srcDir);
2683
2685
  const files = await glob(markdownGlobPattern(srcDir, options.extensions), { absolute: true });
2684
2686
  const pages = [];
2685
2687
  const generateOgImage = options.ogImage || options.ssg.generateOgImage;
@@ -2694,7 +2696,7 @@ async function collectPages(options, root) {
2694
2696
  const urlPath = getUrlPath(file, srcDir, options.extensions);
2695
2697
  const ogImageUrl = computeOgImageUrl(urlPath, options.base, options.ssg.siteUrl, generateOgImage, options.ssg.ogImage);
2696
2698
  const page = {
2697
- path: path$1.relative(srcDir, file),
2699
+ path: path$2.relative(srcDir, file),
2698
2700
  urlPath,
2699
2701
  title,
2700
2702
  description,
@@ -3007,14 +3009,14 @@ function createI18nPlugin(resolvedOptions) {
3007
3009
  },
3008
3010
  async buildStart() {
3009
3011
  if (!i18nOptions || !i18nOptions.check) return;
3010
- const dictDir = path$1.resolve(root, i18nOptions.dir);
3012
+ const dictDir = path$2.resolve(root, i18nOptions.dir);
3011
3013
  if (!fs$1.existsSync(dictDir)) {
3012
3014
  console.warn(`[ox-content:i18n] Dictionary directory not found: ${dictDir}`);
3013
3015
  return;
3014
3016
  }
3015
3017
  try {
3016
3018
  const { checkI18nProject } = await importNapiModule();
3017
- const checkResult = checkI18nProject(dictDir, [path$1.resolve(root, "src"), path$1.resolve(root, "content")], i18nOptions.functionNames, i18nOptions.defaultLocale);
3019
+ const checkResult = checkI18nProject(dictDir, [path$2.resolve(root, "src"), path$2.resolve(root, "content")], i18nOptions.functionNames, i18nOptions.defaultLocale);
3018
3020
  if (checkResult.errorCount > 0 || checkResult.warningCount > 0) {
3019
3021
  for (const diag of checkResult.diagnostics) if (diag.severity === "error") console.error(`[ox-content:i18n] ${diag.message}`);
3020
3022
  else if (diag.severity === "warning") console.warn(`[ox-content:i18n] ${diag.message}`);
@@ -3023,7 +3025,7 @@ function createI18nPlugin(resolvedOptions) {
3023
3025
  },
3024
3026
  configureServer(server) {
3025
3027
  if (!i18nOptions) return;
3026
- const dictDir = path$1.resolve(root, i18nOptions.dir);
3028
+ const dictDir = path$2.resolve(root, i18nOptions.dir);
3027
3029
  if (fs$1.existsSync(dictDir)) {
3028
3030
  server.watcher.add(dictDir);
3029
3031
  server.watcher.on("change", (filePath) => {
@@ -3050,7 +3052,7 @@ function createI18nPlugin(resolvedOptions) {
3050
3052
  * Generates the virtual module for i18n configuration.
3051
3053
  */
3052
3054
  function generateI18nModule(options, root) {
3053
- const dictDir = path$1.resolve(root, options.dir);
3055
+ const dictDir = path$2.resolve(root, options.dir);
3054
3056
  const config = {
3055
3057
  defaultLocale: options.defaultLocale,
3056
3058
  locales: options.locales,
@@ -3307,7 +3309,7 @@ function resolveCollectionsOptions(options) {
3307
3309
  async function buildCollectionManifest(root, options) {
3308
3310
  if (!options.collections.enabled) return { collections: {} };
3309
3311
  return parseCollectionManifest((await importNapiModule()).buildCollectionManifest({
3310
- srcDir: path.resolve(root, options.srcDir),
3312
+ srcDir: path$1.resolve(root, options.srcDir),
3311
3313
  extensions: [...options.extensions],
3312
3314
  frontmatter: options.frontmatter,
3313
3315
  collections: Object.values(options.collections.collections).map((collection) => ({
@@ -3340,6 +3342,8 @@ function createNativeTransformOptions(options) {
3340
3342
  taskLists: options.taskLists,
3341
3343
  tables: options.tables,
3342
3344
  strikethrough: options.strikethrough,
3345
+ autolinks: options.autolinks,
3346
+ autolinkUrls: options.autolinks,
3343
3347
  frontmatter: options.frontmatter,
3344
3348
  tocMaxDepth: options.tocMaxDepth,
3345
3349
  codeAnnotations: options.codeAnnotations?.enabled ?? false,
@@ -3504,6 +3508,7 @@ function createFrameworkMarkdownOptions(options) {
3504
3508
  tables: true,
3505
3509
  taskLists: true,
3506
3510
  strikethrough: true,
3511
+ autolinks: options.gfm,
3507
3512
  highlight: false,
3508
3513
  highlightTheme: "github-dark",
3509
3514
  highlightLangs: [],
@@ -3624,7 +3629,7 @@ var DocsTestRunError = class extends Error {
3624
3629
  }
3625
3630
  };
3626
3631
  async function collectDocsTests(options) {
3627
- const cwd = path.resolve(options.cwd ?? process.cwd());
3632
+ const cwd = path$1.resolve(options.cwd ?? process.cwd());
3628
3633
  if ((options.source ?? "markdown") === "jsdoc") return collectJsdocDocsTests(options, cwd);
3629
3634
  return collectMarkdownDocsTests(options, cwd);
3630
3635
  }
@@ -3641,8 +3646,8 @@ async function collectMarkdownDocsTests(options, cwd) {
3641
3646
  nodir: true
3642
3647
  });
3643
3648
  for (const filePath of matches) {
3644
- const absolutePath = path.resolve(filePath);
3645
- files.set(absolutePath, normalizePath$1(path.relative(cwd, absolutePath)));
3649
+ const absolutePath = path$1.resolve(filePath);
3650
+ files.set(absolutePath, normalizePath$1(path$1.relative(cwd, absolutePath)));
3646
3651
  }
3647
3652
  }
3648
3653
  const blocks = [];
@@ -3698,10 +3703,10 @@ function resolveJsdocDocsOptions(options, cwd) {
3698
3703
  const resolved = resolveDocsOptions(docsOptions);
3699
3704
  return {
3700
3705
  ...resolved,
3701
- src: resolved.src.map((sourceDir) => path.resolve(cwd, sourceDir)),
3706
+ src: resolved.src.map((sourceDir) => path$1.resolve(cwd, sourceDir)),
3702
3707
  entryPoints: resolved.entryPoints?.map((entryPoint) => ({
3703
3708
  ...entryPoint,
3704
- path: path.resolve(cwd, entryPoint.path)
3709
+ path: path$1.resolve(cwd, entryPoint.path)
3705
3710
  }))
3706
3711
  };
3707
3712
  }
@@ -3719,16 +3724,16 @@ function sortEntries(entries) {
3719
3724
  }
3720
3725
  function resolveEntrySourcePath(entry, doc, cwd) {
3721
3726
  const sourcePath = entry.file || doc.file;
3722
- return path.isAbsolute(sourcePath) ? path.resolve(sourcePath) : path.resolve(cwd, sourcePath);
3727
+ return path$1.isAbsolute(sourcePath) ? path$1.resolve(sourcePath) : path$1.resolve(cwd, sourcePath);
3723
3728
  }
3724
3729
  function relativeSourcePath(cwd, sourcePath) {
3725
- const relativePath = path.relative(cwd, sourcePath);
3726
- if (!relativePath.startsWith("..") && !path.isAbsolute(relativePath)) return normalizePath$1(relativePath);
3730
+ const relativePath = path$1.relative(cwd, sourcePath);
3731
+ if (!relativePath.startsWith("..") && !path$1.isAbsolute(relativePath)) return normalizePath$1(relativePath);
3727
3732
  return normalizePath$1(sourcePath);
3728
3733
  }
3729
3734
  async function writeDocsTestFiles(options) {
3730
- const cwd = path.resolve(options.cwd ?? process.cwd());
3731
- const generatedDir = path.resolve(cwd, options.generatedDir ?? ".cache/ox-content-docs-tests");
3735
+ const cwd = path$1.resolve(options.cwd ?? process.cwd());
3736
+ const generatedDir = path$1.resolve(cwd, options.generatedDir ?? ".cache/ox-content-docs-tests");
3732
3737
  const clean = options.clean ?? true;
3733
3738
  const blocks = await collectDocsTests({
3734
3739
  ...options,
@@ -3744,7 +3749,7 @@ async function writeDocsTestFiles(options) {
3744
3749
  generatedDir,
3745
3750
  blocks,
3746
3751
  files: await Promise.all(blocks.map(async (block) => {
3747
- const filePath = path.join(generatedDir, docsTestFileName(block));
3752
+ const filePath = path$1.join(generatedDir, docsTestFileName(block));
3748
3753
  await fs.writeFile(filePath, renderDocsTestFile(block, options), "utf-8");
3749
3754
  return {
3750
3755
  filePath,
@@ -3900,7 +3905,7 @@ function toArray(value) {
3900
3905
  return Array.isArray(value) ? value : [value];
3901
3906
  }
3902
3907
  function normalizePath$1(value) {
3903
- return value.split(path.sep).join("/");
3908
+ return value.split(path$1.sep).join("/");
3904
3909
  }
3905
3910
  function mergeEnv(overrides) {
3906
3911
  const env = { ...process.env };
@@ -4210,7 +4215,7 @@ const DEFAULT_LINT_FILE_EXCLUDE = [
4210
4215
  */
4211
4216
  function shouldLintMarkdownFile(filePath, options = {}) {
4212
4217
  const resolvedOptions = resolveMarkdownLintFileOptions(options);
4213
- return shouldLintAbsoluteFile(path.resolve(resolvedOptions.cwd, filePath), resolvedOptions);
4218
+ return shouldLintAbsoluteFile(path$1.resolve(resolvedOptions.cwd, filePath), resolvedOptions);
4214
4219
  }
4215
4220
  /**
4216
4221
  * Lints a single Markdown file using project-style include/exclude settings.
@@ -4220,7 +4225,7 @@ function shouldLintMarkdownFile(filePath, options = {}) {
4220
4225
  */
4221
4226
  async function lintMarkdownFile(filePath, options = {}) {
4222
4227
  const resolvedOptions = resolveMarkdownLintFileOptions(options);
4223
- return lintMarkdownFileWithResolvedOptions(path.resolve(resolvedOptions.cwd, filePath), resolvedOptions);
4228
+ return lintMarkdownFileWithResolvedOptions(path$1.resolve(resolvedOptions.cwd, filePath), resolvedOptions);
4224
4229
  }
4225
4230
  /**
4226
4231
  * Lints all Markdown files matched by the configured include/exclude patterns.
@@ -4251,7 +4256,7 @@ async function lintMarkdownFiles(options = {}) {
4251
4256
  }
4252
4257
  function resolveMarkdownLintFileOptions(options) {
4253
4258
  return {
4254
- cwd: path.resolve(options.cwd ?? process.cwd()),
4259
+ cwd: path$1.resolve(options.cwd ?? process.cwd()),
4255
4260
  exclude: [...new Set([...options.exclude ?? DEFAULT_LINT_FILE_EXCLUDE, ...options.ignore ?? []])],
4256
4261
  include: [...new Set(options.include ?? DEFAULT_LINT_FILE_INCLUDE)],
4257
4262
  lintOptions: {
@@ -4262,8 +4267,8 @@ function resolveMarkdownLintFileOptions(options) {
4262
4267
  };
4263
4268
  }
4264
4269
  async function lintMarkdownFileWithResolvedOptions(filePath, options) {
4265
- const absoluteFilePath = path.resolve(filePath);
4266
- const relativePath = normalizePath(path.relative(options.cwd, absoluteFilePath));
4270
+ const absoluteFilePath = path$1.resolve(filePath);
4271
+ const relativePath = normalizePath(path$1.relative(options.cwd, absoluteFilePath));
4267
4272
  if (!shouldLintAbsoluteFile(absoluteFilePath, options)) return {
4268
4273
  ...createEmptyLintResult(),
4269
4274
  filePath: absoluteFilePath,
@@ -4287,26 +4292,26 @@ async function collectMarkdownLintFileEntries(options) {
4287
4292
  nodir: true
4288
4293
  });
4289
4294
  for (const filePath of matches) {
4290
- const absoluteFilePath = path.resolve(filePath);
4295
+ const absoluteFilePath = path$1.resolve(filePath);
4291
4296
  if (shouldLintAbsoluteFile(absoluteFilePath, options)) files.set(absoluteFilePath, {
4292
4297
  filePath: absoluteFilePath,
4293
- relativePath: normalizePath(path.relative(options.cwd, absoluteFilePath))
4298
+ relativePath: normalizePath(path$1.relative(options.cwd, absoluteFilePath))
4294
4299
  });
4295
4300
  }
4296
4301
  }
4297
4302
  return [...files.values()].sort((left, right) => left.filePath.localeCompare(right.filePath));
4298
4303
  }
4299
4304
  function shouldLintAbsoluteFile(filePath, options) {
4300
- const absolutePath = normalizePath(path.resolve(filePath));
4301
- const relativePath = normalizePath(path.relative(options.cwd, absolutePath));
4305
+ const absolutePath = normalizePath(path$1.resolve(filePath));
4306
+ const relativePath = normalizePath(path$1.relative(options.cwd, absolutePath));
4302
4307
  const matches = (patterns) => patterns.some((pattern) => {
4303
4308
  const normalizedPattern = normalizePath(pattern);
4304
- return path.matchesGlob(relativePath, normalizedPattern) || path.matchesGlob(absolutePath, normalizedPattern);
4309
+ return path$1.matchesGlob(relativePath, normalizedPattern) || path$1.matchesGlob(absolutePath, normalizedPattern);
4305
4310
  });
4306
4311
  return matches(options.include) && !matches(options.exclude);
4307
4312
  }
4308
4313
  function normalizePath(value) {
4309
- return value.split(path.sep).join("/");
4314
+ return value.split(path$1.sep).join("/");
4310
4315
  }
4311
4316
  function createEmptyLintResult() {
4312
4317
  return {
@@ -4907,8 +4912,8 @@ function oxContent(options = {}) {
4907
4912
  async function regenerateDocs(resolvedOptions, root) {
4908
4913
  const docsOptions = resolvedOptions.docs;
4909
4914
  if (!docsOptions || !docsOptions.enabled) return 0;
4910
- const srcDirs = docsOptions.src.map((src) => path$1.resolve(root, src));
4911
- const outDir = path$1.resolve(root, docsOptions.out);
4915
+ const srcDirs = docsOptions.src.map((src) => path$2.resolve(root, src));
4916
+ const outDir = path$2.resolve(root, docsOptions.out);
4912
4917
  const extracted = await extractDocs(srcDirs, docsOptions);
4913
4918
  const generated = generateMarkdown(extracted, docsOptions);
4914
4919
  await writeDocs(generated, outDir, extracted, docsOptions);
@@ -4976,7 +4981,7 @@ function createCollectionsPlugin(resolvedOptions, getRoot) {
4976
4981
  },
4977
4982
  configureServer(devServer) {
4978
4983
  if (!resolvedOptions.collections.enabled) return;
4979
- const srcDir = path$1.resolve(getRoot(), resolvedOptions.srcDir);
4984
+ const srcDir = path$2.resolve(getRoot(), resolvedOptions.srcDir);
4980
4985
  devServer.watcher.add(srcDir);
4981
4986
  devServer.watcher.on("all", (_event, file) => {
4982
4987
  if (file.startsWith(srcDir) && isMarkdownFilePath(file, resolvedOptions.extensions)) invalidate(devServer);
@@ -5009,7 +5014,7 @@ function createDocsPlugin(resolvedOptions, getRoot) {
5009
5014
  const docsOptions = resolvedOptions.docs;
5010
5015
  if (!docsOptions || !docsOptions.enabled) return;
5011
5016
  const root = getRoot();
5012
- const srcDirs = docsOptions.src.map((src) => path$1.resolve(root, src));
5017
+ const srcDirs = docsOptions.src.map((src) => path$2.resolve(root, src));
5013
5018
  for (const srcDir of srcDirs) devServer.watcher.add(srcDir);
5014
5019
  devServer.watcher.on("all", async (event, file) => {
5015
5020
  if (event !== "add" && event !== "change" && event !== "unlink") return;
@@ -5027,7 +5032,7 @@ function createSsgPlugin(resolvedOptions, getRoot, ssgDevCache) {
5027
5032
  configureServer(devServer) {
5028
5033
  if (!resolvedOptions.ssg.enabled) return;
5029
5034
  const root = getRoot();
5030
- const srcDir = path$1.resolve(root, resolvedOptions.srcDir);
5035
+ const srcDir = path$2.resolve(root, resolvedOptions.srcDir);
5031
5036
  devServer.middlewares.use(createDevServerMiddleware(resolvedOptions, root, ssgDevCache));
5032
5037
  devServer.watcher.on("add", (file) => {
5033
5038
  notifySsgFileAddedOrRemoved(devServer, resolvedOptions, ssgDevCache, srcDir, file, "add");
@@ -5079,7 +5084,7 @@ function createSearchPlugin(resolvedOptions, getRoot) {
5079
5084
  },
5080
5085
  async buildStart() {
5081
5086
  if (!resolvedOptions.search.enabled) return;
5082
- const srcDir = path$1.resolve(getRoot(), resolvedOptions.srcDir);
5087
+ const srcDir = path$2.resolve(getRoot(), resolvedOptions.srcDir);
5083
5088
  try {
5084
5089
  searchIndexJson = await buildSearchIndex(srcDir, resolvedOptions.base, resolvedOptions.extensions);
5085
5090
  console.log("[ox-content] Search index built");
@@ -5087,12 +5092,36 @@ function createSearchPlugin(resolvedOptions, getRoot) {
5087
5092
  console.warn("[ox-content] Failed to build search index:", err);
5088
5093
  }
5089
5094
  },
5095
+ configureServer(devServer) {
5096
+ if (!resolvedOptions.search.enabled) return;
5097
+ const srcDir = path$2.resolve(getRoot(), resolvedOptions.srcDir);
5098
+ let stale = false;
5099
+ devServer.watcher.on("all", (event, file) => {
5100
+ if (event !== "add" && event !== "change" && event !== "unlink") return;
5101
+ const relative = path$2.relative(srcDir, file);
5102
+ if (relative !== ".." && !relative.startsWith(`..${path$2.sep}`) && !path$2.isAbsolute(relative) && isMarkdownFilePath(file, resolvedOptions.extensions)) stale = true;
5103
+ });
5104
+ const indexPath = resolvedOptions.base + "search-index.json";
5105
+ devServer.middlewares.use(async (req, res, next) => {
5106
+ if (req.url?.split("?")[0] !== indexPath) return next();
5107
+ try {
5108
+ if (stale || !searchIndexJson) {
5109
+ searchIndexJson = await buildSearchIndex(srcDir, resolvedOptions.base, resolvedOptions.extensions);
5110
+ stale = false;
5111
+ }
5112
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
5113
+ res.end(searchIndexJson);
5114
+ } catch (err) {
5115
+ next(err);
5116
+ }
5117
+ });
5118
+ },
5090
5119
  async closeBundle() {
5091
5120
  if (!resolvedOptions.search.enabled || !searchIndexJson) return;
5092
- const outDir = path$1.resolve(getRoot(), resolvedOptions.outDir);
5121
+ const outDir = path$2.resolve(getRoot(), resolvedOptions.outDir);
5093
5122
  try {
5094
5123
  await writeSearchIndex(searchIndexJson, outDir);
5095
- console.log("[ox-content] Search index written to", path$1.join(outDir, "search-index.json"));
5124
+ console.log("[ox-content] Search index written to", path$2.join(outDir, "search-index.json"));
5096
5125
  } catch (err) {
5097
5126
  console.warn("[ox-content] Failed to write search index:", err);
5098
5127
  }
@@ -5114,6 +5143,7 @@ function resolveOptions(options) {
5114
5143
  tables: options.tables ?? true,
5115
5144
  taskLists: options.taskLists ?? true,
5116
5145
  strikethrough: options.strikethrough ?? true,
5146
+ autolinks: options.autolinks ?? options.gfm ?? true,
5117
5147
  highlight: options.highlight ?? false,
5118
5148
  highlightTheme: options.highlightTheme ?? "github-dark",
5119
5149
  highlightLangs: options.highlightLangs ?? [],
@@ -5160,7 +5190,7 @@ function resolveBuiltinEmbedOptions(options) {
5160
5190
  pm: resolvePmOptions(options?.pm),
5161
5191
  spotify: options?.spotify === true,
5162
5192
  stackBlitz: options?.stackBlitz === true,
5163
- twitter: options?.twitter === true,
5193
+ twitter: resolveTwitterEmbedOptions(options?.twitter),
5164
5194
  bluesky: options?.bluesky === true,
5165
5195
  webContainer: options?.webContainer === true
5166
5196
  };
@@ -5170,6 +5200,11 @@ function resolveSingleEmbedOptions(options) {
5170
5200
  if (options === true || options === void 0) return {};
5171
5201
  return options;
5172
5202
  }
5203
+ function resolveTwitterEmbedOptions(options) {
5204
+ if (options === false || options === void 0) return false;
5205
+ if (options === true) return {};
5206
+ return options;
5207
+ }
5173
5208
  function resolvePmOptions(options) {
5174
5209
  if (options === false || options === void 0) return false;
5175
5210
  if (options === true) return {};