@ox-content/vite-plugin-vue 0.17.0 → 1.1.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.cjs +93 -83
- package/dist/index.d.cts +9 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/{index.d.ts → index.d.mts} +10 -3
- package/dist/index.d.mts.map +1 -0
- package/dist/{index.js → index.mjs} +67 -52
- package/dist/index.mjs.map +1 -0
- package/package.json +37 -36
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
2
3
|
var __create = Object.create;
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -6,16 +7,12 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
|
6
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
9
|
var __copyProps = (to, from, except, desc) => {
|
|
9
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
}
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
19
16
|
}
|
|
20
17
|
return to;
|
|
21
18
|
};
|
|
@@ -23,14 +20,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
20
|
value: mod,
|
|
24
21
|
enumerable: true
|
|
25
22
|
}) : target, mod));
|
|
26
|
-
|
|
27
23
|
//#endregion
|
|
28
24
|
let fs = require("fs");
|
|
29
25
|
fs = __toESM(fs);
|
|
30
|
-
let path
|
|
31
|
-
path
|
|
26
|
+
let path = require("path");
|
|
27
|
+
path = __toESM(path);
|
|
32
28
|
let _ox_content_vite_plugin = require("@ox-content/vite-plugin");
|
|
33
|
-
|
|
34
29
|
//#region src/transform.ts
|
|
35
30
|
/**
|
|
36
31
|
* Markdown to Vue SFC transformation.
|
|
@@ -77,50 +72,52 @@ async function transformMarkdownWithVue(code, id, options) {
|
|
|
77
72
|
lastIndex = matchEnd;
|
|
78
73
|
}
|
|
79
74
|
processedContent += markdownContent.slice(lastIndex);
|
|
75
|
+
const baseOptions = {
|
|
76
|
+
srcDir: options.srcDir,
|
|
77
|
+
outDir: options.outDir,
|
|
78
|
+
base: options.base,
|
|
79
|
+
ssg: {
|
|
80
|
+
enabled: false,
|
|
81
|
+
extension: ".html",
|
|
82
|
+
clean: false,
|
|
83
|
+
bare: false,
|
|
84
|
+
generateOgImage: false
|
|
85
|
+
},
|
|
86
|
+
gfm: options.gfm,
|
|
87
|
+
frontmatter: false,
|
|
88
|
+
toc: options.toc,
|
|
89
|
+
tocMaxDepth: options.tocMaxDepth,
|
|
90
|
+
codeAnnotations: options.codeAnnotations,
|
|
91
|
+
footnotes: true,
|
|
92
|
+
tables: true,
|
|
93
|
+
taskLists: true,
|
|
94
|
+
strikethrough: true,
|
|
95
|
+
highlight: false,
|
|
96
|
+
highlightTheme: "github-dark",
|
|
97
|
+
highlightLangs: [],
|
|
98
|
+
mermaid: false,
|
|
99
|
+
ogImage: false,
|
|
100
|
+
ogImageOptions: {
|
|
101
|
+
vuePlugin: "vitejs",
|
|
102
|
+
width: 1200,
|
|
103
|
+
height: 630,
|
|
104
|
+
cache: true,
|
|
105
|
+
concurrency: 1
|
|
106
|
+
},
|
|
107
|
+
transformers: [],
|
|
108
|
+
docs: false,
|
|
109
|
+
ogViewer: false,
|
|
110
|
+
search: {
|
|
111
|
+
enabled: false,
|
|
112
|
+
limit: 10,
|
|
113
|
+
prefix: true,
|
|
114
|
+
placeholder: "Search...",
|
|
115
|
+
hotkey: "k"
|
|
116
|
+
},
|
|
117
|
+
i18n: false
|
|
118
|
+
};
|
|
80
119
|
return {
|
|
81
|
-
code: generateVueSFC(injectIslandMarkers((await (0, _ox_content_vite_plugin.transformMarkdown)(processedContent, id,
|
|
82
|
-
srcDir: options.srcDir,
|
|
83
|
-
outDir: options.outDir,
|
|
84
|
-
base: options.base,
|
|
85
|
-
ssg: {
|
|
86
|
-
enabled: false,
|
|
87
|
-
extension: ".html",
|
|
88
|
-
clean: false,
|
|
89
|
-
bare: false,
|
|
90
|
-
generateOgImage: false
|
|
91
|
-
},
|
|
92
|
-
gfm: options.gfm,
|
|
93
|
-
frontmatter: false,
|
|
94
|
-
toc: options.toc,
|
|
95
|
-
tocMaxDepth: options.tocMaxDepth,
|
|
96
|
-
footnotes: true,
|
|
97
|
-
tables: true,
|
|
98
|
-
taskLists: true,
|
|
99
|
-
strikethrough: true,
|
|
100
|
-
highlight: false,
|
|
101
|
-
highlightTheme: "github-dark",
|
|
102
|
-
highlightLangs: [],
|
|
103
|
-
mermaid: false,
|
|
104
|
-
ogImage: false,
|
|
105
|
-
ogImageOptions: {
|
|
106
|
-
vuePlugin: "vitejs",
|
|
107
|
-
width: 1200,
|
|
108
|
-
height: 630,
|
|
109
|
-
cache: true,
|
|
110
|
-
concurrency: 1
|
|
111
|
-
},
|
|
112
|
-
transformers: [],
|
|
113
|
-
docs: false,
|
|
114
|
-
ogViewer: false,
|
|
115
|
-
search: {
|
|
116
|
-
enabled: false,
|
|
117
|
-
limit: 10,
|
|
118
|
-
prefix: true,
|
|
119
|
-
placeholder: "Search...",
|
|
120
|
-
hotkey: "k"
|
|
121
|
-
},
|
|
122
|
-
i18n: false
|
|
123
|
-
})).html, islands), usedComponents, islands, frontmatter, options, id),
|
|
120
|
+
code: generateVueSFC(injectIslandMarkers((await (0, _ox_content_vite_plugin.transformMarkdown)(processedContent, id, baseOptions)).html, islands), usedComponents, islands, frontmatter, options, id),
|
|
124
121
|
map: null,
|
|
125
122
|
usedComponents,
|
|
126
123
|
frontmatter
|
|
@@ -239,13 +236,13 @@ function parseProps(propsString) {
|
|
|
239
236
|
* Generates a Vue component as JavaScript module from the processed Markdown.
|
|
240
237
|
*/
|
|
241
238
|
function generateVueSFC(content, usedComponents, islands, frontmatter, options, id) {
|
|
242
|
-
const mdDir = path
|
|
239
|
+
const mdDir = path.dirname(id);
|
|
243
240
|
const root = options.root || process.cwd();
|
|
244
241
|
const componentImports = usedComponents.map((name) => {
|
|
245
242
|
const componentPath = options.components.get(name);
|
|
246
243
|
if (!componentPath) return "";
|
|
247
|
-
const absolutePath = path
|
|
248
|
-
const relativePath = path
|
|
244
|
+
const absolutePath = path.resolve(root, componentPath.replace(/^\.\//, ""));
|
|
245
|
+
const relativePath = path.relative(mdDir, absolutePath).replace(/\\/g, "/");
|
|
249
246
|
return `import ${name} from '${relativePath.startsWith(".") ? relativePath : "./" + relativePath}';`;
|
|
250
247
|
}).filter(Boolean).join("\n");
|
|
251
248
|
const componentMap = usedComponents.map((name) => ` ${name},`).join("\n");
|
|
@@ -332,7 +329,6 @@ export default defineComponent({
|
|
|
332
329
|
});
|
|
333
330
|
`;
|
|
334
331
|
}
|
|
335
|
-
|
|
336
332
|
//#endregion
|
|
337
333
|
//#region src/environment.ts
|
|
338
334
|
/**
|
|
@@ -368,7 +364,6 @@ function createVueMarkdownEnvironment(mode, options) {
|
|
|
368
364
|
...!isSSR && { dev: { warmup: ["./src/**/*.vue", "./docs/**/*.md"] } }
|
|
369
365
|
};
|
|
370
366
|
}
|
|
371
|
-
|
|
372
367
|
//#endregion
|
|
373
368
|
//#region src/index.ts
|
|
374
369
|
/**
|
|
@@ -461,7 +456,7 @@ function oxContentVue(options = {}) {
|
|
|
461
456
|
name: "ox-content:vue-hmr",
|
|
462
457
|
apply: "serve",
|
|
463
458
|
handleHotUpdate({ file, server, modules }) {
|
|
464
|
-
if (Array.from(componentMap.values()).some((path) => file.endsWith(path.replace(/^\.\//, "")))) {
|
|
459
|
+
if (Array.from(componentMap.values()).some((path$1) => file.endsWith(path$1.replace(/^\.\//, "")))) {
|
|
465
460
|
const mdModules = Array.from(server.moduleGraph.idToModuleMap.values()).filter((mod) => mod.file?.endsWith(".md"));
|
|
466
461
|
if (mdModules.length > 0) {
|
|
467
462
|
server.ws.send({
|
|
@@ -475,13 +470,14 @@ function oxContentVue(options = {}) {
|
|
|
475
470
|
return modules;
|
|
476
471
|
}
|
|
477
472
|
};
|
|
478
|
-
const environmentPlugin = (0, _ox_content_vite_plugin.oxContent)(options).find((
|
|
479
|
-
|
|
473
|
+
const environmentPlugin = (0, _ox_content_vite_plugin.oxContent)(options).flatMap((plugin) => Array.isArray(plugin) ? plugin : [plugin]).find((plugin) => plugin.name === "ox-content:environment");
|
|
474
|
+
const plugins = [
|
|
480
475
|
vueTransformPlugin,
|
|
481
476
|
vueEnvironmentPlugin,
|
|
482
|
-
vueHmrPlugin
|
|
483
|
-
...environmentPlugin ? [environmentPlugin] : []
|
|
477
|
+
vueHmrPlugin
|
|
484
478
|
];
|
|
479
|
+
if (environmentPlugin) plugins.push(environmentPlugin);
|
|
480
|
+
return plugins;
|
|
485
481
|
}
|
|
486
482
|
/**
|
|
487
483
|
* Resolves Vue integration options with defaults.
|
|
@@ -495,11 +491,26 @@ function resolveVueOptions(options) {
|
|
|
495
491
|
frontmatter: options.frontmatter ?? true,
|
|
496
492
|
toc: options.toc ?? true,
|
|
497
493
|
tocMaxDepth: options.tocMaxDepth ?? 3,
|
|
494
|
+
codeAnnotations: resolveCodeAnnotationsOptions(options.codeAnnotations),
|
|
498
495
|
components: options.components ?? {},
|
|
499
496
|
reactivityTransform: options.reactivityTransform ?? false,
|
|
500
497
|
customBlocks: options.customBlocks ?? true
|
|
501
498
|
};
|
|
502
499
|
}
|
|
500
|
+
function resolveCodeAnnotationsOptions(options) {
|
|
501
|
+
if (!options) return {
|
|
502
|
+
enabled: false,
|
|
503
|
+
metaKey: "annotate"
|
|
504
|
+
};
|
|
505
|
+
if (options === true) return {
|
|
506
|
+
enabled: true,
|
|
507
|
+
metaKey: "annotate"
|
|
508
|
+
};
|
|
509
|
+
return {
|
|
510
|
+
enabled: true,
|
|
511
|
+
metaKey: options.metaKey ?? "annotate"
|
|
512
|
+
};
|
|
513
|
+
}
|
|
503
514
|
/**
|
|
504
515
|
* Generates the runtime module for Vue markdown rendering.
|
|
505
516
|
*/
|
|
@@ -553,8 +564,8 @@ export function useOxContent() {
|
|
|
553
564
|
function generateComponentsModule(componentMap) {
|
|
554
565
|
const imports = [];
|
|
555
566
|
const exports = [];
|
|
556
|
-
componentMap.forEach((path, name) => {
|
|
557
|
-
imports.push(`import ${name} from '${path}';`);
|
|
567
|
+
componentMap.forEach((path$2, name) => {
|
|
568
|
+
imports.push(`import ${name} from '${path$2}';`);
|
|
558
569
|
exports.push(` ${name},`);
|
|
559
570
|
});
|
|
560
571
|
return `
|
|
@@ -577,8 +588,8 @@ async function resolveComponentsGlob(componentsOption, root) {
|
|
|
577
588
|
for (const pattern of patterns) {
|
|
578
589
|
const files = await globFiles(pattern, root);
|
|
579
590
|
for (const file of files) {
|
|
580
|
-
const componentName = toPascalCase(path
|
|
581
|
-
result[componentName] = "./" + path
|
|
591
|
+
const componentName = toPascalCase(path.basename(file, path.extname(file)));
|
|
592
|
+
result[componentName] = "./" + path.relative(root, file).replace(/\\/g, "/");
|
|
582
593
|
}
|
|
583
594
|
}
|
|
584
595
|
return result;
|
|
@@ -589,18 +600,18 @@ async function resolveComponentsGlob(componentsOption, root) {
|
|
|
589
600
|
async function globFiles(pattern, root) {
|
|
590
601
|
const files = [];
|
|
591
602
|
if (!pattern.includes("*")) {
|
|
592
|
-
const fullPath = path
|
|
603
|
+
const fullPath = path.resolve(root, pattern);
|
|
593
604
|
if (fs.existsSync(fullPath)) files.push(fullPath);
|
|
594
605
|
return files;
|
|
595
606
|
}
|
|
596
607
|
const parts = pattern.split("*");
|
|
597
|
-
const baseDir = path
|
|
608
|
+
const baseDir = path.resolve(root, parts[0]);
|
|
598
609
|
const ext = parts[1] || "";
|
|
599
610
|
if (!fs.existsSync(baseDir)) return files;
|
|
600
611
|
if (pattern.includes("**")) await walkDir(baseDir, files, ext);
|
|
601
612
|
else {
|
|
602
613
|
const entries = await fs.promises.readdir(baseDir, { withFileTypes: true });
|
|
603
|
-
for (const entry of entries) if (entry.isFile() && entry.name.endsWith(ext)) files.push(path
|
|
614
|
+
for (const entry of entries) if (entry.isFile() && entry.name.endsWith(ext)) files.push(path.join(baseDir, entry.name));
|
|
604
615
|
}
|
|
605
616
|
return files;
|
|
606
617
|
}
|
|
@@ -610,7 +621,7 @@ async function globFiles(pattern, root) {
|
|
|
610
621
|
async function walkDir(dir, files, ext) {
|
|
611
622
|
const entries = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
612
623
|
for (const entry of entries) {
|
|
613
|
-
const fullPath = path
|
|
624
|
+
const fullPath = path.join(dir, entry.name);
|
|
614
625
|
if (entry.isDirectory()) await walkDir(fullPath, files, ext);
|
|
615
626
|
else if (entry.isFile() && entry.name.endsWith(ext)) files.push(fullPath);
|
|
616
627
|
}
|
|
@@ -621,12 +632,11 @@ async function walkDir(dir, files, ext) {
|
|
|
621
632
|
function toPascalCase(str) {
|
|
622
633
|
return str.replace(/[-_](\w)/g, (_, c) => c.toUpperCase()).replace(/^\w/, (c) => c.toUpperCase());
|
|
623
634
|
}
|
|
624
|
-
|
|
625
635
|
//#endregion
|
|
626
|
-
Object.defineProperty(exports,
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
636
|
+
Object.defineProperty(exports, "oxContent", {
|
|
637
|
+
enumerable: true,
|
|
638
|
+
get: function() {
|
|
639
|
+
return _ox_content_vite_plugin.oxContent;
|
|
640
|
+
}
|
|
631
641
|
});
|
|
632
|
-
exports.oxContentVue = oxContentVue;
|
|
642
|
+
exports.oxContentVue = oxContentVue;
|
package/dist/index.d.cts
CHANGED
|
@@ -2,7 +2,13 @@ import { PluginOption } from "vite";
|
|
|
2
2
|
import { OxContentOptions, oxContent } from "@ox-content/vite-plugin";
|
|
3
3
|
|
|
4
4
|
//#region src/types.d.ts
|
|
5
|
-
|
|
5
|
+
interface CodeAnnotationsOptions {
|
|
6
|
+
metaKey?: string;
|
|
7
|
+
}
|
|
8
|
+
interface ResolvedCodeAnnotationsOptions {
|
|
9
|
+
enabled: boolean;
|
|
10
|
+
metaKey: string;
|
|
11
|
+
}
|
|
6
12
|
/**
|
|
7
13
|
* Component registration map.
|
|
8
14
|
* Key is the component name to use in Markdown, value is the import path.
|
|
@@ -56,6 +62,7 @@ interface VueIntegrationOptions extends OxContentOptions {
|
|
|
56
62
|
* @default true
|
|
57
63
|
*/
|
|
58
64
|
components?: ComponentsOption;
|
|
65
|
+
codeAnnotations?: boolean | CodeAnnotationsOptions;
|
|
59
66
|
reactivityTransform?: boolean;
|
|
60
67
|
customBlocks?: boolean;
|
|
61
68
|
}
|
|
@@ -70,6 +77,7 @@ interface ResolvedVueOptions {
|
|
|
70
77
|
frontmatter: boolean;
|
|
71
78
|
toc: boolean;
|
|
72
79
|
tocMaxDepth: number;
|
|
80
|
+
codeAnnotations: ResolvedCodeAnnotationsOptions;
|
|
73
81
|
components: ComponentsOption;
|
|
74
82
|
reactivityTransform: boolean;
|
|
75
83
|
customBlocks: boolean;
|
|
@@ -144,7 +152,6 @@ interface TocEntry {
|
|
|
144
152
|
slug: string;
|
|
145
153
|
children?: TocEntry[];
|
|
146
154
|
}
|
|
147
|
-
//# sourceMappingURL=types.d.ts.map
|
|
148
155
|
//#endregion
|
|
149
156
|
//#region src/index.d.ts
|
|
150
157
|
/**
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/index.ts"],"
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/index.ts"],"mappings":";;;;UAMiB,sBAAA;EACf,OAAA;AAAA;AAAA,UAGe,8BAAA;EACf,OAAA;EACA,OAAA;AAAA;;;;AAOF;KAAY,aAAA,GAAgB,MAAA;;;;AAoB5B;;;;;AAKA;;;;;;;;;;KALY,gBAAA,GAAmB,aAAA;;;;UAKd,qBAAA,SAA8B,gBAAA;EA8BjC;;AAMd;;;;;;;;;;;;;;EASc;;;;EAEA;AAMd;;;EA1BE,UAAA,GAAa,gBAAA;EACb,eAAA,aAA4B,sBAAA;EAC5B,mBAAA;EACA,YAAA;AAAA;;;;UAMe,kBAAA;EACf,MAAA;EACA,MAAA;EACA,IAAA;EACA,GAAA;EACA,WAAA;EACA,GAAA;EACA,WAAA;EACA,eAAA,EAAiB,8BAAA;EACjB,UAAA,EAAY,gBAAA;EACZ,mBAAA;EACA,YAAA;AAAA;;;;UAMe,kBAAA;EACf,IAAA;EACA,GAAA;EAwDa;;;EApDb,cAAA;EAgDA;;;EA5CA,WAAA,EAAa,MAAA;AAAA;;AAsDf;;UAhDiB,eAAA;EAoDI;;;EAhDnB,IAAA;EAgDA;;;EA5CA,KAAA,EAAO,MAAA;;;;EAIP,QAAA;ECvE0B;;;ED2E1B,EAAA;EC3E2B;;;ED+E3B,OAAA;AAAA;;;;UAMe,qBAAA;;;;EAIf,IAAA;;;;EAIA,OAAA,EAAS,eAAA;;;;EAIT,WAAA,EAAa,MAAA;;;;EAIb,GAAA,EAAK,QAAA;AAAA;;;;UAMU,QAAA;EACf,KAAA;EACA,IAAA;EACA,IAAA;EACA,QAAA,GAAW,QAAA;AAAA;;;AA3Jb;;;;;AASA;;;;;AAoBA;;;;;AAKA;;;;;;;;AAlCA,iBC4CgB,YAAA,CAAa,OAAA,GAAS,qBAAA,GAA6B,YAAA"}
|
|
@@ -2,7 +2,13 @@ import { OxContentOptions, oxContent } from "@ox-content/vite-plugin";
|
|
|
2
2
|
import { PluginOption } from "vite";
|
|
3
3
|
|
|
4
4
|
//#region src/types.d.ts
|
|
5
|
-
|
|
5
|
+
interface CodeAnnotationsOptions {
|
|
6
|
+
metaKey?: string;
|
|
7
|
+
}
|
|
8
|
+
interface ResolvedCodeAnnotationsOptions {
|
|
9
|
+
enabled: boolean;
|
|
10
|
+
metaKey: string;
|
|
11
|
+
}
|
|
6
12
|
/**
|
|
7
13
|
* Component registration map.
|
|
8
14
|
* Key is the component name to use in Markdown, value is the import path.
|
|
@@ -56,6 +62,7 @@ interface VueIntegrationOptions extends OxContentOptions {
|
|
|
56
62
|
* @default true
|
|
57
63
|
*/
|
|
58
64
|
components?: ComponentsOption;
|
|
65
|
+
codeAnnotations?: boolean | CodeAnnotationsOptions;
|
|
59
66
|
reactivityTransform?: boolean;
|
|
60
67
|
customBlocks?: boolean;
|
|
61
68
|
}
|
|
@@ -70,6 +77,7 @@ interface ResolvedVueOptions {
|
|
|
70
77
|
frontmatter: boolean;
|
|
71
78
|
toc: boolean;
|
|
72
79
|
tocMaxDepth: number;
|
|
80
|
+
codeAnnotations: ResolvedCodeAnnotationsOptions;
|
|
73
81
|
components: ComponentsOption;
|
|
74
82
|
reactivityTransform: boolean;
|
|
75
83
|
customBlocks: boolean;
|
|
@@ -144,7 +152,6 @@ interface TocEntry {
|
|
|
144
152
|
slug: string;
|
|
145
153
|
children?: TocEntry[];
|
|
146
154
|
}
|
|
147
|
-
//# sourceMappingURL=types.d.ts.map
|
|
148
155
|
//#endregion
|
|
149
156
|
//#region src/index.d.ts
|
|
150
157
|
/**
|
|
@@ -173,4 +180,4 @@ interface TocEntry {
|
|
|
173
180
|
declare function oxContentVue(options?: VueIntegrationOptions): PluginOption[];
|
|
174
181
|
//#endregion
|
|
175
182
|
export { type ComponentIsland, type ComponentsMap, type ComponentsOption, type ParsedMarkdownContent, type ResolvedVueOptions, type TocEntry, type VueIntegrationOptions, type VueTransformResult, oxContent, oxContentVue };
|
|
176
|
-
//# sourceMappingURL=index.d.
|
|
183
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/index.ts"],"mappings":";;;;UAMiB,sBAAA;EACf,OAAA;AAAA;AAAA,UAGe,8BAAA;EACf,OAAA;EACA,OAAA;AAAA;;;;AAOF;KAAY,aAAA,GAAgB,MAAA;;;;AAoB5B;;;;;AAKA;;;;;;;;;;KALY,gBAAA,GAAmB,aAAA;;;;UAKd,qBAAA,SAA8B,gBAAA;EA8BjC;;AAMd;;;;;;;;;;;;;;EASc;;;;EAEA;AAMd;;;EA1BE,UAAA,GAAa,gBAAA;EACb,eAAA,aAA4B,sBAAA;EAC5B,mBAAA;EACA,YAAA;AAAA;;;;UAMe,kBAAA;EACf,MAAA;EACA,MAAA;EACA,IAAA;EACA,GAAA;EACA,WAAA;EACA,GAAA;EACA,WAAA;EACA,eAAA,EAAiB,8BAAA;EACjB,UAAA,EAAY,gBAAA;EACZ,mBAAA;EACA,YAAA;AAAA;;;;UAMe,kBAAA;EACf,IAAA;EACA,GAAA;EAwDa;;;EApDb,cAAA;EAgDA;;;EA5CA,WAAA,EAAa,MAAA;AAAA;;AAsDf;;UAhDiB,eAAA;EAoDI;;;EAhDnB,IAAA;EAgDA;;;EA5CA,KAAA,EAAO,MAAA;;;;EAIP,QAAA;ECvE0B;;;ED2E1B,EAAA;EC3E2B;;;ED+E3B,OAAA;AAAA;;;;UAMe,qBAAA;;;;EAIf,IAAA;;;;EAIA,OAAA,EAAS,eAAA;;;;EAIT,WAAA,EAAa,MAAA;;;;EAIb,GAAA,EAAK,QAAA;AAAA;;;;UAMU,QAAA;EACf,KAAA;EACA,IAAA;EACA,IAAA;EACA,QAAA,GAAW,QAAA;AAAA;;;AA3Jb;;;;;AASA;;;;;AAoBA;;;;;AAKA;;;;;;;;AAlCA,iBC4CgB,YAAA,CAAa,OAAA,GAAS,qBAAA,GAA6B,YAAA"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as fs from "fs";
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
import { oxContent, oxContent as oxContent$1, transformMarkdown } from "@ox-content/vite-plugin";
|
|
4
|
-
|
|
5
4
|
//#region src/transform.ts
|
|
6
5
|
/**
|
|
7
6
|
* Markdown to Vue SFC transformation.
|
|
@@ -48,50 +47,52 @@ async function transformMarkdownWithVue(code, id, options) {
|
|
|
48
47
|
lastIndex = matchEnd;
|
|
49
48
|
}
|
|
50
49
|
processedContent += markdownContent.slice(lastIndex);
|
|
50
|
+
const baseOptions = {
|
|
51
|
+
srcDir: options.srcDir,
|
|
52
|
+
outDir: options.outDir,
|
|
53
|
+
base: options.base,
|
|
54
|
+
ssg: {
|
|
55
|
+
enabled: false,
|
|
56
|
+
extension: ".html",
|
|
57
|
+
clean: false,
|
|
58
|
+
bare: false,
|
|
59
|
+
generateOgImage: false
|
|
60
|
+
},
|
|
61
|
+
gfm: options.gfm,
|
|
62
|
+
frontmatter: false,
|
|
63
|
+
toc: options.toc,
|
|
64
|
+
tocMaxDepth: options.tocMaxDepth,
|
|
65
|
+
codeAnnotations: options.codeAnnotations,
|
|
66
|
+
footnotes: true,
|
|
67
|
+
tables: true,
|
|
68
|
+
taskLists: true,
|
|
69
|
+
strikethrough: true,
|
|
70
|
+
highlight: false,
|
|
71
|
+
highlightTheme: "github-dark",
|
|
72
|
+
highlightLangs: [],
|
|
73
|
+
mermaid: false,
|
|
74
|
+
ogImage: false,
|
|
75
|
+
ogImageOptions: {
|
|
76
|
+
vuePlugin: "vitejs",
|
|
77
|
+
width: 1200,
|
|
78
|
+
height: 630,
|
|
79
|
+
cache: true,
|
|
80
|
+
concurrency: 1
|
|
81
|
+
},
|
|
82
|
+
transformers: [],
|
|
83
|
+
docs: false,
|
|
84
|
+
ogViewer: false,
|
|
85
|
+
search: {
|
|
86
|
+
enabled: false,
|
|
87
|
+
limit: 10,
|
|
88
|
+
prefix: true,
|
|
89
|
+
placeholder: "Search...",
|
|
90
|
+
hotkey: "k"
|
|
91
|
+
},
|
|
92
|
+
i18n: false
|
|
93
|
+
};
|
|
51
94
|
return {
|
|
52
|
-
code: generateVueSFC(injectIslandMarkers((await transformMarkdown(processedContent, id,
|
|
53
|
-
srcDir: options.srcDir,
|
|
54
|
-
outDir: options.outDir,
|
|
55
|
-
base: options.base,
|
|
56
|
-
ssg: {
|
|
57
|
-
enabled: false,
|
|
58
|
-
extension: ".html",
|
|
59
|
-
clean: false,
|
|
60
|
-
bare: false,
|
|
61
|
-
generateOgImage: false
|
|
62
|
-
},
|
|
63
|
-
gfm: options.gfm,
|
|
64
|
-
frontmatter: false,
|
|
65
|
-
toc: options.toc,
|
|
66
|
-
tocMaxDepth: options.tocMaxDepth,
|
|
67
|
-
footnotes: true,
|
|
68
|
-
tables: true,
|
|
69
|
-
taskLists: true,
|
|
70
|
-
strikethrough: true,
|
|
71
|
-
highlight: false,
|
|
72
|
-
highlightTheme: "github-dark",
|
|
73
|
-
highlightLangs: [],
|
|
74
|
-
mermaid: false,
|
|
75
|
-
ogImage: false,
|
|
76
|
-
ogImageOptions: {
|
|
77
|
-
vuePlugin: "vitejs",
|
|
78
|
-
width: 1200,
|
|
79
|
-
height: 630,
|
|
80
|
-
cache: true,
|
|
81
|
-
concurrency: 1
|
|
82
|
-
},
|
|
83
|
-
transformers: [],
|
|
84
|
-
docs: false,
|
|
85
|
-
ogViewer: false,
|
|
86
|
-
search: {
|
|
87
|
-
enabled: false,
|
|
88
|
-
limit: 10,
|
|
89
|
-
prefix: true,
|
|
90
|
-
placeholder: "Search...",
|
|
91
|
-
hotkey: "k"
|
|
92
|
-
},
|
|
93
|
-
i18n: false
|
|
94
|
-
})).html, islands), usedComponents, islands, frontmatter, options, id),
|
|
95
|
+
code: generateVueSFC(injectIslandMarkers((await transformMarkdown(processedContent, id, baseOptions)).html, islands), usedComponents, islands, frontmatter, options, id),
|
|
95
96
|
map: null,
|
|
96
97
|
usedComponents,
|
|
97
98
|
frontmatter
|
|
@@ -303,7 +304,6 @@ export default defineComponent({
|
|
|
303
304
|
});
|
|
304
305
|
`;
|
|
305
306
|
}
|
|
306
|
-
|
|
307
307
|
//#endregion
|
|
308
308
|
//#region src/environment.ts
|
|
309
309
|
/**
|
|
@@ -339,7 +339,6 @@ function createVueMarkdownEnvironment(mode, options) {
|
|
|
339
339
|
...!isSSR && { dev: { warmup: ["./src/**/*.vue", "./docs/**/*.md"] } }
|
|
340
340
|
};
|
|
341
341
|
}
|
|
342
|
-
|
|
343
342
|
//#endregion
|
|
344
343
|
//#region src/index.ts
|
|
345
344
|
/**
|
|
@@ -446,13 +445,14 @@ function oxContentVue(options = {}) {
|
|
|
446
445
|
return modules;
|
|
447
446
|
}
|
|
448
447
|
};
|
|
449
|
-
const environmentPlugin = oxContent$1(options).find((
|
|
450
|
-
|
|
448
|
+
const environmentPlugin = oxContent$1(options).flatMap((plugin) => Array.isArray(plugin) ? plugin : [plugin]).find((plugin) => plugin.name === "ox-content:environment");
|
|
449
|
+
const plugins = [
|
|
451
450
|
vueTransformPlugin,
|
|
452
451
|
vueEnvironmentPlugin,
|
|
453
|
-
vueHmrPlugin
|
|
454
|
-
...environmentPlugin ? [environmentPlugin] : []
|
|
452
|
+
vueHmrPlugin
|
|
455
453
|
];
|
|
454
|
+
if (environmentPlugin) plugins.push(environmentPlugin);
|
|
455
|
+
return plugins;
|
|
456
456
|
}
|
|
457
457
|
/**
|
|
458
458
|
* Resolves Vue integration options with defaults.
|
|
@@ -466,11 +466,26 @@ function resolveVueOptions(options) {
|
|
|
466
466
|
frontmatter: options.frontmatter ?? true,
|
|
467
467
|
toc: options.toc ?? true,
|
|
468
468
|
tocMaxDepth: options.tocMaxDepth ?? 3,
|
|
469
|
+
codeAnnotations: resolveCodeAnnotationsOptions(options.codeAnnotations),
|
|
469
470
|
components: options.components ?? {},
|
|
470
471
|
reactivityTransform: options.reactivityTransform ?? false,
|
|
471
472
|
customBlocks: options.customBlocks ?? true
|
|
472
473
|
};
|
|
473
474
|
}
|
|
475
|
+
function resolveCodeAnnotationsOptions(options) {
|
|
476
|
+
if (!options) return {
|
|
477
|
+
enabled: false,
|
|
478
|
+
metaKey: "annotate"
|
|
479
|
+
};
|
|
480
|
+
if (options === true) return {
|
|
481
|
+
enabled: true,
|
|
482
|
+
metaKey: "annotate"
|
|
483
|
+
};
|
|
484
|
+
return {
|
|
485
|
+
enabled: true,
|
|
486
|
+
metaKey: options.metaKey ?? "annotate"
|
|
487
|
+
};
|
|
488
|
+
}
|
|
474
489
|
/**
|
|
475
490
|
* Generates the runtime module for Vue markdown rendering.
|
|
476
491
|
*/
|
|
@@ -592,7 +607,7 @@ async function walkDir(dir, files, ext) {
|
|
|
592
607
|
function toPascalCase(str) {
|
|
593
608
|
return str.replace(/[-_](\w)/g, (_, c) => c.toUpperCase()).replace(/^\w/, (c) => c.toUpperCase());
|
|
594
609
|
}
|
|
595
|
-
|
|
596
610
|
//#endregion
|
|
597
611
|
export { oxContent, oxContentVue };
|
|
598
|
-
|
|
612
|
+
|
|
613
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +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 ssg: {\n enabled: false,\n extension: \".html\",\n clean: false,\n bare: false,\n generateOgImage: 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 highlight: false,\n highlightTheme: \"github-dark\",\n highlightLangs: [],\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 i18n: false,\n } 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, \"'\")}'`\n : \"\";\n const contentAttr = island.content\n ? ` data-ox-content='${island.content.replace(/'/g, \"'\")}'`\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\"],\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} from \"./types\";\n\nexport type {\n VueIntegrationOptions,\n ResolvedVueOptions,\n ComponentsOption,\n ComponentsMap,\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 (!id.endsWith(\".md\")) {\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((mod) =>\n mod.file?.endsWith(\".md\"),\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 gfm: 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 // 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,58 +1,59 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ox-content/vite-plugin-vue",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Vue integration for Ox Content - Embed Vue components in Markdown",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"markdown",
|
|
7
|
+
"mdx",
|
|
8
|
+
"ox-content",
|
|
9
|
+
"vite",
|
|
10
|
+
"vite-plugin",
|
|
11
|
+
"vue"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"author": "ubugeeei",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/ubugeeei/ox-content.git",
|
|
18
|
+
"directory": "npm/vite-plugin-ox-content-vue"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
5
23
|
"type": "module",
|
|
6
|
-
"main": "./dist/index.
|
|
7
|
-
"types": "./dist/index.d.
|
|
24
|
+
"main": "./dist/index.cjs",
|
|
25
|
+
"types": "./dist/index.d.mts",
|
|
8
26
|
"exports": {
|
|
9
27
|
".": {
|
|
10
|
-
"import": "./dist/index.
|
|
11
|
-
"
|
|
28
|
+
"import": "./dist/index.mjs",
|
|
29
|
+
"require": "./dist/index.cjs",
|
|
30
|
+
"types": "./dist/index.d.mts"
|
|
12
31
|
}
|
|
13
32
|
},
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
"peerDependencies": {
|
|
18
|
-
"vite": "^8.0.0",
|
|
19
|
-
"vue": "^3.5.0"
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public",
|
|
35
|
+
"provenance": true
|
|
20
36
|
},
|
|
21
37
|
"dependencies": {
|
|
22
|
-
"@ox-content/vite-plugin": "
|
|
23
|
-
"@ox-content/islands": "
|
|
38
|
+
"@ox-content/vite-plugin": "1.1.0",
|
|
39
|
+
"@ox-content/islands": "1.1.0"
|
|
24
40
|
},
|
|
25
41
|
"devDependencies": {
|
|
26
42
|
"@types/node": "^22.0.0",
|
|
27
|
-
"@vitejs/plugin-vue": "^6.0.0",
|
|
28
|
-
"tsdown": "^0.12.0",
|
|
29
43
|
"@typescript/native-preview": "^7.0.0-dev.20250601",
|
|
44
|
+
"@vitejs/plugin-vue": "^6.0.0",
|
|
30
45
|
"typescript": "^5.7.0",
|
|
31
|
-
"vite": "
|
|
46
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@0.1.11",
|
|
47
|
+
"vite-plus": "0.1.11",
|
|
32
48
|
"vue": "^3.5.0"
|
|
33
49
|
},
|
|
34
|
-
"
|
|
35
|
-
"vite",
|
|
36
|
-
"
|
|
37
|
-
"vue",
|
|
38
|
-
"markdown",
|
|
39
|
-
"ox-content",
|
|
40
|
-
"mdx"
|
|
41
|
-
],
|
|
42
|
-
"license": "MIT",
|
|
43
|
-
"author": "ubugeeei",
|
|
44
|
-
"repository": {
|
|
45
|
-
"type": "git",
|
|
46
|
-
"url": "https://github.com/ubugeeei/ox-content.git",
|
|
47
|
-
"directory": "npm/vite-plugin-ox-content-vue"
|
|
48
|
-
},
|
|
49
|
-
"publishConfig": {
|
|
50
|
-
"provenance": true,
|
|
51
|
-
"access": "public"
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@0.1.11",
|
|
52
|
+
"vue": "^3.5.0"
|
|
52
53
|
},
|
|
53
54
|
"scripts": {
|
|
54
|
-
"build": "
|
|
55
|
-
"dev": "
|
|
55
|
+
"build": "vp pack",
|
|
56
|
+
"dev": "vp pack --watch",
|
|
56
57
|
"typecheck": "tsgo --noEmit"
|
|
57
58
|
}
|
|
58
59
|
}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/index.ts"],"sourcesContent":[],"mappings":";;;;;AAUA;AAoBA;AAKA;;AA2Be,KApDH,aAAA,GAAgB,MAoDb,CAAA,MAAA,EAAA,MAAA,CAAA;;;AAQf;AAgBA;AAgBA;AA0BA;;;;;;AAsBA;;;;AChGA;;;AAAmE,KDxBvD,gBAAA,GAAmB,aCwBoC,GAAA,MAAA,GAAA,MAAA,EAAA;;;;UDnBlD,qBAAA,SAA8B;;;;;;;;;;;;;;;;;;;;;;;;;eA2BhC;;;;;;;UAQE,kBAAA;;;;;;;;cAQH;;;;;;;UAQG,kBAAA;;;;;;;;;;eAUF;;;;;UAME,eAAA;;;;;;;;SAQR;;;;;;;;;;;;;;;;;UAkBQ,qBAAA;;;;;;;;WAQN;;;;eAII;;;;OAIR;;;;;UAMU,QAAA;;;;aAIJ;;;;;;;AApFb;AAgBA;AAgBA;AA0BA;;;;;;AAsBA;;;;AChGA;;;;;;;;iBAAgB,YAAA,WAAsB,wBAA6B"}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","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 transformed = await baseTransformMarkdown(processedContent, id, {\n srcDir: options.srcDir,\n outDir: options.outDir,\n base: options.base,\n ssg: {\n enabled: false,\n extension: \".html\",\n clean: false,\n bare: false,\n generateOgImage: false,\n },\n gfm: options.gfm,\n frontmatter: false, // Already extracted\n toc: options.toc,\n tocMaxDepth: options.tocMaxDepth,\n footnotes: true,\n tables: true,\n taskLists: true,\n strikethrough: true,\n highlight: false,\n highlightTheme: \"github-dark\",\n highlightLangs: [],\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 i18n: false,\n });\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, \"'\")}'`\n : \"\";\n const contentAttr = island.content\n ? ` data-ox-content='${island.content.replace(/'/g, \"'\")}'`\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\"],\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} from \"./types\";\n\nexport type {\n VueIntegrationOptions,\n ResolvedVueOptions,\n ComponentsOption,\n ComponentsMap,\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 (!id.endsWith(\".md\")) {\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((mod) =>\n mod.file?.endsWith(\".md\"),\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);\n const environmentPlugin = basePlugins.find((p) => p.name === \"ox-content:environment\");\n\n return [\n vueTransformPlugin,\n vueEnvironmentPlugin,\n vueHmrPlugin,\n ...(environmentPlugin ? [environmentPlugin] : []),\n ];\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 gfm: options.gfm ?? true,\n frontmatter: options.frontmatter ?? true,\n toc: options.toc ?? true,\n tocMaxDepth: options.tocMaxDepth ?? 3,\n components: options.components ?? {},\n // Vue-specific options\n reactivityTransform: options.reactivityTransform ?? false,\n customBlocks: options.customBlocks ?? true,\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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"}
|