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.
- package/README.md +84 -108
- package/dist/astro.cjs +1 -1
- package/dist/astro.cjs.map +1 -1
- package/dist/astro.js +1 -1
- package/dist/astro.js.map +1 -1
- package/dist/bun.cjs +1 -1
- package/dist/bun.cjs.map +1 -1
- package/dist/bun.js +1 -1
- package/dist/bun.js.map +1 -1
- package/dist/esbuild.cjs +1 -1
- package/dist/esbuild.cjs.map +1 -1
- package/dist/esbuild.js +1 -1
- package/dist/esbuild.js.map +1 -1
- package/dist/farm.cjs +1 -1
- package/dist/farm.cjs.map +1 -1
- package/dist/farm.js +1 -1
- package/dist/farm.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/next.cjs +1 -1
- package/dist/next.cjs.map +1 -1
- package/dist/next.js +1 -1
- package/dist/next.js.map +1 -1
- package/dist/nuxt.cjs +1 -1
- package/dist/nuxt.cjs.map +1 -1
- package/dist/nuxt.js +1 -1
- package/dist/nuxt.js.map +1 -1
- package/dist/rolldown.cjs +1 -1
- package/dist/rolldown.cjs.map +1 -1
- package/dist/rolldown.js +1 -1
- package/dist/rolldown.js.map +1 -1
- package/dist/rollup.cjs +1 -1
- package/dist/rollup.cjs.map +1 -1
- package/dist/rollup.js +1 -1
- package/dist/rollup.js.map +1 -1
- package/dist/rspack.cjs +1 -1
- package/dist/rspack.cjs.map +1 -1
- package/dist/rspack.js +1 -1
- package/dist/rspack.js.map +1 -1
- package/dist/vite.cjs +1 -1
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.js +1 -1
- package/dist/vite.js.map +1 -1
- package/dist/webpack.cjs +1 -1
- package/dist/webpack.cjs.map +1 -1
- package/dist/webpack.js +1 -1
- package/dist/webpack.js.map +1 -1
- 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**:
|
|
8
|
-
- 🛠️ **Unified Pipeline**: Built on top of
|
|
9
|
-
- 📦 **
|
|
10
|
-
-
|
|
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
|
-
##
|
|
16
|
+
## 🛠️ Installation
|
|
13
17
|
|
|
18
|
+
### 1. Install Package
|
|
14
19
|
```bash
|
|
15
20
|
npm install unplugin-docubook
|
|
16
21
|
```
|
|
17
22
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
import DocuBook from 'unplugin-docubook/rollup'
|
|
29
|
+
# For Vue / Nuxt
|
|
30
|
+
npm install lucide-vue-next
|
|
39
31
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
DocuBook({ /* options */ }),
|
|
43
|
-
],
|
|
44
|
-
}
|
|
32
|
+
# For Svelte / Astro
|
|
33
|
+
npm install lucide-svelte
|
|
45
34
|
```
|
|
46
35
|
|
|
47
|
-
###
|
|
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
|
-
```
|
|
50
|
-
|
|
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
|
-
|
|
43
|
+
---
|
|
60
44
|
|
|
61
|
-
|
|
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
|
-
|
|
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
|
-
|
|
79
|
-
|
|
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({
|
|
57
|
+
DocuBook({
|
|
58
|
+
framework: 'react', // or 'vue' | 'svelte'
|
|
59
|
+
}),
|
|
93
60
|
],
|
|
94
|
-
})
|
|
61
|
+
});
|
|
95
62
|
```
|
|
96
63
|
|
|
97
|
-
###
|
|
64
|
+
### Next.js
|
|
65
|
+
```javascript
|
|
66
|
+
// next.config.mjs
|
|
67
|
+
import DocuBook from 'unplugin-docubook/webpack';
|
|
98
68
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
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', {
|
|
119
|
-
]
|
|
85
|
+
['unplugin-docubook/nuxt', { framework: 'vue' }]
|
|
86
|
+
]
|
|
120
87
|
})
|
|
121
88
|
```
|
|
122
89
|
|
|
123
|
-
###
|
|
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
|
-
|
|
93
|
+
---
|
|
136
94
|
|
|
137
|
-
|
|
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
|
-
|
|
97
|
+
### MDX Content
|
|
98
|
+
No imports needed for core components!
|
|
145
99
|
|
|
146
100
|
```mdx
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
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
|
}
|
package/dist/astro.cjs.map
CHANGED
|
@@ -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":";;;;;;;;;;;;;;;;;;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;AAEX,UAAM,WAAW,GAAG,YAAY,GAAG,KAAK,IAAI;AAC5C,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;AAhF7C;AAiFI,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;;;AF1FO,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"]}
|
|
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":["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
|
}
|
package/dist/esbuild.cjs.map
CHANGED
|
@@ -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
|
}
|