unplugin-docubook 1.1.0 → 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 (55) hide show
  1. package/README.md +84 -108
  2. package/dist/astro.cjs +52 -13
  3. package/dist/astro.cjs.map +1 -1
  4. package/dist/astro.js +55 -13
  5. package/dist/astro.js.map +1 -1
  6. package/dist/bun.cjs +52 -13
  7. package/dist/bun.cjs.map +1 -1
  8. package/dist/bun.js +55 -13
  9. package/dist/bun.js.map +1 -1
  10. package/dist/components/index.cjs +4 -2
  11. package/dist/components/index.cjs.map +1 -1
  12. package/dist/components/index.js +4 -2
  13. package/dist/components/index.js.map +1 -1
  14. package/dist/esbuild.cjs +52 -13
  15. package/dist/esbuild.cjs.map +1 -1
  16. package/dist/esbuild.js +55 -13
  17. package/dist/esbuild.js.map +1 -1
  18. package/dist/farm.cjs +52 -13
  19. package/dist/farm.cjs.map +1 -1
  20. package/dist/farm.js +55 -13
  21. package/dist/farm.js.map +1 -1
  22. package/dist/index.cjs +52 -13
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.js +55 -13
  25. package/dist/index.js.map +1 -1
  26. package/dist/next.cjs +52 -13
  27. package/dist/next.cjs.map +1 -1
  28. package/dist/next.js +55 -13
  29. package/dist/next.js.map +1 -1
  30. package/dist/nuxt.cjs +52 -13
  31. package/dist/nuxt.cjs.map +1 -1
  32. package/dist/nuxt.js +55 -13
  33. package/dist/nuxt.js.map +1 -1
  34. package/dist/rolldown.cjs +52 -13
  35. package/dist/rolldown.cjs.map +1 -1
  36. package/dist/rolldown.js +55 -13
  37. package/dist/rolldown.js.map +1 -1
  38. package/dist/rollup.cjs +52 -13
  39. package/dist/rollup.cjs.map +1 -1
  40. package/dist/rollup.js +55 -13
  41. package/dist/rollup.js.map +1 -1
  42. package/dist/rspack.cjs +52 -13
  43. package/dist/rspack.cjs.map +1 -1
  44. package/dist/rspack.js +55 -13
  45. package/dist/rspack.js.map +1 -1
  46. package/dist/types.cjs.map +1 -1
  47. package/dist/vite.cjs +52 -13
  48. package/dist/vite.cjs.map +1 -1
  49. package/dist/vite.js +55 -13
  50. package/dist/vite.js.map +1 -1
  51. package/dist/webpack.cjs +52 -13
  52. package/dist/webpack.cjs.map +1 -1
  53. package/dist/webpack.js +55 -13
  54. package/dist/webpack.js.map +1 -1
  55. package/package.json +1 -1
package/dist/farm.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/farm.ts","../src/index.ts","../src/core/registry.ts","../src/core/transform.ts"],"sourcesContent":["import { createFarmPlugin } from 'unplugin'\nimport { unpluginFactory } from '.'\n\nexport default createFarmPlugin(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\nexport function getComponentRegistry(framework: Framework = 'react'): Record<string, ComponentMeta> {\n return createRegistry(framework)\n}\n\nexport function buildComponentDetectionRegex(framework: Framework = 'react'): RegExp {\n const registry = getComponentRegistry(framework)\n const names = Object.keys(registry)\n return new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n}\n","import type { Options, Framework } from '../types'\nimport { getComponentRegistry, buildComponentDetectionRegex } from './registry'\n\nconst DEFAULT_IMPORT_SOURCE = 'unplugin-docubook/components'\nconst DEFAULT_FRAMEWORK: Framework = 'react'\n\nexport function detectComponents(code: string, framework: Framework = DEFAULT_FRAMEWORK): string[] {\n const regex = buildComponentDetectionRegex(framework)\n const registry = getComponentRegistry(framework)\n const found = new Set<string>()\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(code)) !== 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): string {\n const registry = getComponentRegistry(framework)\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)\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)\n\n return {\n code: `${importStatements}\\n\\n${code}`,\n hasTransformed: true,\n }\n}\n"],"mappings":";AAAA,SAAS,wBAAwB;;;ACEjC,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;AAEO,SAAS,qBAAqB,YAAuB,SAAwC;AAChG,SAAO,eAAe,SAAS;AACnC;AAEO,SAAS,6BAA6B,YAAuB,SAAiB;AACjF,QAAM,WAAW,qBAAqB,SAAS;AAC/C,QAAM,QAAQ,OAAO,KAAK,QAAQ;AAClC,SAAO,IAAI,OAAO,KAAK,MAAM,KAAK,GAAG,CAAC,gBAAgB,GAAG;AAC7D;;;AC7CA,IAAM,wBAAwB;AAC9B,IAAM,oBAA+B;AAE9B,SAAS,iBAAiB,MAAc,YAAuB,mBAA6B;AAC/F,QAAM,QAAQ,6BAA6B,SAAS;AACpD,QAAM,WAAW,qBAAqB,SAAS;AAC/C,QAAM,QAAQ,oBAAI,IAAY;AAC9B,MAAI;AAEJ,UAAQ,QAAQ,MAAM,KAAK,IAAI,OAAO,MAAM;AACxC,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,mBACjB;AACN,QAAM,WAAW,qBAAqB,SAAS;AAC/C,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;AAvD7C;AAwDI,QAAM,aAAY,aAAQ,cAAR,YAAqB;AACvC,QAAM,iBAAiB,iBAAiB,MAAM,SAAS;AAEvD,MAAI,eAAe,WAAW,GAAG;AAC7B,WAAO,EAAE,MAAM,gBAAgB,MAAM;AAAA,EACzC;AAEA,QAAM,gBAAe,aAAQ,iBAAR,YAAwB;AAC7C,QAAM,mBAAmB,gBAAgB,gBAAgB,cAAc,SAAS;AAEhF,SAAO;AAAA,IACH,MAAM,GAAG,gBAAgB;AAAA;AAAA,EAAO,IAAI;AAAA,IACpC,gBAAgB;AAAA,EACpB;AACJ;;;AFjEO,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,eAAQ,iBAAiB,eAAe;","names":[]}
1
+ {"version":3,"sources":["../src/farm.ts","../src/index.ts","../src/core/registry.ts","../src/core/transform.ts"],"sourcesContent":["import { createFarmPlugin } from 'unplugin'\nimport { unpluginFactory } from '.'\n\nexport default createFarmPlugin(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/index.cjs CHANGED
@@ -2,7 +2,21 @@
2
2
  var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __spreadValues = (a, b) => {
10
+ for (var prop in b || (b = {}))
11
+ if (__hasOwnProp.call(b, prop))
12
+ __defNormalProp(a, prop, b[prop]);
13
+ if (__getOwnPropSymbols)
14
+ for (var prop of __getOwnPropSymbols(b)) {
15
+ if (__propIsEnum.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ }
18
+ return a;
19
+ };
6
20
  var __export = (target, all) => {
7
21
  for (var name in all)
8
22
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -58,24 +72,49 @@ function createRegistry(framework) {
58
72
  DocuBookProvider: { exports: ["DocuBookProvider"], path: basePath }
59
73
  };
60
74
  }
61
- function getComponentRegistry(framework = "react") {
62
- return createRegistry(framework);
75
+ var registryCache = /* @__PURE__ */ new Map();
76
+ var regexCache = /* @__PURE__ */ new Map();
77
+ function getComponentRegistry(framework = "react", customComponents) {
78
+ if (!customComponents || Object.keys(customComponents).length === 0) {
79
+ const cached = registryCache.get(framework);
80
+ if (cached) return cached;
81
+ const registry = createRegistry(framework);
82
+ registryCache.set(framework, registry);
83
+ return registry;
84
+ }
85
+ return __spreadValues(__spreadValues({}, createRegistry(framework)), customComponents);
63
86
  }
64
- function buildComponentDetectionRegex(framework = "react") {
87
+ function buildComponentDetectionRegex(framework = "react", customComponents) {
88
+ if (customComponents && Object.keys(customComponents).length > 0) {
89
+ const registry2 = getComponentRegistry(framework, customComponents);
90
+ const names2 = Object.keys(registry2);
91
+ return new RegExp(`<(${names2.join("|")})(?=[\\s/>])`, "g");
92
+ }
93
+ const cached = regexCache.get(framework);
94
+ if (cached) {
95
+ cached.lastIndex = 0;
96
+ return cached;
97
+ }
65
98
  const registry = getComponentRegistry(framework);
66
99
  const names = Object.keys(registry);
67
- return new RegExp(`<(${names.join("|")})(?=[\\s/>])`, "g");
100
+ const regex = new RegExp(`<(${names.join("|")})(?=[\\s/>])`, "g");
101
+ regexCache.set(framework, regex);
102
+ return regex;
68
103
  }
69
104
 
70
105
  // src/core/transform.ts
71
106
  var DEFAULT_IMPORT_SOURCE = "unplugin-docubook/components";
72
107
  var DEFAULT_FRAMEWORK = "react";
73
- function detectComponents(code, framework = DEFAULT_FRAMEWORK) {
74
- const regex = buildComponentDetectionRegex(framework);
75
- const registry = getComponentRegistry(framework);
108
+ function stripIgnoredZones(code) {
109
+ return code.replace(/```[\s\S]*?```/g, "").replace(/`[^`]+`/g, "").replace(/\{\/\*[\s\S]*?\*\/\}/g, "").replace(/<!--[\s\S]*?-->/g, "").replace(/^import\s.+$/gm, "").replace(/^export\s.+$/gm, "");
110
+ }
111
+ function detectComponents(code, framework = DEFAULT_FRAMEWORK, customComponents) {
112
+ const strippedCode = stripIgnoredZones(code);
113
+ const regex = buildComponentDetectionRegex(framework, customComponents);
114
+ const registry = getComponentRegistry(framework, customComponents);
76
115
  const found = /* @__PURE__ */ new Set();
77
116
  let match;
78
- while ((match = regex.exec(code)) !== null) {
117
+ while ((match = regex.exec(strippedCode)) !== null) {
79
118
  const name = match[1];
80
119
  if (name && registry[name]) {
81
120
  found.add(name);
@@ -83,13 +122,13 @@ function detectComponents(code, framework = DEFAULT_FRAMEWORK) {
83
122
  }
84
123
  return Array.from(found);
85
124
  }
86
- function generateImports(componentNames, importSource, framework = DEFAULT_FRAMEWORK) {
87
- const registry = getComponentRegistry(framework);
125
+ function generateImports(componentNames, importSource, framework = DEFAULT_FRAMEWORK, customComponents) {
126
+ const registry = getComponentRegistry(framework, customComponents);
88
127
  const pathToExports = /* @__PURE__ */ new Map();
89
128
  for (const name of componentNames) {
90
129
  const meta = registry[name];
91
130
  if (!meta) continue;
92
- const fullPath = `${importSource}${meta.path}`;
131
+ const fullPath = meta.path.startsWith("/") ? `${importSource}${meta.path}` : meta.path;
93
132
  if (!pathToExports.has(fullPath)) {
94
133
  pathToExports.set(fullPath, /* @__PURE__ */ new Set());
95
134
  }
@@ -107,12 +146,12 @@ function generateImports(componentNames, importSource, framework = DEFAULT_FRAME
107
146
  function transformMdx(code, options = {}) {
108
147
  var _a, _b;
109
148
  const framework = (_a = options.framework) != null ? _a : DEFAULT_FRAMEWORK;
110
- const usedComponents = detectComponents(code, framework);
149
+ const usedComponents = detectComponents(code, framework, options.customComponents);
111
150
  if (usedComponents.length === 0) {
112
151
  return { code, hasTransformed: false };
113
152
  }
114
153
  const importSource = (_b = options.importSource) != null ? _b : DEFAULT_IMPORT_SOURCE;
115
- const importStatements = generateImports(usedComponents, importSource, framework);
154
+ const importStatements = generateImports(usedComponents, importSource, framework, options.customComponents);
116
155
  return {
117
156
  code: `${importStatements}
118
157
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/core/registry.ts","../src/core/transform.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\nexport function getComponentRegistry(framework: Framework = 'react'): Record<string, ComponentMeta> {\n return createRegistry(framework)\n}\n\nexport function buildComponentDetectionRegex(framework: Framework = 'react'): RegExp {\n const registry = getComponentRegistry(framework)\n const names = Object.keys(registry)\n return new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n}\n","import type { Options, Framework } from '../types'\nimport { getComponentRegistry, buildComponentDetectionRegex } from './registry'\n\nconst DEFAULT_IMPORT_SOURCE = 'unplugin-docubook/components'\nconst DEFAULT_FRAMEWORK: Framework = 'react'\n\nexport function detectComponents(code: string, framework: Framework = DEFAULT_FRAMEWORK): string[] {\n const regex = buildComponentDetectionRegex(framework)\n const registry = getComponentRegistry(framework)\n const found = new Set<string>()\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(code)) !== 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): string {\n const registry = getComponentRegistry(framework)\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)\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)\n\n return {\n code: `${importStatements}\\n\\n${code}`,\n hasTransformed: true,\n }\n}\n"],"mappings":"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","names":["exports"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/core/registry.ts","../src/core/transform.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"],"mappings":"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","names":["registry","names","exports"]}
package/dist/index.js CHANGED
@@ -1,3 +1,20 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
4
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __spreadValues = (a, b) => {
7
+ for (var prop in b || (b = {}))
8
+ if (__hasOwnProp.call(b, prop))
9
+ __defNormalProp(a, prop, b[prop]);
10
+ if (__getOwnPropSymbols)
11
+ for (var prop of __getOwnPropSymbols(b)) {
12
+ if (__propIsEnum.call(b, prop))
13
+ __defNormalProp(a, prop, b[prop]);
14
+ }
15
+ return a;
16
+ };
17
+
1
18
  // src/index.ts
2
19
  import { createUnplugin } from "unplugin";
3
20
 
@@ -32,24 +49,49 @@ function createRegistry(framework) {
32
49
  DocuBookProvider: { exports: ["DocuBookProvider"], path: basePath }
33
50
  };
34
51
  }
35
- function getComponentRegistry(framework = "react") {
36
- return createRegistry(framework);
52
+ var registryCache = /* @__PURE__ */ new Map();
53
+ var regexCache = /* @__PURE__ */ new Map();
54
+ function getComponentRegistry(framework = "react", customComponents) {
55
+ if (!customComponents || Object.keys(customComponents).length === 0) {
56
+ const cached = registryCache.get(framework);
57
+ if (cached) return cached;
58
+ const registry = createRegistry(framework);
59
+ registryCache.set(framework, registry);
60
+ return registry;
61
+ }
62
+ return __spreadValues(__spreadValues({}, createRegistry(framework)), customComponents);
37
63
  }
38
- function buildComponentDetectionRegex(framework = "react") {
64
+ function buildComponentDetectionRegex(framework = "react", customComponents) {
65
+ if (customComponents && Object.keys(customComponents).length > 0) {
66
+ const registry2 = getComponentRegistry(framework, customComponents);
67
+ const names2 = Object.keys(registry2);
68
+ return new RegExp(`<(${names2.join("|")})(?=[\\s/>])`, "g");
69
+ }
70
+ const cached = regexCache.get(framework);
71
+ if (cached) {
72
+ cached.lastIndex = 0;
73
+ return cached;
74
+ }
39
75
  const registry = getComponentRegistry(framework);
40
76
  const names = Object.keys(registry);
41
- return new RegExp(`<(${names.join("|")})(?=[\\s/>])`, "g");
77
+ const regex = new RegExp(`<(${names.join("|")})(?=[\\s/>])`, "g");
78
+ regexCache.set(framework, regex);
79
+ return regex;
42
80
  }
43
81
 
44
82
  // src/core/transform.ts
45
83
  var DEFAULT_IMPORT_SOURCE = "unplugin-docubook/components";
46
84
  var DEFAULT_FRAMEWORK = "react";
47
- function detectComponents(code, framework = DEFAULT_FRAMEWORK) {
48
- const regex = buildComponentDetectionRegex(framework);
49
- const registry = getComponentRegistry(framework);
85
+ function stripIgnoredZones(code) {
86
+ return code.replace(/```[\s\S]*?```/g, "").replace(/`[^`]+`/g, "").replace(/\{\/\*[\s\S]*?\*\/\}/g, "").replace(/<!--[\s\S]*?-->/g, "").replace(/^import\s.+$/gm, "").replace(/^export\s.+$/gm, "");
87
+ }
88
+ function detectComponents(code, framework = DEFAULT_FRAMEWORK, customComponents) {
89
+ const strippedCode = stripIgnoredZones(code);
90
+ const regex = buildComponentDetectionRegex(framework, customComponents);
91
+ const registry = getComponentRegistry(framework, customComponents);
50
92
  const found = /* @__PURE__ */ new Set();
51
93
  let match;
52
- while ((match = regex.exec(code)) !== null) {
94
+ while ((match = regex.exec(strippedCode)) !== null) {
53
95
  const name = match[1];
54
96
  if (name && registry[name]) {
55
97
  found.add(name);
@@ -57,13 +99,13 @@ function detectComponents(code, framework = DEFAULT_FRAMEWORK) {
57
99
  }
58
100
  return Array.from(found);
59
101
  }
60
- function generateImports(componentNames, importSource, framework = DEFAULT_FRAMEWORK) {
61
- const registry = getComponentRegistry(framework);
102
+ function generateImports(componentNames, importSource, framework = DEFAULT_FRAMEWORK, customComponents) {
103
+ const registry = getComponentRegistry(framework, customComponents);
62
104
  const pathToExports = /* @__PURE__ */ new Map();
63
105
  for (const name of componentNames) {
64
106
  const meta = registry[name];
65
107
  if (!meta) continue;
66
- const fullPath = `${importSource}${meta.path}`;
108
+ const fullPath = meta.path.startsWith("/") ? `${importSource}${meta.path}` : meta.path;
67
109
  if (!pathToExports.has(fullPath)) {
68
110
  pathToExports.set(fullPath, /* @__PURE__ */ new Set());
69
111
  }
@@ -81,12 +123,12 @@ function generateImports(componentNames, importSource, framework = DEFAULT_FRAME
81
123
  function transformMdx(code, options = {}) {
82
124
  var _a, _b;
83
125
  const framework = (_a = options.framework) != null ? _a : DEFAULT_FRAMEWORK;
84
- const usedComponents = detectComponents(code, framework);
126
+ const usedComponents = detectComponents(code, framework, options.customComponents);
85
127
  if (usedComponents.length === 0) {
86
128
  return { code, hasTransformed: false };
87
129
  }
88
130
  const importSource = (_b = options.importSource) != null ? _b : DEFAULT_IMPORT_SOURCE;
89
- const importStatements = generateImports(usedComponents, importSource, framework);
131
+ const importStatements = generateImports(usedComponents, importSource, framework, options.customComponents);
90
132
  return {
91
133
  code: `${importStatements}
92
134
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/core/registry.ts","../src/core/transform.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\nexport function getComponentRegistry(framework: Framework = 'react'): Record<string, ComponentMeta> {\n return createRegistry(framework)\n}\n\nexport function buildComponentDetectionRegex(framework: Framework = 'react'): RegExp {\n const registry = getComponentRegistry(framework)\n const names = Object.keys(registry)\n return new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n}\n","import type { Options, Framework } from '../types'\nimport { getComponentRegistry, buildComponentDetectionRegex } from './registry'\n\nconst DEFAULT_IMPORT_SOURCE = 'unplugin-docubook/components'\nconst DEFAULT_FRAMEWORK: Framework = 'react'\n\nexport function detectComponents(code: string, framework: Framework = DEFAULT_FRAMEWORK): string[] {\n const regex = buildComponentDetectionRegex(framework)\n const registry = getComponentRegistry(framework)\n const found = new Set<string>()\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(code)) !== 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): string {\n const registry = getComponentRegistry(framework)\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)\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)\n\n return {\n code: `${importStatements}\\n\\n${code}`,\n hasTransformed: true,\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/core/registry.ts","../src/core/transform.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"],"mappings":"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","names":["registry","names"]}
package/dist/next.cjs CHANGED
@@ -2,7 +2,21 @@
2
2
  var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __spreadValues = (a, b) => {
10
+ for (var prop in b || (b = {}))
11
+ if (__hasOwnProp.call(b, prop))
12
+ __defNormalProp(a, prop, b[prop]);
13
+ if (__getOwnPropSymbols)
14
+ for (var prop of __getOwnPropSymbols(b)) {
15
+ if (__propIsEnum.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ }
18
+ return a;
19
+ };
6
20
  var __export = (target, all) => {
7
21
  for (var name in all)
8
22
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -59,24 +73,49 @@ function createRegistry(framework) {
59
73
  DocuBookProvider: { exports: ["DocuBookProvider"], path: basePath }
60
74
  };
61
75
  }
62
- function getComponentRegistry(framework = "react") {
63
- return createRegistry(framework);
76
+ var registryCache = /* @__PURE__ */ new Map();
77
+ var regexCache = /* @__PURE__ */ new Map();
78
+ function getComponentRegistry(framework = "react", customComponents) {
79
+ if (!customComponents || Object.keys(customComponents).length === 0) {
80
+ const cached = registryCache.get(framework);
81
+ if (cached) return cached;
82
+ const registry = createRegistry(framework);
83
+ registryCache.set(framework, registry);
84
+ return registry;
85
+ }
86
+ return __spreadValues(__spreadValues({}, createRegistry(framework)), customComponents);
64
87
  }
65
- function buildComponentDetectionRegex(framework = "react") {
88
+ function buildComponentDetectionRegex(framework = "react", customComponents) {
89
+ if (customComponents && Object.keys(customComponents).length > 0) {
90
+ const registry2 = getComponentRegistry(framework, customComponents);
91
+ const names2 = Object.keys(registry2);
92
+ return new RegExp(`<(${names2.join("|")})(?=[\\s/>])`, "g");
93
+ }
94
+ const cached = regexCache.get(framework);
95
+ if (cached) {
96
+ cached.lastIndex = 0;
97
+ return cached;
98
+ }
66
99
  const registry = getComponentRegistry(framework);
67
100
  const names = Object.keys(registry);
68
- return new RegExp(`<(${names.join("|")})(?=[\\s/>])`, "g");
101
+ const regex = new RegExp(`<(${names.join("|")})(?=[\\s/>])`, "g");
102
+ regexCache.set(framework, regex);
103
+ return regex;
69
104
  }
70
105
 
71
106
  // src/core/transform.ts
72
107
  var DEFAULT_IMPORT_SOURCE = "unplugin-docubook/components";
73
108
  var DEFAULT_FRAMEWORK = "react";
74
- function detectComponents(code, framework = DEFAULT_FRAMEWORK) {
75
- const regex = buildComponentDetectionRegex(framework);
76
- const registry = getComponentRegistry(framework);
109
+ function stripIgnoredZones(code) {
110
+ return code.replace(/```[\s\S]*?```/g, "").replace(/`[^`]+`/g, "").replace(/\{\/\*[\s\S]*?\*\/\}/g, "").replace(/<!--[\s\S]*?-->/g, "").replace(/^import\s.+$/gm, "").replace(/^export\s.+$/gm, "");
111
+ }
112
+ function detectComponents(code, framework = DEFAULT_FRAMEWORK, customComponents) {
113
+ const strippedCode = stripIgnoredZones(code);
114
+ const regex = buildComponentDetectionRegex(framework, customComponents);
115
+ const registry = getComponentRegistry(framework, customComponents);
77
116
  const found = /* @__PURE__ */ new Set();
78
117
  let match;
79
- while ((match = regex.exec(code)) !== null) {
118
+ while ((match = regex.exec(strippedCode)) !== null) {
80
119
  const name = match[1];
81
120
  if (name && registry[name]) {
82
121
  found.add(name);
@@ -84,13 +123,13 @@ function detectComponents(code, framework = DEFAULT_FRAMEWORK) {
84
123
  }
85
124
  return Array.from(found);
86
125
  }
87
- function generateImports(componentNames, importSource, framework = DEFAULT_FRAMEWORK) {
88
- const registry = getComponentRegistry(framework);
126
+ function generateImports(componentNames, importSource, framework = DEFAULT_FRAMEWORK, customComponents) {
127
+ const registry = getComponentRegistry(framework, customComponents);
89
128
  const pathToExports = /* @__PURE__ */ new Map();
90
129
  for (const name of componentNames) {
91
130
  const meta = registry[name];
92
131
  if (!meta) continue;
93
- const fullPath = `${importSource}${meta.path}`;
132
+ const fullPath = meta.path.startsWith("/") ? `${importSource}${meta.path}` : meta.path;
94
133
  if (!pathToExports.has(fullPath)) {
95
134
  pathToExports.set(fullPath, /* @__PURE__ */ new Set());
96
135
  }
@@ -108,12 +147,12 @@ function generateImports(componentNames, importSource, framework = DEFAULT_FRAME
108
147
  function transformMdx(code, options = {}) {
109
148
  var _a, _b;
110
149
  const framework = (_a = options.framework) != null ? _a : DEFAULT_FRAMEWORK;
111
- const usedComponents = detectComponents(code, framework);
150
+ const usedComponents = detectComponents(code, framework, options.customComponents);
112
151
  if (usedComponents.length === 0) {
113
152
  return { code, hasTransformed: false };
114
153
  }
115
154
  const importSource = (_b = options.importSource) != null ? _b : DEFAULT_IMPORT_SOURCE;
116
- const importStatements = generateImports(usedComponents, importSource, framework);
155
+ const importStatements = generateImports(usedComponents, importSource, framework, options.customComponents);
117
156
  return {
118
157
  code: `${importStatements}
119
158
 
package/dist/next.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/next.ts","../src/index.ts","../src/core/registry.ts","../src/core/transform.ts"],"sourcesContent":["import { createWebpackPlugin } from 'unplugin'\nimport { unpluginFactory } from '.'\n\nexport default createWebpackPlugin(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\nexport function getComponentRegistry(framework: Framework = 'react'): Record<string, ComponentMeta> {\n return createRegistry(framework)\n}\n\nexport function buildComponentDetectionRegex(framework: Framework = 'react'): RegExp {\n const registry = getComponentRegistry(framework)\n const names = Object.keys(registry)\n return new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n}\n","import type { Options, Framework } from '../types'\nimport { getComponentRegistry, buildComponentDetectionRegex } from './registry'\n\nconst DEFAULT_IMPORT_SOURCE = 'unplugin-docubook/components'\nconst DEFAULT_FRAMEWORK: Framework = 'react'\n\nexport function detectComponents(code: string, framework: Framework = DEFAULT_FRAMEWORK): string[] {\n const regex = buildComponentDetectionRegex(framework)\n const registry = getComponentRegistry(framework)\n const found = new Set<string>()\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(code)) !== 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): string {\n const registry = getComponentRegistry(framework)\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)\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)\n\n return {\n code: `${importStatements}\\n\\n${code}`,\n hasTransformed: true,\n }\n}\n"],"mappings":"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","names":["import_unplugin","exports"]}
1
+ {"version":3,"sources":["../src/next.ts","../src/index.ts","../src/core/registry.ts","../src/core/transform.ts"],"sourcesContent":["import { createWebpackPlugin } from 'unplugin'\nimport { unpluginFactory } from '.'\n\nexport default createWebpackPlugin(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"]}