@ox-content/vite-plugin-vue 0.7.0 → 0.9.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 +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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 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 search: {\n enabled: false,\n limit: 10,\n prefix: true,\n placeholder: \"Search...\",\n hotkey: \"k\",\n },\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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"}
|
|
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 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 });\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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ox-content/vite-plugin-vue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Vue integration for Ox Content - Embed Vue components in Markdown",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"vue": "^3.5.0"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@ox-content/islands": "0.
|
|
23
|
-
"@ox-content/vite-plugin": "0.
|
|
22
|
+
"@ox-content/islands": "0.9.0",
|
|
23
|
+
"@ox-content/vite-plugin": "0.9.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/node": "^22.0.0",
|