@ox-content/vite-plugin-vue 3.0.0-alpha.1 → 3.0.0-alpha.2

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.cjs CHANGED
@@ -39,44 +39,14 @@ const ISLAND_MARKER_SUFFIX = "-PLACEHOLDER";
39
39
  */
40
40
  async function transformMarkdownWithVue(code, id, options) {
41
41
  const { components } = options;
42
- const usedComponents = [];
43
- const islands = [];
44
- let islandIndex = 0;
45
42
  const { content: markdownContent, frontmatter } = extractFrontmatter(code);
46
- const fenceRanges = collectFenceRanges(markdownContent);
47
- let processedContent = "";
48
- let lastIndex = 0;
49
- let match;
50
- COMPONENT_REGEX.lastIndex = 0;
51
- while ((match = COMPONENT_REGEX.exec(markdownContent)) !== null) {
52
- const [fullMatch, componentName, propsString, rawIslandContent] = match;
53
- const matchStart = match.index;
54
- const matchEnd = matchStart + fullMatch.length;
55
- if (!components.has(componentName) || isInRanges(matchStart, matchEnd, fenceRanges)) {
56
- processedContent += markdownContent.slice(lastIndex, matchEnd);
57
- lastIndex = matchEnd;
58
- continue;
59
- }
60
- if (!usedComponents.includes(componentName)) usedComponents.push(componentName);
61
- const props = parseProps(propsString);
62
- const islandId = `ox-island-${islandIndex++}`;
63
- const islandContent = typeof rawIslandContent === "string" ? rawIslandContent.trim() : void 0;
64
- islands.push({
65
- name: componentName,
66
- props,
67
- position: matchStart,
68
- id: islandId,
69
- content: islandContent
70
- });
71
- processedContent += markdownContent.slice(lastIndex, matchStart) + createIslandMarker(islandId);
72
- lastIndex = matchEnd;
73
- }
74
- processedContent += markdownContent.slice(lastIndex);
43
+ const mdx = (0, _ox_content_vite_plugin.resolveMdxForFilePath)(id, options.mdx);
75
44
  const baseOptions = {
76
45
  srcDir: options.srcDir,
77
46
  outDir: options.outDir,
78
47
  base: options.base,
79
48
  extensions: options.extensions,
49
+ mdx,
80
50
  ssg: {
81
51
  enabled: false,
82
52
  extension: ".html",
@@ -86,6 +56,7 @@ async function transformMarkdownWithVue(code, id, options) {
86
56
  lastUpdated: false,
87
57
  pagination: false,
88
58
  breadcrumbs: false,
59
+ jsonLd: false,
89
60
  readerChrome: false,
90
61
  localeSwitcher: false,
91
62
  a11y: false,
@@ -124,6 +95,59 @@ async function transformMarkdownWithVue(code, id, options) {
124
95
  embeds: options.embeds,
125
96
  i18n: false
126
97
  };
98
+ if (mdx) {
99
+ const transformed = await (0, _ox_content_vite_plugin.transformMarkdown)(markdownContent, id, baseOptions);
100
+ const discovered = await (0, _ox_content_vite_plugin.discoverDocumentMdxIslands)({
101
+ source: markdownContent,
102
+ html: transformed.html,
103
+ components,
104
+ imports: transformed.imports,
105
+ documentPath: id,
106
+ contentRoot: (0, _ox_content_vite_plugin.resolveContentRootPath)({
107
+ srcDir: options.srcDir,
108
+ root: options.root
109
+ }),
110
+ srcDir: options.srcDir
111
+ });
112
+ return {
113
+ code: generateVueSFC(options.renderIsland ? await (0, _ox_content_vite_plugin.applyIslandSsrHtml)(transformed.html, options.renderIsland, id, discovered.usedComponents) : transformed.html, discovered.usedComponents, discovered.usedComponents, frontmatter, options, id, discovered.localBindings),
114
+ map: null,
115
+ usedComponents: discovered.usedComponents,
116
+ frontmatter
117
+ };
118
+ }
119
+ const usedComponents = [];
120
+ const islands = [];
121
+ let islandIndex = 0;
122
+ const fenceRanges = collectFenceRanges(markdownContent);
123
+ let processedContent = "";
124
+ let lastIndex = 0;
125
+ let match;
126
+ COMPONENT_REGEX.lastIndex = 0;
127
+ while ((match = COMPONENT_REGEX.exec(markdownContent)) !== null) {
128
+ const [fullMatch, componentName, propsString, rawIslandContent] = match;
129
+ const matchStart = match.index;
130
+ const matchEnd = matchStart + fullMatch.length;
131
+ if (!components.has(componentName) || isInRanges(matchStart, matchEnd, fenceRanges)) {
132
+ processedContent += markdownContent.slice(lastIndex, matchEnd);
133
+ lastIndex = matchEnd;
134
+ continue;
135
+ }
136
+ if (!usedComponents.includes(componentName)) usedComponents.push(componentName);
137
+ const props = parseProps(propsString);
138
+ const islandId = `ox-island-${islandIndex++}`;
139
+ const islandContent = typeof rawIslandContent === "string" ? rawIslandContent.trim() : void 0;
140
+ islands.push({
141
+ name: componentName,
142
+ props,
143
+ position: matchStart,
144
+ id: islandId,
145
+ content: islandContent
146
+ });
147
+ processedContent += markdownContent.slice(lastIndex, matchStart) + createIslandMarker(islandId);
148
+ lastIndex = matchEnd;
149
+ }
150
+ processedContent += markdownContent.slice(lastIndex);
127
151
  return {
128
152
  code: generateVueSFC(injectIslandMarkers((await (0, _ox_content_vite_plugin.transformMarkdown)(processedContent, id, baseOptions)).html, islands), usedComponents, islands, frontmatter, options, id),
129
153
  map: null,
@@ -245,18 +269,15 @@ function parseProps(propsString) {
245
269
  /**
246
270
  * Generates a Vue component as JavaScript module from the processed Markdown.
247
271
  */
248
- function generateVueSFC(content, usedComponents, islands, frontmatter, options, id) {
249
- const mdDir = path.dirname(id);
250
- const root = options.root || process.cwd();
251
- const componentImports = usedComponents.map((name) => {
252
- const componentPath = options.components.get(name);
253
- if (!componentPath) return "";
254
- const absolutePath = path.resolve(root, componentPath.replace(/^\.\//, ""));
255
- const relativePath = path.relative(mdDir, absolutePath).replace(/\\/g, "/");
256
- return `import ${name} from '${relativePath.startsWith(".") ? relativePath : "./" + relativePath}';`;
257
- }).filter(Boolean).join("\n");
272
+ function generateVueSFC(content, usedComponents, _islands, frontmatter, options, id, localBindings) {
273
+ const componentImports = (0, _ox_content_vite_plugin.renderIslandComponentImports)(usedComponents, {
274
+ globalComponents: options.components,
275
+ localBindings,
276
+ documentPath: id,
277
+ root: options.root
278
+ });
258
279
  const componentMap = usedComponents.map((name) => ` ${name},`).join("\n");
259
- if (islands.length === 0) return `
280
+ if (usedComponents.length === 0) return `
260
281
  import { h, ref, defineComponent } from 'vue';
261
282
 
262
283
  export const frontmatter = ${JSON.stringify(frontmatter)};
@@ -278,7 +299,7 @@ export default defineComponent({
278
299
  `;
279
300
  return `
280
301
  import { h, ref, onMounted, onBeforeUnmount, defineComponent, render } from 'vue';
281
- import { initIslands } from '@ox-content/islands';
302
+ import { initIslands, readIslandSlotHtml } from '@ox-content/islands';
282
303
  ${componentImports}
283
304
 
284
305
  export const frontmatter = ${JSON.stringify(frontmatter)};
@@ -296,7 +317,7 @@ function createVueHydrate(container) {
296
317
  const Component = components[componentName];
297
318
  if (!Component) return;
298
319
 
299
- const islandContent = element.dataset.oxContent || element.innerHTML;
320
+ const islandContent = readIslandSlotHtml(element);
300
321
  const children = islandContent
301
322
  ? { default: () => h('div', { innerHTML: islandContent }) }
302
323
  : undefined;
@@ -457,7 +478,8 @@ function oxContentVue(options = {}) {
457
478
  const result = await transformMarkdownWithVue(code, id, {
458
479
  ...resolved,
459
480
  components: componentMap,
460
- root: config.root
481
+ root: config.root,
482
+ renderIsland: options.renderIsland
461
483
  });
462
484
  return {
463
485
  code: result.code,
@@ -537,6 +559,7 @@ function resolveVueOptions(options) {
537
559
  codeAnnotations: resolveCodeAnnotationsOptions(options.codeAnnotations),
538
560
  components: options.components ?? {},
539
561
  embeds: resolveBuiltinEmbedOptions(options.embeds),
562
+ mdx: options.mdx,
540
563
  reactivityTransform: options.reactivityTransform ?? false,
541
564
  customBlocks: options.customBlocks ?? true
542
565
  };
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { PluginOption } from "vite";
2
- import { OxContentOptions, oxContent } from "@ox-content/vite-plugin";
2
+ import { OxContentOptions, RenderIslandFn, oxContent } from "@ox-content/vite-plugin";
3
3
  //#region src/types.d.ts
4
4
  /**
5
5
  * Code annotation options for the Vue integration.
@@ -117,6 +117,12 @@ interface VueIntegrationOptions extends OxContentOptions {
117
117
  * @default { github: true, openGraph: true }
118
118
  */
119
119
  embeds?: BuiltinEmbedOptions | false;
120
+ /**
121
+ * Optional adapter hook that replaces island inner HTML at transform time.
122
+ * The core renderer stays framework-neutral; do not import a framework SSR
123
+ * runtime from `@ox-content/vite-plugin`.
124
+ */
125
+ renderIsland?: RenderIslandFn;
120
126
  }
121
127
  /**
122
128
  * Fetch options for Vue GitHub embeds.
@@ -210,6 +216,8 @@ interface ResolvedVueOptions {
210
216
  reactivityTransform: boolean;
211
217
  customBlocks: boolean;
212
218
  embeds: ResolvedBuiltinEmbedOptions;
219
+ mdx?: boolean;
220
+ renderIsland?: RenderIslandFn;
213
221
  }
214
222
  /**
215
223
  * Transform result with Vue component information.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/index.ts"],"mappings":";;;;;;;;;UAYiB;;;;;;EAMf;;UAGe;EACf;EACA;;;;;;KAOU,gBAAgB;;;;;;;;;;;;;;;;;;;;;;KAuBhB,mBAAmB;;;;;;;;UASd,8BAA8B;;;;;;;;EAQ7C;;;;;;;;;;;;;;;;;;;;EAqBA,aAAa;;;;;;;;EASb,4BAA4B;;;;;;;;;EAU5B;;;;;;;;;EAUA;;;;;;;;;EAUA,SAAS;;;;;UAMM;;;;;EAKf;;;;;EAMA;;;;;EAMA;;;;;EAMA;;;;;EAMA;;;;;UAMe;;;;;EAKf;;;;;EAMA;;;;;EAMA;;;;;EAMA;;;;;UAMe;;;;;EAKf,mBAAmB;;;;;EAMnB,sBAAsB;;UAGP;EACf,QAAQ;EACR,WAAW;;;;;UAMI;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,iBAAiB;EACjB,YAAY;EACZ;EACA;EACA,QAAQ;;;;;UAMO;EACf;EACA;;;;EAKA;;;;EAKA,aAAa;;;;;UAME;;;;EAIf;;;;EAKA,OAAO;;;;EAKP;;;;EAKA;;;;EAKA;;;;;UAMe;;;;EAIf;;;;EAKA,SAAS;;;;EAKT,aAAa;;;;EAKb,KAAK;;;;;UAMU;EACf;EACA;EACA;EACA,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCjOG,aAAa,UAAS,wBAA6B"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/index.ts"],"mappings":";;;;;;;;;UAYiB;;;;;;EAMf;;UAGe;EACf;EACA;;;;;;KAOU,gBAAgB;;;;;;;;;;;;;;;;;;;;;;KAuBhB,mBAAmB;;;;;;;;UASd,8BAA8B;;;;;;;;EAQ7C;;;;;;;;;;;;;;;;;;;;EAqBA,aAAa;;;;;;;;EASb,4BAA4B;;;;;;;;;EAU5B;;;;;;;;;EAUA;;;;;;;;;EAUA,SAAS;;;;;;EAOT,eAAe;;;;;UAMA;;;;;EAKf;;;;;EAMA;;;;;EAMA;;;;;EAMA;;;;;EAMA;;;;;UAMe;;;;;EAKf;;;;;EAMA;;;;;EAMA;;;;;EAMA;;;;;UAMe;;;;;EAKf,mBAAmB;;;;;EAMnB,sBAAsB;;UAGP;EACf,QAAQ;EACR,WAAW;;;;;UAMI;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,iBAAiB;EACjB,YAAY;EACZ;EACA;EACA,QAAQ;EACR;EACA,eAAe;;;;;UAMA;EACf;EACA;;;;EAKA;;;;EAKA,aAAa;;;;;UAME;;;;EAIf;;;;EAKA,OAAO;;;;EAKP;;;;EAKA;;;;EAKA;;;;;UAMe;;;;EAIf;;;;EAKA,SAAS;;;;EAKT,aAAa;;;;EAKb,KAAK;;;;;UAMU;EACf;EACA;EACA;EACA,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;iBC1OG,aAAa,UAAS,wBAA6B"}
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { OxContentOptions, oxContent } from "@ox-content/vite-plugin";
1
+ import { OxContentOptions, RenderIslandFn, oxContent } from "@ox-content/vite-plugin";
2
2
  import { PluginOption } from "vite";
3
3
  //#region src/types.d.ts
4
4
  /**
@@ -117,6 +117,12 @@ interface VueIntegrationOptions extends OxContentOptions {
117
117
  * @default { github: true, openGraph: true }
118
118
  */
119
119
  embeds?: BuiltinEmbedOptions | false;
120
+ /**
121
+ * Optional adapter hook that replaces island inner HTML at transform time.
122
+ * The core renderer stays framework-neutral; do not import a framework SSR
123
+ * runtime from `@ox-content/vite-plugin`.
124
+ */
125
+ renderIsland?: RenderIslandFn;
120
126
  }
121
127
  /**
122
128
  * Fetch options for Vue GitHub embeds.
@@ -210,6 +216,8 @@ interface ResolvedVueOptions {
210
216
  reactivityTransform: boolean;
211
217
  customBlocks: boolean;
212
218
  embeds: ResolvedBuiltinEmbedOptions;
219
+ mdx?: boolean;
220
+ renderIsland?: RenderIslandFn;
213
221
  }
214
222
  /**
215
223
  * Transform result with Vue component information.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/index.ts"],"mappings":";;;;;;;;;UAYiB;;;;;;EAMf;;UAGe;EACf;EACA;;;;;;KAOU,gBAAgB;;;;;;;;;;;;;;;;;;;;;;KAuBhB,mBAAmB;;;;;;;;UASd,8BAA8B;;;;;;;;EAQ7C;;;;;;;;;;;;;;;;;;;;EAqBA,aAAa;;;;;;;;EASb,4BAA4B;;;;;;;;;EAU5B;;;;;;;;;EAUA;;;;;;;;;EAUA,SAAS;;;;;UAMM;;;;;EAKf;;;;;EAMA;;;;;EAMA;;;;;EAMA;;;;;EAMA;;;;;UAMe;;;;;EAKf;;;;;EAMA;;;;;EAMA;;;;;EAMA;;;;;UAMe;;;;;EAKf,mBAAmB;;;;;EAMnB,sBAAsB;;UAGP;EACf,QAAQ;EACR,WAAW;;;;;UAMI;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,iBAAiB;EACjB,YAAY;EACZ;EACA;EACA,QAAQ;;;;;UAMO;EACf;EACA;;;;EAKA;;;;EAKA,aAAa;;;;;UAME;;;;EAIf;;;;EAKA,OAAO;;;;EAKP;;;;EAKA;;;;EAKA;;;;;UAMe;;;;EAIf;;;;EAKA,SAAS;;;;EAKT,aAAa;;;;EAKb,KAAK;;;;;UAMU;EACf;EACA;EACA;EACA,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCjOG,aAAa,UAAS,wBAA6B"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/index.ts"],"mappings":";;;;;;;;;UAYiB;;;;;;EAMf;;UAGe;EACf;EACA;;;;;;KAOU,gBAAgB;;;;;;;;;;;;;;;;;;;;;;KAuBhB,mBAAmB;;;;;;;;UASd,8BAA8B;;;;;;;;EAQ7C;;;;;;;;;;;;;;;;;;;;EAqBA,aAAa;;;;;;;;EASb,4BAA4B;;;;;;;;;EAU5B;;;;;;;;;EAUA;;;;;;;;;EAUA,SAAS;;;;;;EAOT,eAAe;;;;;UAMA;;;;;EAKf;;;;;EAMA;;;;;EAMA;;;;;EAMA;;;;;EAMA;;;;;UAMe;;;;;EAKf;;;;;EAMA;;;;;EAMA;;;;;EAMA;;;;;UAMe;;;;;EAKf,mBAAmB;;;;;EAMnB,sBAAsB;;UAGP;EACf,QAAQ;EACR,WAAW;;;;;UAMI;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,iBAAiB;EACjB,YAAY;EACZ;EACA;EACA,QAAQ;EACR;EACA,eAAe;;;;;UAMA;EACf;EACA;;;;EAKA;;;;EAKA,aAAa;;;;;UAME;;;;EAIf;;;;EAKA,OAAO;;;;EAKP;;;;EAKA;;;;EAKA;;;;;UAMe;;;;EAIf;;;;EAKA,SAAS;;;;EAKT,aAAa;;;;EAKb,KAAK;;;;;UAMU;EACf;EACA;EACA;EACA,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;iBC1OG,aAAa,UAAS,wBAA6B"}
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as fs from "fs";
2
2
  import * as path from "path";
3
- import { oxContent, oxContent as oxContent$1, transformMarkdown } from "@ox-content/vite-plugin";
3
+ import { applyIslandSsrHtml, discoverDocumentMdxIslands, oxContent, oxContent as oxContent$1, renderIslandComponentImports, resolveContentRootPath, resolveMdxForFilePath, transformMarkdown } from "@ox-content/vite-plugin";
4
4
  //#region src/transform.ts
5
5
  /**
6
6
  * Markdown to Vue SFC transformation.
@@ -14,44 +14,14 @@ const ISLAND_MARKER_SUFFIX = "-PLACEHOLDER";
14
14
  */
15
15
  async function transformMarkdownWithVue(code, id, options) {
16
16
  const { components } = options;
17
- const usedComponents = [];
18
- const islands = [];
19
- let islandIndex = 0;
20
17
  const { content: markdownContent, frontmatter } = extractFrontmatter(code);
21
- const fenceRanges = collectFenceRanges(markdownContent);
22
- let processedContent = "";
23
- let lastIndex = 0;
24
- let match;
25
- COMPONENT_REGEX.lastIndex = 0;
26
- while ((match = COMPONENT_REGEX.exec(markdownContent)) !== null) {
27
- const [fullMatch, componentName, propsString, rawIslandContent] = match;
28
- const matchStart = match.index;
29
- const matchEnd = matchStart + fullMatch.length;
30
- if (!components.has(componentName) || isInRanges(matchStart, matchEnd, fenceRanges)) {
31
- processedContent += markdownContent.slice(lastIndex, matchEnd);
32
- lastIndex = matchEnd;
33
- continue;
34
- }
35
- if (!usedComponents.includes(componentName)) usedComponents.push(componentName);
36
- const props = parseProps(propsString);
37
- const islandId = `ox-island-${islandIndex++}`;
38
- const islandContent = typeof rawIslandContent === "string" ? rawIslandContent.trim() : void 0;
39
- islands.push({
40
- name: componentName,
41
- props,
42
- position: matchStart,
43
- id: islandId,
44
- content: islandContent
45
- });
46
- processedContent += markdownContent.slice(lastIndex, matchStart) + createIslandMarker(islandId);
47
- lastIndex = matchEnd;
48
- }
49
- processedContent += markdownContent.slice(lastIndex);
18
+ const mdx = resolveMdxForFilePath(id, options.mdx);
50
19
  const baseOptions = {
51
20
  srcDir: options.srcDir,
52
21
  outDir: options.outDir,
53
22
  base: options.base,
54
23
  extensions: options.extensions,
24
+ mdx,
55
25
  ssg: {
56
26
  enabled: false,
57
27
  extension: ".html",
@@ -61,6 +31,7 @@ async function transformMarkdownWithVue(code, id, options) {
61
31
  lastUpdated: false,
62
32
  pagination: false,
63
33
  breadcrumbs: false,
34
+ jsonLd: false,
64
35
  readerChrome: false,
65
36
  localeSwitcher: false,
66
37
  a11y: false,
@@ -99,6 +70,59 @@ async function transformMarkdownWithVue(code, id, options) {
99
70
  embeds: options.embeds,
100
71
  i18n: false
101
72
  };
73
+ if (mdx) {
74
+ const transformed = await transformMarkdown(markdownContent, id, baseOptions);
75
+ const discovered = await discoverDocumentMdxIslands({
76
+ source: markdownContent,
77
+ html: transformed.html,
78
+ components,
79
+ imports: transformed.imports,
80
+ documentPath: id,
81
+ contentRoot: resolveContentRootPath({
82
+ srcDir: options.srcDir,
83
+ root: options.root
84
+ }),
85
+ srcDir: options.srcDir
86
+ });
87
+ return {
88
+ code: generateVueSFC(options.renderIsland ? await applyIslandSsrHtml(transformed.html, options.renderIsland, id, discovered.usedComponents) : transformed.html, discovered.usedComponents, discovered.usedComponents, frontmatter, options, id, discovered.localBindings),
89
+ map: null,
90
+ usedComponents: discovered.usedComponents,
91
+ frontmatter
92
+ };
93
+ }
94
+ const usedComponents = [];
95
+ const islands = [];
96
+ let islandIndex = 0;
97
+ const fenceRanges = collectFenceRanges(markdownContent);
98
+ let processedContent = "";
99
+ let lastIndex = 0;
100
+ let match;
101
+ COMPONENT_REGEX.lastIndex = 0;
102
+ while ((match = COMPONENT_REGEX.exec(markdownContent)) !== null) {
103
+ const [fullMatch, componentName, propsString, rawIslandContent] = match;
104
+ const matchStart = match.index;
105
+ const matchEnd = matchStart + fullMatch.length;
106
+ if (!components.has(componentName) || isInRanges(matchStart, matchEnd, fenceRanges)) {
107
+ processedContent += markdownContent.slice(lastIndex, matchEnd);
108
+ lastIndex = matchEnd;
109
+ continue;
110
+ }
111
+ if (!usedComponents.includes(componentName)) usedComponents.push(componentName);
112
+ const props = parseProps(propsString);
113
+ const islandId = `ox-island-${islandIndex++}`;
114
+ const islandContent = typeof rawIslandContent === "string" ? rawIslandContent.trim() : void 0;
115
+ islands.push({
116
+ name: componentName,
117
+ props,
118
+ position: matchStart,
119
+ id: islandId,
120
+ content: islandContent
121
+ });
122
+ processedContent += markdownContent.slice(lastIndex, matchStart) + createIslandMarker(islandId);
123
+ lastIndex = matchEnd;
124
+ }
125
+ processedContent += markdownContent.slice(lastIndex);
102
126
  return {
103
127
  code: generateVueSFC(injectIslandMarkers((await transformMarkdown(processedContent, id, baseOptions)).html, islands), usedComponents, islands, frontmatter, options, id),
104
128
  map: null,
@@ -220,18 +244,15 @@ function parseProps(propsString) {
220
244
  /**
221
245
  * Generates a Vue component as JavaScript module from the processed Markdown.
222
246
  */
223
- function generateVueSFC(content, usedComponents, islands, frontmatter, options, id) {
224
- const mdDir = path.dirname(id);
225
- const root = options.root || process.cwd();
226
- const componentImports = usedComponents.map((name) => {
227
- const componentPath = options.components.get(name);
228
- if (!componentPath) return "";
229
- const absolutePath = path.resolve(root, componentPath.replace(/^\.\//, ""));
230
- const relativePath = path.relative(mdDir, absolutePath).replace(/\\/g, "/");
231
- return `import ${name} from '${relativePath.startsWith(".") ? relativePath : "./" + relativePath}';`;
232
- }).filter(Boolean).join("\n");
247
+ function generateVueSFC(content, usedComponents, _islands, frontmatter, options, id, localBindings) {
248
+ const componentImports = renderIslandComponentImports(usedComponents, {
249
+ globalComponents: options.components,
250
+ localBindings,
251
+ documentPath: id,
252
+ root: options.root
253
+ });
233
254
  const componentMap = usedComponents.map((name) => ` ${name},`).join("\n");
234
- if (islands.length === 0) return `
255
+ if (usedComponents.length === 0) return `
235
256
  import { h, ref, defineComponent } from 'vue';
236
257
 
237
258
  export const frontmatter = ${JSON.stringify(frontmatter)};
@@ -253,7 +274,7 @@ export default defineComponent({
253
274
  `;
254
275
  return `
255
276
  import { h, ref, onMounted, onBeforeUnmount, defineComponent, render } from 'vue';
256
- import { initIslands } from '@ox-content/islands';
277
+ import { initIslands, readIslandSlotHtml } from '@ox-content/islands';
257
278
  ${componentImports}
258
279
 
259
280
  export const frontmatter = ${JSON.stringify(frontmatter)};
@@ -271,7 +292,7 @@ function createVueHydrate(container) {
271
292
  const Component = components[componentName];
272
293
  if (!Component) return;
273
294
 
274
- const islandContent = element.dataset.oxContent || element.innerHTML;
295
+ const islandContent = readIslandSlotHtml(element);
275
296
  const children = islandContent
276
297
  ? { default: () => h('div', { innerHTML: islandContent }) }
277
298
  : undefined;
@@ -432,7 +453,8 @@ function oxContentVue(options = {}) {
432
453
  const result = await transformMarkdownWithVue(code, id, {
433
454
  ...resolved,
434
455
  components: componentMap,
435
- root: config.root
456
+ root: config.root,
457
+ renderIsland: options.renderIsland
436
458
  });
437
459
  return {
438
460
  code: result.code,
@@ -512,6 +534,7 @@ function resolveVueOptions(options) {
512
534
  codeAnnotations: resolveCodeAnnotationsOptions(options.codeAnnotations),
513
535
  components: options.components ?? {},
514
536
  embeds: resolveBuiltinEmbedOptions(options.embeds),
537
+ mdx: options.mdx,
515
538
  reactivityTransform: options.reactivityTransform ?? false,
516
539
  customBlocks: options.customBlocks ?? true
517
540
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["baseTransformMarkdown","oxContent"],"sources":["../src/transform.ts","../src/environment.ts","../src/index.ts"],"sourcesContent":["/**\n * Markdown to Vue SFC transformation.\n */\n\nimport * as path from \"path\";\nimport { transformMarkdown as baseTransformMarkdown } from \"@ox-content/vite-plugin\";\nimport type { ResolvedVueOptions, VueTransformResult, ComponentIsland } from \"./types\";\n\n// Regex to match Vue-like component tags in Markdown\nconst COMPONENT_REGEX = /<([A-Z][a-zA-Z0-9]*)\\s*([^>]*?)\\s*(?:\\/>|>([\\s\\S]*?)<\\/\\1>)/g;\n\n// Regex to parse component props\nconst PROP_REGEX =\n /(?::|v-bind:)?([a-zA-Z0-9-]+)(?:=(?:\"([^\"]*)\"|'([^']*)'|{([^}]*)}|\\[([^\\]]*)\\]))?/g;\n\nconst ISLAND_MARKER_PREFIX = \"OXCONTENT-ISLAND-\";\nconst ISLAND_MARKER_SUFFIX = \"-PLACEHOLDER\";\n\ninterface Range {\n start: number;\n end: number;\n}\n\n/**\n * Options for transformMarkdownWithVue.\n */\ninterface TransformOptions extends Omit<ResolvedVueOptions, \"components\"> {\n components: Map<string, string>;\n root?: string;\n}\n\n/**\n * Transforms Markdown content with Vue component support.\n */\nexport async function transformMarkdownWithVue(\n code: string,\n id: string,\n options: TransformOptions,\n): Promise<VueTransformResult> {\n const { components } = options;\n const usedComponents: string[] = [];\n const islands: ComponentIsland[] = [];\n let islandIndex = 0;\n\n // Extract frontmatter\n const { content: markdownContent, frontmatter } = extractFrontmatter(code);\n\n // Find and extract component usages\n const fenceRanges = collectFenceRanges(markdownContent);\n let processedContent = \"\";\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n COMPONENT_REGEX.lastIndex = 0;\n while ((match = COMPONENT_REGEX.exec(markdownContent)) !== null) {\n const [fullMatch, componentName, propsString, rawIslandContent] = match;\n const matchStart = match.index;\n const matchEnd = matchStart + fullMatch.length;\n\n // Check if component is registered\n if (!components.has(componentName) || isInRanges(matchStart, matchEnd, fenceRanges)) {\n processedContent += markdownContent.slice(lastIndex, matchEnd);\n lastIndex = matchEnd;\n continue;\n }\n\n if (!usedComponents.includes(componentName)) {\n usedComponents.push(componentName);\n }\n\n // Parse props\n const props = parseProps(propsString);\n\n // Create island placeholder\n const islandId = `ox-island-${islandIndex++}`;\n const islandContent =\n typeof rawIslandContent === \"string\" ? rawIslandContent.trim() : undefined;\n islands.push({\n name: componentName,\n props,\n position: matchStart,\n id: islandId,\n content: islandContent,\n });\n\n // Replace component with island marker text\n processedContent += markdownContent.slice(lastIndex, matchStart) + createIslandMarker(islandId);\n lastIndex = matchEnd;\n }\n processedContent += markdownContent.slice(lastIndex);\n\n // Transform Markdown to HTML using ox-content\n const baseOptions = {\n srcDir: options.srcDir,\n outDir: options.outDir,\n base: options.base,\n extensions: options.extensions,\n ssg: {\n enabled: false,\n extension: \".html\",\n clean: false,\n bare: false,\n generateOgImage: false,\n lastUpdated: false,\n pagination: false,\n breadcrumbs: false,\n readerChrome: false,\n localeSwitcher: false,\n a11y: false,\n pageChrome: false,\n },\n gfm: options.gfm,\n frontmatter: false, // Already extracted\n toc: options.toc,\n tocMaxDepth: options.tocMaxDepth,\n codeAnnotations: options.codeAnnotations,\n footnotes: true,\n tables: true,\n taskLists: true,\n strikethrough: true,\n autolinks: options.autolinks,\n highlight: false,\n mermaid: false,\n ogImage: false,\n ogImageOptions: {\n vuePlugin: \"vitejs\",\n width: 1200,\n height: 630,\n cache: true,\n concurrency: 1,\n },\n transformers: [],\n docs: false,\n ogViewer: false,\n search: {\n enabled: false,\n limit: 10,\n prefix: true,\n placeholder: \"Search...\",\n hotkey: \"k\",\n },\n embeds: options.embeds,\n i18n: false,\n } as unknown as Parameters<typeof baseTransformMarkdown>[2] & {\n codeAnnotations?: TransformOptions[\"codeAnnotations\"];\n };\n\n const transformed = await baseTransformMarkdown(processedContent, id, baseOptions);\n\n // Generate Vue SFC code\n const htmlWithIslands = injectIslandMarkers(transformed.html, islands);\n const sfcCode = generateVueSFC(\n htmlWithIslands,\n usedComponents,\n islands,\n frontmatter,\n options,\n id,\n );\n\n return {\n code: sfcCode,\n map: null,\n usedComponents,\n frontmatter,\n };\n}\n\nfunction createIslandMarker(islandId: string): string {\n return `${ISLAND_MARKER_PREFIX}${islandId}${ISLAND_MARKER_SUFFIX}`;\n}\n\nfunction collectFenceRanges(content: string): Range[] {\n const ranges: Range[] = [];\n let inFence = false;\n let fenceChar = \"\";\n let fenceLength = 0;\n let fenceStart = 0;\n let pos = 0;\n\n while (pos < content.length) {\n const lineEnd = content.indexOf(\"\\n\", pos);\n const next = lineEnd === -1 ? content.length : lineEnd + 1;\n const line = content.slice(pos, lineEnd === -1 ? content.length : lineEnd);\n const fenceMatch = line.match(/^\\s{0,3}([`~]{3,})/);\n\n if (fenceMatch) {\n const marker = fenceMatch[1];\n if (!inFence) {\n inFence = true;\n fenceChar = marker[0];\n fenceLength = marker.length;\n fenceStart = pos;\n } else if (marker[0] === fenceChar && marker.length >= fenceLength) {\n inFence = false;\n ranges.push({ start: fenceStart, end: next });\n fenceChar = \"\";\n fenceLength = 0;\n }\n }\n\n pos = next;\n }\n\n if (inFence) {\n ranges.push({ start: fenceStart, end: content.length });\n }\n\n return ranges;\n}\n\nfunction isInRanges(start: number, end: number, ranges: Range[]): boolean {\n for (const range of ranges) {\n if (start < range.end && end > range.start) {\n return true;\n }\n }\n return false;\n}\n\nfunction injectIslandMarkers(html: string, islands: ComponentIsland[]): string {\n let output = html;\n\n for (const island of islands) {\n const marker = createIslandMarker(island.id);\n const propsAttr =\n Object.keys(island.props).length > 0\n ? ` data-ox-props='${JSON.stringify(island.props).replace(/'/g, \"&#39;\")}'`\n : \"\";\n const contentAttr = island.content\n ? ` data-ox-content='${island.content.replace(/'/g, \"&#39;\")}'`\n : \"\";\n const attrs = `data-ox-island=\"${island.name}\"${propsAttr}${contentAttr}`;\n output = output.replaceAll(`<p>${marker}</p>`, `<div ${attrs}></div>`);\n output = output.replaceAll(marker, `<span ${attrs}></span>`);\n }\n\n return output;\n}\n\n/**\n * Extracts frontmatter from Markdown content.\n */\nfunction extractFrontmatter(content: string): {\n content: string;\n frontmatter: Record<string, unknown>;\n} {\n const frontmatterRegex = /^---\\n([\\s\\S]*?)\\n---\\n/;\n const match = frontmatterRegex.exec(content);\n\n if (!match) {\n return { content, frontmatter: {} };\n }\n\n const frontmatterStr = match[1];\n const frontmatter: Record<string, unknown> = {};\n\n // Simple YAML-like parsing\n for (const line of frontmatterStr.split(\"\\n\")) {\n const colonIndex = line.indexOf(\":\");\n if (colonIndex > 0) {\n const key = line.slice(0, colonIndex).trim();\n let value: unknown = line.slice(colonIndex + 1).trim();\n\n // Try to parse as JSON for complex values\n try {\n value = JSON.parse(value as string);\n } catch {\n // Keep as string if not valid JSON\n // Remove quotes if present\n if (\n typeof value === \"string\" &&\n ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\")))\n ) {\n value = value.slice(1, -1);\n }\n }\n\n frontmatter[key] = value;\n }\n }\n\n return {\n content: content.slice(match[0].length),\n frontmatter,\n };\n}\n\n/**\n * Parses component props from a string.\n */\nfunction parseProps(propsString: string): Record<string, unknown> {\n const props: Record<string, unknown> = {};\n\n if (!propsString) return props;\n\n let match: RegExpExecArray | null;\n while ((match = PROP_REGEX.exec(propsString)) !== null) {\n const [, name, doubleQuoted, singleQuoted, braceValue, bracketValue] = match;\n\n if (name) {\n if (doubleQuoted !== undefined) {\n props[name] = doubleQuoted;\n } else if (singleQuoted !== undefined) {\n props[name] = singleQuoted;\n } else if (braceValue !== undefined) {\n // Try to parse as JSON\n try {\n props[name] = JSON.parse(`{${braceValue}}`);\n } catch {\n props[name] = braceValue;\n }\n } else if (bracketValue !== undefined) {\n try {\n props[name] = JSON.parse(`[${bracketValue}]`);\n } catch {\n props[name] = bracketValue;\n }\n } else {\n // Boolean prop\n props[name] = true;\n }\n }\n }\n\n return props;\n}\n\n/**\n * Generates a Vue component as JavaScript module from the processed Markdown.\n */\nfunction generateVueSFC(\n content: string,\n usedComponents: string[],\n islands: ComponentIsland[],\n frontmatter: Record<string, unknown>,\n options: TransformOptions,\n id: string,\n): string {\n const mdDir = path.dirname(id);\n const root = options.root || process.cwd();\n\n const componentImports = usedComponents\n .map((name) => {\n const componentPath = options.components.get(name);\n if (!componentPath) return \"\";\n // Convert relative-to-root path to relative-to-md-file path\n const absolutePath = path.resolve(root, componentPath.replace(/^\\.\\//, \"\"));\n const relativePath = path.relative(mdDir, absolutePath).replace(/\\\\/g, \"/\");\n // Ensure the path starts with ./ or ../\n const importPath = relativePath.startsWith(\".\") ? relativePath : \"./\" + relativePath;\n return `import ${name} from '${importPath}';`;\n })\n .filter(Boolean)\n .join(\"\\n\");\n\n const componentMap = usedComponents.map((name) => ` ${name},`).join(\"\\n\");\n\n // If no islands, generate simpler code without island runtime\n if (islands.length === 0) {\n return `\nimport { h, ref, defineComponent } from 'vue';\n\nexport const frontmatter = ${JSON.stringify(frontmatter)};\n\nconst rawHtml = ${JSON.stringify(content)};\n\nexport default defineComponent({\n name: 'MarkdownContent',\n setup(_, { expose }) {\n expose({ frontmatter });\n\n return () =>\n h('div', {\n class: 'ox-content',\n innerHTML: rawHtml,\n });\n },\n});\n`;\n }\n\n return `\nimport { h, ref, onMounted, onBeforeUnmount, defineComponent, render } from 'vue';\nimport { initIslands } from '@ox-content/islands';\n${componentImports}\n\nexport const frontmatter = ${JSON.stringify(frontmatter)};\n\nconst rawHtml = ${JSON.stringify(content)};\nconst components = {\n${componentMap}\n};\n\nfunction createVueHydrate(container) {\n const mountedTargets = [];\n\n return (element, props) => {\n const componentName = element.dataset.oxIsland;\n const Component = components[componentName];\n if (!Component) return;\n\n const islandContent = element.dataset.oxContent || element.innerHTML;\n const children = islandContent\n ? { default: () => h('div', { innerHTML: islandContent }) }\n : undefined;\n\n const vnode = h(Component, props, children);\n render(vnode, element);\n mountedTargets.push(element);\n\n return () => render(null, element);\n };\n}\n\nexport default defineComponent({\n name: 'MarkdownContent',\n setup(_, { expose }) {\n const container = ref(null);\n let controller;\n\n onMounted(() => {\n if (container.value) {\n controller = initIslands(createVueHydrate(container.value), {\n selector: '.ox-content [data-ox-island]',\n });\n }\n });\n\n onBeforeUnmount(() => {\n if (controller) controller.destroy();\n });\n\n expose({ frontmatter });\n\n return () =>\n h('div', {\n class: 'ox-content',\n ref: container,\n innerHTML: rawHtml,\n });\n },\n});\n`;\n}\n","/**\n * Vite Environment API configuration for Vue integration.\n */\n\nimport type { EnvironmentOptions } from \"vite\";\nimport type { ResolvedVueOptions } from \"./types\";\n\n/**\n * Creates a Vite environment for Vue markdown processing.\n *\n * @param mode - 'ssr' for server-side rendering, 'client' for client hydration\n * @param options - Resolved Vue integration options\n */\nexport function createVueMarkdownEnvironment(\n mode: \"ssr\" | \"client\",\n options: ResolvedVueOptions,\n): EnvironmentOptions {\n const isSSR = mode === \"ssr\";\n\n return {\n build: {\n outDir: isSSR ? `${options.outDir}/.ox-content/ssr` : `${options.outDir}/.ox-content/client`,\n\n ssr: isSSR,\n\n rollupOptions: {\n input: isSSR ? undefined : undefined,\n output: {\n format: isSSR ? \"esm\" : \"esm\",\n entryFileNames: isSSR ? \"[name].js\" : \"[name].[hash].js\",\n chunkFileNames: isSSR ? \"chunks/[name].js\" : \"chunks/[name].[hash].js\",\n },\n },\n\n // SSR-specific optimizations\n ...(isSSR && {\n target: \"node18\",\n minify: false,\n }),\n },\n\n resolve: {\n conditions: isSSR ? [\"node\", \"import\"] : [\"browser\", \"import\"],\n },\n\n optimizeDeps: {\n // Pre-bundle Vue for faster cold starts\n include: isSSR ? [] : [\"vue\"],\n\n // Exclude ox-content packages from optimization (they're local)\n exclude: [\"@ox-content/vite-plugin\", \"@ox-content/vite-plugin-vue\"],\n },\n\n // Development server options (client only)\n ...(!isSSR && {\n dev: {\n warmup: [\"./src/**/*.vue\", \"./docs/**/*.{md,markdown,mdx}\"],\n },\n }),\n };\n}\n\n/**\n * Creates environment-specific virtual modules.\n */\nexport function createVirtualModules(\n mode: \"ssr\" | \"client\",\n _options: ResolvedVueOptions,\n): Record<string, string> {\n const isSSR = mode === \"ssr\";\n\n return {\n // Environment detection module\n \"virtual:ox-content/env\": `\n export const isSSR = ${isSSR};\n export const isClient = ${!isSSR};\n export const mode = '${mode}';\n `,\n\n // Hydration utilities\n \"virtual:ox-content/hydration\": isSSR\n ? `\n // SSR: No-op hydration\n export function hydrate() {}\n export function createSSRApp(component) {\n return component;\n }\n `\n : `\n import { createApp } from 'vue';\n\n export function hydrate(component, container, props = {}) {\n const app = createApp(component, props);\n app.mount(container);\n return app;\n }\n\n export function createClientApp(component) {\n return createApp(component);\n }\n `,\n };\n}\n","/**\n * Vite Plugin for Ox Content Vue Integration\n *\n * Uses Vite's Environment API to enable embedding Vue components in Markdown.\n * Provides SSR and client environments for proper hydration.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport type { Plugin, PluginOption, ResolvedConfig } from \"vite\";\nimport { oxContent } from \"@ox-content/vite-plugin\";\nimport { transformMarkdownWithVue } from \"./transform\";\nimport { createVueMarkdownEnvironment } from \"./environment\";\nimport type {\n VueIntegrationOptions,\n ResolvedVueOptions,\n ComponentsMap,\n ComponentsOption,\n BuiltinEmbedOptions,\n} from \"./types\";\n\nconst DEFAULT_MARKDOWN_EXTENSIONS = [\".md\", \".markdown\", \".mdx\"] as const;\n\nfunction normalizeMarkdownExtensions(extensions?: readonly string[]): string[] {\n const values = extensions?.length ? extensions : DEFAULT_MARKDOWN_EXTENSIONS;\n return Array.from(\n new Map(\n values.map((extension) => {\n const value = extension.startsWith(\".\") ? extension : `.${extension}`;\n return [value.toLowerCase(), value] as const;\n }),\n ).values(),\n );\n}\n\nfunction isMarkdownFilePath(filePath: string, extensions: readonly string[]): boolean {\n const pathname = filePath.split(\"?\")[0].split(\"#\")[0].toLowerCase();\n return extensions.some((extension) => pathname.endsWith(extension.toLowerCase()));\n}\n\nfunction resolveBuiltinEmbedOptions(\n options: BuiltinEmbedOptions | false | undefined,\n): ResolvedVueOptions[\"embeds\"] {\n if (options === false) return { github: false, openGraph: false };\n return {\n github: resolveSingleEmbedOptions(options?.github),\n openGraph: resolveSingleEmbedOptions(options?.openGraph),\n };\n}\n\nfunction resolveSingleEmbedOptions<T extends object>(options: boolean | T | undefined): T | false {\n if (options === false) return false;\n if (options === true || options === undefined) return {} as T;\n return options;\n}\n\nexport type {\n VueIntegrationOptions,\n ResolvedVueOptions,\n ComponentsOption,\n ComponentsMap,\n BuiltinEmbedOptions,\n GitHubEmbedOptions,\n OpenGraphEmbedOptions,\n ResolvedBuiltinEmbedOptions,\n VueTransformResult,\n ComponentIsland,\n ParsedMarkdownContent,\n TocEntry,\n} from \"./types\";\n\n/**\n * Creates the Ox Content Vue integration plugin with Environment API support.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import vue from '@vitejs/plugin-vue';\n * import { oxContentVue } from 'vite-plugin-ox-content-vue';\n *\n * export default defineConfig({\n * plugins: [\n * vue(),\n * oxContentVue({\n * srcDir: 'docs',\n * components: {\n * Counter: './src/components/Counter.vue',\n * },\n * }),\n * ],\n * });\n * ```\n */\nexport function oxContentVue(options: VueIntegrationOptions = {}): PluginOption[] {\n const resolved = resolveVueOptions(options);\n let componentMap = new Map<string, string>();\n let config: ResolvedConfig;\n\n // Pre-resolve components if it's a map (not glob)\n if (typeof options.components === \"object\" && !Array.isArray(options.components)) {\n componentMap = new Map(Object.entries(options.components));\n }\n\n // Main Vue transformation plugin\n const vueTransformPlugin: Plugin = {\n name: \"ox-content:vue-transform\",\n enforce: \"pre\",\n\n async configResolved(resolvedConfig) {\n config = resolvedConfig;\n\n // Resolve glob patterns for components\n const componentsOption = options.components;\n if (componentsOption) {\n const resolvedComponents = await resolveComponentsGlob(componentsOption, config.root);\n componentMap = new Map(Object.entries(resolvedComponents));\n }\n },\n\n async transform(code, id) {\n if (!isMarkdownFilePath(id, resolved.extensions)) {\n return null;\n }\n\n const result = await transformMarkdownWithVue(code, id, {\n ...resolved,\n components: componentMap,\n root: config.root,\n });\n\n return {\n code: result.code,\n map: result.map,\n };\n },\n };\n\n // Environment API plugin for Vue-specific SSR/client handling\n const vueEnvironmentPlugin: Plugin = {\n name: \"ox-content:vue-environment\",\n\n config() {\n return {\n environments: {\n // SSR environment for Vue component rendering\n oxcontent_ssr: createVueMarkdownEnvironment(\"ssr\", resolved),\n // Client environment for hydration\n oxcontent_client: createVueMarkdownEnvironment(\"client\", resolved),\n },\n };\n },\n\n // Environment-specific module resolution\n resolveId: {\n order: \"pre\",\n async handler(id, _importer, _options) {\n // Handle virtual modules for Vue markdown runtime\n if (id === \"virtual:ox-content-vue/runtime\") {\n return \"\\0virtual:ox-content-vue/runtime\";\n }\n\n if (id === \"virtual:ox-content-vue/components\") {\n return \"\\0virtual:ox-content-vue/components\";\n }\n\n return null;\n },\n },\n\n load: {\n order: \"pre\",\n async handler(id) {\n if (id === \"\\0virtual:ox-content-vue/runtime\") {\n return generateRuntimeModule(resolved);\n }\n\n if (id === \"\\0virtual:ox-content-vue/components\") {\n return generateComponentsModule(componentMap);\n }\n\n return null;\n },\n },\n\n // Per-environment build hooks\n applyToEnvironment(environment) {\n return (\n environment.name === \"oxcontent_ssr\" ||\n environment.name === \"oxcontent_client\" ||\n environment.name === \"client\" ||\n environment.name === \"ssr\"\n );\n },\n };\n\n // HMR plugin for component updates\n const vueHmrPlugin: Plugin = {\n name: \"ox-content:vue-hmr\",\n apply: \"serve\",\n\n handleHotUpdate({ file, server, modules }) {\n // Check if updated file is a registered component\n const isComponent = Array.from(componentMap.values()).some((path) =>\n file.endsWith(path.replace(/^\\.\\//, \"\")),\n );\n\n if (isComponent) {\n // Invalidate all Markdown modules that might use this component\n const mdModules = Array.from(server.moduleGraph.idToModuleMap.values()).filter(\n (mod) => mod.file && isMarkdownFilePath(mod.file, resolved.extensions),\n );\n\n if (mdModules.length > 0) {\n server.ws.send({\n type: \"custom\",\n event: \"ox-content:vue-update\",\n data: { file },\n });\n return [...modules, ...mdModules];\n }\n }\n\n return modules;\n },\n };\n\n // Get base ox-content plugins (environment plugin only)\n const basePlugins = oxContent(options).flatMap((plugin) =>\n Array.isArray(plugin) ? plugin : [plugin],\n ) as Plugin[];\n const environmentPlugin = basePlugins.find((plugin) => plugin.name === \"ox-content:environment\");\n const plugins: Plugin[] = [vueTransformPlugin, vueEnvironmentPlugin, vueHmrPlugin];\n\n if (environmentPlugin) {\n plugins.push(environmentPlugin);\n }\n\n return plugins;\n}\n\n/**\n * Resolves Vue integration options with defaults.\n */\nfunction resolveVueOptions(options: VueIntegrationOptions): ResolvedVueOptions {\n return {\n srcDir: options.srcDir ?? \"docs\",\n outDir: options.outDir ?? \"dist\",\n base: options.base ?? \"/\",\n extensions: normalizeMarkdownExtensions(options.extensions),\n gfm: options.gfm ?? true,\n autolinks: options.autolinks ?? options.gfm ?? true,\n frontmatter: options.frontmatter ?? true,\n toc: options.toc ?? true,\n tocMaxDepth: options.tocMaxDepth ?? 3,\n codeAnnotations: resolveCodeAnnotationsOptions(options.codeAnnotations),\n components: options.components ?? {},\n embeds: resolveBuiltinEmbedOptions(options.embeds),\n // Vue-specific options\n reactivityTransform: options.reactivityTransform ?? false,\n customBlocks: options.customBlocks ?? true,\n };\n}\n\nfunction resolveCodeAnnotationsOptions(\n options: VueIntegrationOptions[\"codeAnnotations\"],\n): ResolvedVueOptions[\"codeAnnotations\"] {\n if (!options) {\n return {\n enabled: false,\n metaKey: \"annotate\",\n };\n }\n\n if (options === true) {\n return {\n enabled: true,\n metaKey: \"annotate\",\n };\n }\n\n return {\n enabled: true,\n metaKey: options.metaKey ?? \"annotate\",\n };\n}\n\n/**\n * Generates the runtime module for Vue markdown rendering.\n */\nfunction generateRuntimeModule(_options: ResolvedVueOptions): string {\n return `\nimport { h, defineComponent, ref, onMounted } from 'vue';\n\nexport const OxContentRenderer = defineComponent({\n name: 'OxContentRenderer',\n props: {\n content: { type: Object, required: true },\n components: { type: Object, default: () => ({}) },\n },\n setup(props) {\n const mounted = ref(false);\n\n onMounted(() => {\n mounted.value = true;\n });\n\n return () => {\n if (!props.content) return null;\n\n const { html, frontmatter, toc, islands } = props.content;\n\n // Render static HTML with component islands\n return h('div', {\n class: 'ox-content',\n innerHTML: mounted.value ? undefined : html,\n }, mounted.value ? renderWithIslands(html, islands, props.components) : undefined);\n };\n },\n});\n\nfunction renderWithIslands(html, islands, components) {\n // Parse and render islands with Vue components\n // This is a simplified version - full implementation would use proper parsing\n return h('div', { innerHTML: html });\n}\n\nexport function useOxContent() {\n return {\n OxContentRenderer,\n };\n}\n`;\n}\n\n/**\n * Generates the components registration module.\n */\nfunction generateComponentsModule(componentMap: Map<string, string>): string {\n const imports: string[] = [];\n const exports: string[] = [];\n\n componentMap.forEach((path, name) => {\n imports.push(`import ${name} from '${path}';`);\n exports.push(` ${name},`);\n });\n\n return `\n${imports.join(\"\\n\")}\n\nexport const components = {\n${exports.join(\"\\n\")}\n};\n\nexport default components;\n`;\n}\n\n/**\n * Resolves component glob patterns to a component map.\n */\nasync function resolveComponentsGlob(\n componentsOption: ComponentsOption,\n root: string,\n): Promise<ComponentsMap> {\n // If it's already a map, return as-is\n if (typeof componentsOption === \"object\" && !Array.isArray(componentsOption)) {\n return componentsOption;\n }\n\n const patterns = Array.isArray(componentsOption) ? componentsOption : [componentsOption];\n\n const result: ComponentsMap = {};\n\n for (const pattern of patterns) {\n const files = await globFiles(pattern, root);\n\n for (const file of files) {\n // Derive component name from file name (PascalCase)\n const baseName = path.basename(file, path.extname(file));\n const componentName = toPascalCase(baseName);\n const relativePath = \"./\" + path.relative(root, file).replace(/\\\\/g, \"/\");\n\n result[componentName] = relativePath;\n }\n }\n\n return result;\n}\n\n/**\n * Simple glob matcher for component files.\n */\nasync function globFiles(pattern: string, root: string): Promise<string[]> {\n const files: string[] = [];\n\n // Parse glob pattern\n const isGlob = pattern.includes(\"*\");\n\n if (!isGlob) {\n // It's a direct path\n const fullPath = path.resolve(root, pattern);\n if (fs.existsSync(fullPath)) {\n files.push(fullPath);\n }\n return files;\n }\n\n // Handle glob patterns like './src/components/*.vue'\n const parts = pattern.split(\"*\");\n const baseDir = path.resolve(root, parts[0]);\n const ext = parts[1] || \"\";\n\n if (!fs.existsSync(baseDir)) {\n return files;\n }\n\n // Handle ** recursive pattern\n if (pattern.includes(\"**\")) {\n await walkDir(baseDir, files, ext);\n } else {\n // Single level glob\n const entries = await fs.promises.readdir(baseDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isFile() && entry.name.endsWith(ext)) {\n files.push(path.join(baseDir, entry.name));\n }\n }\n }\n\n return files;\n}\n\n/**\n * Recursively walks a directory.\n */\nasync function walkDir(dir: string, files: string[], ext: string): Promise<void> {\n const entries = await fs.promises.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n await walkDir(fullPath, files, ext);\n } else if (entry.isFile() && entry.name.endsWith(ext)) {\n files.push(fullPath);\n }\n }\n}\n\n/**\n * Converts a string to PascalCase.\n */\nfunction toPascalCase(str: string): string {\n return str.replace(/[-_](\\w)/g, (_, c) => c.toUpperCase()).replace(/^\\w/, (c) => c.toUpperCase());\n}\n\n// Re-export\nexport { oxContent } from \"@ox-content/vite-plugin\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["baseTransformMarkdown","oxContent"],"sources":["../src/transform.ts","../src/environment.ts","../src/index.ts"],"sourcesContent":["/**\n * Markdown to Vue SFC transformation.\n */\n\nimport {\n applyIslandSsrHtml,\n discoverDocumentMdxIslands,\n renderIslandComponentImports,\n resolveContentRootPath,\n resolveMdxForFilePath,\n transformMarkdown as baseTransformMarkdown,\n type ResolvedDocumentComponentImport,\n} from \"@ox-content/vite-plugin\";\nimport type { ResolvedVueOptions, VueTransformResult, ComponentIsland } from \"./types\";\n\n// Regex to match Vue-like component tags in Markdown\nconst COMPONENT_REGEX = /<([A-Z][a-zA-Z0-9]*)\\s*([^>]*?)\\s*(?:\\/>|>([\\s\\S]*?)<\\/\\1>)/g;\n\n// Regex to parse component props\nconst PROP_REGEX =\n /(?::|v-bind:)?([a-zA-Z0-9-]+)(?:=(?:\"([^\"]*)\"|'([^']*)'|{([^}]*)}|\\[([^\\]]*)\\]))?/g;\n\nconst ISLAND_MARKER_PREFIX = \"OXCONTENT-ISLAND-\";\nconst ISLAND_MARKER_SUFFIX = \"-PLACEHOLDER\";\n\ninterface Range {\n start: number;\n end: number;\n}\n\n/**\n * Options for transformMarkdownWithVue.\n */\ninterface TransformOptions extends Omit<ResolvedVueOptions, \"components\"> {\n components: Map<string, string>;\n root?: string;\n}\n\n/**\n * Transforms Markdown content with Vue component support.\n */\nexport async function transformMarkdownWithVue(\n code: string,\n id: string,\n options: TransformOptions,\n): Promise<VueTransformResult> {\n const { components } = options;\n const { content: markdownContent, frontmatter } = extractFrontmatter(code);\n const mdx = resolveMdxForFilePath(id, options.mdx);\n\n const baseOptions = {\n srcDir: options.srcDir,\n outDir: options.outDir,\n base: options.base,\n extensions: options.extensions,\n mdx,\n ssg: {\n enabled: false,\n extension: \".html\",\n clean: false,\n bare: false,\n generateOgImage: false,\n lastUpdated: false,\n pagination: false,\n breadcrumbs: false,\n jsonLd: false,\n readerChrome: false,\n localeSwitcher: false,\n a11y: false,\n pageChrome: false,\n },\n gfm: options.gfm,\n frontmatter: false,\n toc: options.toc,\n tocMaxDepth: options.tocMaxDepth,\n codeAnnotations: options.codeAnnotations,\n footnotes: true,\n tables: true,\n taskLists: true,\n strikethrough: true,\n autolinks: options.autolinks,\n highlight: false,\n mermaid: false,\n ogImage: false,\n ogImageOptions: {\n vuePlugin: \"vitejs\",\n width: 1200,\n height: 630,\n cache: true,\n concurrency: 1,\n },\n transformers: [],\n docs: false,\n ogViewer: false,\n search: {\n enabled: false,\n limit: 10,\n prefix: true,\n placeholder: \"Search...\",\n hotkey: \"k\",\n },\n embeds: options.embeds,\n i18n: false,\n } as unknown as Parameters<typeof baseTransformMarkdown>[2] & {\n codeAnnotations?: TransformOptions[\"codeAnnotations\"];\n };\n\n if (mdx) {\n const transformed = await baseTransformMarkdown(markdownContent, id, baseOptions);\n const discovered = await discoverDocumentMdxIslands({\n source: markdownContent,\n html: transformed.html,\n components,\n imports: transformed.imports,\n documentPath: id,\n contentRoot: resolveContentRootPath({ srcDir: options.srcDir, root: options.root }),\n srcDir: options.srcDir,\n });\n const html = options.renderIsland\n ? await applyIslandSsrHtml(\n transformed.html,\n options.renderIsland,\n id,\n discovered.usedComponents,\n )\n : transformed.html;\n return {\n code: generateVueSFC(\n html,\n discovered.usedComponents,\n discovered.usedComponents,\n frontmatter,\n options,\n id,\n discovered.localBindings,\n ),\n map: null,\n usedComponents: discovered.usedComponents,\n frontmatter,\n };\n }\n\n const usedComponents: string[] = [];\n const islands: ComponentIsland[] = [];\n let islandIndex = 0;\n\n const fenceRanges = collectFenceRanges(markdownContent);\n let processedContent = \"\";\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n COMPONENT_REGEX.lastIndex = 0;\n while ((match = COMPONENT_REGEX.exec(markdownContent)) !== null) {\n const [fullMatch, componentName, propsString, rawIslandContent] = match;\n const matchStart = match.index;\n const matchEnd = matchStart + fullMatch.length;\n\n // Check if component is registered\n if (!components.has(componentName) || isInRanges(matchStart, matchEnd, fenceRanges)) {\n processedContent += markdownContent.slice(lastIndex, matchEnd);\n lastIndex = matchEnd;\n continue;\n }\n\n if (!usedComponents.includes(componentName)) {\n usedComponents.push(componentName);\n }\n\n // Parse props\n const props = parseProps(propsString);\n\n // Create island placeholder\n const islandId = `ox-island-${islandIndex++}`;\n const islandContent =\n typeof rawIslandContent === \"string\" ? rawIslandContent.trim() : undefined;\n islands.push({\n name: componentName,\n props,\n position: matchStart,\n id: islandId,\n content: islandContent,\n });\n\n // Replace component with island marker text\n processedContent += markdownContent.slice(lastIndex, matchStart) + createIslandMarker(islandId);\n lastIndex = matchEnd;\n }\n processedContent += markdownContent.slice(lastIndex);\n\n const transformed = await baseTransformMarkdown(processedContent, id, baseOptions);\n\n // Generate Vue SFC code\n const htmlWithIslands = injectIslandMarkers(transformed.html, islands);\n const sfcCode = generateVueSFC(\n htmlWithIslands,\n usedComponents,\n islands,\n frontmatter,\n options,\n id,\n );\n\n return {\n code: sfcCode,\n map: null,\n usedComponents,\n frontmatter,\n };\n}\n\nfunction createIslandMarker(islandId: string): string {\n return `${ISLAND_MARKER_PREFIX}${islandId}${ISLAND_MARKER_SUFFIX}`;\n}\n\nfunction collectFenceRanges(content: string): Range[] {\n const ranges: Range[] = [];\n let inFence = false;\n let fenceChar = \"\";\n let fenceLength = 0;\n let fenceStart = 0;\n let pos = 0;\n\n while (pos < content.length) {\n const lineEnd = content.indexOf(\"\\n\", pos);\n const next = lineEnd === -1 ? content.length : lineEnd + 1;\n const line = content.slice(pos, lineEnd === -1 ? content.length : lineEnd);\n const fenceMatch = line.match(/^\\s{0,3}([`~]{3,})/);\n\n if (fenceMatch) {\n const marker = fenceMatch[1];\n if (!inFence) {\n inFence = true;\n fenceChar = marker[0];\n fenceLength = marker.length;\n fenceStart = pos;\n } else if (marker[0] === fenceChar && marker.length >= fenceLength) {\n inFence = false;\n ranges.push({ start: fenceStart, end: next });\n fenceChar = \"\";\n fenceLength = 0;\n }\n }\n\n pos = next;\n }\n\n if (inFence) {\n ranges.push({ start: fenceStart, end: content.length });\n }\n\n return ranges;\n}\n\nfunction isInRanges(start: number, end: number, ranges: Range[]): boolean {\n for (const range of ranges) {\n if (start < range.end && end > range.start) {\n return true;\n }\n }\n return false;\n}\n\nfunction injectIslandMarkers(html: string, islands: ComponentIsland[]): string {\n let output = html;\n\n for (const island of islands) {\n const marker = createIslandMarker(island.id);\n const propsAttr =\n Object.keys(island.props).length > 0\n ? ` data-ox-props='${JSON.stringify(island.props).replace(/'/g, \"&#39;\")}'`\n : \"\";\n const contentAttr = island.content\n ? ` data-ox-content='${island.content.replace(/'/g, \"&#39;\")}'`\n : \"\";\n const attrs = `data-ox-island=\"${island.name}\"${propsAttr}${contentAttr}`;\n output = output.replaceAll(`<p>${marker}</p>`, `<div ${attrs}></div>`);\n output = output.replaceAll(marker, `<span ${attrs}></span>`);\n }\n\n return output;\n}\n\n/**\n * Extracts frontmatter from Markdown content.\n */\nfunction extractFrontmatter(content: string): {\n content: string;\n frontmatter: Record<string, unknown>;\n} {\n const frontmatterRegex = /^---\\n([\\s\\S]*?)\\n---\\n/;\n const match = frontmatterRegex.exec(content);\n\n if (!match) {\n return { content, frontmatter: {} };\n }\n\n const frontmatterStr = match[1];\n const frontmatter: Record<string, unknown> = {};\n\n // Simple YAML-like parsing\n for (const line of frontmatterStr.split(\"\\n\")) {\n const colonIndex = line.indexOf(\":\");\n if (colonIndex > 0) {\n const key = line.slice(0, colonIndex).trim();\n let value: unknown = line.slice(colonIndex + 1).trim();\n\n // Try to parse as JSON for complex values\n try {\n value = JSON.parse(value as string);\n } catch {\n // Keep as string if not valid JSON\n // Remove quotes if present\n if (\n typeof value === \"string\" &&\n ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\")))\n ) {\n value = value.slice(1, -1);\n }\n }\n\n frontmatter[key] = value;\n }\n }\n\n return {\n content: content.slice(match[0].length),\n frontmatter,\n };\n}\n\n/**\n * Parses component props from a string.\n */\nfunction parseProps(propsString: string): Record<string, unknown> {\n const props: Record<string, unknown> = {};\n\n if (!propsString) return props;\n\n let match: RegExpExecArray | null;\n while ((match = PROP_REGEX.exec(propsString)) !== null) {\n const [, name, doubleQuoted, singleQuoted, braceValue, bracketValue] = match;\n\n if (name) {\n if (doubleQuoted !== undefined) {\n props[name] = doubleQuoted;\n } else if (singleQuoted !== undefined) {\n props[name] = singleQuoted;\n } else if (braceValue !== undefined) {\n // Try to parse as JSON\n try {\n props[name] = JSON.parse(`{${braceValue}}`);\n } catch {\n props[name] = braceValue;\n }\n } else if (bracketValue !== undefined) {\n try {\n props[name] = JSON.parse(`[${bracketValue}]`);\n } catch {\n props[name] = bracketValue;\n }\n } else {\n // Boolean prop\n props[name] = true;\n }\n }\n }\n\n return props;\n}\n\n/**\n * Generates a Vue component as JavaScript module from the processed Markdown.\n */\nfunction generateVueSFC(\n content: string,\n usedComponents: string[],\n _islands: ComponentIsland[] | string[],\n frontmatter: Record<string, unknown>,\n options: TransformOptions,\n id: string,\n localBindings?: ReadonlyMap<string, ResolvedDocumentComponentImport>,\n): string {\n const componentImports = renderIslandComponentImports(usedComponents, {\n globalComponents: options.components,\n localBindings,\n documentPath: id,\n root: options.root,\n });\n\n const componentMap = usedComponents.map((name) => ` ${name},`).join(\"\\n\");\n\n // If no registered islands, generate simpler code without island runtime\n if (usedComponents.length === 0) {\n return `\nimport { h, ref, defineComponent } from 'vue';\n\nexport const frontmatter = ${JSON.stringify(frontmatter)};\n\nconst rawHtml = ${JSON.stringify(content)};\n\nexport default defineComponent({\n name: 'MarkdownContent',\n setup(_, { expose }) {\n expose({ frontmatter });\n\n return () =>\n h('div', {\n class: 'ox-content',\n innerHTML: rawHtml,\n });\n },\n});\n`;\n }\n\n return `\nimport { h, ref, onMounted, onBeforeUnmount, defineComponent, render } from 'vue';\nimport { initIslands, readIslandSlotHtml } from '@ox-content/islands';\n${componentImports}\n\nexport const frontmatter = ${JSON.stringify(frontmatter)};\n\nconst rawHtml = ${JSON.stringify(content)};\nconst components = {\n${componentMap}\n};\n\nfunction createVueHydrate(container) {\n const mountedTargets = [];\n\n return (element, props) => {\n const componentName = element.dataset.oxIsland;\n const Component = components[componentName];\n if (!Component) return;\n\n const islandContent = readIslandSlotHtml(element);\n const children = islandContent\n ? { default: () => h('div', { innerHTML: islandContent }) }\n : undefined;\n\n const vnode = h(Component, props, children);\n render(vnode, element);\n mountedTargets.push(element);\n\n return () => render(null, element);\n };\n}\n\nexport default defineComponent({\n name: 'MarkdownContent',\n setup(_, { expose }) {\n const container = ref(null);\n let controller;\n\n onMounted(() => {\n if (container.value) {\n controller = initIslands(createVueHydrate(container.value), {\n selector: '.ox-content [data-ox-island]',\n });\n }\n });\n\n onBeforeUnmount(() => {\n if (controller) controller.destroy();\n });\n\n expose({ frontmatter });\n\n return () =>\n h('div', {\n class: 'ox-content',\n ref: container,\n innerHTML: rawHtml,\n });\n },\n});\n`;\n}\n","/**\n * Vite Environment API configuration for Vue integration.\n */\n\nimport type { EnvironmentOptions } from \"vite\";\nimport type { ResolvedVueOptions } from \"./types\";\n\n/**\n * Creates a Vite environment for Vue markdown processing.\n *\n * @param mode - 'ssr' for server-side rendering, 'client' for client hydration\n * @param options - Resolved Vue integration options\n */\nexport function createVueMarkdownEnvironment(\n mode: \"ssr\" | \"client\",\n options: ResolvedVueOptions,\n): EnvironmentOptions {\n const isSSR = mode === \"ssr\";\n\n return {\n build: {\n outDir: isSSR ? `${options.outDir}/.ox-content/ssr` : `${options.outDir}/.ox-content/client`,\n\n ssr: isSSR,\n\n rollupOptions: {\n input: isSSR ? undefined : undefined,\n output: {\n format: isSSR ? \"esm\" : \"esm\",\n entryFileNames: isSSR ? \"[name].js\" : \"[name].[hash].js\",\n chunkFileNames: isSSR ? \"chunks/[name].js\" : \"chunks/[name].[hash].js\",\n },\n },\n\n // SSR-specific optimizations\n ...(isSSR && {\n target: \"node18\",\n minify: false,\n }),\n },\n\n resolve: {\n conditions: isSSR ? [\"node\", \"import\"] : [\"browser\", \"import\"],\n },\n\n optimizeDeps: {\n // Pre-bundle Vue for faster cold starts\n include: isSSR ? [] : [\"vue\"],\n\n // Exclude ox-content packages from optimization (they're local)\n exclude: [\"@ox-content/vite-plugin\", \"@ox-content/vite-plugin-vue\"],\n },\n\n // Development server options (client only)\n ...(!isSSR && {\n dev: {\n warmup: [\"./src/**/*.vue\", \"./docs/**/*.{md,markdown,mdx}\"],\n },\n }),\n };\n}\n\n/**\n * Creates environment-specific virtual modules.\n */\nexport function createVirtualModules(\n mode: \"ssr\" | \"client\",\n _options: ResolvedVueOptions,\n): Record<string, string> {\n const isSSR = mode === \"ssr\";\n\n return {\n // Environment detection module\n \"virtual:ox-content/env\": `\n export const isSSR = ${isSSR};\n export const isClient = ${!isSSR};\n export const mode = '${mode}';\n `,\n\n // Hydration utilities\n \"virtual:ox-content/hydration\": isSSR\n ? `\n // SSR: No-op hydration\n export function hydrate() {}\n export function createSSRApp(component) {\n return component;\n }\n `\n : `\n import { createApp } from 'vue';\n\n export function hydrate(component, container, props = {}) {\n const app = createApp(component, props);\n app.mount(container);\n return app;\n }\n\n export function createClientApp(component) {\n return createApp(component);\n }\n `,\n };\n}\n","/**\n * Vite Plugin for Ox Content Vue Integration\n *\n * Uses Vite's Environment API to enable embedding Vue components in Markdown.\n * Provides SSR and client environments for proper hydration.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport type { Plugin, PluginOption, ResolvedConfig } from \"vite\";\nimport { oxContent } from \"@ox-content/vite-plugin\";\nimport { transformMarkdownWithVue } from \"./transform\";\nimport { createVueMarkdownEnvironment } from \"./environment\";\nimport type {\n VueIntegrationOptions,\n ResolvedVueOptions,\n ComponentsMap,\n ComponentsOption,\n BuiltinEmbedOptions,\n} from \"./types\";\n\nconst DEFAULT_MARKDOWN_EXTENSIONS = [\".md\", \".markdown\", \".mdx\"] as const;\n\nfunction normalizeMarkdownExtensions(extensions?: readonly string[]): string[] {\n const values = extensions?.length ? extensions : DEFAULT_MARKDOWN_EXTENSIONS;\n return Array.from(\n new Map(\n values.map((extension) => {\n const value = extension.startsWith(\".\") ? extension : `.${extension}`;\n return [value.toLowerCase(), value] as const;\n }),\n ).values(),\n );\n}\n\nfunction isMarkdownFilePath(filePath: string, extensions: readonly string[]): boolean {\n const pathname = filePath.split(\"?\")[0].split(\"#\")[0].toLowerCase();\n return extensions.some((extension) => pathname.endsWith(extension.toLowerCase()));\n}\n\nfunction resolveBuiltinEmbedOptions(\n options: BuiltinEmbedOptions | false | undefined,\n): ResolvedVueOptions[\"embeds\"] {\n if (options === false) return { github: false, openGraph: false };\n return {\n github: resolveSingleEmbedOptions(options?.github),\n openGraph: resolveSingleEmbedOptions(options?.openGraph),\n };\n}\n\nfunction resolveSingleEmbedOptions<T extends object>(options: boolean | T | undefined): T | false {\n if (options === false) return false;\n if (options === true || options === undefined) return {} as T;\n return options;\n}\n\nexport type {\n VueIntegrationOptions,\n ResolvedVueOptions,\n ComponentsOption,\n ComponentsMap,\n BuiltinEmbedOptions,\n GitHubEmbedOptions,\n OpenGraphEmbedOptions,\n ResolvedBuiltinEmbedOptions,\n VueTransformResult,\n ComponentIsland,\n ParsedMarkdownContent,\n TocEntry,\n} from \"./types\";\n\n/**\n * Creates the Ox Content Vue integration plugin with Environment API support.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import vue from '@vitejs/plugin-vue';\n * import { oxContentVue } from 'vite-plugin-ox-content-vue';\n *\n * export default defineConfig({\n * plugins: [\n * vue(),\n * oxContentVue({\n * srcDir: 'docs',\n * components: {\n * Counter: './src/components/Counter.vue',\n * },\n * }),\n * ],\n * });\n * ```\n */\nexport function oxContentVue(options: VueIntegrationOptions = {}): PluginOption[] {\n const resolved = resolveVueOptions(options);\n let componentMap = new Map<string, string>();\n let config: ResolvedConfig;\n\n // Pre-resolve components if it's a map (not glob)\n if (typeof options.components === \"object\" && !Array.isArray(options.components)) {\n componentMap = new Map(Object.entries(options.components));\n }\n\n // Main Vue transformation plugin\n const vueTransformPlugin: Plugin = {\n name: \"ox-content:vue-transform\",\n enforce: \"pre\",\n\n async configResolved(resolvedConfig) {\n config = resolvedConfig;\n\n // Resolve glob patterns for components\n const componentsOption = options.components;\n if (componentsOption) {\n const resolvedComponents = await resolveComponentsGlob(componentsOption, config.root);\n componentMap = new Map(Object.entries(resolvedComponents));\n }\n },\n\n async transform(code, id) {\n if (!isMarkdownFilePath(id, resolved.extensions)) {\n return null;\n }\n\n const result = await transformMarkdownWithVue(code, id, {\n ...resolved,\n components: componentMap,\n root: config.root,\n renderIsland: options.renderIsland,\n });\n\n return {\n code: result.code,\n map: result.map,\n };\n },\n };\n\n // Environment API plugin for Vue-specific SSR/client handling\n const vueEnvironmentPlugin: Plugin = {\n name: \"ox-content:vue-environment\",\n\n config() {\n return {\n environments: {\n // SSR environment for Vue component rendering\n oxcontent_ssr: createVueMarkdownEnvironment(\"ssr\", resolved),\n // Client environment for hydration\n oxcontent_client: createVueMarkdownEnvironment(\"client\", resolved),\n },\n };\n },\n\n // Environment-specific module resolution\n resolveId: {\n order: \"pre\",\n async handler(id, _importer, _options) {\n // Handle virtual modules for Vue markdown runtime\n if (id === \"virtual:ox-content-vue/runtime\") {\n return \"\\0virtual:ox-content-vue/runtime\";\n }\n\n if (id === \"virtual:ox-content-vue/components\") {\n return \"\\0virtual:ox-content-vue/components\";\n }\n\n return null;\n },\n },\n\n load: {\n order: \"pre\",\n async handler(id) {\n if (id === \"\\0virtual:ox-content-vue/runtime\") {\n return generateRuntimeModule(resolved);\n }\n\n if (id === \"\\0virtual:ox-content-vue/components\") {\n return generateComponentsModule(componentMap);\n }\n\n return null;\n },\n },\n\n // Per-environment build hooks\n applyToEnvironment(environment) {\n return (\n environment.name === \"oxcontent_ssr\" ||\n environment.name === \"oxcontent_client\" ||\n environment.name === \"client\" ||\n environment.name === \"ssr\"\n );\n },\n };\n\n // HMR plugin for component updates\n const vueHmrPlugin: Plugin = {\n name: \"ox-content:vue-hmr\",\n apply: \"serve\",\n\n handleHotUpdate({ file, server, modules }) {\n // Check if updated file is a registered component\n const isComponent = Array.from(componentMap.values()).some((path) =>\n file.endsWith(path.replace(/^\\.\\//, \"\")),\n );\n\n if (isComponent) {\n // Invalidate all Markdown modules that might use this component\n const mdModules = Array.from(server.moduleGraph.idToModuleMap.values()).filter(\n (mod) => mod.file && isMarkdownFilePath(mod.file, resolved.extensions),\n );\n\n if (mdModules.length > 0) {\n server.ws.send({\n type: \"custom\",\n event: \"ox-content:vue-update\",\n data: { file },\n });\n return [...modules, ...mdModules];\n }\n }\n\n return modules;\n },\n };\n\n // Get base ox-content plugins (environment plugin only)\n const basePlugins = oxContent(options).flatMap((plugin) =>\n Array.isArray(plugin) ? plugin : [plugin],\n ) as Plugin[];\n const environmentPlugin = basePlugins.find((plugin) => plugin.name === \"ox-content:environment\");\n const plugins: Plugin[] = [vueTransformPlugin, vueEnvironmentPlugin, vueHmrPlugin];\n\n if (environmentPlugin) {\n plugins.push(environmentPlugin);\n }\n\n return plugins;\n}\n\n/**\n * Resolves Vue integration options with defaults.\n */\nfunction resolveVueOptions(options: VueIntegrationOptions): ResolvedVueOptions {\n return {\n srcDir: options.srcDir ?? \"docs\",\n outDir: options.outDir ?? \"dist\",\n base: options.base ?? \"/\",\n extensions: normalizeMarkdownExtensions(options.extensions),\n gfm: options.gfm ?? true,\n autolinks: options.autolinks ?? options.gfm ?? true,\n frontmatter: options.frontmatter ?? true,\n toc: options.toc ?? true,\n tocMaxDepth: options.tocMaxDepth ?? 3,\n codeAnnotations: resolveCodeAnnotationsOptions(options.codeAnnotations),\n components: options.components ?? {},\n embeds: resolveBuiltinEmbedOptions(options.embeds),\n mdx: options.mdx,\n // Vue-specific options\n reactivityTransform: options.reactivityTransform ?? false,\n customBlocks: options.customBlocks ?? true,\n };\n}\n\nfunction resolveCodeAnnotationsOptions(\n options: VueIntegrationOptions[\"codeAnnotations\"],\n): ResolvedVueOptions[\"codeAnnotations\"] {\n if (!options) {\n return {\n enabled: false,\n metaKey: \"annotate\",\n };\n }\n\n if (options === true) {\n return {\n enabled: true,\n metaKey: \"annotate\",\n };\n }\n\n return {\n enabled: true,\n metaKey: options.metaKey ?? \"annotate\",\n };\n}\n\n/**\n * Generates the runtime module for Vue markdown rendering.\n */\nfunction generateRuntimeModule(_options: ResolvedVueOptions): string {\n return `\nimport { h, defineComponent, ref, onMounted } from 'vue';\n\nexport const OxContentRenderer = defineComponent({\n name: 'OxContentRenderer',\n props: {\n content: { type: Object, required: true },\n components: { type: Object, default: () => ({}) },\n },\n setup(props) {\n const mounted = ref(false);\n\n onMounted(() => {\n mounted.value = true;\n });\n\n return () => {\n if (!props.content) return null;\n\n const { html, frontmatter, toc, islands } = props.content;\n\n // Render static HTML with component islands\n return h('div', {\n class: 'ox-content',\n innerHTML: mounted.value ? undefined : html,\n }, mounted.value ? renderWithIslands(html, islands, props.components) : undefined);\n };\n },\n});\n\nfunction renderWithIslands(html, islands, components) {\n // Parse and render islands with Vue components\n // This is a simplified version - full implementation would use proper parsing\n return h('div', { innerHTML: html });\n}\n\nexport function useOxContent() {\n return {\n OxContentRenderer,\n };\n}\n`;\n}\n\n/**\n * Generates the components registration module.\n */\nfunction generateComponentsModule(componentMap: Map<string, string>): string {\n const imports: string[] = [];\n const exports: string[] = [];\n\n componentMap.forEach((path, name) => {\n imports.push(`import ${name} from '${path}';`);\n exports.push(` ${name},`);\n });\n\n return `\n${imports.join(\"\\n\")}\n\nexport const components = {\n${exports.join(\"\\n\")}\n};\n\nexport default components;\n`;\n}\n\n/**\n * Resolves component glob patterns to a component map.\n */\nasync function resolveComponentsGlob(\n componentsOption: ComponentsOption,\n root: string,\n): Promise<ComponentsMap> {\n // If it's already a map, return as-is\n if (typeof componentsOption === \"object\" && !Array.isArray(componentsOption)) {\n return componentsOption;\n }\n\n const patterns = Array.isArray(componentsOption) ? componentsOption : [componentsOption];\n\n const result: ComponentsMap = {};\n\n for (const pattern of patterns) {\n const files = await globFiles(pattern, root);\n\n for (const file of files) {\n // Derive component name from file name (PascalCase)\n const baseName = path.basename(file, path.extname(file));\n const componentName = toPascalCase(baseName);\n const relativePath = \"./\" + path.relative(root, file).replace(/\\\\/g, \"/\");\n\n result[componentName] = relativePath;\n }\n }\n\n return result;\n}\n\n/**\n * Simple glob matcher for component files.\n */\nasync function globFiles(pattern: string, root: string): Promise<string[]> {\n const files: string[] = [];\n\n // Parse glob pattern\n const isGlob = pattern.includes(\"*\");\n\n if (!isGlob) {\n // It's a direct path\n const fullPath = path.resolve(root, pattern);\n if (fs.existsSync(fullPath)) {\n files.push(fullPath);\n }\n return files;\n }\n\n // Handle glob patterns like './src/components/*.vue'\n const parts = pattern.split(\"*\");\n const baseDir = path.resolve(root, parts[0]);\n const ext = parts[1] || \"\";\n\n if (!fs.existsSync(baseDir)) {\n return files;\n }\n\n // Handle ** recursive pattern\n if (pattern.includes(\"**\")) {\n await walkDir(baseDir, files, ext);\n } else {\n // Single level glob\n const entries = await fs.promises.readdir(baseDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isFile() && entry.name.endsWith(ext)) {\n files.push(path.join(baseDir, entry.name));\n }\n }\n }\n\n return files;\n}\n\n/**\n * Recursively walks a directory.\n */\nasync function walkDir(dir: string, files: string[], ext: string): Promise<void> {\n const entries = await fs.promises.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n await walkDir(fullPath, files, ext);\n } else if (entry.isFile() && entry.name.endsWith(ext)) {\n files.push(fullPath);\n }\n }\n}\n\n/**\n * Converts a string to PascalCase.\n */\nfunction toPascalCase(str: string): string {\n return str.replace(/[-_](\\w)/g, (_, c) => c.toUpperCase()).replace(/^\\w/, (c) => c.toUpperCase());\n}\n\n// Re-export\nexport { oxContent } from \"@ox-content/vite-plugin\";\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ox-content/vite-plugin-vue",
3
- "version": "3.0.0-alpha.1",
3
+ "version": "3.0.0-alpha.2",
4
4
  "description": "Vue integration for Ox Content - Embed Vue components in Markdown",
5
5
  "keywords": [
6
6
  "markdown",
@@ -35,8 +35,8 @@
35
35
  "provenance": true
36
36
  },
37
37
  "dependencies": {
38
- "@ox-content/islands": "3.0.0-alpha.1",
39
- "@ox-content/vite-plugin": "3.0.0-alpha.1"
38
+ "@ox-content/islands": "3.0.0-alpha.2",
39
+ "@ox-content/vite-plugin": "3.0.0-alpha.2"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/node": "^26.2.0",