unplugin-docubook 1.1.1 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +84 -108
  2. package/dist/astro.cjs +1 -1
  3. package/dist/astro.cjs.map +1 -1
  4. package/dist/astro.js +1 -1
  5. package/dist/astro.js.map +1 -1
  6. package/dist/bun.cjs +1 -1
  7. package/dist/bun.cjs.map +1 -1
  8. package/dist/bun.js +1 -1
  9. package/dist/bun.js.map +1 -1
  10. package/dist/esbuild.cjs +1 -1
  11. package/dist/esbuild.cjs.map +1 -1
  12. package/dist/esbuild.js +1 -1
  13. package/dist/esbuild.js.map +1 -1
  14. package/dist/farm.cjs +1 -1
  15. package/dist/farm.cjs.map +1 -1
  16. package/dist/farm.js +1 -1
  17. package/dist/farm.js.map +1 -1
  18. package/dist/index.cjs +1 -1
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.js +1 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/next.cjs +1 -1
  23. package/dist/next.cjs.map +1 -1
  24. package/dist/next.js +1 -1
  25. package/dist/next.js.map +1 -1
  26. package/dist/nuxt.cjs +1 -1
  27. package/dist/nuxt.cjs.map +1 -1
  28. package/dist/nuxt.js +1 -1
  29. package/dist/nuxt.js.map +1 -1
  30. package/dist/rolldown.cjs +1 -1
  31. package/dist/rolldown.cjs.map +1 -1
  32. package/dist/rolldown.js +1 -1
  33. package/dist/rolldown.js.map +1 -1
  34. package/dist/rollup.cjs +1 -1
  35. package/dist/rollup.cjs.map +1 -1
  36. package/dist/rollup.js +1 -1
  37. package/dist/rollup.js.map +1 -1
  38. package/dist/rspack.cjs +1 -1
  39. package/dist/rspack.cjs.map +1 -1
  40. package/dist/rspack.js +1 -1
  41. package/dist/rspack.js.map +1 -1
  42. package/dist/vite.cjs +1 -1
  43. package/dist/vite.cjs.map +1 -1
  44. package/dist/vite.js +1 -1
  45. package/dist/vite.js.map +1 -1
  46. package/dist/webpack.cjs +1 -1
  47. package/dist/webpack.cjs.map +1 -1
  48. package/dist/webpack.js +1 -1
  49. package/dist/webpack.js.map +1 -1
  50. package/package.json +1 -1
package/README.md CHANGED
@@ -1,156 +1,132 @@
1
1
  # 📚 DocuBook
2
+
2
3
  The Universal Documentation Engine for any JavaScript Framework.
3
4
 
4
5
  > Write with MDX — works with pretty much any JS framework: Vite, React, Vue, Svelte, you name it!
5
6
 
6
7
  ## Features
7
- - 🚀 **Framework Agnostic**: Works with React, Vue, Svelte, and Vite.
8
- - 🛠️ **Unified Pipeline**: Built on top of Remark/Rehype and Unplugin.
9
- - 📦 **Smart Components**: Use `<Accordion />`, `<Tabs />`, and `<Step />` directly in your Markdown without manual imports.
10
- - **Optimized**: Static-first approach for maximum performance.
8
+ - 🚀 **Framework Agnostic**: Native support for React, Vue, and Svelte.
9
+ - 🛠️ **Unified Pipeline**: Built on top of Unplugin for cross-bundler compatibility.
10
+ - 📦 **Zero-Import Components**: Use `<Accordion />`, `<Tabs />`, `<Note />` etc., directly in MDX without manual imports.
11
+ - 🎨 **Themeable**: Built-in beautiful design tokens, easily customizable via CSS variables.
12
+ - ⚡ **Performance First**: Regex-based detection with memoization and safe-stripping logic.
13
+
14
+ ---
11
15
 
12
- ## Install
16
+ ## 🛠️ Installation
13
17
 
18
+ ### 1. Install Package
14
19
  ```bash
15
20
  npm install unplugin-docubook
16
21
  ```
17
22
 
18
- ## Bundler & Framework Integration
19
-
20
- ### Vite
21
-
22
- ```ts
23
- // vite.config.ts
24
- import DocuBook from 'unplugin-docubook/vite'
25
- import { defineConfig } from 'vite'
26
-
27
- export default defineConfig({
28
- plugins: [
29
- DocuBook({ /* options */ }),
30
- ],
31
- })
32
- ```
33
-
34
- ### Rollup
23
+ ### 2. Install Icon Dependencies
24
+ DocuBook uses Lucide for its UI icons. Install the version corresponding to your framework:
25
+ ```bash
26
+ # For React / Next.js
27
+ npm install lucide-react
35
28
 
36
- ```ts
37
- // rollup.config.ts
38
- import DocuBook from 'unplugin-docubook/rollup'
29
+ # For Vue / Nuxt
30
+ npm install lucide-vue-next
39
31
 
40
- export default {
41
- plugins: [
42
- DocuBook({ /* options */ }),
43
- ],
44
- }
32
+ # For Svelte / Astro
33
+ npm install lucide-svelte
45
34
  ```
46
35
 
47
- ### webpack
36
+ ### 3. Setup Tailwind CSS
37
+ DocuBook components are styled with Tailwind. Ensure Tailwind is installed in your project, then import the DocuBook theme in your entry file (`main.ts`, `App.tsx`, etc.):
48
38
 
49
- ```js
50
- // webpack.config.js
51
- module.exports = {
52
- /* ... */
53
- plugins: [
54
- require('unplugin-docubook/webpack')({ /* options */ }),
55
- ],
56
- }
39
+ ```typescript
40
+ import 'unplugin-docubook/theme.css';
57
41
  ```
58
42
 
59
- ### Rspack
43
+ ---
60
44
 
61
- ```js
62
- // rspack.config.js
63
- module.exports = {
64
- /* ... */
65
- plugins: [
66
- require('unplugin-docubook/rspack')({ /* options */ }),
67
- ],
68
- }
69
- ```
70
-
71
- ### esbuild
45
+ ## ⚙️ Configuration
72
46
 
73
- ```ts
74
- // esbuild.config.ts
75
- import { build } from 'esbuild'
76
- import DocuBook from 'unplugin-docubook/esbuild'
47
+ Docubook supports all major bundlers via `unplugin`.
77
48
 
78
- build({
79
- plugins: [DocuBook()],
80
- })
81
- ```
82
-
83
- ### Farm
84
-
85
- ```ts
86
- // farm.config.ts
87
- import DocuBook from 'unplugin-docubook/farm'
88
- import { defineConfig } from '@farmfe/core'
49
+ ### Vite (React/Vue/Svelte/Astro)
50
+ ```typescript
51
+ // vite.config.ts
52
+ import { defineConfig } from 'vite';
53
+ import DocuBook from 'unplugin-docubook/vite';
89
54
 
90
55
  export default defineConfig({
91
56
  plugins: [
92
- DocuBook({ /* options */ }),
57
+ DocuBook({
58
+ framework: 'react', // or 'vue' | 'svelte'
59
+ }),
93
60
  ],
94
- })
61
+ });
95
62
  ```
96
63
 
97
- ### Bun
64
+ ### Next.js
65
+ ```javascript
66
+ // next.config.mjs
67
+ import DocuBook from 'unplugin-docubook/webpack';
98
68
 
99
- ```ts
100
- // bun.config.ts
101
- import DocuBook from 'unplugin-docubook/bun'
69
+ /** @type {import('next').NextConfig} */
70
+ const nextConfig = {
71
+ webpack(config) {
72
+ config.plugins.push(DocuBook({ framework: 'react' }));
73
+ return config;
74
+ },
75
+ };
102
76
 
103
- await Bun.build({
104
- entrypoints: ['./src/index.ts'],
105
- outdir: './dist',
106
- plugins: [
107
- DocuBook({ /* options */ }),
108
- ],
109
- })
77
+ export default nextConfig;
110
78
  ```
111
79
 
112
- ### Nuxt
113
-
114
- ```ts
80
+ ### Nuxt (Vue)
81
+ ```typescript
115
82
  // nuxt.config.ts
116
83
  export default defineNuxtConfig({
117
84
  modules: [
118
- ['unplugin-docubook/nuxt', { /* options */ }],
119
- ],
85
+ ['unplugin-docubook/nuxt', { framework: 'vue' }]
86
+ ]
120
87
  })
121
88
  ```
122
89
 
123
- ### Astro
124
-
125
- ```js
126
- // astro.config.mjs
127
- import { defineConfig } from 'astro/config'
128
- import DocuBook from 'unplugin-docubook/astro'
129
-
130
- export default defineConfig({
131
- integrations: [DocuBook()],
132
- })
133
- ```
90
+ ### Webpack/Rollup
91
+ Import from `unplugin-docubook/webpack` or `unplugin-docubook/rollup` and add to your plugins array.
134
92
 
135
- ## Options
93
+ ---
136
94
 
137
- | Option | Type | Default | Description |
138
- |--------|------|---------|-------------|
139
- | `framework` | `'react' \| 'vue' \| 'svelte'` | `'react'` | Target framework |
140
- | `include` | `string[]` | `['**/*.mdx', '**/*.md']` | Files to include |
141
- | `exclude` | `string[]` | - | Files to exclude |
142
- | `importSource` | `string` | `'unplugin-docubook/components'` | Import source for components |
95
+ ## 🚀 Usage
143
96
 
144
- ## Usage
97
+ ### MDX Content
98
+ No imports needed for core components!
145
99
 
146
100
  ```mdx
147
- # My Documentation
148
-
149
- <Accordion title="What is DocuBook?">
150
- DocuBook is awesome!
101
+ <Accordion title="Getting Started">
102
+ <Note type="success">
103
+ Docubook is now managing your imports.
104
+ </Note>
105
+
106
+ <Card title="Quick Link" icon="zap">
107
+ Check our docs.
108
+ </Card>
151
109
  </Accordion>
152
110
  ```
153
111
 
154
- ## License
112
+ ### Custom Components
113
+ You can register your own components (project-specific or external) for auto-import:
114
+
115
+ ```typescript
116
+ DocuBook({
117
+ customComponents: {
118
+ // Relative path (to unplugin-docubook/components)
119
+ MyWidget: { exports: ['MyWidget'], path: '/custom' },
120
+
121
+ // Absolute/Alias path (to your project)
122
+ SpecialButton: { exports: ['Button'], path: '@/components/ui/Button' }
123
+ }
124
+ })
125
+ ```
126
+
127
+ ---
155
128
 
129
+ ## License
156
130
  MIT
131
+
132
+
package/dist/astro.cjs CHANGED
@@ -128,7 +128,7 @@ function generateImports(componentNames, importSource, framework = DEFAULT_FRAME
128
128
  for (const name of componentNames) {
129
129
  const meta = registry[name];
130
130
  if (!meta) continue;
131
- const fullPath = `${importSource}${meta.path}`;
131
+ const fullPath = meta.path.startsWith("/") ? `${importSource}${meta.path}` : meta.path;
132
132
  if (!pathToExports.has(fullPath)) {
133
133
  pathToExports.set(fullPath, /* @__PURE__ */ new Set());
134
134
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/astro.ts","../src/index.ts","../src/core/registry.ts","../src/core/transform.ts"],"sourcesContent":["import type { Options } from './types'\nimport unplugin from '.'\n\ninterface AstroConfig {\n config: {\n vite: {\n plugins: unknown[]\n }\n }\n}\n\nexport default function (options: Options) {\n return {\n name: 'unplugin-docubook',\n hooks: {\n 'astro:config:setup': async (astro: AstroConfig) => {\n astro.config.vite.plugins ||= []\n astro.config.vite.plugins.push(unplugin.vite(options))\n },\n },\n }\n}\n","import type { UnpluginFactory } from 'unplugin'\nimport type { Options } from './types'\nimport { createUnplugin } from 'unplugin'\nimport { transformMdx } from './core/transform'\n\nexport const unpluginFactory: UnpluginFactory<Options | undefined> = (\n options,\n) => ({\n name: 'unplugin-docubook',\n\n transformInclude(id) {\n // Only process .mdx and .md files\n return /\\.mdx?$/.test(id)\n },\n\n transform(code, _id) {\n const result = transformMdx(code, options)\n if (!result.hasTransformed) return\n return result.code\n },\n})\n\nexport const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory)\n\nexport default unplugin\n","import type { Framework } from '../types'\n\nexport interface ComponentMeta {\n exports: string[]\n path: string\n}\n\nconst FRAMEWORK_PATHS: Record<Framework, string> = {\n react: '/react',\n vue: '/vue',\n svelte: '/svelte',\n}\n\nfunction createRegistry(framework: Framework): Record<string, ComponentMeta> {\n const basePath = FRAMEWORK_PATHS[framework]\n\n return {\n Note: { exports: ['Note'], path: basePath },\n Card: { exports: ['Card'], path: basePath },\n CardGroup: { exports: ['CardGroup'], path: basePath },\n Accordion: { exports: ['Accordion'], path: basePath },\n AccordionGroup: { exports: ['AccordionGroup'], path: basePath },\n Stepper: { exports: ['Stepper', 'StepperItem'], path: basePath },\n Kbd: { exports: ['Kbd'], path: basePath },\n Tooltip: { exports: ['Tooltip'], path: basePath },\n Youtube: { exports: ['Youtube'], path: basePath },\n Button: { exports: ['Button'], path: basePath },\n DocuLink: { exports: ['DocuLink'], path: basePath },\n DocuImage: { exports: ['DocuImage'], path: basePath },\n Files: { exports: ['Files'], path: basePath },\n Folder: { exports: ['Folder'], path: basePath },\n File: { exports: ['File'], path: basePath },\n Release: { exports: ['Release'], path: basePath },\n Changes: { exports: ['Changes'], path: basePath },\n Pre: { exports: ['Pre'], path: basePath },\n Copy: { exports: ['Copy'], path: basePath },\n DocuBookProvider: { exports: ['DocuBookProvider'], path: basePath },\n }\n}\n\nconst registryCache = new Map<Framework, Record<string, ComponentMeta>>()\nconst regexCache = new Map<Framework, RegExp>()\n\nexport function getComponentRegistry(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): Record<string, ComponentMeta> {\n if (!customComponents || Object.keys(customComponents).length === 0) {\n const cached = registryCache.get(framework)\n if (cached) return cached\n const registry = createRegistry(framework)\n registryCache.set(framework, registry)\n return registry\n }\n // Merge custom components with built-in (custom overrides built-in)\n return { ...createRegistry(framework), ...customComponents }\n}\n\nexport function buildComponentDetectionRegex(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): RegExp {\n // Custom components: always build fresh regex (not cached)\n if (customComponents && Object.keys(customComponents).length > 0) {\n const registry = getComponentRegistry(framework, customComponents)\n const names = Object.keys(registry)\n return new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n }\n\n const cached = regexCache.get(framework)\n if (cached) {\n cached.lastIndex = 0 // Reset regex state because of /g flag\n return cached\n }\n const registry = getComponentRegistry(framework)\n const names = Object.keys(registry)\n const regex = new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n regexCache.set(framework, regex)\n return regex\n}\n","import type { Options, Framework } from '../types'\nimport type { ComponentMeta } from './registry'\nimport { getComponentRegistry, buildComponentDetectionRegex } from './registry'\n\nconst DEFAULT_IMPORT_SOURCE = 'unplugin-docubook/components'\nconst DEFAULT_FRAMEWORK: Framework = 'react'\n\n/**\n * Strip content zones where component tags should NOT be detected:\n * - Fenced code blocks (triple backticks)\n * - Inline code (single backticks)\n * - MDX comments\n * - HTML comments\n * - Existing import/export statements\n */\nfunction stripIgnoredZones(code: string): string {\n return code\n .replace(/```[\\s\\S]*?```/g, '') // fenced code blocks\n .replace(/`[^`]+`/g, '') // inline code\n .replace(/\\{\\/\\*[\\s\\S]*?\\*\\/\\}/g, '') // MDX comments {/* */}\n .replace(/<!--[\\s\\S]*?-->/g, '') // HTML comments\n .replace(/^import\\s.+$/gm, '') // existing imports\n .replace(/^export\\s.+$/gm, '') // exports\n}\n\nexport function detectComponents(\n code: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string[] {\n const strippedCode = stripIgnoredZones(code)\n const regex = buildComponentDetectionRegex(framework, customComponents)\n const registry = getComponentRegistry(framework, customComponents)\n const found = new Set<string>()\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(strippedCode)) !== null) {\n const name = match[1]\n if (name && registry[name]) {\n found.add(name)\n }\n }\n\n return Array.from(found)\n}\n\nexport function generateImports(\n componentNames: string[],\n importSource: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string {\n const registry = getComponentRegistry(framework, customComponents)\n const pathToExports = new Map<string, Set<string>>()\n\n for (const name of componentNames) {\n const meta = registry[name]\n if (!meta) continue\n\n const fullPath = `${importSource}${meta.path}`\n if (!pathToExports.has(fullPath)) {\n pathToExports.set(fullPath, new Set())\n }\n for (const exp of meta.exports) {\n pathToExports.get(fullPath)!.add(exp)\n }\n }\n\n const lines: string[] = []\n for (const [path, exports] of pathToExports) {\n const names = Array.from(exports).sort().join(', ')\n lines.push(`import { ${names} } from '${path}'`)\n }\n\n return lines.join('\\n')\n}\n\nexport function transformMdx(\n code: string,\n options: Options = {},\n): { code: string; hasTransformed: boolean } {\n const framework = options.framework ?? DEFAULT_FRAMEWORK\n const usedComponents = detectComponents(code, framework, options.customComponents)\n\n if (usedComponents.length === 0) {\n return { code, hasTransformed: false }\n }\n\n const importSource = options.importSource ?? DEFAULT_IMPORT_SOURCE\n const importStatements = generateImports(usedComponents, importSource, framework, options.customComponents)\n\n return {\n code: `${importStatements}\\n\\n${code}`,\n hasTransformed: true,\n }\n}\n\n"],"mappings":"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","names":["registry","names","exports"]}
1
+ {"version":3,"sources":["../src/astro.ts","../src/index.ts","../src/core/registry.ts","../src/core/transform.ts"],"sourcesContent":["import type { Options } from './types'\nimport unplugin from '.'\n\ninterface AstroConfig {\n config: {\n vite: {\n plugins: unknown[]\n }\n }\n}\n\nexport default function (options: Options) {\n return {\n name: 'unplugin-docubook',\n hooks: {\n 'astro:config:setup': async (astro: AstroConfig) => {\n astro.config.vite.plugins ||= []\n astro.config.vite.plugins.push(unplugin.vite(options))\n },\n },\n }\n}\n","import type { UnpluginFactory } from 'unplugin'\nimport type { Options } from './types'\nimport { createUnplugin } from 'unplugin'\nimport { transformMdx } from './core/transform'\n\nexport const unpluginFactory: UnpluginFactory<Options | undefined> = (\n options,\n) => ({\n name: 'unplugin-docubook',\n\n transformInclude(id) {\n // Only process .mdx and .md files\n return /\\.mdx?$/.test(id)\n },\n\n transform(code, _id) {\n const result = transformMdx(code, options)\n if (!result.hasTransformed) return\n return result.code\n },\n})\n\nexport const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory)\n\nexport default unplugin\n","import type { Framework } from '../types'\n\nexport interface ComponentMeta {\n exports: string[]\n path: string\n}\n\nconst FRAMEWORK_PATHS: Record<Framework, string> = {\n react: '/react',\n vue: '/vue',\n svelte: '/svelte',\n}\n\nfunction createRegistry(framework: Framework): Record<string, ComponentMeta> {\n const basePath = FRAMEWORK_PATHS[framework]\n\n return {\n Note: { exports: ['Note'], path: basePath },\n Card: { exports: ['Card'], path: basePath },\n CardGroup: { exports: ['CardGroup'], path: basePath },\n Accordion: { exports: ['Accordion'], path: basePath },\n AccordionGroup: { exports: ['AccordionGroup'], path: basePath },\n Stepper: { exports: ['Stepper', 'StepperItem'], path: basePath },\n Kbd: { exports: ['Kbd'], path: basePath },\n Tooltip: { exports: ['Tooltip'], path: basePath },\n Youtube: { exports: ['Youtube'], path: basePath },\n Button: { exports: ['Button'], path: basePath },\n DocuLink: { exports: ['DocuLink'], path: basePath },\n DocuImage: { exports: ['DocuImage'], path: basePath },\n Files: { exports: ['Files'], path: basePath },\n Folder: { exports: ['Folder'], path: basePath },\n File: { exports: ['File'], path: basePath },\n Release: { exports: ['Release'], path: basePath },\n Changes: { exports: ['Changes'], path: basePath },\n Pre: { exports: ['Pre'], path: basePath },\n Copy: { exports: ['Copy'], path: basePath },\n DocuBookProvider: { exports: ['DocuBookProvider'], path: basePath },\n }\n}\n\nconst registryCache = new Map<Framework, Record<string, ComponentMeta>>()\nconst regexCache = new Map<Framework, RegExp>()\n\nexport function getComponentRegistry(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): Record<string, ComponentMeta> {\n if (!customComponents || Object.keys(customComponents).length === 0) {\n const cached = registryCache.get(framework)\n if (cached) return cached\n const registry = createRegistry(framework)\n registryCache.set(framework, registry)\n return registry\n }\n // Merge custom components with built-in (custom overrides built-in)\n return { ...createRegistry(framework), ...customComponents }\n}\n\nexport function buildComponentDetectionRegex(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): RegExp {\n // Custom components: always build fresh regex (not cached)\n if (customComponents && Object.keys(customComponents).length > 0) {\n const registry = getComponentRegistry(framework, customComponents)\n const names = Object.keys(registry)\n return new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n }\n\n const cached = regexCache.get(framework)\n if (cached) {\n cached.lastIndex = 0 // Reset regex state because of /g flag\n return cached\n }\n const registry = getComponentRegistry(framework)\n const names = Object.keys(registry)\n const regex = new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n regexCache.set(framework, regex)\n return regex\n}\n","import type { Options, Framework } from '../types'\nimport type { ComponentMeta } from './registry'\nimport { getComponentRegistry, buildComponentDetectionRegex } from './registry'\n\nconst DEFAULT_IMPORT_SOURCE = 'unplugin-docubook/components'\nconst DEFAULT_FRAMEWORK: Framework = 'react'\n\n/**\n * Strip content zones where component tags should NOT be detected:\n * - Fenced code blocks (triple backticks)\n * - Inline code (single backticks)\n * - MDX comments\n * - HTML comments\n * - Existing import/export statements\n */\nfunction stripIgnoredZones(code: string): string {\n return code\n .replace(/```[\\s\\S]*?```/g, '') // fenced code blocks\n .replace(/`[^`]+`/g, '') // inline code\n .replace(/\\{\\/\\*[\\s\\S]*?\\*\\/\\}/g, '') // MDX comments {/* */}\n .replace(/<!--[\\s\\S]*?-->/g, '') // HTML comments\n .replace(/^import\\s.+$/gm, '') // existing imports\n .replace(/^export\\s.+$/gm, '') // exports\n}\n\nexport function detectComponents(\n code: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string[] {\n const strippedCode = stripIgnoredZones(code)\n const regex = buildComponentDetectionRegex(framework, customComponents)\n const registry = getComponentRegistry(framework, customComponents)\n const found = new Set<string>()\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(strippedCode)) !== null) {\n const name = match[1]\n if (name && registry[name]) {\n found.add(name)\n }\n }\n\n return Array.from(found)\n}\n\nexport function generateImports(\n componentNames: string[],\n importSource: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string {\n const registry = getComponentRegistry(framework, customComponents)\n const pathToExports = new Map<string, Set<string>>()\n\n for (const name of componentNames) {\n const meta = registry[name]\n if (!meta) continue\n\n // If path starts with '/', it's relative to importSource.\n // Otherwise, it's a full import path (e.g. '@/components/MyComp' or 'my-lib')\n const fullPath = meta.path.startsWith('/')\n ? `${importSource}${meta.path}`\n : meta.path\n\n if (!pathToExports.has(fullPath)) {\n pathToExports.set(fullPath, new Set())\n }\n for (const exp of meta.exports) {\n pathToExports.get(fullPath)!.add(exp)\n }\n }\n\n const lines: string[] = []\n for (const [path, exports] of pathToExports) {\n const names = Array.from(exports).sort().join(', ')\n lines.push(`import { ${names} } from '${path}'`)\n }\n\n return lines.join('\\n')\n}\n\nexport function transformMdx(\n code: string,\n options: Options = {},\n): { code: string; hasTransformed: boolean } {\n const framework = options.framework ?? DEFAULT_FRAMEWORK\n const usedComponents = detectComponents(code, framework, options.customComponents)\n\n if (usedComponents.length === 0) {\n return { code, hasTransformed: false }\n }\n\n const importSource = options.importSource ?? DEFAULT_IMPORT_SOURCE\n const importStatements = generateImports(usedComponents, importSource, framework, options.customComponents)\n\n return {\n code: `${importStatements}\\n\\n${code}`,\n hasTransformed: true,\n }\n}\n\n"],"mappings":"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","names":["registry","names","exports"]}
package/dist/astro.js CHANGED
@@ -105,7 +105,7 @@ function generateImports(componentNames, importSource, framework = DEFAULT_FRAME
105
105
  for (const name of componentNames) {
106
106
  const meta = registry[name];
107
107
  if (!meta) continue;
108
- const fullPath = `${importSource}${meta.path}`;
108
+ const fullPath = meta.path.startsWith("/") ? `${importSource}${meta.path}` : meta.path;
109
109
  if (!pathToExports.has(fullPath)) {
110
110
  pathToExports.set(fullPath, /* @__PURE__ */ new Set());
111
111
  }
package/dist/astro.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/core/registry.ts","../src/core/transform.ts","../src/astro.ts"],"sourcesContent":["import type { UnpluginFactory } from 'unplugin'\nimport type { Options } from './types'\nimport { createUnplugin } from 'unplugin'\nimport { transformMdx } from './core/transform'\n\nexport const unpluginFactory: UnpluginFactory<Options | undefined> = (\n options,\n) => ({\n name: 'unplugin-docubook',\n\n transformInclude(id) {\n // Only process .mdx and .md files\n return /\\.mdx?$/.test(id)\n },\n\n transform(code, _id) {\n const result = transformMdx(code, options)\n if (!result.hasTransformed) return\n return result.code\n },\n})\n\nexport const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory)\n\nexport default unplugin\n","import type { Framework } from '../types'\n\nexport interface ComponentMeta {\n exports: string[]\n path: string\n}\n\nconst FRAMEWORK_PATHS: Record<Framework, string> = {\n react: '/react',\n vue: '/vue',\n svelte: '/svelte',\n}\n\nfunction createRegistry(framework: Framework): Record<string, ComponentMeta> {\n const basePath = FRAMEWORK_PATHS[framework]\n\n return {\n Note: { exports: ['Note'], path: basePath },\n Card: { exports: ['Card'], path: basePath },\n CardGroup: { exports: ['CardGroup'], path: basePath },\n Accordion: { exports: ['Accordion'], path: basePath },\n AccordionGroup: { exports: ['AccordionGroup'], path: basePath },\n Stepper: { exports: ['Stepper', 'StepperItem'], path: basePath },\n Kbd: { exports: ['Kbd'], path: basePath },\n Tooltip: { exports: ['Tooltip'], path: basePath },\n Youtube: { exports: ['Youtube'], path: basePath },\n Button: { exports: ['Button'], path: basePath },\n DocuLink: { exports: ['DocuLink'], path: basePath },\n DocuImage: { exports: ['DocuImage'], path: basePath },\n Files: { exports: ['Files'], path: basePath },\n Folder: { exports: ['Folder'], path: basePath },\n File: { exports: ['File'], path: basePath },\n Release: { exports: ['Release'], path: basePath },\n Changes: { exports: ['Changes'], path: basePath },\n Pre: { exports: ['Pre'], path: basePath },\n Copy: { exports: ['Copy'], path: basePath },\n DocuBookProvider: { exports: ['DocuBookProvider'], path: basePath },\n }\n}\n\nconst registryCache = new Map<Framework, Record<string, ComponentMeta>>()\nconst regexCache = new Map<Framework, RegExp>()\n\nexport function getComponentRegistry(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): Record<string, ComponentMeta> {\n if (!customComponents || Object.keys(customComponents).length === 0) {\n const cached = registryCache.get(framework)\n if (cached) return cached\n const registry = createRegistry(framework)\n registryCache.set(framework, registry)\n return registry\n }\n // Merge custom components with built-in (custom overrides built-in)\n return { ...createRegistry(framework), ...customComponents }\n}\n\nexport function buildComponentDetectionRegex(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): RegExp {\n // Custom components: always build fresh regex (not cached)\n if (customComponents && Object.keys(customComponents).length > 0) {\n const registry = getComponentRegistry(framework, customComponents)\n const names = Object.keys(registry)\n return new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n }\n\n const cached = regexCache.get(framework)\n if (cached) {\n cached.lastIndex = 0 // Reset regex state because of /g flag\n return cached\n }\n const registry = getComponentRegistry(framework)\n const names = Object.keys(registry)\n const regex = new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n regexCache.set(framework, regex)\n return regex\n}\n","import type { Options, Framework } from '../types'\nimport type { ComponentMeta } from './registry'\nimport { getComponentRegistry, buildComponentDetectionRegex } from './registry'\n\nconst DEFAULT_IMPORT_SOURCE = 'unplugin-docubook/components'\nconst DEFAULT_FRAMEWORK: Framework = 'react'\n\n/**\n * Strip content zones where component tags should NOT be detected:\n * - Fenced code blocks (triple backticks)\n * - Inline code (single backticks)\n * - MDX comments\n * - HTML comments\n * - Existing import/export statements\n */\nfunction stripIgnoredZones(code: string): string {\n return code\n .replace(/```[\\s\\S]*?```/g, '') // fenced code blocks\n .replace(/`[^`]+`/g, '') // inline code\n .replace(/\\{\\/\\*[\\s\\S]*?\\*\\/\\}/g, '') // MDX comments {/* */}\n .replace(/<!--[\\s\\S]*?-->/g, '') // HTML comments\n .replace(/^import\\s.+$/gm, '') // existing imports\n .replace(/^export\\s.+$/gm, '') // exports\n}\n\nexport function detectComponents(\n code: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string[] {\n const strippedCode = stripIgnoredZones(code)\n const regex = buildComponentDetectionRegex(framework, customComponents)\n const registry = getComponentRegistry(framework, customComponents)\n const found = new Set<string>()\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(strippedCode)) !== null) {\n const name = match[1]\n if (name && registry[name]) {\n found.add(name)\n }\n }\n\n return Array.from(found)\n}\n\nexport function generateImports(\n componentNames: string[],\n importSource: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string {\n const registry = getComponentRegistry(framework, customComponents)\n const pathToExports = new Map<string, Set<string>>()\n\n for (const name of componentNames) {\n const meta = registry[name]\n if (!meta) continue\n\n const fullPath = `${importSource}${meta.path}`\n if (!pathToExports.has(fullPath)) {\n pathToExports.set(fullPath, new Set())\n }\n for (const exp of meta.exports) {\n pathToExports.get(fullPath)!.add(exp)\n }\n }\n\n const lines: string[] = []\n for (const [path, exports] of pathToExports) {\n const names = Array.from(exports).sort().join(', ')\n lines.push(`import { ${names} } from '${path}'`)\n }\n\n return lines.join('\\n')\n}\n\nexport function transformMdx(\n code: string,\n options: Options = {},\n): { code: string; hasTransformed: boolean } {\n const framework = options.framework ?? DEFAULT_FRAMEWORK\n const usedComponents = detectComponents(code, framework, options.customComponents)\n\n if (usedComponents.length === 0) {\n return { code, hasTransformed: false }\n }\n\n const importSource = options.importSource ?? DEFAULT_IMPORT_SOURCE\n const importStatements = generateImports(usedComponents, importSource, framework, options.customComponents)\n\n return {\n code: `${importStatements}\\n\\n${code}`,\n hasTransformed: true,\n }\n}\n\n","import type { Options } from './types'\nimport unplugin from '.'\n\ninterface AstroConfig {\n config: {\n vite: {\n plugins: unknown[]\n }\n }\n}\n\nexport default function (options: Options) {\n return {\n name: 'unplugin-docubook',\n hooks: {\n 'astro:config:setup': async (astro: AstroConfig) => {\n astro.config.vite.plugins ||= []\n astro.config.vite.plugins.push(unplugin.vite(options))\n },\n },\n }\n}\n"],"mappings":"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","names":["registry","names"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/core/registry.ts","../src/core/transform.ts","../src/astro.ts"],"sourcesContent":["import type { UnpluginFactory } from 'unplugin'\nimport type { Options } from './types'\nimport { createUnplugin } from 'unplugin'\nimport { transformMdx } from './core/transform'\n\nexport const unpluginFactory: UnpluginFactory<Options | undefined> = (\n options,\n) => ({\n name: 'unplugin-docubook',\n\n transformInclude(id) {\n // Only process .mdx and .md files\n return /\\.mdx?$/.test(id)\n },\n\n transform(code, _id) {\n const result = transformMdx(code, options)\n if (!result.hasTransformed) return\n return result.code\n },\n})\n\nexport const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory)\n\nexport default unplugin\n","import type { Framework } from '../types'\n\nexport interface ComponentMeta {\n exports: string[]\n path: string\n}\n\nconst FRAMEWORK_PATHS: Record<Framework, string> = {\n react: '/react',\n vue: '/vue',\n svelte: '/svelte',\n}\n\nfunction createRegistry(framework: Framework): Record<string, ComponentMeta> {\n const basePath = FRAMEWORK_PATHS[framework]\n\n return {\n Note: { exports: ['Note'], path: basePath },\n Card: { exports: ['Card'], path: basePath },\n CardGroup: { exports: ['CardGroup'], path: basePath },\n Accordion: { exports: ['Accordion'], path: basePath },\n AccordionGroup: { exports: ['AccordionGroup'], path: basePath },\n Stepper: { exports: ['Stepper', 'StepperItem'], path: basePath },\n Kbd: { exports: ['Kbd'], path: basePath },\n Tooltip: { exports: ['Tooltip'], path: basePath },\n Youtube: { exports: ['Youtube'], path: basePath },\n Button: { exports: ['Button'], path: basePath },\n DocuLink: { exports: ['DocuLink'], path: basePath },\n DocuImage: { exports: ['DocuImage'], path: basePath },\n Files: { exports: ['Files'], path: basePath },\n Folder: { exports: ['Folder'], path: basePath },\n File: { exports: ['File'], path: basePath },\n Release: { exports: ['Release'], path: basePath },\n Changes: { exports: ['Changes'], path: basePath },\n Pre: { exports: ['Pre'], path: basePath },\n Copy: { exports: ['Copy'], path: basePath },\n DocuBookProvider: { exports: ['DocuBookProvider'], path: basePath },\n }\n}\n\nconst registryCache = new Map<Framework, Record<string, ComponentMeta>>()\nconst regexCache = new Map<Framework, RegExp>()\n\nexport function getComponentRegistry(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): Record<string, ComponentMeta> {\n if (!customComponents || Object.keys(customComponents).length === 0) {\n const cached = registryCache.get(framework)\n if (cached) return cached\n const registry = createRegistry(framework)\n registryCache.set(framework, registry)\n return registry\n }\n // Merge custom components with built-in (custom overrides built-in)\n return { ...createRegistry(framework), ...customComponents }\n}\n\nexport function buildComponentDetectionRegex(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): RegExp {\n // Custom components: always build fresh regex (not cached)\n if (customComponents && Object.keys(customComponents).length > 0) {\n const registry = getComponentRegistry(framework, customComponents)\n const names = Object.keys(registry)\n return new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n }\n\n const cached = regexCache.get(framework)\n if (cached) {\n cached.lastIndex = 0 // Reset regex state because of /g flag\n return cached\n }\n const registry = getComponentRegistry(framework)\n const names = Object.keys(registry)\n const regex = new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n regexCache.set(framework, regex)\n return regex\n}\n","import type { Options, Framework } from '../types'\nimport type { ComponentMeta } from './registry'\nimport { getComponentRegistry, buildComponentDetectionRegex } from './registry'\n\nconst DEFAULT_IMPORT_SOURCE = 'unplugin-docubook/components'\nconst DEFAULT_FRAMEWORK: Framework = 'react'\n\n/**\n * Strip content zones where component tags should NOT be detected:\n * - Fenced code blocks (triple backticks)\n * - Inline code (single backticks)\n * - MDX comments\n * - HTML comments\n * - Existing import/export statements\n */\nfunction stripIgnoredZones(code: string): string {\n return code\n .replace(/```[\\s\\S]*?```/g, '') // fenced code blocks\n .replace(/`[^`]+`/g, '') // inline code\n .replace(/\\{\\/\\*[\\s\\S]*?\\*\\/\\}/g, '') // MDX comments {/* */}\n .replace(/<!--[\\s\\S]*?-->/g, '') // HTML comments\n .replace(/^import\\s.+$/gm, '') // existing imports\n .replace(/^export\\s.+$/gm, '') // exports\n}\n\nexport function detectComponents(\n code: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string[] {\n const strippedCode = stripIgnoredZones(code)\n const regex = buildComponentDetectionRegex(framework, customComponents)\n const registry = getComponentRegistry(framework, customComponents)\n const found = new Set<string>()\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(strippedCode)) !== null) {\n const name = match[1]\n if (name && registry[name]) {\n found.add(name)\n }\n }\n\n return Array.from(found)\n}\n\nexport function generateImports(\n componentNames: string[],\n importSource: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string {\n const registry = getComponentRegistry(framework, customComponents)\n const pathToExports = new Map<string, Set<string>>()\n\n for (const name of componentNames) {\n const meta = registry[name]\n if (!meta) continue\n\n // If path starts with '/', it's relative to importSource.\n // Otherwise, it's a full import path (e.g. '@/components/MyComp' or 'my-lib')\n const fullPath = meta.path.startsWith('/')\n ? `${importSource}${meta.path}`\n : meta.path\n\n if (!pathToExports.has(fullPath)) {\n pathToExports.set(fullPath, new Set())\n }\n for (const exp of meta.exports) {\n pathToExports.get(fullPath)!.add(exp)\n }\n }\n\n const lines: string[] = []\n for (const [path, exports] of pathToExports) {\n const names = Array.from(exports).sort().join(', ')\n lines.push(`import { ${names} } from '${path}'`)\n }\n\n return lines.join('\\n')\n}\n\nexport function transformMdx(\n code: string,\n options: Options = {},\n): { code: string; hasTransformed: boolean } {\n const framework = options.framework ?? DEFAULT_FRAMEWORK\n const usedComponents = detectComponents(code, framework, options.customComponents)\n\n if (usedComponents.length === 0) {\n return { code, hasTransformed: false }\n }\n\n const importSource = options.importSource ?? DEFAULT_IMPORT_SOURCE\n const importStatements = generateImports(usedComponents, importSource, framework, options.customComponents)\n\n return {\n code: `${importStatements}\\n\\n${code}`,\n hasTransformed: true,\n }\n}\n\n","import type { Options } from './types'\nimport unplugin from '.'\n\ninterface AstroConfig {\n config: {\n vite: {\n plugins: unknown[]\n }\n }\n}\n\nexport default function (options: Options) {\n return {\n name: 'unplugin-docubook',\n hooks: {\n 'astro:config:setup': async (astro: AstroConfig) => {\n astro.config.vite.plugins ||= []\n astro.config.vite.plugins.push(unplugin.vite(options))\n },\n },\n }\n}\n"],"mappings":"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","names":["registry","names"]}
package/dist/bun.cjs CHANGED
@@ -129,7 +129,7 @@ function generateImports(componentNames, importSource, framework = DEFAULT_FRAME
129
129
  for (const name of componentNames) {
130
130
  const meta = registry[name];
131
131
  if (!meta) continue;
132
- const fullPath = `${importSource}${meta.path}`;
132
+ const fullPath = meta.path.startsWith("/") ? `${importSource}${meta.path}` : meta.path;
133
133
  if (!pathToExports.has(fullPath)) {
134
134
  pathToExports.set(fullPath, /* @__PURE__ */ new Set());
135
135
  }
package/dist/bun.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/bun.ts","../src/index.ts","../src/core/registry.ts","../src/core/transform.ts"],"sourcesContent":["import { createBunPlugin } from 'unplugin'\nimport { unpluginFactory } from '.'\n\nexport default createBunPlugin(unpluginFactory)\n","import type { UnpluginFactory } from 'unplugin'\nimport type { Options } from './types'\nimport { createUnplugin } from 'unplugin'\nimport { transformMdx } from './core/transform'\n\nexport const unpluginFactory: UnpluginFactory<Options | undefined> = (\n options,\n) => ({\n name: 'unplugin-docubook',\n\n transformInclude(id) {\n // Only process .mdx and .md files\n return /\\.mdx?$/.test(id)\n },\n\n transform(code, _id) {\n const result = transformMdx(code, options)\n if (!result.hasTransformed) return\n return result.code\n },\n})\n\nexport const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory)\n\nexport default unplugin\n","import type { Framework } from '../types'\n\nexport interface ComponentMeta {\n exports: string[]\n path: string\n}\n\nconst FRAMEWORK_PATHS: Record<Framework, string> = {\n react: '/react',\n vue: '/vue',\n svelte: '/svelte',\n}\n\nfunction createRegistry(framework: Framework): Record<string, ComponentMeta> {\n const basePath = FRAMEWORK_PATHS[framework]\n\n return {\n Note: { exports: ['Note'], path: basePath },\n Card: { exports: ['Card'], path: basePath },\n CardGroup: { exports: ['CardGroup'], path: basePath },\n Accordion: { exports: ['Accordion'], path: basePath },\n AccordionGroup: { exports: ['AccordionGroup'], path: basePath },\n Stepper: { exports: ['Stepper', 'StepperItem'], path: basePath },\n Kbd: { exports: ['Kbd'], path: basePath },\n Tooltip: { exports: ['Tooltip'], path: basePath },\n Youtube: { exports: ['Youtube'], path: basePath },\n Button: { exports: ['Button'], path: basePath },\n DocuLink: { exports: ['DocuLink'], path: basePath },\n DocuImage: { exports: ['DocuImage'], path: basePath },\n Files: { exports: ['Files'], path: basePath },\n Folder: { exports: ['Folder'], path: basePath },\n File: { exports: ['File'], path: basePath },\n Release: { exports: ['Release'], path: basePath },\n Changes: { exports: ['Changes'], path: basePath },\n Pre: { exports: ['Pre'], path: basePath },\n Copy: { exports: ['Copy'], path: basePath },\n DocuBookProvider: { exports: ['DocuBookProvider'], path: basePath },\n }\n}\n\nconst registryCache = new Map<Framework, Record<string, ComponentMeta>>()\nconst regexCache = new Map<Framework, RegExp>()\n\nexport function getComponentRegistry(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): Record<string, ComponentMeta> {\n if (!customComponents || Object.keys(customComponents).length === 0) {\n const cached = registryCache.get(framework)\n if (cached) return cached\n const registry = createRegistry(framework)\n registryCache.set(framework, registry)\n return registry\n }\n // Merge custom components with built-in (custom overrides built-in)\n return { ...createRegistry(framework), ...customComponents }\n}\n\nexport function buildComponentDetectionRegex(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): RegExp {\n // Custom components: always build fresh regex (not cached)\n if (customComponents && Object.keys(customComponents).length > 0) {\n const registry = getComponentRegistry(framework, customComponents)\n const names = Object.keys(registry)\n return new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n }\n\n const cached = regexCache.get(framework)\n if (cached) {\n cached.lastIndex = 0 // Reset regex state because of /g flag\n return cached\n }\n const registry = getComponentRegistry(framework)\n const names = Object.keys(registry)\n const regex = new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n regexCache.set(framework, regex)\n return regex\n}\n","import type { Options, Framework } from '../types'\nimport type { ComponentMeta } from './registry'\nimport { getComponentRegistry, buildComponentDetectionRegex } from './registry'\n\nconst DEFAULT_IMPORT_SOURCE = 'unplugin-docubook/components'\nconst DEFAULT_FRAMEWORK: Framework = 'react'\n\n/**\n * Strip content zones where component tags should NOT be detected:\n * - Fenced code blocks (triple backticks)\n * - Inline code (single backticks)\n * - MDX comments\n * - HTML comments\n * - Existing import/export statements\n */\nfunction stripIgnoredZones(code: string): string {\n return code\n .replace(/```[\\s\\S]*?```/g, '') // fenced code blocks\n .replace(/`[^`]+`/g, '') // inline code\n .replace(/\\{\\/\\*[\\s\\S]*?\\*\\/\\}/g, '') // MDX comments {/* */}\n .replace(/<!--[\\s\\S]*?-->/g, '') // HTML comments\n .replace(/^import\\s.+$/gm, '') // existing imports\n .replace(/^export\\s.+$/gm, '') // exports\n}\n\nexport function detectComponents(\n code: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string[] {\n const strippedCode = stripIgnoredZones(code)\n const regex = buildComponentDetectionRegex(framework, customComponents)\n const registry = getComponentRegistry(framework, customComponents)\n const found = new Set<string>()\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(strippedCode)) !== null) {\n const name = match[1]\n if (name && registry[name]) {\n found.add(name)\n }\n }\n\n return Array.from(found)\n}\n\nexport function generateImports(\n componentNames: string[],\n importSource: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string {\n const registry = getComponentRegistry(framework, customComponents)\n const pathToExports = new Map<string, Set<string>>()\n\n for (const name of componentNames) {\n const meta = registry[name]\n if (!meta) continue\n\n const fullPath = `${importSource}${meta.path}`\n if (!pathToExports.has(fullPath)) {\n pathToExports.set(fullPath, new Set())\n }\n for (const exp of meta.exports) {\n pathToExports.get(fullPath)!.add(exp)\n }\n }\n\n const lines: string[] = []\n for (const [path, exports] of pathToExports) {\n const names = Array.from(exports).sort().join(', ')\n lines.push(`import { ${names} } from '${path}'`)\n }\n\n return lines.join('\\n')\n}\n\nexport function transformMdx(\n code: string,\n options: Options = {},\n): { code: string; hasTransformed: boolean } {\n const framework = options.framework ?? DEFAULT_FRAMEWORK\n const usedComponents = detectComponents(code, framework, options.customComponents)\n\n if (usedComponents.length === 0) {\n return { code, hasTransformed: false }\n }\n\n const importSource = options.importSource ?? DEFAULT_IMPORT_SOURCE\n const importStatements = generateImports(usedComponents, importSource, framework, options.customComponents)\n\n return {\n code: `${importStatements}\\n\\n${code}`,\n hasTransformed: true,\n }\n}\n\n"],"mappings":"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","names":["import_unplugin","registry","names","exports"]}
1
+ {"version":3,"sources":["../src/bun.ts","../src/index.ts","../src/core/registry.ts","../src/core/transform.ts"],"sourcesContent":["import { createBunPlugin } from 'unplugin'\nimport { unpluginFactory } from '.'\n\nexport default createBunPlugin(unpluginFactory)\n","import type { UnpluginFactory } from 'unplugin'\nimport type { Options } from './types'\nimport { createUnplugin } from 'unplugin'\nimport { transformMdx } from './core/transform'\n\nexport const unpluginFactory: UnpluginFactory<Options | undefined> = (\n options,\n) => ({\n name: 'unplugin-docubook',\n\n transformInclude(id) {\n // Only process .mdx and .md files\n return /\\.mdx?$/.test(id)\n },\n\n transform(code, _id) {\n const result = transformMdx(code, options)\n if (!result.hasTransformed) return\n return result.code\n },\n})\n\nexport const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory)\n\nexport default unplugin\n","import type { Framework } from '../types'\n\nexport interface ComponentMeta {\n exports: string[]\n path: string\n}\n\nconst FRAMEWORK_PATHS: Record<Framework, string> = {\n react: '/react',\n vue: '/vue',\n svelte: '/svelte',\n}\n\nfunction createRegistry(framework: Framework): Record<string, ComponentMeta> {\n const basePath = FRAMEWORK_PATHS[framework]\n\n return {\n Note: { exports: ['Note'], path: basePath },\n Card: { exports: ['Card'], path: basePath },\n CardGroup: { exports: ['CardGroup'], path: basePath },\n Accordion: { exports: ['Accordion'], path: basePath },\n AccordionGroup: { exports: ['AccordionGroup'], path: basePath },\n Stepper: { exports: ['Stepper', 'StepperItem'], path: basePath },\n Kbd: { exports: ['Kbd'], path: basePath },\n Tooltip: { exports: ['Tooltip'], path: basePath },\n Youtube: { exports: ['Youtube'], path: basePath },\n Button: { exports: ['Button'], path: basePath },\n DocuLink: { exports: ['DocuLink'], path: basePath },\n DocuImage: { exports: ['DocuImage'], path: basePath },\n Files: { exports: ['Files'], path: basePath },\n Folder: { exports: ['Folder'], path: basePath },\n File: { exports: ['File'], path: basePath },\n Release: { exports: ['Release'], path: basePath },\n Changes: { exports: ['Changes'], path: basePath },\n Pre: { exports: ['Pre'], path: basePath },\n Copy: { exports: ['Copy'], path: basePath },\n DocuBookProvider: { exports: ['DocuBookProvider'], path: basePath },\n }\n}\n\nconst registryCache = new Map<Framework, Record<string, ComponentMeta>>()\nconst regexCache = new Map<Framework, RegExp>()\n\nexport function getComponentRegistry(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): Record<string, ComponentMeta> {\n if (!customComponents || Object.keys(customComponents).length === 0) {\n const cached = registryCache.get(framework)\n if (cached) return cached\n const registry = createRegistry(framework)\n registryCache.set(framework, registry)\n return registry\n }\n // Merge custom components with built-in (custom overrides built-in)\n return { ...createRegistry(framework), ...customComponents }\n}\n\nexport function buildComponentDetectionRegex(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): RegExp {\n // Custom components: always build fresh regex (not cached)\n if (customComponents && Object.keys(customComponents).length > 0) {\n const registry = getComponentRegistry(framework, customComponents)\n const names = Object.keys(registry)\n return new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n }\n\n const cached = regexCache.get(framework)\n if (cached) {\n cached.lastIndex = 0 // Reset regex state because of /g flag\n return cached\n }\n const registry = getComponentRegistry(framework)\n const names = Object.keys(registry)\n const regex = new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n regexCache.set(framework, regex)\n return regex\n}\n","import type { Options, Framework } from '../types'\nimport type { ComponentMeta } from './registry'\nimport { getComponentRegistry, buildComponentDetectionRegex } from './registry'\n\nconst DEFAULT_IMPORT_SOURCE = 'unplugin-docubook/components'\nconst DEFAULT_FRAMEWORK: Framework = 'react'\n\n/**\n * Strip content zones where component tags should NOT be detected:\n * - Fenced code blocks (triple backticks)\n * - Inline code (single backticks)\n * - MDX comments\n * - HTML comments\n * - Existing import/export statements\n */\nfunction stripIgnoredZones(code: string): string {\n return code\n .replace(/```[\\s\\S]*?```/g, '') // fenced code blocks\n .replace(/`[^`]+`/g, '') // inline code\n .replace(/\\{\\/\\*[\\s\\S]*?\\*\\/\\}/g, '') // MDX comments {/* */}\n .replace(/<!--[\\s\\S]*?-->/g, '') // HTML comments\n .replace(/^import\\s.+$/gm, '') // existing imports\n .replace(/^export\\s.+$/gm, '') // exports\n}\n\nexport function detectComponents(\n code: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string[] {\n const strippedCode = stripIgnoredZones(code)\n const regex = buildComponentDetectionRegex(framework, customComponents)\n const registry = getComponentRegistry(framework, customComponents)\n const found = new Set<string>()\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(strippedCode)) !== null) {\n const name = match[1]\n if (name && registry[name]) {\n found.add(name)\n }\n }\n\n return Array.from(found)\n}\n\nexport function generateImports(\n componentNames: string[],\n importSource: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string {\n const registry = getComponentRegistry(framework, customComponents)\n const pathToExports = new Map<string, Set<string>>()\n\n for (const name of componentNames) {\n const meta = registry[name]\n if (!meta) continue\n\n // If path starts with '/', it's relative to importSource.\n // Otherwise, it's a full import path (e.g. '@/components/MyComp' or 'my-lib')\n const fullPath = meta.path.startsWith('/')\n ? `${importSource}${meta.path}`\n : meta.path\n\n if (!pathToExports.has(fullPath)) {\n pathToExports.set(fullPath, new Set())\n }\n for (const exp of meta.exports) {\n pathToExports.get(fullPath)!.add(exp)\n }\n }\n\n const lines: string[] = []\n for (const [path, exports] of pathToExports) {\n const names = Array.from(exports).sort().join(', ')\n lines.push(`import { ${names} } from '${path}'`)\n }\n\n return lines.join('\\n')\n}\n\nexport function transformMdx(\n code: string,\n options: Options = {},\n): { code: string; hasTransformed: boolean } {\n const framework = options.framework ?? DEFAULT_FRAMEWORK\n const usedComponents = detectComponents(code, framework, options.customComponents)\n\n if (usedComponents.length === 0) {\n return { code, hasTransformed: false }\n }\n\n const importSource = options.importSource ?? DEFAULT_IMPORT_SOURCE\n const importStatements = generateImports(usedComponents, importSource, framework, options.customComponents)\n\n return {\n code: `${importStatements}\\n\\n${code}`,\n hasTransformed: true,\n }\n}\n\n"],"mappings":"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","names":["import_unplugin","registry","names","exports"]}
package/dist/bun.js CHANGED
@@ -108,7 +108,7 @@ function generateImports(componentNames, importSource, framework = DEFAULT_FRAME
108
108
  for (const name of componentNames) {
109
109
  const meta = registry[name];
110
110
  if (!meta) continue;
111
- const fullPath = `${importSource}${meta.path}`;
111
+ const fullPath = meta.path.startsWith("/") ? `${importSource}${meta.path}` : meta.path;
112
112
  if (!pathToExports.has(fullPath)) {
113
113
  pathToExports.set(fullPath, /* @__PURE__ */ new Set());
114
114
  }
package/dist/bun.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/bun.ts","../src/index.ts","../src/core/registry.ts","../src/core/transform.ts"],"sourcesContent":["import { createBunPlugin } from 'unplugin'\nimport { unpluginFactory } from '.'\n\nexport default createBunPlugin(unpluginFactory)\n","import type { UnpluginFactory } from 'unplugin'\nimport type { Options } from './types'\nimport { createUnplugin } from 'unplugin'\nimport { transformMdx } from './core/transform'\n\nexport const unpluginFactory: UnpluginFactory<Options | undefined> = (\n options,\n) => ({\n name: 'unplugin-docubook',\n\n transformInclude(id) {\n // Only process .mdx and .md files\n return /\\.mdx?$/.test(id)\n },\n\n transform(code, _id) {\n const result = transformMdx(code, options)\n if (!result.hasTransformed) return\n return result.code\n },\n})\n\nexport const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory)\n\nexport default unplugin\n","import type { Framework } from '../types'\n\nexport interface ComponentMeta {\n exports: string[]\n path: string\n}\n\nconst FRAMEWORK_PATHS: Record<Framework, string> = {\n react: '/react',\n vue: '/vue',\n svelte: '/svelte',\n}\n\nfunction createRegistry(framework: Framework): Record<string, ComponentMeta> {\n const basePath = FRAMEWORK_PATHS[framework]\n\n return {\n Note: { exports: ['Note'], path: basePath },\n Card: { exports: ['Card'], path: basePath },\n CardGroup: { exports: ['CardGroup'], path: basePath },\n Accordion: { exports: ['Accordion'], path: basePath },\n AccordionGroup: { exports: ['AccordionGroup'], path: basePath },\n Stepper: { exports: ['Stepper', 'StepperItem'], path: basePath },\n Kbd: { exports: ['Kbd'], path: basePath },\n Tooltip: { exports: ['Tooltip'], path: basePath },\n Youtube: { exports: ['Youtube'], path: basePath },\n Button: { exports: ['Button'], path: basePath },\n DocuLink: { exports: ['DocuLink'], path: basePath },\n DocuImage: { exports: ['DocuImage'], path: basePath },\n Files: { exports: ['Files'], path: basePath },\n Folder: { exports: ['Folder'], path: basePath },\n File: { exports: ['File'], path: basePath },\n Release: { exports: ['Release'], path: basePath },\n Changes: { exports: ['Changes'], path: basePath },\n Pre: { exports: ['Pre'], path: basePath },\n Copy: { exports: ['Copy'], path: basePath },\n DocuBookProvider: { exports: ['DocuBookProvider'], path: basePath },\n }\n}\n\nconst registryCache = new Map<Framework, Record<string, ComponentMeta>>()\nconst regexCache = new Map<Framework, RegExp>()\n\nexport function getComponentRegistry(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): Record<string, ComponentMeta> {\n if (!customComponents || Object.keys(customComponents).length === 0) {\n const cached = registryCache.get(framework)\n if (cached) return cached\n const registry = createRegistry(framework)\n registryCache.set(framework, registry)\n return registry\n }\n // Merge custom components with built-in (custom overrides built-in)\n return { ...createRegistry(framework), ...customComponents }\n}\n\nexport function buildComponentDetectionRegex(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): RegExp {\n // Custom components: always build fresh regex (not cached)\n if (customComponents && Object.keys(customComponents).length > 0) {\n const registry = getComponentRegistry(framework, customComponents)\n const names = Object.keys(registry)\n return new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n }\n\n const cached = regexCache.get(framework)\n if (cached) {\n cached.lastIndex = 0 // Reset regex state because of /g flag\n return cached\n }\n const registry = getComponentRegistry(framework)\n const names = Object.keys(registry)\n const regex = new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n regexCache.set(framework, regex)\n return regex\n}\n","import type { Options, Framework } from '../types'\nimport type { ComponentMeta } from './registry'\nimport { getComponentRegistry, buildComponentDetectionRegex } from './registry'\n\nconst DEFAULT_IMPORT_SOURCE = 'unplugin-docubook/components'\nconst DEFAULT_FRAMEWORK: Framework = 'react'\n\n/**\n * Strip content zones where component tags should NOT be detected:\n * - Fenced code blocks (triple backticks)\n * - Inline code (single backticks)\n * - MDX comments\n * - HTML comments\n * - Existing import/export statements\n */\nfunction stripIgnoredZones(code: string): string {\n return code\n .replace(/```[\\s\\S]*?```/g, '') // fenced code blocks\n .replace(/`[^`]+`/g, '') // inline code\n .replace(/\\{\\/\\*[\\s\\S]*?\\*\\/\\}/g, '') // MDX comments {/* */}\n .replace(/<!--[\\s\\S]*?-->/g, '') // HTML comments\n .replace(/^import\\s.+$/gm, '') // existing imports\n .replace(/^export\\s.+$/gm, '') // exports\n}\n\nexport function detectComponents(\n code: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string[] {\n const strippedCode = stripIgnoredZones(code)\n const regex = buildComponentDetectionRegex(framework, customComponents)\n const registry = getComponentRegistry(framework, customComponents)\n const found = new Set<string>()\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(strippedCode)) !== null) {\n const name = match[1]\n if (name && registry[name]) {\n found.add(name)\n }\n }\n\n return Array.from(found)\n}\n\nexport function generateImports(\n componentNames: string[],\n importSource: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string {\n const registry = getComponentRegistry(framework, customComponents)\n const pathToExports = new Map<string, Set<string>>()\n\n for (const name of componentNames) {\n const meta = registry[name]\n if (!meta) continue\n\n const fullPath = `${importSource}${meta.path}`\n if (!pathToExports.has(fullPath)) {\n pathToExports.set(fullPath, new Set())\n }\n for (const exp of meta.exports) {\n pathToExports.get(fullPath)!.add(exp)\n }\n }\n\n const lines: string[] = []\n for (const [path, exports] of pathToExports) {\n const names = Array.from(exports).sort().join(', ')\n lines.push(`import { ${names} } from '${path}'`)\n }\n\n return lines.join('\\n')\n}\n\nexport function transformMdx(\n code: string,\n options: Options = {},\n): { code: string; hasTransformed: boolean } {\n const framework = options.framework ?? DEFAULT_FRAMEWORK\n const usedComponents = detectComponents(code, framework, options.customComponents)\n\n if (usedComponents.length === 0) {\n return { code, hasTransformed: false }\n }\n\n const importSource = options.importSource ?? DEFAULT_IMPORT_SOURCE\n const importStatements = generateImports(usedComponents, importSource, framework, options.customComponents)\n\n return {\n code: `${importStatements}\\n\\n${code}`,\n hasTransformed: true,\n }\n}\n\n"],"mappings":"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","names":["registry","names"]}
1
+ {"version":3,"sources":["../src/bun.ts","../src/index.ts","../src/core/registry.ts","../src/core/transform.ts"],"sourcesContent":["import { createBunPlugin } from 'unplugin'\nimport { unpluginFactory } from '.'\n\nexport default createBunPlugin(unpluginFactory)\n","import type { UnpluginFactory } from 'unplugin'\nimport type { Options } from './types'\nimport { createUnplugin } from 'unplugin'\nimport { transformMdx } from './core/transform'\n\nexport const unpluginFactory: UnpluginFactory<Options | undefined> = (\n options,\n) => ({\n name: 'unplugin-docubook',\n\n transformInclude(id) {\n // Only process .mdx and .md files\n return /\\.mdx?$/.test(id)\n },\n\n transform(code, _id) {\n const result = transformMdx(code, options)\n if (!result.hasTransformed) return\n return result.code\n },\n})\n\nexport const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory)\n\nexport default unplugin\n","import type { Framework } from '../types'\n\nexport interface ComponentMeta {\n exports: string[]\n path: string\n}\n\nconst FRAMEWORK_PATHS: Record<Framework, string> = {\n react: '/react',\n vue: '/vue',\n svelte: '/svelte',\n}\n\nfunction createRegistry(framework: Framework): Record<string, ComponentMeta> {\n const basePath = FRAMEWORK_PATHS[framework]\n\n return {\n Note: { exports: ['Note'], path: basePath },\n Card: { exports: ['Card'], path: basePath },\n CardGroup: { exports: ['CardGroup'], path: basePath },\n Accordion: { exports: ['Accordion'], path: basePath },\n AccordionGroup: { exports: ['AccordionGroup'], path: basePath },\n Stepper: { exports: ['Stepper', 'StepperItem'], path: basePath },\n Kbd: { exports: ['Kbd'], path: basePath },\n Tooltip: { exports: ['Tooltip'], path: basePath },\n Youtube: { exports: ['Youtube'], path: basePath },\n Button: { exports: ['Button'], path: basePath },\n DocuLink: { exports: ['DocuLink'], path: basePath },\n DocuImage: { exports: ['DocuImage'], path: basePath },\n Files: { exports: ['Files'], path: basePath },\n Folder: { exports: ['Folder'], path: basePath },\n File: { exports: ['File'], path: basePath },\n Release: { exports: ['Release'], path: basePath },\n Changes: { exports: ['Changes'], path: basePath },\n Pre: { exports: ['Pre'], path: basePath },\n Copy: { exports: ['Copy'], path: basePath },\n DocuBookProvider: { exports: ['DocuBookProvider'], path: basePath },\n }\n}\n\nconst registryCache = new Map<Framework, Record<string, ComponentMeta>>()\nconst regexCache = new Map<Framework, RegExp>()\n\nexport function getComponentRegistry(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): Record<string, ComponentMeta> {\n if (!customComponents || Object.keys(customComponents).length === 0) {\n const cached = registryCache.get(framework)\n if (cached) return cached\n const registry = createRegistry(framework)\n registryCache.set(framework, registry)\n return registry\n }\n // Merge custom components with built-in (custom overrides built-in)\n return { ...createRegistry(framework), ...customComponents }\n}\n\nexport function buildComponentDetectionRegex(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): RegExp {\n // Custom components: always build fresh regex (not cached)\n if (customComponents && Object.keys(customComponents).length > 0) {\n const registry = getComponentRegistry(framework, customComponents)\n const names = Object.keys(registry)\n return new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n }\n\n const cached = regexCache.get(framework)\n if (cached) {\n cached.lastIndex = 0 // Reset regex state because of /g flag\n return cached\n }\n const registry = getComponentRegistry(framework)\n const names = Object.keys(registry)\n const regex = new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n regexCache.set(framework, regex)\n return regex\n}\n","import type { Options, Framework } from '../types'\nimport type { ComponentMeta } from './registry'\nimport { getComponentRegistry, buildComponentDetectionRegex } from './registry'\n\nconst DEFAULT_IMPORT_SOURCE = 'unplugin-docubook/components'\nconst DEFAULT_FRAMEWORK: Framework = 'react'\n\n/**\n * Strip content zones where component tags should NOT be detected:\n * - Fenced code blocks (triple backticks)\n * - Inline code (single backticks)\n * - MDX comments\n * - HTML comments\n * - Existing import/export statements\n */\nfunction stripIgnoredZones(code: string): string {\n return code\n .replace(/```[\\s\\S]*?```/g, '') // fenced code blocks\n .replace(/`[^`]+`/g, '') // inline code\n .replace(/\\{\\/\\*[\\s\\S]*?\\*\\/\\}/g, '') // MDX comments {/* */}\n .replace(/<!--[\\s\\S]*?-->/g, '') // HTML comments\n .replace(/^import\\s.+$/gm, '') // existing imports\n .replace(/^export\\s.+$/gm, '') // exports\n}\n\nexport function detectComponents(\n code: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string[] {\n const strippedCode = stripIgnoredZones(code)\n const regex = buildComponentDetectionRegex(framework, customComponents)\n const registry = getComponentRegistry(framework, customComponents)\n const found = new Set<string>()\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(strippedCode)) !== null) {\n const name = match[1]\n if (name && registry[name]) {\n found.add(name)\n }\n }\n\n return Array.from(found)\n}\n\nexport function generateImports(\n componentNames: string[],\n importSource: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string {\n const registry = getComponentRegistry(framework, customComponents)\n const pathToExports = new Map<string, Set<string>>()\n\n for (const name of componentNames) {\n const meta = registry[name]\n if (!meta) continue\n\n // If path starts with '/', it's relative to importSource.\n // Otherwise, it's a full import path (e.g. '@/components/MyComp' or 'my-lib')\n const fullPath = meta.path.startsWith('/')\n ? `${importSource}${meta.path}`\n : meta.path\n\n if (!pathToExports.has(fullPath)) {\n pathToExports.set(fullPath, new Set())\n }\n for (const exp of meta.exports) {\n pathToExports.get(fullPath)!.add(exp)\n }\n }\n\n const lines: string[] = []\n for (const [path, exports] of pathToExports) {\n const names = Array.from(exports).sort().join(', ')\n lines.push(`import { ${names} } from '${path}'`)\n }\n\n return lines.join('\\n')\n}\n\nexport function transformMdx(\n code: string,\n options: Options = {},\n): { code: string; hasTransformed: boolean } {\n const framework = options.framework ?? DEFAULT_FRAMEWORK\n const usedComponents = detectComponents(code, framework, options.customComponents)\n\n if (usedComponents.length === 0) {\n return { code, hasTransformed: false }\n }\n\n const importSource = options.importSource ?? DEFAULT_IMPORT_SOURCE\n const importStatements = generateImports(usedComponents, importSource, framework, options.customComponents)\n\n return {\n code: `${importStatements}\\n\\n${code}`,\n hasTransformed: true,\n }\n}\n\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA,SAAS,uBAAuB;;;ACEhC,SAAS,sBAAsB;;;ACK/B,IAAM,kBAA6C;AAAA,EAC/C,OAAO;AAAA,EACP,KAAK;AAAA,EACL,QAAQ;AACZ;AAEA,SAAS,eAAe,WAAqD;AACzE,QAAM,WAAW,gBAAgB,SAAS;AAE1C,SAAO;AAAA,IACH,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,SAAS;AAAA,IAC1C,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,SAAS;AAAA,IAC1C,WAAW,EAAE,SAAS,CAAC,WAAW,GAAG,MAAM,SAAS;AAAA,IACpD,WAAW,EAAE,SAAS,CAAC,WAAW,GAAG,MAAM,SAAS;AAAA,IACpD,gBAAgB,EAAE,SAAS,CAAC,gBAAgB,GAAG,MAAM,SAAS;AAAA,IAC9D,SAAS,EAAE,SAAS,CAAC,WAAW,aAAa,GAAG,MAAM,SAAS;AAAA,IAC/D,KAAK,EAAE,SAAS,CAAC,KAAK,GAAG,MAAM,SAAS;AAAA,IACxC,SAAS,EAAE,SAAS,CAAC,SAAS,GAAG,MAAM,SAAS;AAAA,IAChD,SAAS,EAAE,SAAS,CAAC,SAAS,GAAG,MAAM,SAAS;AAAA,IAChD,QAAQ,EAAE,SAAS,CAAC,QAAQ,GAAG,MAAM,SAAS;AAAA,IAC9C,UAAU,EAAE,SAAS,CAAC,UAAU,GAAG,MAAM,SAAS;AAAA,IAClD,WAAW,EAAE,SAAS,CAAC,WAAW,GAAG,MAAM,SAAS;AAAA,IACpD,OAAO,EAAE,SAAS,CAAC,OAAO,GAAG,MAAM,SAAS;AAAA,IAC5C,QAAQ,EAAE,SAAS,CAAC,QAAQ,GAAG,MAAM,SAAS;AAAA,IAC9C,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,SAAS;AAAA,IAC1C,SAAS,EAAE,SAAS,CAAC,SAAS,GAAG,MAAM,SAAS;AAAA,IAChD,SAAS,EAAE,SAAS,CAAC,SAAS,GAAG,MAAM,SAAS;AAAA,IAChD,KAAK,EAAE,SAAS,CAAC,KAAK,GAAG,MAAM,SAAS;AAAA,IACxC,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,SAAS;AAAA,IAC1C,kBAAkB,EAAE,SAAS,CAAC,kBAAkB,GAAG,MAAM,SAAS;AAAA,EACtE;AACJ;AAEA,IAAM,gBAAgB,oBAAI,IAA8C;AACxE,IAAM,aAAa,oBAAI,IAAuB;AAEvC,SAAS,qBACZ,YAAuB,SACvB,kBAC6B;AAC7B,MAAI,CAAC,oBAAoB,OAAO,KAAK,gBAAgB,EAAE,WAAW,GAAG;AACjE,UAAM,SAAS,cAAc,IAAI,SAAS;AAC1C,QAAI,OAAQ,QAAO;AACnB,UAAM,WAAW,eAAe,SAAS;AACzC,kBAAc,IAAI,WAAW,QAAQ;AACrC,WAAO;AAAA,EACX;AAEA,SAAO,kCAAK,eAAe,SAAS,IAAM;AAC9C;AAEO,SAAS,6BACZ,YAAuB,SACvB,kBACM;AAEN,MAAI,oBAAoB,OAAO,KAAK,gBAAgB,EAAE,SAAS,GAAG;AAC9D,UAAMA,YAAW,qBAAqB,WAAW,gBAAgB;AACjE,UAAMC,SAAQ,OAAO,KAAKD,SAAQ;AAClC,WAAO,IAAI,OAAO,KAAKC,OAAM,KAAK,GAAG,CAAC,gBAAgB,GAAG;AAAA,EAC7D;AAEA,QAAM,SAAS,WAAW,IAAI,SAAS;AACvC,MAAI,QAAQ;AACR,WAAO,YAAY;AACnB,WAAO;AAAA,EACX;AACA,QAAM,WAAW,qBAAqB,SAAS;AAC/C,QAAM,QAAQ,OAAO,KAAK,QAAQ;AAClC,QAAM,QAAQ,IAAI,OAAO,KAAK,MAAM,KAAK,GAAG,CAAC,gBAAgB,GAAG;AAChE,aAAW,IAAI,WAAW,KAAK;AAC/B,SAAO;AACX;;;AC3EA,IAAM,wBAAwB;AAC9B,IAAM,oBAA+B;AAUrC,SAAS,kBAAkB,MAAsB;AAC7C,SAAO,KACF,QAAQ,mBAAmB,EAAE,EAC7B,QAAQ,YAAY,EAAE,EACtB,QAAQ,yBAAyB,EAAE,EACnC,QAAQ,oBAAoB,EAAE,EAC9B,QAAQ,kBAAkB,EAAE,EAC5B,QAAQ,kBAAkB,EAAE;AACrC;AAEO,SAAS,iBACZ,MACA,YAAuB,mBACvB,kBACQ;AACR,QAAM,eAAe,kBAAkB,IAAI;AAC3C,QAAM,QAAQ,6BAA6B,WAAW,gBAAgB;AACtE,QAAM,WAAW,qBAAqB,WAAW,gBAAgB;AACjE,QAAM,QAAQ,oBAAI,IAAY;AAC9B,MAAI;AAEJ,UAAQ,QAAQ,MAAM,KAAK,YAAY,OAAO,MAAM;AAChD,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,QAAQ,SAAS,IAAI,GAAG;AACxB,YAAM,IAAI,IAAI;AAAA,IAClB;AAAA,EACJ;AAEA,SAAO,MAAM,KAAK,KAAK;AAC3B;AAEO,SAAS,gBACZ,gBACA,cACA,YAAuB,mBACvB,kBACM;AACN,QAAM,WAAW,qBAAqB,WAAW,gBAAgB;AACjE,QAAM,gBAAgB,oBAAI,IAAyB;AAEnD,aAAW,QAAQ,gBAAgB;AAC/B,UAAM,OAAO,SAAS,IAAI;AAC1B,QAAI,CAAC,KAAM;AAIX,UAAM,WAAW,KAAK,KAAK,WAAW,GAAG,IACnC,GAAG,YAAY,GAAG,KAAK,IAAI,KAC3B,KAAK;AAEX,QAAI,CAAC,cAAc,IAAI,QAAQ,GAAG;AAC9B,oBAAc,IAAI,UAAU,oBAAI,IAAI,CAAC;AAAA,IACzC;AACA,eAAW,OAAO,KAAK,SAAS;AAC5B,oBAAc,IAAI,QAAQ,EAAG,IAAI,GAAG;AAAA,IACxC;AAAA,EACJ;AAEA,QAAM,QAAkB,CAAC;AACzB,aAAW,CAAC,MAAM,OAAO,KAAK,eAAe;AACzC,UAAM,QAAQ,MAAM,KAAK,OAAO,EAAE,KAAK,EAAE,KAAK,IAAI;AAClD,UAAM,KAAK,YAAY,KAAK,YAAY,IAAI,GAAG;AAAA,EACnD;AAEA,SAAO,MAAM,KAAK,IAAI;AAC1B;AAEO,SAAS,aACZ,MACA,UAAmB,CAAC,GACqB;AArF7C;AAsFI,QAAM,aAAY,aAAQ,cAAR,YAAqB;AACvC,QAAM,iBAAiB,iBAAiB,MAAM,WAAW,QAAQ,gBAAgB;AAEjF,MAAI,eAAe,WAAW,GAAG;AAC7B,WAAO,EAAE,MAAM,gBAAgB,MAAM;AAAA,EACzC;AAEA,QAAM,gBAAe,aAAQ,iBAAR,YAAwB;AAC7C,QAAM,mBAAmB,gBAAgB,gBAAgB,cAAc,WAAW,QAAQ,gBAAgB;AAE1G,SAAO;AAAA,IACH,MAAM,GAAG,gBAAgB;AAAA;AAAA,EAAO,IAAI;AAAA,IACpC,gBAAgB;AAAA,EACpB;AACJ;;;AF/FO,IAAM,kBAAwD,CACjE,aACE;AAAA,EACF,MAAM;AAAA,EAEN,iBAAiB,IAAI;AAEjB,WAAO,UAAU,KAAK,EAAE;AAAA,EAC5B;AAAA,EAEA,UAAU,MAAM,KAAK;AACjB,UAAM,SAAS,aAAa,MAAM,OAAO;AACzC,QAAI,CAAC,OAAO,eAAgB;AAC5B,WAAO,OAAO;AAAA,EAClB;AACJ;;;ADjBA,IAAO,cAAQ,gBAAgB,eAAe;","names":["registry","names"]}
package/dist/esbuild.cjs CHANGED
@@ -129,7 +129,7 @@ function generateImports(componentNames, importSource, framework = DEFAULT_FRAME
129
129
  for (const name of componentNames) {
130
130
  const meta = registry[name];
131
131
  if (!meta) continue;
132
- const fullPath = `${importSource}${meta.path}`;
132
+ const fullPath = meta.path.startsWith("/") ? `${importSource}${meta.path}` : meta.path;
133
133
  if (!pathToExports.has(fullPath)) {
134
134
  pathToExports.set(fullPath, /* @__PURE__ */ new Set());
135
135
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/esbuild.ts","../src/index.ts","../src/core/registry.ts","../src/core/transform.ts"],"sourcesContent":["import { createEsbuildPlugin } from 'unplugin'\nimport { unpluginFactory } from '.'\n\nexport default createEsbuildPlugin(unpluginFactory)\n","import type { UnpluginFactory } from 'unplugin'\nimport type { Options } from './types'\nimport { createUnplugin } from 'unplugin'\nimport { transformMdx } from './core/transform'\n\nexport const unpluginFactory: UnpluginFactory<Options | undefined> = (\n options,\n) => ({\n name: 'unplugin-docubook',\n\n transformInclude(id) {\n // Only process .mdx and .md files\n return /\\.mdx?$/.test(id)\n },\n\n transform(code, _id) {\n const result = transformMdx(code, options)\n if (!result.hasTransformed) return\n return result.code\n },\n})\n\nexport const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory)\n\nexport default unplugin\n","import type { Framework } from '../types'\n\nexport interface ComponentMeta {\n exports: string[]\n path: string\n}\n\nconst FRAMEWORK_PATHS: Record<Framework, string> = {\n react: '/react',\n vue: '/vue',\n svelte: '/svelte',\n}\n\nfunction createRegistry(framework: Framework): Record<string, ComponentMeta> {\n const basePath = FRAMEWORK_PATHS[framework]\n\n return {\n Note: { exports: ['Note'], path: basePath },\n Card: { exports: ['Card'], path: basePath },\n CardGroup: { exports: ['CardGroup'], path: basePath },\n Accordion: { exports: ['Accordion'], path: basePath },\n AccordionGroup: { exports: ['AccordionGroup'], path: basePath },\n Stepper: { exports: ['Stepper', 'StepperItem'], path: basePath },\n Kbd: { exports: ['Kbd'], path: basePath },\n Tooltip: { exports: ['Tooltip'], path: basePath },\n Youtube: { exports: ['Youtube'], path: basePath },\n Button: { exports: ['Button'], path: basePath },\n DocuLink: { exports: ['DocuLink'], path: basePath },\n DocuImage: { exports: ['DocuImage'], path: basePath },\n Files: { exports: ['Files'], path: basePath },\n Folder: { exports: ['Folder'], path: basePath },\n File: { exports: ['File'], path: basePath },\n Release: { exports: ['Release'], path: basePath },\n Changes: { exports: ['Changes'], path: basePath },\n Pre: { exports: ['Pre'], path: basePath },\n Copy: { exports: ['Copy'], path: basePath },\n DocuBookProvider: { exports: ['DocuBookProvider'], path: basePath },\n }\n}\n\nconst registryCache = new Map<Framework, Record<string, ComponentMeta>>()\nconst regexCache = new Map<Framework, RegExp>()\n\nexport function getComponentRegistry(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): Record<string, ComponentMeta> {\n if (!customComponents || Object.keys(customComponents).length === 0) {\n const cached = registryCache.get(framework)\n if (cached) return cached\n const registry = createRegistry(framework)\n registryCache.set(framework, registry)\n return registry\n }\n // Merge custom components with built-in (custom overrides built-in)\n return { ...createRegistry(framework), ...customComponents }\n}\n\nexport function buildComponentDetectionRegex(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): RegExp {\n // Custom components: always build fresh regex (not cached)\n if (customComponents && Object.keys(customComponents).length > 0) {\n const registry = getComponentRegistry(framework, customComponents)\n const names = Object.keys(registry)\n return new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n }\n\n const cached = regexCache.get(framework)\n if (cached) {\n cached.lastIndex = 0 // Reset regex state because of /g flag\n return cached\n }\n const registry = getComponentRegistry(framework)\n const names = Object.keys(registry)\n const regex = new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n regexCache.set(framework, regex)\n return regex\n}\n","import type { Options, Framework } from '../types'\nimport type { ComponentMeta } from './registry'\nimport { getComponentRegistry, buildComponentDetectionRegex } from './registry'\n\nconst DEFAULT_IMPORT_SOURCE = 'unplugin-docubook/components'\nconst DEFAULT_FRAMEWORK: Framework = 'react'\n\n/**\n * Strip content zones where component tags should NOT be detected:\n * - Fenced code blocks (triple backticks)\n * - Inline code (single backticks)\n * - MDX comments\n * - HTML comments\n * - Existing import/export statements\n */\nfunction stripIgnoredZones(code: string): string {\n return code\n .replace(/```[\\s\\S]*?```/g, '') // fenced code blocks\n .replace(/`[^`]+`/g, '') // inline code\n .replace(/\\{\\/\\*[\\s\\S]*?\\*\\/\\}/g, '') // MDX comments {/* */}\n .replace(/<!--[\\s\\S]*?-->/g, '') // HTML comments\n .replace(/^import\\s.+$/gm, '') // existing imports\n .replace(/^export\\s.+$/gm, '') // exports\n}\n\nexport function detectComponents(\n code: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string[] {\n const strippedCode = stripIgnoredZones(code)\n const regex = buildComponentDetectionRegex(framework, customComponents)\n const registry = getComponentRegistry(framework, customComponents)\n const found = new Set<string>()\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(strippedCode)) !== null) {\n const name = match[1]\n if (name && registry[name]) {\n found.add(name)\n }\n }\n\n return Array.from(found)\n}\n\nexport function generateImports(\n componentNames: string[],\n importSource: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string {\n const registry = getComponentRegistry(framework, customComponents)\n const pathToExports = new Map<string, Set<string>>()\n\n for (const name of componentNames) {\n const meta = registry[name]\n if (!meta) continue\n\n const fullPath = `${importSource}${meta.path}`\n if (!pathToExports.has(fullPath)) {\n pathToExports.set(fullPath, new Set())\n }\n for (const exp of meta.exports) {\n pathToExports.get(fullPath)!.add(exp)\n }\n }\n\n const lines: string[] = []\n for (const [path, exports] of pathToExports) {\n const names = Array.from(exports).sort().join(', ')\n lines.push(`import { ${names} } from '${path}'`)\n }\n\n return lines.join('\\n')\n}\n\nexport function transformMdx(\n code: string,\n options: Options = {},\n): { code: string; hasTransformed: boolean } {\n const framework = options.framework ?? DEFAULT_FRAMEWORK\n const usedComponents = detectComponents(code, framework, options.customComponents)\n\n if (usedComponents.length === 0) {\n return { code, hasTransformed: false }\n }\n\n const importSource = options.importSource ?? DEFAULT_IMPORT_SOURCE\n const importStatements = generateImports(usedComponents, importSource, framework, options.customComponents)\n\n return {\n code: `${importStatements}\\n\\n${code}`,\n hasTransformed: true,\n }\n}\n\n"],"mappings":"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","names":["import_unplugin","registry","names","exports"]}
1
+ {"version":3,"sources":["../src/esbuild.ts","../src/index.ts","../src/core/registry.ts","../src/core/transform.ts"],"sourcesContent":["import { createEsbuildPlugin } from 'unplugin'\nimport { unpluginFactory } from '.'\n\nexport default createEsbuildPlugin(unpluginFactory)\n","import type { UnpluginFactory } from 'unplugin'\nimport type { Options } from './types'\nimport { createUnplugin } from 'unplugin'\nimport { transformMdx } from './core/transform'\n\nexport const unpluginFactory: UnpluginFactory<Options | undefined> = (\n options,\n) => ({\n name: 'unplugin-docubook',\n\n transformInclude(id) {\n // Only process .mdx and .md files\n return /\\.mdx?$/.test(id)\n },\n\n transform(code, _id) {\n const result = transformMdx(code, options)\n if (!result.hasTransformed) return\n return result.code\n },\n})\n\nexport const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory)\n\nexport default unplugin\n","import type { Framework } from '../types'\n\nexport interface ComponentMeta {\n exports: string[]\n path: string\n}\n\nconst FRAMEWORK_PATHS: Record<Framework, string> = {\n react: '/react',\n vue: '/vue',\n svelte: '/svelte',\n}\n\nfunction createRegistry(framework: Framework): Record<string, ComponentMeta> {\n const basePath = FRAMEWORK_PATHS[framework]\n\n return {\n Note: { exports: ['Note'], path: basePath },\n Card: { exports: ['Card'], path: basePath },\n CardGroup: { exports: ['CardGroup'], path: basePath },\n Accordion: { exports: ['Accordion'], path: basePath },\n AccordionGroup: { exports: ['AccordionGroup'], path: basePath },\n Stepper: { exports: ['Stepper', 'StepperItem'], path: basePath },\n Kbd: { exports: ['Kbd'], path: basePath },\n Tooltip: { exports: ['Tooltip'], path: basePath },\n Youtube: { exports: ['Youtube'], path: basePath },\n Button: { exports: ['Button'], path: basePath },\n DocuLink: { exports: ['DocuLink'], path: basePath },\n DocuImage: { exports: ['DocuImage'], path: basePath },\n Files: { exports: ['Files'], path: basePath },\n Folder: { exports: ['Folder'], path: basePath },\n File: { exports: ['File'], path: basePath },\n Release: { exports: ['Release'], path: basePath },\n Changes: { exports: ['Changes'], path: basePath },\n Pre: { exports: ['Pre'], path: basePath },\n Copy: { exports: ['Copy'], path: basePath },\n DocuBookProvider: { exports: ['DocuBookProvider'], path: basePath },\n }\n}\n\nconst registryCache = new Map<Framework, Record<string, ComponentMeta>>()\nconst regexCache = new Map<Framework, RegExp>()\n\nexport function getComponentRegistry(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): Record<string, ComponentMeta> {\n if (!customComponents || Object.keys(customComponents).length === 0) {\n const cached = registryCache.get(framework)\n if (cached) return cached\n const registry = createRegistry(framework)\n registryCache.set(framework, registry)\n return registry\n }\n // Merge custom components with built-in (custom overrides built-in)\n return { ...createRegistry(framework), ...customComponents }\n}\n\nexport function buildComponentDetectionRegex(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): RegExp {\n // Custom components: always build fresh regex (not cached)\n if (customComponents && Object.keys(customComponents).length > 0) {\n const registry = getComponentRegistry(framework, customComponents)\n const names = Object.keys(registry)\n return new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n }\n\n const cached = regexCache.get(framework)\n if (cached) {\n cached.lastIndex = 0 // Reset regex state because of /g flag\n return cached\n }\n const registry = getComponentRegistry(framework)\n const names = Object.keys(registry)\n const regex = new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n regexCache.set(framework, regex)\n return regex\n}\n","import type { Options, Framework } from '../types'\nimport type { ComponentMeta } from './registry'\nimport { getComponentRegistry, buildComponentDetectionRegex } from './registry'\n\nconst DEFAULT_IMPORT_SOURCE = 'unplugin-docubook/components'\nconst DEFAULT_FRAMEWORK: Framework = 'react'\n\n/**\n * Strip content zones where component tags should NOT be detected:\n * - Fenced code blocks (triple backticks)\n * - Inline code (single backticks)\n * - MDX comments\n * - HTML comments\n * - Existing import/export statements\n */\nfunction stripIgnoredZones(code: string): string {\n return code\n .replace(/```[\\s\\S]*?```/g, '') // fenced code blocks\n .replace(/`[^`]+`/g, '') // inline code\n .replace(/\\{\\/\\*[\\s\\S]*?\\*\\/\\}/g, '') // MDX comments {/* */}\n .replace(/<!--[\\s\\S]*?-->/g, '') // HTML comments\n .replace(/^import\\s.+$/gm, '') // existing imports\n .replace(/^export\\s.+$/gm, '') // exports\n}\n\nexport function detectComponents(\n code: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string[] {\n const strippedCode = stripIgnoredZones(code)\n const regex = buildComponentDetectionRegex(framework, customComponents)\n const registry = getComponentRegistry(framework, customComponents)\n const found = new Set<string>()\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(strippedCode)) !== null) {\n const name = match[1]\n if (name && registry[name]) {\n found.add(name)\n }\n }\n\n return Array.from(found)\n}\n\nexport function generateImports(\n componentNames: string[],\n importSource: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string {\n const registry = getComponentRegistry(framework, customComponents)\n const pathToExports = new Map<string, Set<string>>()\n\n for (const name of componentNames) {\n const meta = registry[name]\n if (!meta) continue\n\n // If path starts with '/', it's relative to importSource.\n // Otherwise, it's a full import path (e.g. '@/components/MyComp' or 'my-lib')\n const fullPath = meta.path.startsWith('/')\n ? `${importSource}${meta.path}`\n : meta.path\n\n if (!pathToExports.has(fullPath)) {\n pathToExports.set(fullPath, new Set())\n }\n for (const exp of meta.exports) {\n pathToExports.get(fullPath)!.add(exp)\n }\n }\n\n const lines: string[] = []\n for (const [path, exports] of pathToExports) {\n const names = Array.from(exports).sort().join(', ')\n lines.push(`import { ${names} } from '${path}'`)\n }\n\n return lines.join('\\n')\n}\n\nexport function transformMdx(\n code: string,\n options: Options = {},\n): { code: string; hasTransformed: boolean } {\n const framework = options.framework ?? DEFAULT_FRAMEWORK\n const usedComponents = detectComponents(code, framework, options.customComponents)\n\n if (usedComponents.length === 0) {\n return { code, hasTransformed: false }\n }\n\n const importSource = options.importSource ?? DEFAULT_IMPORT_SOURCE\n const importStatements = generateImports(usedComponents, importSource, framework, options.customComponents)\n\n return {\n code: `${importStatements}\\n\\n${code}`,\n hasTransformed: true,\n }\n}\n\n"],"mappings":"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","names":["import_unplugin","registry","names","exports"]}
package/dist/esbuild.js CHANGED
@@ -108,7 +108,7 @@ function generateImports(componentNames, importSource, framework = DEFAULT_FRAME
108
108
  for (const name of componentNames) {
109
109
  const meta = registry[name];
110
110
  if (!meta) continue;
111
- const fullPath = `${importSource}${meta.path}`;
111
+ const fullPath = meta.path.startsWith("/") ? `${importSource}${meta.path}` : meta.path;
112
112
  if (!pathToExports.has(fullPath)) {
113
113
  pathToExports.set(fullPath, /* @__PURE__ */ new Set());
114
114
  }