@anfo/nuxt-dialogs-plugin 1.0.0 → 1.0.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/dist/module.cjs +25 -3
- package/dist/module.cjs.map +1 -1
- package/dist/module.js +25 -3
- package/dist/module.js.map +1 -1
- package/package.json +1 -1
package/dist/module.cjs
CHANGED
|
@@ -63,11 +63,21 @@ function generateModuleCode(files, options) {
|
|
|
63
63
|
`;
|
|
64
64
|
const contextInherit = inheritNuxtApp ? ` const nuxtVueApp = getDialogsNuxtVueApp();
|
|
65
65
|
if (nuxtVueApp) {
|
|
66
|
+
const mergeConfig = (baseConfig, mainConfig) => {
|
|
67
|
+
const out = {};
|
|
68
|
+
for (const source of [baseConfig, mainConfig]) {
|
|
69
|
+
for (const key of Reflect.ownKeys(source)) {
|
|
70
|
+
const desc = Object.getOwnPropertyDescriptor(source, key);
|
|
71
|
+
if (desc && "value" in desc) Object.defineProperty(out, key, desc);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return out;
|
|
75
|
+
};
|
|
66
76
|
const base = app._context;
|
|
67
77
|
const main = nuxtVueApp._context;
|
|
68
78
|
app._context = {
|
|
69
79
|
...base,
|
|
70
|
-
config:
|
|
80
|
+
config: mergeConfig(base.config, main.config),
|
|
71
81
|
components: { ...base.components, ...main.components },
|
|
72
82
|
directives: { ...base.directives, ...main.directives },
|
|
73
83
|
provides: { ...base.provides, ...main.provides },
|
|
@@ -159,7 +169,19 @@ function generateDialogsDts(options) {
|
|
|
159
169
|
const comp = `typeof import(${JSON.stringify(rel)})["default"]`;
|
|
160
170
|
lines.push(` ${name}: (...args: _A<${comp}>) => _H<${comp}>;`);
|
|
161
171
|
}
|
|
162
|
-
lines.push(" };", "}"
|
|
172
|
+
lines.push(" };", "}");
|
|
173
|
+
lines.push(
|
|
174
|
+
"",
|
|
175
|
+
// Mirror the virtual module's `dialogs` export as a real named export so
|
|
176
|
+
// this file can serve as the `typeFrom` target of the Nuxt auto-import
|
|
177
|
+
// (see module.ts): Nuxt's static type-path resolution cannot resolve
|
|
178
|
+
// virtual ids (NUXT_B6005 warning), but it can resolve this on-disk
|
|
179
|
+
// declaration file. Adding a top-level export keeps the ambient module
|
|
180
|
+
// declaration above globally visible (ambient declarations are
|
|
181
|
+
// unaffected by the file becoming a module).
|
|
182
|
+
'export const dialogs: typeof import("virtual:dialogs").dialogs',
|
|
183
|
+
""
|
|
184
|
+
);
|
|
163
185
|
return lines.join("\n");
|
|
164
186
|
}
|
|
165
187
|
function createDialogsVitePlugin(options) {
|
|
@@ -263,7 +285,7 @@ export default (nuxtApp) => { provideDialogsNuxtApp(nuxtApp.vueApp); };
|
|
|
263
285
|
});
|
|
264
286
|
}
|
|
265
287
|
(0, import_kit.addImports)([
|
|
266
|
-
{ name: "dialogs", from: "virtual:dialogs" },
|
|
288
|
+
{ name: "dialogs", from: "virtual:dialogs", typeFrom: dtsPath },
|
|
267
289
|
{ name: "useDialogContext", from: RUNTIME_PKG },
|
|
268
290
|
{ name: "createDialogExpose", from: RUNTIME_PKG },
|
|
269
291
|
{ name: "configureDialogs", from: RUNTIME_PKG }
|
package/dist/module.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/module.ts","../src/vite-plugin.ts"],"sourcesContent":["import {\n addImports,\n addPluginTemplate,\n addTypeTemplate,\n defineNuxtModule,\n} from \"@nuxt/kit\";\nimport type { Nuxt } from \"@nuxt/schema\";\nimport { dirname, resolve } from \"node:path\";\nimport {\n createDialogsVitePlugin,\n generateDialogsDts,\n scanDialogFiles,\n} from \"./vite-plugin\";\n\nexport interface ModuleOptions {\n /**\n * Directory that contains dialog components.\n * Relative paths are resolved against `srcDir`. Defaults to `dialogs`.\n */\n dir?: string;\n /**\n * RegExp used to identify dialog component files.\n * Defaults to files whose name ends with `Dialog.vue` or `Drawer.vue`.\n */\n pattern?: RegExp;\n /**\n * When true (default), every dialog app inherits the Nuxt app's context:\n * global components, directives and provides — Pinia, i18n, UI libraries,\n * the `nuxtApp` itself — are all available inside dialogs with no wiring.\n */\n inheritNuxtApp?: boolean;\n}\n\nconst RUNTIME_PKG = \"@anfo/nuxt-dialogs-plugin/runtime\";\nconst IMPORT_ALIAS = \"#dialogs-components\";\nconst TYPE_TEMPLATE = \"types/dialogs.d.ts\";\n\nexport default defineNuxtModule<ModuleOptions>({\n meta: {\n name: \"@anfo/nuxt-dialogs-plugin\",\n configKey: \"dialogs\",\n version: \"1.0.0\",\n compatibility: { nuxt: \">=3.5.0\" },\n },\n defaults: {\n dir: \"dialogs\",\n pattern: /(Dialog|Drawer)\\.vue$/,\n inheritNuxtApp: true,\n },\n setup(options, nuxt: Nuxt) {\n const dialogsDir = resolve(nuxt.options.srcDir, options.dir ?? \"dialogs\");\n const pattern = options.pattern ?? /(Dialog|Drawer)\\.vue$/;\n const dtsPath = resolve(nuxt.options.buildDir, TYPE_TEMPLATE);\n\n if (String(nuxt.options.builder ?? \"\").includes(\"webpack\")) {\n console.warn(\n \"[@anfo/nuxt-dialogs-plugin] only the Vite builder is supported; `virtual:dialogs` will not resolve in webpack builds.\",\n );\n }\n\n // Let the generated virtual module import components through a stable\n // alias, so the dialogs directory can live anywhere.\n nuxt.options.alias[IMPORT_ALIAS] = dialogsDir;\n\n // Register the dialogs virtual module in every Vite build (client and\n // server bundles both need to resolve `virtual:dialogs` imports).\n const vitePlugin = createDialogsVitePlugin({\n dir: dialogsDir,\n pattern,\n importAlias: IMPORT_ALIAS,\n runtimePkg: RUNTIME_PKG,\n dtsPath,\n inheritNuxtApp: options.inheritNuxtApp ?? true,\n });\n nuxt.hook(\"vite:extendConfig\", (config) => {\n (config as { plugins: unknown[] }).plugins ??= [];\n (config.plugins as unknown[]).push(vitePlugin);\n });\n\n // Capture the Nuxt app so generated dialog mounts can inherit its\n // context (global components, directives, provides).\n if (options.inheritNuxtApp) {\n addPluginTemplate({\n filename: \"dialogs-context-plugin.mjs\",\n getContents: () =>\n `import { provideDialogsNuxtApp } from ${JSON.stringify(RUNTIME_PKG)};\\n` +\n `export default (nuxtApp) => { provideDialogsNuxtApp(nuxtApp.vueApp); };\\n`,\n });\n }\n\n // Auto-imports — explicit imports from the runtime keep working too.\n addImports([\n { name: \"dialogs\", from: \"virtual:dialogs\" },\n { name: \"useDialogContext\", from: RUNTIME_PKG },\n { name: \"createDialogExpose\", from: RUNTIME_PKG },\n { name: \"configureDialogs\", from: RUNTIME_PKG },\n ]);\n\n // Type declarations for `virtual:dialogs`, included in the generated\n // tsconfig automatically — no user tsconfig changes required. The Vite\n // plugin rewrites this same file when dialog files are added/removed.\n const files = scanDialogFiles(dialogsDir, pattern);\n addTypeTemplate({\n filename: TYPE_TEMPLATE,\n getContents: () =>\n generateDialogsDts({\n files,\n dtsDir: dirname(dtsPath),\n dialogsDir,\n runtimePkg: RUNTIME_PKG,\n }),\n });\n },\n});\n","import type { Plugin, ViteDevServer } from \"vite\";\nimport { mkdirSync, readdirSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, relative, resolve } from \"node:path\";\n\nexport interface DialogsVitePluginOptions {\n /** Absolute path to the directory that contains dialog components. */\n dir: string;\n /** RegExp used to identify dialog component files. */\n pattern: RegExp;\n /**\n * Alias registered on the Nuxt app (e.g. `#dialogs-components`) that maps\n * to `dir`. The virtual module imports components through it so the\n * generated code never depends on where the directory lives.\n */\n importAlias: string;\n /** Runtime package specifier, e.g. `@anfo/nuxt-dialogs-plugin/runtime`. */\n runtimePkg: string;\n /** Absolute path of the generated declaration file. */\n dtsPath: string;\n /**\n * When true, generated dialog apps inherit the Nuxt app's context\n * (global components, directives, provides — Pinia, i18n, UI libs…).\n */\n inheritNuxtApp: boolean;\n}\n\nconst VIRTUAL_ID = \"virtual:dialogs\";\nconst RESOLVED_VIRTUAL_ID = \"\\0virtual:dialogs\";\n\n// ── Scanning ──────────────────────────────────────────────────────────────────\n\nexport function scanDialogFiles(dir: string, pattern: RegExp): string[] {\n try {\n return readdirSync(dir)\n .filter((f: string) => pattern.test(f))\n .sort()\n .map((f: string) => resolve(dir, f));\n } catch {\n return [];\n }\n}\n\nfunction componentName(filePath: string): string {\n return basename(filePath, \".vue\");\n}\n\n// ── Virtual module code generation ────────────────────────────────────────────\n\nfunction generateModuleCode(\n files: string[],\n options: DialogsVitePluginOptions,\n): string {\n const { dir, importAlias, runtimePkg, inheritNuxtApp } = options;\n\n const runtimeImports = inheritNuxtApp\n ? \"applyDialogAppPlugins, dialogControllerKey, getDialogsNuxtVueApp\"\n : \"applyDialogAppPlugins, dialogControllerKey\";\n\n const lines: string[] = [\n `import { createApp } from \"vue\";`,\n `import { ${runtimeImports} } from ${JSON.stringify(runtimePkg)};`,\n ];\n for (let i = 0; i < files.length; i++) {\n lines.push(\n `import _D${i} from ${JSON.stringify(`${importAlias}/${basename(files[i])}`)};`,\n );\n }\n\n // Dialogs are DOM-only; calling one during SSR resolves as a rejection\n // instead of crashing the server render.\n const ssrGuard = ` if (typeof document === \"undefined\") {\n console.warn(\"[nuxt-dialogs] dialogs can only be opened in the browser; ignoring a dialog opened during SSR.\");\n return Object.assign(Promise.resolve({ type: \"reject\", reason: new Error(\"Dialogs are client-only (opened during SSR).\") }), {\n resolve() { return this; },\n reject() { return this; },\n });\n }\n`;\n\n // Shallow-clone the Nuxt app's context onto the dialog app. Every bucket\n // must be copied (not shared by reference) so the `provide()` below — and\n // any plugin install — cannot leak into the main Nuxt app.\n const contextInherit = inheritNuxtApp\n ? ` const nuxtVueApp = getDialogsNuxtVueApp();\n if (nuxtVueApp) {\n const base = app._context;\n const main = nuxtVueApp._context;\n app._context = {\n ...base,\n config: { ...base.config, ...main.config },\n components: { ...base.components, ...main.components },\n directives: { ...base.directives, ...main.directives },\n provides: { ...base.provides, ...main.provides },\n };\n }\n`\n : \"\";\n\n lines.push(`\nfunction mountDialog(component, props) {\n${ssrGuard} const result = new Promise((resolve) => {\n const host = document.createElement(\"div\");\n document.body.appendChild(host);\n let settled = false;\n function cleanup() { app.unmount(); host.remove(); }\n function finish(cb) {\n if (settled) return;\n settled = true;\n cb();\n cleanup();\n }\n function handleResolve(...args) {\n finish(() => {\n if (args.length === 0) { resolve({ type: \"resolve\" }); return; }\n resolve({ type: \"resolve\", value: args[0] });\n });\n }\n const controller = {\n resolve: handleResolve,\n reject: (reason) => { finish(() => resolve({ type: \"reject\", reason })); },\n };\n const app = createApp(component, props);\n${contextInherit} app.provide(dialogControllerKey, controller);\n applyDialogAppPlugins(app);\n app.mount(host);\n });\n return Object.assign(result, {\n resolve(callback) {\n result.then((value) => {\n if (value.type === \"resolve\") callback?.(value.value);\n });\n return this;\n },\n reject(callback) {\n result.then((value) => {\n if (value.type === \"reject\") callback(value.reason);\n });\n return this;\n },\n });\n}`);\n\n lines.push(\"\");\n lines.push(\"export const dialogs = {\");\n for (let i = 0; i < files.length; i++) {\n lines.push(\n `\\t${componentName(files[i])}: (props) => mountDialog(_D${i}, props),`,\n );\n }\n lines.push(\"};\");\n return lines.join(\"\\n\");\n}\n\n// ── Declaration file generation ───────────────────────────────────────────────\n\nexport function generateDialogsDts(options: {\n files: string[];\n /** Absolute path of the directory the .d.ts is written to. */\n dtsDir: string;\n /** Directory containing the dialog components (absolute). */\n dialogsDir: string;\n /** Runtime package specifier for type imports. */\n runtimePkg: string;\n}): string {\n const { files, dtsDir, dialogsDir, runtimePkg } = options;\n\n const lines: string[] = [\n \"// Auto-generated by @anfo/nuxt-dialogs-plugin — do not edit manually.\",\n \"\",\n `declare module \"${VIRTUAL_ID}\" {`,\n `\\ttype _C = import(\"vue\").Component;`,\n `\\ttype _CE<T extends _C> = import(\"vue-component-type-helpers\").ComponentExposed<T>;`,\n `\\ttype _CP<T extends _C> = import(\"vue-component-type-helpers\").ComponentProps<T>;`,\n `\\ttype _DE<T> = import(${JSON.stringify(runtimePkg)}).DialogExposed<T>;`,\n `\\ttype _DS<T> = import(${JSON.stringify(runtimePkg)}).DialogSettledResult<T>;`,\n `\\ttype _DR = import(${JSON.stringify(runtimePkg)}).DialogRejectedResult;`,\n `\\ttype _IK = \"key\" | \"ref\" | \"ref_for\" | \"ref_key\" | \"class\" | \"style\" | \\`on\\${string}\\`;`,\n `\\ttype _P<T extends _C> = Omit<_CP<T>, _IK>;`,\n `\\ttype _RK<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? never : K }[keyof T];`,\n `\\ttype _A<T extends _C> = [_RK<_P<T>>] extends [never] ? [props?: _P<T>] : [props: _P<T>];`,\n `\\ttype _V<T extends _C> = _CE<T> extends _DE<infer R> ? R : void;`,\n `\\ttype _R<T extends _C> = _DS<_V<T>>;`,\n `\\ttype _RN = _DR[\"reason\"];`,\n `\\ttype _H<T extends _C> = Promise<_R<T>> & {`,\n `\\t\\tresolve(callback?: (value: _V<T> | undefined) => void): _H<T>;`,\n `\\t\\treject(callback: (reason: _RN) => void): _H<T>;`,\n `\\t};`,\n `\\texport const dialogs: {`,\n ];\n\n for (const filePath of files) {\n const name = componentName(filePath);\n let rel = relative(dtsDir, filePath).replace(/\\\\/g, \"/\");\n if (!rel.startsWith(\".\")) rel = `./${rel}`;\n const comp = `typeof import(${JSON.stringify(rel)})[\"default\"]`;\n lines.push(`\\t\\t${name}: (...args: _A<${comp}>) => _H<${comp}>;`);\n }\n\n lines.push(\"\\t};\", \"}\", \"\");\n return lines.join(\"\\n\");\n}\n\n// ── Plugin ────────────────────────────────────────────────────────────────────\n\nexport function createDialogsVitePlugin(\n options: DialogsVitePluginOptions,\n): Plugin {\n const { dir, pattern, dtsPath } = options;\n\n function writeDts(): void {\n const dtsDir = dirname(dtsPath);\n mkdirSync(dtsDir, { recursive: true });\n writeFileSync(\n dtsPath,\n generateDialogsDts({\n files: scanDialogFiles(dir, pattern),\n dtsDir,\n dialogsDir: dir,\n runtimePkg: options.runtimePkg,\n }),\n \"utf-8\",\n );\n }\n\n function invalidate(server: ViteDevServer): void {\n const mod = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_ID);\n if (mod) server.moduleGraph.invalidateModule(mod);\n writeDts();\n server.hot.send({ type: \"full-reload\" });\n }\n\n return {\n name: \"nuxt-dialogs-plugin\",\n\n buildStart() {\n writeDts();\n },\n\n resolveId(id) {\n if (id === VIRTUAL_ID) return RESOLVED_VIRTUAL_ID;\n },\n\n load(id) {\n if (id !== RESOLVED_VIRTUAL_ID) return;\n const files = scanDialogFiles(dir, pattern);\n return {\n code: generateModuleCode(files, options),\n moduleType: \"js\",\n };\n },\n\n configureServer(server) {\n server.watcher.add(dir);\n\n server.watcher.on(\"add\", (file) => {\n if (pattern.test(file) && file.startsWith(dir)) {\n invalidate(server);\n }\n });\n\n server.watcher.on(\"unlink\", (file) => {\n if (pattern.test(file) && file.startsWith(dir)) {\n invalidate(server);\n }\n });\n },\n };\n}\n"],"mappings":"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","names":["import_node_path"]}
|
|
1
|
+
{"version":3,"sources":["../src/module.ts","../src/vite-plugin.ts"],"sourcesContent":["import {\n addImports,\n addPluginTemplate,\n addTypeTemplate,\n defineNuxtModule,\n} from \"@nuxt/kit\";\nimport type { Nuxt } from \"@nuxt/schema\";\nimport { dirname, resolve } from \"node:path\";\nimport {\n createDialogsVitePlugin,\n generateDialogsDts,\n scanDialogFiles,\n} from \"./vite-plugin\";\n\nexport interface ModuleOptions {\n /**\n * Directory that contains dialog components.\n * Relative paths are resolved against `srcDir`. Defaults to `dialogs`.\n */\n dir?: string;\n /**\n * RegExp used to identify dialog component files.\n * Defaults to files whose name ends with `Dialog.vue` or `Drawer.vue`.\n */\n pattern?: RegExp;\n /**\n * When true (default), every dialog app inherits the Nuxt app's context:\n * global components, directives and provides — Pinia, i18n, UI libraries,\n * the `nuxtApp` itself — are all available inside dialogs with no wiring.\n */\n inheritNuxtApp?: boolean;\n}\n\nconst RUNTIME_PKG = \"@anfo/nuxt-dialogs-plugin/runtime\";\nconst IMPORT_ALIAS = \"#dialogs-components\";\nconst TYPE_TEMPLATE = \"types/dialogs.d.ts\";\n\nexport default defineNuxtModule<ModuleOptions>({\n meta: {\n name: \"@anfo/nuxt-dialogs-plugin\",\n configKey: \"dialogs\",\n version: \"1.0.0\",\n compatibility: { nuxt: \">=3.5.0\" },\n },\n defaults: {\n dir: \"dialogs\",\n pattern: /(Dialog|Drawer)\\.vue$/,\n inheritNuxtApp: true,\n },\n setup(options, nuxt: Nuxt) {\n const dialogsDir = resolve(nuxt.options.srcDir, options.dir ?? \"dialogs\");\n const pattern = options.pattern ?? /(Dialog|Drawer)\\.vue$/;\n const dtsPath = resolve(nuxt.options.buildDir, TYPE_TEMPLATE);\n\n if (String(nuxt.options.builder ?? \"\").includes(\"webpack\")) {\n console.warn(\n \"[@anfo/nuxt-dialogs-plugin] only the Vite builder is supported; `virtual:dialogs` will not resolve in webpack builds.\",\n );\n }\n\n // Let the generated virtual module import components through a stable\n // alias, so the dialogs directory can live anywhere.\n nuxt.options.alias[IMPORT_ALIAS] = dialogsDir;\n\n // Register the dialogs virtual module in every Vite build (client and\n // server bundles both need to resolve `virtual:dialogs` imports).\n const vitePlugin = createDialogsVitePlugin({\n dir: dialogsDir,\n pattern,\n importAlias: IMPORT_ALIAS,\n runtimePkg: RUNTIME_PKG,\n dtsPath,\n inheritNuxtApp: options.inheritNuxtApp ?? true,\n });\n nuxt.hook(\"vite:extendConfig\", (config) => {\n (config as { plugins: unknown[] }).plugins ??= [];\n (config.plugins as unknown[]).push(vitePlugin);\n });\n\n // Capture the Nuxt app so generated dialog mounts can inherit its\n // context (global components, directives, provides).\n if (options.inheritNuxtApp) {\n addPluginTemplate({\n filename: \"dialogs-context-plugin.mjs\",\n getContents: () =>\n `import { provideDialogsNuxtApp } from ${JSON.stringify(RUNTIME_PKG)};\\n` +\n `export default (nuxtApp) => { provideDialogsNuxtApp(nuxtApp.vueApp); };\\n`,\n });\n }\n\n // Auto-imports — explicit imports from the runtime keep working too.\n // The `dialogs` entry declares `typeFrom` pointing at the generated\n // declaration file (inside buildDir): Nuxt's static type-path\n // resolution cannot resolve the `virtual:dialogs` id and would emit a\n // NUXT_B6005 warning (\"unresolvable module\") on every start. Runtime\n // injection still comes from `virtual:dialogs` — unimport uses `from`\n // for the actual import and `typeFrom` for type declarations, and the\n // declaration file mirrors the virtual module's `dialogs` export (see\n // generateDialogsDts).\n addImports([\n { name: \"dialogs\", from: \"virtual:dialogs\", typeFrom: dtsPath },\n { name: \"useDialogContext\", from: RUNTIME_PKG },\n { name: \"createDialogExpose\", from: RUNTIME_PKG },\n { name: \"configureDialogs\", from: RUNTIME_PKG },\n ]);\n\n // Type declarations for `virtual:dialogs`, included in the generated\n // tsconfig automatically — no user tsconfig changes required. The Vite\n // plugin rewrites this same file when dialog files are added/removed.\n const files = scanDialogFiles(dialogsDir, pattern);\n addTypeTemplate({\n filename: TYPE_TEMPLATE,\n getContents: () =>\n generateDialogsDts({\n files,\n dtsDir: dirname(dtsPath),\n dialogsDir,\n runtimePkg: RUNTIME_PKG,\n }),\n });\n },\n});\n","import type { Plugin, ViteDevServer } from \"vite\";\nimport { mkdirSync, readdirSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, relative, resolve } from \"node:path\";\n\nexport interface DialogsVitePluginOptions {\n /** Absolute path to the directory that contains dialog components. */\n dir: string;\n /** RegExp used to identify dialog component files. */\n pattern: RegExp;\n /**\n * Alias registered on the Nuxt app (e.g. `#dialogs-components`) that maps\n * to `dir`. The virtual module imports components through it so the\n * generated code never depends on where the directory lives.\n */\n importAlias: string;\n /** Runtime package specifier, e.g. `@anfo/nuxt-dialogs-plugin/runtime`. */\n runtimePkg: string;\n /** Absolute path of the generated declaration file. */\n dtsPath: string;\n /**\n * When true, generated dialog apps inherit the Nuxt app's context\n * (global components, directives, provides — Pinia, i18n, UI libs…).\n */\n inheritNuxtApp: boolean;\n}\n\nconst VIRTUAL_ID = \"virtual:dialogs\";\nconst RESOLVED_VIRTUAL_ID = \"\\0virtual:dialogs\";\n\n// ── Scanning ──────────────────────────────────────────────────────────────────\n\nexport function scanDialogFiles(dir: string, pattern: RegExp): string[] {\n try {\n return readdirSync(dir)\n .filter((f: string) => pattern.test(f))\n .sort()\n .map((f: string) => resolve(dir, f));\n } catch {\n return [];\n }\n}\n\nfunction componentName(filePath: string): string {\n return basename(filePath, \".vue\");\n}\n\n// ── Virtual module code generation ────────────────────────────────────────────\n\nfunction generateModuleCode(\n files: string[],\n options: DialogsVitePluginOptions,\n): string {\n const { dir, importAlias, runtimePkg, inheritNuxtApp } = options;\n\n const runtimeImports = inheritNuxtApp\n ? \"applyDialogAppPlugins, dialogControllerKey, getDialogsNuxtVueApp\"\n : \"applyDialogAppPlugins, dialogControllerKey\";\n\n const lines: string[] = [\n `import { createApp } from \"vue\";`,\n `import { ${runtimeImports} } from ${JSON.stringify(runtimePkg)};`,\n ];\n for (let i = 0; i < files.length; i++) {\n lines.push(\n `import _D${i} from ${JSON.stringify(`${importAlias}/${basename(files[i])}`)};`,\n );\n }\n\n // Dialogs are DOM-only; calling one during SSR resolves as a rejection\n // instead of crashing the server render.\n const ssrGuard = ` if (typeof document === \"undefined\") {\n console.warn(\"[nuxt-dialogs] dialogs can only be opened in the browser; ignoring a dialog opened during SSR.\");\n return Object.assign(Promise.resolve({ type: \"reject\", reason: new Error(\"Dialogs are client-only (opened during SSR).\") }), {\n resolve() { return this; },\n reject() { return this; },\n });\n }\n`;\n\n // Shallow-clone the Nuxt app's context onto the dialog app. Every bucket\n // must be copied (not shared by reference) so the `provide()` below — and\n // any plugin install — cannot leak into the main Nuxt app.\n //\n // `config` must NOT be merged with object spread: spread reads every\n // source accessor, and dev builds of Vue define `app.config.compilerOptions`\n // as a warn-on-access getter (runtime-only builds), so opening a dialog\n // would spam two Vue warnings per open. Merge data properties by\n // descriptor instead — accessors are skipped on purpose.\n const contextInherit = inheritNuxtApp\n ? ` const nuxtVueApp = getDialogsNuxtVueApp();\n if (nuxtVueApp) {\n const mergeConfig = (baseConfig, mainConfig) => {\n const out = {};\n for (const source of [baseConfig, mainConfig]) {\n for (const key of Reflect.ownKeys(source)) {\n const desc = Object.getOwnPropertyDescriptor(source, key);\n if (desc && \"value\" in desc) Object.defineProperty(out, key, desc);\n }\n }\n return out;\n };\n const base = app._context;\n const main = nuxtVueApp._context;\n app._context = {\n ...base,\n config: mergeConfig(base.config, main.config),\n components: { ...base.components, ...main.components },\n directives: { ...base.directives, ...main.directives },\n provides: { ...base.provides, ...main.provides },\n };\n }\n`\n : \"\";\n\n lines.push(`\nfunction mountDialog(component, props) {\n${ssrGuard} const result = new Promise((resolve) => {\n const host = document.createElement(\"div\");\n document.body.appendChild(host);\n let settled = false;\n function cleanup() { app.unmount(); host.remove(); }\n function finish(cb) {\n if (settled) return;\n settled = true;\n cb();\n cleanup();\n }\n function handleResolve(...args) {\n finish(() => {\n if (args.length === 0) { resolve({ type: \"resolve\" }); return; }\n resolve({ type: \"resolve\", value: args[0] });\n });\n }\n const controller = {\n resolve: handleResolve,\n reject: (reason) => { finish(() => resolve({ type: \"reject\", reason })); },\n };\n const app = createApp(component, props);\n${contextInherit} app.provide(dialogControllerKey, controller);\n applyDialogAppPlugins(app);\n app.mount(host);\n });\n return Object.assign(result, {\n resolve(callback) {\n result.then((value) => {\n if (value.type === \"resolve\") callback?.(value.value);\n });\n return this;\n },\n reject(callback) {\n result.then((value) => {\n if (value.type === \"reject\") callback(value.reason);\n });\n return this;\n },\n });\n}`);\n\n lines.push(\"\");\n lines.push(\"export const dialogs = {\");\n for (let i = 0; i < files.length; i++) {\n lines.push(\n `\\t${componentName(files[i])}: (props) => mountDialog(_D${i}, props),`,\n );\n }\n lines.push(\"};\");\n return lines.join(\"\\n\");\n}\n\n// ── Declaration file generation ───────────────────────────────────────────────\n\nexport function generateDialogsDts(options: {\n files: string[];\n /** Absolute path of the directory the .d.ts is written to. */\n dtsDir: string;\n /** Directory containing the dialog components (absolute). */\n dialogsDir: string;\n /** Runtime package specifier for type imports. */\n runtimePkg: string;\n}): string {\n const { files, dtsDir, dialogsDir, runtimePkg } = options;\n\n const lines: string[] = [\n \"// Auto-generated by @anfo/nuxt-dialogs-plugin — do not edit manually.\",\n \"\",\n `declare module \"${VIRTUAL_ID}\" {`,\n `\\ttype _C = import(\"vue\").Component;`,\n `\\ttype _CE<T extends _C> = import(\"vue-component-type-helpers\").ComponentExposed<T>;`,\n `\\ttype _CP<T extends _C> = import(\"vue-component-type-helpers\").ComponentProps<T>;`,\n `\\ttype _DE<T> = import(${JSON.stringify(runtimePkg)}).DialogExposed<T>;`,\n `\\ttype _DS<T> = import(${JSON.stringify(runtimePkg)}).DialogSettledResult<T>;`,\n `\\ttype _DR = import(${JSON.stringify(runtimePkg)}).DialogRejectedResult;`,\n `\\ttype _IK = \"key\" | \"ref\" | \"ref_for\" | \"ref_key\" | \"class\" | \"style\" | \\`on\\${string}\\`;`,\n `\\ttype _P<T extends _C> = Omit<_CP<T>, _IK>;`,\n `\\ttype _RK<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? never : K }[keyof T];`,\n `\\ttype _A<T extends _C> = [_RK<_P<T>>] extends [never] ? [props?: _P<T>] : [props: _P<T>];`,\n `\\ttype _V<T extends _C> = _CE<T> extends _DE<infer R> ? R : void;`,\n `\\ttype _R<T extends _C> = _DS<_V<T>>;`,\n `\\ttype _RN = _DR[\"reason\"];`,\n `\\ttype _H<T extends _C> = Promise<_R<T>> & {`,\n `\\t\\tresolve(callback?: (value: _V<T> | undefined) => void): _H<T>;`,\n `\\t\\treject(callback: (reason: _RN) => void): _H<T>;`,\n `\\t};`,\n `\\texport const dialogs: {`,\n ];\n\n for (const filePath of files) {\n const name = componentName(filePath);\n let rel = relative(dtsDir, filePath).replace(/\\\\/g, \"/\");\n if (!rel.startsWith(\".\")) rel = `./${rel}`;\n const comp = `typeof import(${JSON.stringify(rel)})[\"default\"]`;\n lines.push(`\\t\\t${name}: (...args: _A<${comp}>) => _H<${comp}>;`);\n }\n\n lines.push(\"\\t};\", \"}\");\n lines.push(\n \"\",\n // Mirror the virtual module's `dialogs` export as a real named export so\n // this file can serve as the `typeFrom` target of the Nuxt auto-import\n // (see module.ts): Nuxt's static type-path resolution cannot resolve\n // virtual ids (NUXT_B6005 warning), but it can resolve this on-disk\n // declaration file. Adding a top-level export keeps the ambient module\n // declaration above globally visible (ambient declarations are\n // unaffected by the file becoming a module).\n \"export const dialogs: typeof import(\\\"virtual:dialogs\\\").dialogs\",\n \"\",\n );\n return lines.join(\"\\n\");\n}\n\n// ── Plugin ────────────────────────────────────────────────────────────────────\n\nexport function createDialogsVitePlugin(\n options: DialogsVitePluginOptions,\n): Plugin {\n const { dir, pattern, dtsPath } = options;\n\n function writeDts(): void {\n const dtsDir = dirname(dtsPath);\n mkdirSync(dtsDir, { recursive: true });\n writeFileSync(\n dtsPath,\n generateDialogsDts({\n files: scanDialogFiles(dir, pattern),\n dtsDir,\n dialogsDir: dir,\n runtimePkg: options.runtimePkg,\n }),\n \"utf-8\",\n );\n }\n\n function invalidate(server: ViteDevServer): void {\n const mod = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_ID);\n if (mod) server.moduleGraph.invalidateModule(mod);\n writeDts();\n server.hot.send({ type: \"full-reload\" });\n }\n\n return {\n name: \"nuxt-dialogs-plugin\",\n\n buildStart() {\n writeDts();\n },\n\n resolveId(id) {\n if (id === VIRTUAL_ID) return RESOLVED_VIRTUAL_ID;\n },\n\n load(id) {\n if (id !== RESOLVED_VIRTUAL_ID) return;\n const files = scanDialogFiles(dir, pattern);\n return {\n code: generateModuleCode(files, options),\n moduleType: \"js\",\n };\n },\n\n configureServer(server) {\n server.watcher.add(dir);\n\n server.watcher.on(\"add\", (file) => {\n if (pattern.test(file) && file.startsWith(dir)) {\n invalidate(server);\n }\n });\n\n server.watcher.on(\"unlink\", (file) => {\n if (pattern.test(file) && file.startsWith(dir)) {\n invalidate(server);\n }\n });\n },\n };\n}\n"],"mappings":"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","names":["import_node_path"]}
|
package/dist/module.js
CHANGED
|
@@ -44,11 +44,21 @@ function generateModuleCode(files, options) {
|
|
|
44
44
|
`;
|
|
45
45
|
const contextInherit = inheritNuxtApp ? ` const nuxtVueApp = getDialogsNuxtVueApp();
|
|
46
46
|
if (nuxtVueApp) {
|
|
47
|
+
const mergeConfig = (baseConfig, mainConfig) => {
|
|
48
|
+
const out = {};
|
|
49
|
+
for (const source of [baseConfig, mainConfig]) {
|
|
50
|
+
for (const key of Reflect.ownKeys(source)) {
|
|
51
|
+
const desc = Object.getOwnPropertyDescriptor(source, key);
|
|
52
|
+
if (desc && "value" in desc) Object.defineProperty(out, key, desc);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
56
|
+
};
|
|
47
57
|
const base = app._context;
|
|
48
58
|
const main = nuxtVueApp._context;
|
|
49
59
|
app._context = {
|
|
50
60
|
...base,
|
|
51
|
-
config:
|
|
61
|
+
config: mergeConfig(base.config, main.config),
|
|
52
62
|
components: { ...base.components, ...main.components },
|
|
53
63
|
directives: { ...base.directives, ...main.directives },
|
|
54
64
|
provides: { ...base.provides, ...main.provides },
|
|
@@ -140,7 +150,19 @@ function generateDialogsDts(options) {
|
|
|
140
150
|
const comp = `typeof import(${JSON.stringify(rel)})["default"]`;
|
|
141
151
|
lines.push(` ${name}: (...args: _A<${comp}>) => _H<${comp}>;`);
|
|
142
152
|
}
|
|
143
|
-
lines.push(" };", "}"
|
|
153
|
+
lines.push(" };", "}");
|
|
154
|
+
lines.push(
|
|
155
|
+
"",
|
|
156
|
+
// Mirror the virtual module's `dialogs` export as a real named export so
|
|
157
|
+
// this file can serve as the `typeFrom` target of the Nuxt auto-import
|
|
158
|
+
// (see module.ts): Nuxt's static type-path resolution cannot resolve
|
|
159
|
+
// virtual ids (NUXT_B6005 warning), but it can resolve this on-disk
|
|
160
|
+
// declaration file. Adding a top-level export keeps the ambient module
|
|
161
|
+
// declaration above globally visible (ambient declarations are
|
|
162
|
+
// unaffected by the file becoming a module).
|
|
163
|
+
'export const dialogs: typeof import("virtual:dialogs").dialogs',
|
|
164
|
+
""
|
|
165
|
+
);
|
|
144
166
|
return lines.join("\n");
|
|
145
167
|
}
|
|
146
168
|
function createDialogsVitePlugin(options) {
|
|
@@ -244,7 +266,7 @@ export default (nuxtApp) => { provideDialogsNuxtApp(nuxtApp.vueApp); };
|
|
|
244
266
|
});
|
|
245
267
|
}
|
|
246
268
|
addImports([
|
|
247
|
-
{ name: "dialogs", from: "virtual:dialogs" },
|
|
269
|
+
{ name: "dialogs", from: "virtual:dialogs", typeFrom: dtsPath },
|
|
248
270
|
{ name: "useDialogContext", from: RUNTIME_PKG },
|
|
249
271
|
{ name: "createDialogExpose", from: RUNTIME_PKG },
|
|
250
272
|
{ name: "configureDialogs", from: RUNTIME_PKG }
|
package/dist/module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/module.ts","../src/vite-plugin.ts"],"sourcesContent":["import {\n addImports,\n addPluginTemplate,\n addTypeTemplate,\n defineNuxtModule,\n} from \"@nuxt/kit\";\nimport type { Nuxt } from \"@nuxt/schema\";\nimport { dirname, resolve } from \"node:path\";\nimport {\n createDialogsVitePlugin,\n generateDialogsDts,\n scanDialogFiles,\n} from \"./vite-plugin\";\n\nexport interface ModuleOptions {\n /**\n * Directory that contains dialog components.\n * Relative paths are resolved against `srcDir`. Defaults to `dialogs`.\n */\n dir?: string;\n /**\n * RegExp used to identify dialog component files.\n * Defaults to files whose name ends with `Dialog.vue` or `Drawer.vue`.\n */\n pattern?: RegExp;\n /**\n * When true (default), every dialog app inherits the Nuxt app's context:\n * global components, directives and provides — Pinia, i18n, UI libraries,\n * the `nuxtApp` itself — are all available inside dialogs with no wiring.\n */\n inheritNuxtApp?: boolean;\n}\n\nconst RUNTIME_PKG = \"@anfo/nuxt-dialogs-plugin/runtime\";\nconst IMPORT_ALIAS = \"#dialogs-components\";\nconst TYPE_TEMPLATE = \"types/dialogs.d.ts\";\n\nexport default defineNuxtModule<ModuleOptions>({\n meta: {\n name: \"@anfo/nuxt-dialogs-plugin\",\n configKey: \"dialogs\",\n version: \"1.0.0\",\n compatibility: { nuxt: \">=3.5.0\" },\n },\n defaults: {\n dir: \"dialogs\",\n pattern: /(Dialog|Drawer)\\.vue$/,\n inheritNuxtApp: true,\n },\n setup(options, nuxt: Nuxt) {\n const dialogsDir = resolve(nuxt.options.srcDir, options.dir ?? \"dialogs\");\n const pattern = options.pattern ?? /(Dialog|Drawer)\\.vue$/;\n const dtsPath = resolve(nuxt.options.buildDir, TYPE_TEMPLATE);\n\n if (String(nuxt.options.builder ?? \"\").includes(\"webpack\")) {\n console.warn(\n \"[@anfo/nuxt-dialogs-plugin] only the Vite builder is supported; `virtual:dialogs` will not resolve in webpack builds.\",\n );\n }\n\n // Let the generated virtual module import components through a stable\n // alias, so the dialogs directory can live anywhere.\n nuxt.options.alias[IMPORT_ALIAS] = dialogsDir;\n\n // Register the dialogs virtual module in every Vite build (client and\n // server bundles both need to resolve `virtual:dialogs` imports).\n const vitePlugin = createDialogsVitePlugin({\n dir: dialogsDir,\n pattern,\n importAlias: IMPORT_ALIAS,\n runtimePkg: RUNTIME_PKG,\n dtsPath,\n inheritNuxtApp: options.inheritNuxtApp ?? true,\n });\n nuxt.hook(\"vite:extendConfig\", (config) => {\n (config as { plugins: unknown[] }).plugins ??= [];\n (config.plugins as unknown[]).push(vitePlugin);\n });\n\n // Capture the Nuxt app so generated dialog mounts can inherit its\n // context (global components, directives, provides).\n if (options.inheritNuxtApp) {\n addPluginTemplate({\n filename: \"dialogs-context-plugin.mjs\",\n getContents: () =>\n `import { provideDialogsNuxtApp } from ${JSON.stringify(RUNTIME_PKG)};\\n` +\n `export default (nuxtApp) => { provideDialogsNuxtApp(nuxtApp.vueApp); };\\n`,\n });\n }\n\n // Auto-imports — explicit imports from the runtime keep working too.\n addImports([\n { name: \"dialogs\", from: \"virtual:dialogs\" },\n { name: \"useDialogContext\", from: RUNTIME_PKG },\n { name: \"createDialogExpose\", from: RUNTIME_PKG },\n { name: \"configureDialogs\", from: RUNTIME_PKG },\n ]);\n\n // Type declarations for `virtual:dialogs`, included in the generated\n // tsconfig automatically — no user tsconfig changes required. The Vite\n // plugin rewrites this same file when dialog files are added/removed.\n const files = scanDialogFiles(dialogsDir, pattern);\n addTypeTemplate({\n filename: TYPE_TEMPLATE,\n getContents: () =>\n generateDialogsDts({\n files,\n dtsDir: dirname(dtsPath),\n dialogsDir,\n runtimePkg: RUNTIME_PKG,\n }),\n });\n },\n});\n","import type { Plugin, ViteDevServer } from \"vite\";\nimport { mkdirSync, readdirSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, relative, resolve } from \"node:path\";\n\nexport interface DialogsVitePluginOptions {\n /** Absolute path to the directory that contains dialog components. */\n dir: string;\n /** RegExp used to identify dialog component files. */\n pattern: RegExp;\n /**\n * Alias registered on the Nuxt app (e.g. `#dialogs-components`) that maps\n * to `dir`. The virtual module imports components through it so the\n * generated code never depends on where the directory lives.\n */\n importAlias: string;\n /** Runtime package specifier, e.g. `@anfo/nuxt-dialogs-plugin/runtime`. */\n runtimePkg: string;\n /** Absolute path of the generated declaration file. */\n dtsPath: string;\n /**\n * When true, generated dialog apps inherit the Nuxt app's context\n * (global components, directives, provides — Pinia, i18n, UI libs…).\n */\n inheritNuxtApp: boolean;\n}\n\nconst VIRTUAL_ID = \"virtual:dialogs\";\nconst RESOLVED_VIRTUAL_ID = \"\\0virtual:dialogs\";\n\n// ── Scanning ──────────────────────────────────────────────────────────────────\n\nexport function scanDialogFiles(dir: string, pattern: RegExp): string[] {\n try {\n return readdirSync(dir)\n .filter((f: string) => pattern.test(f))\n .sort()\n .map((f: string) => resolve(dir, f));\n } catch {\n return [];\n }\n}\n\nfunction componentName(filePath: string): string {\n return basename(filePath, \".vue\");\n}\n\n// ── Virtual module code generation ────────────────────────────────────────────\n\nfunction generateModuleCode(\n files: string[],\n options: DialogsVitePluginOptions,\n): string {\n const { dir, importAlias, runtimePkg, inheritNuxtApp } = options;\n\n const runtimeImports = inheritNuxtApp\n ? \"applyDialogAppPlugins, dialogControllerKey, getDialogsNuxtVueApp\"\n : \"applyDialogAppPlugins, dialogControllerKey\";\n\n const lines: string[] = [\n `import { createApp } from \"vue\";`,\n `import { ${runtimeImports} } from ${JSON.stringify(runtimePkg)};`,\n ];\n for (let i = 0; i < files.length; i++) {\n lines.push(\n `import _D${i} from ${JSON.stringify(`${importAlias}/${basename(files[i])}`)};`,\n );\n }\n\n // Dialogs are DOM-only; calling one during SSR resolves as a rejection\n // instead of crashing the server render.\n const ssrGuard = ` if (typeof document === \"undefined\") {\n console.warn(\"[nuxt-dialogs] dialogs can only be opened in the browser; ignoring a dialog opened during SSR.\");\n return Object.assign(Promise.resolve({ type: \"reject\", reason: new Error(\"Dialogs are client-only (opened during SSR).\") }), {\n resolve() { return this; },\n reject() { return this; },\n });\n }\n`;\n\n // Shallow-clone the Nuxt app's context onto the dialog app. Every bucket\n // must be copied (not shared by reference) so the `provide()` below — and\n // any plugin install — cannot leak into the main Nuxt app.\n const contextInherit = inheritNuxtApp\n ? ` const nuxtVueApp = getDialogsNuxtVueApp();\n if (nuxtVueApp) {\n const base = app._context;\n const main = nuxtVueApp._context;\n app._context = {\n ...base,\n config: { ...base.config, ...main.config },\n components: { ...base.components, ...main.components },\n directives: { ...base.directives, ...main.directives },\n provides: { ...base.provides, ...main.provides },\n };\n }\n`\n : \"\";\n\n lines.push(`\nfunction mountDialog(component, props) {\n${ssrGuard} const result = new Promise((resolve) => {\n const host = document.createElement(\"div\");\n document.body.appendChild(host);\n let settled = false;\n function cleanup() { app.unmount(); host.remove(); }\n function finish(cb) {\n if (settled) return;\n settled = true;\n cb();\n cleanup();\n }\n function handleResolve(...args) {\n finish(() => {\n if (args.length === 0) { resolve({ type: \"resolve\" }); return; }\n resolve({ type: \"resolve\", value: args[0] });\n });\n }\n const controller = {\n resolve: handleResolve,\n reject: (reason) => { finish(() => resolve({ type: \"reject\", reason })); },\n };\n const app = createApp(component, props);\n${contextInherit} app.provide(dialogControllerKey, controller);\n applyDialogAppPlugins(app);\n app.mount(host);\n });\n return Object.assign(result, {\n resolve(callback) {\n result.then((value) => {\n if (value.type === \"resolve\") callback?.(value.value);\n });\n return this;\n },\n reject(callback) {\n result.then((value) => {\n if (value.type === \"reject\") callback(value.reason);\n });\n return this;\n },\n });\n}`);\n\n lines.push(\"\");\n lines.push(\"export const dialogs = {\");\n for (let i = 0; i < files.length; i++) {\n lines.push(\n `\\t${componentName(files[i])}: (props) => mountDialog(_D${i}, props),`,\n );\n }\n lines.push(\"};\");\n return lines.join(\"\\n\");\n}\n\n// ── Declaration file generation ───────────────────────────────────────────────\n\nexport function generateDialogsDts(options: {\n files: string[];\n /** Absolute path of the directory the .d.ts is written to. */\n dtsDir: string;\n /** Directory containing the dialog components (absolute). */\n dialogsDir: string;\n /** Runtime package specifier for type imports. */\n runtimePkg: string;\n}): string {\n const { files, dtsDir, dialogsDir, runtimePkg } = options;\n\n const lines: string[] = [\n \"// Auto-generated by @anfo/nuxt-dialogs-plugin — do not edit manually.\",\n \"\",\n `declare module \"${VIRTUAL_ID}\" {`,\n `\\ttype _C = import(\"vue\").Component;`,\n `\\ttype _CE<T extends _C> = import(\"vue-component-type-helpers\").ComponentExposed<T>;`,\n `\\ttype _CP<T extends _C> = import(\"vue-component-type-helpers\").ComponentProps<T>;`,\n `\\ttype _DE<T> = import(${JSON.stringify(runtimePkg)}).DialogExposed<T>;`,\n `\\ttype _DS<T> = import(${JSON.stringify(runtimePkg)}).DialogSettledResult<T>;`,\n `\\ttype _DR = import(${JSON.stringify(runtimePkg)}).DialogRejectedResult;`,\n `\\ttype _IK = \"key\" | \"ref\" | \"ref_for\" | \"ref_key\" | \"class\" | \"style\" | \\`on\\${string}\\`;`,\n `\\ttype _P<T extends _C> = Omit<_CP<T>, _IK>;`,\n `\\ttype _RK<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? never : K }[keyof T];`,\n `\\ttype _A<T extends _C> = [_RK<_P<T>>] extends [never] ? [props?: _P<T>] : [props: _P<T>];`,\n `\\ttype _V<T extends _C> = _CE<T> extends _DE<infer R> ? R : void;`,\n `\\ttype _R<T extends _C> = _DS<_V<T>>;`,\n `\\ttype _RN = _DR[\"reason\"];`,\n `\\ttype _H<T extends _C> = Promise<_R<T>> & {`,\n `\\t\\tresolve(callback?: (value: _V<T> | undefined) => void): _H<T>;`,\n `\\t\\treject(callback: (reason: _RN) => void): _H<T>;`,\n `\\t};`,\n `\\texport const dialogs: {`,\n ];\n\n for (const filePath of files) {\n const name = componentName(filePath);\n let rel = relative(dtsDir, filePath).replace(/\\\\/g, \"/\");\n if (!rel.startsWith(\".\")) rel = `./${rel}`;\n const comp = `typeof import(${JSON.stringify(rel)})[\"default\"]`;\n lines.push(`\\t\\t${name}: (...args: _A<${comp}>) => _H<${comp}>;`);\n }\n\n lines.push(\"\\t};\", \"}\", \"\");\n return lines.join(\"\\n\");\n}\n\n// ── Plugin ────────────────────────────────────────────────────────────────────\n\nexport function createDialogsVitePlugin(\n options: DialogsVitePluginOptions,\n): Plugin {\n const { dir, pattern, dtsPath } = options;\n\n function writeDts(): void {\n const dtsDir = dirname(dtsPath);\n mkdirSync(dtsDir, { recursive: true });\n writeFileSync(\n dtsPath,\n generateDialogsDts({\n files: scanDialogFiles(dir, pattern),\n dtsDir,\n dialogsDir: dir,\n runtimePkg: options.runtimePkg,\n }),\n \"utf-8\",\n );\n }\n\n function invalidate(server: ViteDevServer): void {\n const mod = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_ID);\n if (mod) server.moduleGraph.invalidateModule(mod);\n writeDts();\n server.hot.send({ type: \"full-reload\" });\n }\n\n return {\n name: \"nuxt-dialogs-plugin\",\n\n buildStart() {\n writeDts();\n },\n\n resolveId(id) {\n if (id === VIRTUAL_ID) return RESOLVED_VIRTUAL_ID;\n },\n\n load(id) {\n if (id !== RESOLVED_VIRTUAL_ID) return;\n const files = scanDialogFiles(dir, pattern);\n return {\n code: generateModuleCode(files, options),\n moduleType: \"js\",\n };\n },\n\n configureServer(server) {\n server.watcher.add(dir);\n\n server.watcher.on(\"add\", (file) => {\n if (pattern.test(file) && file.startsWith(dir)) {\n invalidate(server);\n }\n });\n\n server.watcher.on(\"unlink\", (file) => {\n if (pattern.test(file) && file.startsWith(dir)) {\n invalidate(server);\n }\n });\n },\n };\n}\n"],"mappings":";AAAA;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACG;AAEP,SAAS,WAAAA,UAAS,WAAAC,gBAAe;;;ACNjC,SAAS,WAAW,aAAa,qBAAqB;AACtD,SAAS,UAAU,SAAS,UAAU,eAAe;AAwBrD,IAAM,aAAa;AACnB,IAAM,sBAAsB;AAIrB,SAAS,gBAAgB,KAAa,SAA2B;AACpE,MAAI;AACA,WAAO,YAAY,GAAG,EACjB,OAAO,CAAC,MAAc,QAAQ,KAAK,CAAC,CAAC,EACrC,KAAK,EACL,IAAI,CAAC,MAAc,QAAQ,KAAK,CAAC,CAAC;AAAA,EAC3C,QAAQ;AACJ,WAAO,CAAC;AAAA,EACZ;AACJ;AAEA,SAAS,cAAc,UAA0B;AAC7C,SAAO,SAAS,UAAU,MAAM;AACpC;AAIA,SAAS,mBACL,OACA,SACM;AACN,QAAM,EAAE,KAAK,aAAa,YAAY,eAAe,IAAI;AAEzD,QAAM,iBAAiB,iBACjB,qEACA;AAEN,QAAM,QAAkB;AAAA,IACpB;AAAA,IACA,YAAY,cAAc,WAAW,KAAK,UAAU,UAAU,CAAC;AAAA,EACnE;AACA,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,UAAM;AAAA,MACF,YAAY,CAAC,SAAS,KAAK,UAAU,GAAG,WAAW,IAAI,SAAS,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;AAAA,IAChF;AAAA,EACJ;AAIA,QAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYjB,QAAM,iBAAiB,iBACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAaA;AAEN,QAAM,KAAK;AAAA;AAAA,EAEb,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBR,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBd;AAEE,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,0BAA0B;AACrC,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,UAAM;AAAA,MACF,IAAK,cAAc,MAAM,CAAC,CAAC,CAAC,8BAA8B,CAAC;AAAA,IAC/D;AAAA,EACJ;AACA,QAAM,KAAK,IAAI;AACf,SAAO,MAAM,KAAK,IAAI;AAC1B;AAIO,SAAS,mBAAmB,SAQxB;AACP,QAAM,EAAE,OAAO,QAAQ,YAAY,WAAW,IAAI;AAElD,QAAM,QAAkB;AAAA,IACpB;AAAA,IACA;AAAA,IACA,mBAAmB,UAAU;AAAA,IAC7B;AAAA,IACA;AAAA,IACA;AAAA,IACA,yBAA0B,KAAK,UAAU,UAAU,CAAC;AAAA,IACpD,yBAA0B,KAAK,UAAU,UAAU,CAAC;AAAA,IACpD,sBAAuB,KAAK,UAAU,UAAU,CAAC;AAAA,IACjD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAEA,aAAW,YAAY,OAAO;AAC1B,UAAM,OAAO,cAAc,QAAQ;AACnC,QAAI,MAAM,SAAS,QAAQ,QAAQ,EAAE,QAAQ,OAAO,GAAG;AACvD,QAAI,CAAC,IAAI,WAAW,GAAG,EAAG,OAAM,KAAK,GAAG;AACxC,UAAM,OAAO,iBAAiB,KAAK,UAAU,GAAG,CAAC;AACjD,UAAM,KAAK,KAAO,IAAI,kBAAkB,IAAI,YAAY,IAAI,IAAI;AAAA,EACpE;AAEA,QAAM,KAAK,OAAQ,KAAK,EAAE;AAC1B,SAAO,MAAM,KAAK,IAAI;AAC1B;AAIO,SAAS,wBACZ,SACM;AACN,QAAM,EAAE,KAAK,SAAS,QAAQ,IAAI;AAElC,WAAS,WAAiB;AACtB,UAAM,SAAS,QAAQ,OAAO;AAC9B,cAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AACrC;AAAA,MACI;AAAA,MACA,mBAAmB;AAAA,QACf,OAAO,gBAAgB,KAAK,OAAO;AAAA,QACnC;AAAA,QACA,YAAY;AAAA,QACZ,YAAY,QAAQ;AAAA,MACxB,CAAC;AAAA,MACD;AAAA,IACJ;AAAA,EACJ;AAEA,WAAS,WAAW,QAA6B;AAC7C,UAAM,MAAM,OAAO,YAAY,cAAc,mBAAmB;AAChE,QAAI,IAAK,QAAO,YAAY,iBAAiB,GAAG;AAChD,aAAS;AACT,WAAO,IAAI,KAAK,EAAE,MAAM,cAAc,CAAC;AAAA,EAC3C;AAEA,SAAO;AAAA,IACH,MAAM;AAAA,IAEN,aAAa;AACT,eAAS;AAAA,IACb;AAAA,IAEA,UAAU,IAAI;AACV,UAAI,OAAO,WAAY,QAAO;AAAA,IAClC;AAAA,IAEA,KAAK,IAAI;AACL,UAAI,OAAO,oBAAqB;AAChC,YAAM,QAAQ,gBAAgB,KAAK,OAAO;AAC1C,aAAO;AAAA,QACH,MAAM,mBAAmB,OAAO,OAAO;AAAA,QACvC,YAAY;AAAA,MAChB;AAAA,IACJ;AAAA,IAEA,gBAAgB,QAAQ;AACpB,aAAO,QAAQ,IAAI,GAAG;AAEtB,aAAO,QAAQ,GAAG,OAAO,CAAC,SAAS;AAC/B,YAAI,QAAQ,KAAK,IAAI,KAAK,KAAK,WAAW,GAAG,GAAG;AAC5C,qBAAW,MAAM;AAAA,QACrB;AAAA,MACJ,CAAC;AAED,aAAO,QAAQ,GAAG,UAAU,CAAC,SAAS;AAClC,YAAI,QAAQ,KAAK,IAAI,KAAK,KAAK,WAAW,GAAG,GAAG;AAC5C,qBAAW,MAAM;AAAA,QACrB;AAAA,MACJ,CAAC;AAAA,IACL;AAAA,EACJ;AACJ;;;AD1OA,IAAM,cAAc;AACpB,IAAM,eAAe;AACrB,IAAM,gBAAgB;AAEtB,IAAO,iBAAQ,iBAAgC;AAAA,EAC3C,MAAM;AAAA,IACF,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,eAAe,EAAE,MAAM,UAAU;AAAA,EACrC;AAAA,EACA,UAAU;AAAA,IACN,KAAK;AAAA,IACL,SAAS;AAAA,IACT,gBAAgB;AAAA,EACpB;AAAA,EACA,MAAM,SAAS,MAAY;AACvB,UAAM,aAAaC,SAAQ,KAAK,QAAQ,QAAQ,QAAQ,OAAO,SAAS;AACxE,UAAM,UAAU,QAAQ,WAAW;AACnC,UAAM,UAAUA,SAAQ,KAAK,QAAQ,UAAU,aAAa;AAE5D,QAAI,OAAO,KAAK,QAAQ,WAAW,EAAE,EAAE,SAAS,SAAS,GAAG;AACxD,cAAQ;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAIA,SAAK,QAAQ,MAAM,YAAY,IAAI;AAInC,UAAM,aAAa,wBAAwB;AAAA,MACvC,KAAK;AAAA,MACL;AAAA,MACA,aAAa;AAAA,MACb,YAAY;AAAA,MACZ;AAAA,MACA,gBAAgB,QAAQ,kBAAkB;AAAA,IAC9C,CAAC;AACD,SAAK,KAAK,qBAAqB,CAAC,WAAW;AACvC,MAAC,OAAkC,YAAlC,OAAkC,UAAY,CAAC;AAChD,MAAC,OAAO,QAAsB,KAAK,UAAU;AAAA,IACjD,CAAC;AAID,QAAI,QAAQ,gBAAgB;AACxB,wBAAkB;AAAA,QACd,UAAU;AAAA,QACV,aAAa,MACT,yCAAyC,KAAK,UAAU,WAAW,CAAC;AAAA;AAAA;AAAA,MAE5E,CAAC;AAAA,IACL;AAGA,eAAW;AAAA,MACP,EAAE,MAAM,WAAW,MAAM,kBAAkB;AAAA,MAC3C,EAAE,MAAM,oBAAoB,MAAM,YAAY;AAAA,MAC9C,EAAE,MAAM,sBAAsB,MAAM,YAAY;AAAA,MAChD,EAAE,MAAM,oBAAoB,MAAM,YAAY;AAAA,IAClD,CAAC;AAKD,UAAM,QAAQ,gBAAgB,YAAY,OAAO;AACjD,oBAAgB;AAAA,MACZ,UAAU;AAAA,MACV,aAAa,MACT,mBAAmB;AAAA,QACf;AAAA,QACA,QAAQC,SAAQ,OAAO;AAAA,QACvB;AAAA,QACA,YAAY;AAAA,MAChB,CAAC;AAAA,IACT,CAAC;AAAA,EACL;AACJ,CAAC;","names":["dirname","resolve","resolve","dirname"]}
|
|
1
|
+
{"version":3,"sources":["../src/module.ts","../src/vite-plugin.ts"],"sourcesContent":["import {\n addImports,\n addPluginTemplate,\n addTypeTemplate,\n defineNuxtModule,\n} from \"@nuxt/kit\";\nimport type { Nuxt } from \"@nuxt/schema\";\nimport { dirname, resolve } from \"node:path\";\nimport {\n createDialogsVitePlugin,\n generateDialogsDts,\n scanDialogFiles,\n} from \"./vite-plugin\";\n\nexport interface ModuleOptions {\n /**\n * Directory that contains dialog components.\n * Relative paths are resolved against `srcDir`. Defaults to `dialogs`.\n */\n dir?: string;\n /**\n * RegExp used to identify dialog component files.\n * Defaults to files whose name ends with `Dialog.vue` or `Drawer.vue`.\n */\n pattern?: RegExp;\n /**\n * When true (default), every dialog app inherits the Nuxt app's context:\n * global components, directives and provides — Pinia, i18n, UI libraries,\n * the `nuxtApp` itself — are all available inside dialogs with no wiring.\n */\n inheritNuxtApp?: boolean;\n}\n\nconst RUNTIME_PKG = \"@anfo/nuxt-dialogs-plugin/runtime\";\nconst IMPORT_ALIAS = \"#dialogs-components\";\nconst TYPE_TEMPLATE = \"types/dialogs.d.ts\";\n\nexport default defineNuxtModule<ModuleOptions>({\n meta: {\n name: \"@anfo/nuxt-dialogs-plugin\",\n configKey: \"dialogs\",\n version: \"1.0.0\",\n compatibility: { nuxt: \">=3.5.0\" },\n },\n defaults: {\n dir: \"dialogs\",\n pattern: /(Dialog|Drawer)\\.vue$/,\n inheritNuxtApp: true,\n },\n setup(options, nuxt: Nuxt) {\n const dialogsDir = resolve(nuxt.options.srcDir, options.dir ?? \"dialogs\");\n const pattern = options.pattern ?? /(Dialog|Drawer)\\.vue$/;\n const dtsPath = resolve(nuxt.options.buildDir, TYPE_TEMPLATE);\n\n if (String(nuxt.options.builder ?? \"\").includes(\"webpack\")) {\n console.warn(\n \"[@anfo/nuxt-dialogs-plugin] only the Vite builder is supported; `virtual:dialogs` will not resolve in webpack builds.\",\n );\n }\n\n // Let the generated virtual module import components through a stable\n // alias, so the dialogs directory can live anywhere.\n nuxt.options.alias[IMPORT_ALIAS] = dialogsDir;\n\n // Register the dialogs virtual module in every Vite build (client and\n // server bundles both need to resolve `virtual:dialogs` imports).\n const vitePlugin = createDialogsVitePlugin({\n dir: dialogsDir,\n pattern,\n importAlias: IMPORT_ALIAS,\n runtimePkg: RUNTIME_PKG,\n dtsPath,\n inheritNuxtApp: options.inheritNuxtApp ?? true,\n });\n nuxt.hook(\"vite:extendConfig\", (config) => {\n (config as { plugins: unknown[] }).plugins ??= [];\n (config.plugins as unknown[]).push(vitePlugin);\n });\n\n // Capture the Nuxt app so generated dialog mounts can inherit its\n // context (global components, directives, provides).\n if (options.inheritNuxtApp) {\n addPluginTemplate({\n filename: \"dialogs-context-plugin.mjs\",\n getContents: () =>\n `import { provideDialogsNuxtApp } from ${JSON.stringify(RUNTIME_PKG)};\\n` +\n `export default (nuxtApp) => { provideDialogsNuxtApp(nuxtApp.vueApp); };\\n`,\n });\n }\n\n // Auto-imports — explicit imports from the runtime keep working too.\n // The `dialogs` entry declares `typeFrom` pointing at the generated\n // declaration file (inside buildDir): Nuxt's static type-path\n // resolution cannot resolve the `virtual:dialogs` id and would emit a\n // NUXT_B6005 warning (\"unresolvable module\") on every start. Runtime\n // injection still comes from `virtual:dialogs` — unimport uses `from`\n // for the actual import and `typeFrom` for type declarations, and the\n // declaration file mirrors the virtual module's `dialogs` export (see\n // generateDialogsDts).\n addImports([\n { name: \"dialogs\", from: \"virtual:dialogs\", typeFrom: dtsPath },\n { name: \"useDialogContext\", from: RUNTIME_PKG },\n { name: \"createDialogExpose\", from: RUNTIME_PKG },\n { name: \"configureDialogs\", from: RUNTIME_PKG },\n ]);\n\n // Type declarations for `virtual:dialogs`, included in the generated\n // tsconfig automatically — no user tsconfig changes required. The Vite\n // plugin rewrites this same file when dialog files are added/removed.\n const files = scanDialogFiles(dialogsDir, pattern);\n addTypeTemplate({\n filename: TYPE_TEMPLATE,\n getContents: () =>\n generateDialogsDts({\n files,\n dtsDir: dirname(dtsPath),\n dialogsDir,\n runtimePkg: RUNTIME_PKG,\n }),\n });\n },\n});\n","import type { Plugin, ViteDevServer } from \"vite\";\nimport { mkdirSync, readdirSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, relative, resolve } from \"node:path\";\n\nexport interface DialogsVitePluginOptions {\n /** Absolute path to the directory that contains dialog components. */\n dir: string;\n /** RegExp used to identify dialog component files. */\n pattern: RegExp;\n /**\n * Alias registered on the Nuxt app (e.g. `#dialogs-components`) that maps\n * to `dir`. The virtual module imports components through it so the\n * generated code never depends on where the directory lives.\n */\n importAlias: string;\n /** Runtime package specifier, e.g. `@anfo/nuxt-dialogs-plugin/runtime`. */\n runtimePkg: string;\n /** Absolute path of the generated declaration file. */\n dtsPath: string;\n /**\n * When true, generated dialog apps inherit the Nuxt app's context\n * (global components, directives, provides — Pinia, i18n, UI libs…).\n */\n inheritNuxtApp: boolean;\n}\n\nconst VIRTUAL_ID = \"virtual:dialogs\";\nconst RESOLVED_VIRTUAL_ID = \"\\0virtual:dialogs\";\n\n// ── Scanning ──────────────────────────────────────────────────────────────────\n\nexport function scanDialogFiles(dir: string, pattern: RegExp): string[] {\n try {\n return readdirSync(dir)\n .filter((f: string) => pattern.test(f))\n .sort()\n .map((f: string) => resolve(dir, f));\n } catch {\n return [];\n }\n}\n\nfunction componentName(filePath: string): string {\n return basename(filePath, \".vue\");\n}\n\n// ── Virtual module code generation ────────────────────────────────────────────\n\nfunction generateModuleCode(\n files: string[],\n options: DialogsVitePluginOptions,\n): string {\n const { dir, importAlias, runtimePkg, inheritNuxtApp } = options;\n\n const runtimeImports = inheritNuxtApp\n ? \"applyDialogAppPlugins, dialogControllerKey, getDialogsNuxtVueApp\"\n : \"applyDialogAppPlugins, dialogControllerKey\";\n\n const lines: string[] = [\n `import { createApp } from \"vue\";`,\n `import { ${runtimeImports} } from ${JSON.stringify(runtimePkg)};`,\n ];\n for (let i = 0; i < files.length; i++) {\n lines.push(\n `import _D${i} from ${JSON.stringify(`${importAlias}/${basename(files[i])}`)};`,\n );\n }\n\n // Dialogs are DOM-only; calling one during SSR resolves as a rejection\n // instead of crashing the server render.\n const ssrGuard = ` if (typeof document === \"undefined\") {\n console.warn(\"[nuxt-dialogs] dialogs can only be opened in the browser; ignoring a dialog opened during SSR.\");\n return Object.assign(Promise.resolve({ type: \"reject\", reason: new Error(\"Dialogs are client-only (opened during SSR).\") }), {\n resolve() { return this; },\n reject() { return this; },\n });\n }\n`;\n\n // Shallow-clone the Nuxt app's context onto the dialog app. Every bucket\n // must be copied (not shared by reference) so the `provide()` below — and\n // any plugin install — cannot leak into the main Nuxt app.\n //\n // `config` must NOT be merged with object spread: spread reads every\n // source accessor, and dev builds of Vue define `app.config.compilerOptions`\n // as a warn-on-access getter (runtime-only builds), so opening a dialog\n // would spam two Vue warnings per open. Merge data properties by\n // descriptor instead — accessors are skipped on purpose.\n const contextInherit = inheritNuxtApp\n ? ` const nuxtVueApp = getDialogsNuxtVueApp();\n if (nuxtVueApp) {\n const mergeConfig = (baseConfig, mainConfig) => {\n const out = {};\n for (const source of [baseConfig, mainConfig]) {\n for (const key of Reflect.ownKeys(source)) {\n const desc = Object.getOwnPropertyDescriptor(source, key);\n if (desc && \"value\" in desc) Object.defineProperty(out, key, desc);\n }\n }\n return out;\n };\n const base = app._context;\n const main = nuxtVueApp._context;\n app._context = {\n ...base,\n config: mergeConfig(base.config, main.config),\n components: { ...base.components, ...main.components },\n directives: { ...base.directives, ...main.directives },\n provides: { ...base.provides, ...main.provides },\n };\n }\n`\n : \"\";\n\n lines.push(`\nfunction mountDialog(component, props) {\n${ssrGuard} const result = new Promise((resolve) => {\n const host = document.createElement(\"div\");\n document.body.appendChild(host);\n let settled = false;\n function cleanup() { app.unmount(); host.remove(); }\n function finish(cb) {\n if (settled) return;\n settled = true;\n cb();\n cleanup();\n }\n function handleResolve(...args) {\n finish(() => {\n if (args.length === 0) { resolve({ type: \"resolve\" }); return; }\n resolve({ type: \"resolve\", value: args[0] });\n });\n }\n const controller = {\n resolve: handleResolve,\n reject: (reason) => { finish(() => resolve({ type: \"reject\", reason })); },\n };\n const app = createApp(component, props);\n${contextInherit} app.provide(dialogControllerKey, controller);\n applyDialogAppPlugins(app);\n app.mount(host);\n });\n return Object.assign(result, {\n resolve(callback) {\n result.then((value) => {\n if (value.type === \"resolve\") callback?.(value.value);\n });\n return this;\n },\n reject(callback) {\n result.then((value) => {\n if (value.type === \"reject\") callback(value.reason);\n });\n return this;\n },\n });\n}`);\n\n lines.push(\"\");\n lines.push(\"export const dialogs = {\");\n for (let i = 0; i < files.length; i++) {\n lines.push(\n `\\t${componentName(files[i])}: (props) => mountDialog(_D${i}, props),`,\n );\n }\n lines.push(\"};\");\n return lines.join(\"\\n\");\n}\n\n// ── Declaration file generation ───────────────────────────────────────────────\n\nexport function generateDialogsDts(options: {\n files: string[];\n /** Absolute path of the directory the .d.ts is written to. */\n dtsDir: string;\n /** Directory containing the dialog components (absolute). */\n dialogsDir: string;\n /** Runtime package specifier for type imports. */\n runtimePkg: string;\n}): string {\n const { files, dtsDir, dialogsDir, runtimePkg } = options;\n\n const lines: string[] = [\n \"// Auto-generated by @anfo/nuxt-dialogs-plugin — do not edit manually.\",\n \"\",\n `declare module \"${VIRTUAL_ID}\" {`,\n `\\ttype _C = import(\"vue\").Component;`,\n `\\ttype _CE<T extends _C> = import(\"vue-component-type-helpers\").ComponentExposed<T>;`,\n `\\ttype _CP<T extends _C> = import(\"vue-component-type-helpers\").ComponentProps<T>;`,\n `\\ttype _DE<T> = import(${JSON.stringify(runtimePkg)}).DialogExposed<T>;`,\n `\\ttype _DS<T> = import(${JSON.stringify(runtimePkg)}).DialogSettledResult<T>;`,\n `\\ttype _DR = import(${JSON.stringify(runtimePkg)}).DialogRejectedResult;`,\n `\\ttype _IK = \"key\" | \"ref\" | \"ref_for\" | \"ref_key\" | \"class\" | \"style\" | \\`on\\${string}\\`;`,\n `\\ttype _P<T extends _C> = Omit<_CP<T>, _IK>;`,\n `\\ttype _RK<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? never : K }[keyof T];`,\n `\\ttype _A<T extends _C> = [_RK<_P<T>>] extends [never] ? [props?: _P<T>] : [props: _P<T>];`,\n `\\ttype _V<T extends _C> = _CE<T> extends _DE<infer R> ? R : void;`,\n `\\ttype _R<T extends _C> = _DS<_V<T>>;`,\n `\\ttype _RN = _DR[\"reason\"];`,\n `\\ttype _H<T extends _C> = Promise<_R<T>> & {`,\n `\\t\\tresolve(callback?: (value: _V<T> | undefined) => void): _H<T>;`,\n `\\t\\treject(callback: (reason: _RN) => void): _H<T>;`,\n `\\t};`,\n `\\texport const dialogs: {`,\n ];\n\n for (const filePath of files) {\n const name = componentName(filePath);\n let rel = relative(dtsDir, filePath).replace(/\\\\/g, \"/\");\n if (!rel.startsWith(\".\")) rel = `./${rel}`;\n const comp = `typeof import(${JSON.stringify(rel)})[\"default\"]`;\n lines.push(`\\t\\t${name}: (...args: _A<${comp}>) => _H<${comp}>;`);\n }\n\n lines.push(\"\\t};\", \"}\");\n lines.push(\n \"\",\n // Mirror the virtual module's `dialogs` export as a real named export so\n // this file can serve as the `typeFrom` target of the Nuxt auto-import\n // (see module.ts): Nuxt's static type-path resolution cannot resolve\n // virtual ids (NUXT_B6005 warning), but it can resolve this on-disk\n // declaration file. Adding a top-level export keeps the ambient module\n // declaration above globally visible (ambient declarations are\n // unaffected by the file becoming a module).\n \"export const dialogs: typeof import(\\\"virtual:dialogs\\\").dialogs\",\n \"\",\n );\n return lines.join(\"\\n\");\n}\n\n// ── Plugin ────────────────────────────────────────────────────────────────────\n\nexport function createDialogsVitePlugin(\n options: DialogsVitePluginOptions,\n): Plugin {\n const { dir, pattern, dtsPath } = options;\n\n function writeDts(): void {\n const dtsDir = dirname(dtsPath);\n mkdirSync(dtsDir, { recursive: true });\n writeFileSync(\n dtsPath,\n generateDialogsDts({\n files: scanDialogFiles(dir, pattern),\n dtsDir,\n dialogsDir: dir,\n runtimePkg: options.runtimePkg,\n }),\n \"utf-8\",\n );\n }\n\n function invalidate(server: ViteDevServer): void {\n const mod = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_ID);\n if (mod) server.moduleGraph.invalidateModule(mod);\n writeDts();\n server.hot.send({ type: \"full-reload\" });\n }\n\n return {\n name: \"nuxt-dialogs-plugin\",\n\n buildStart() {\n writeDts();\n },\n\n resolveId(id) {\n if (id === VIRTUAL_ID) return RESOLVED_VIRTUAL_ID;\n },\n\n load(id) {\n if (id !== RESOLVED_VIRTUAL_ID) return;\n const files = scanDialogFiles(dir, pattern);\n return {\n code: generateModuleCode(files, options),\n moduleType: \"js\",\n };\n },\n\n configureServer(server) {\n server.watcher.add(dir);\n\n server.watcher.on(\"add\", (file) => {\n if (pattern.test(file) && file.startsWith(dir)) {\n invalidate(server);\n }\n });\n\n server.watcher.on(\"unlink\", (file) => {\n if (pattern.test(file) && file.startsWith(dir)) {\n invalidate(server);\n }\n });\n },\n };\n}\n"],"mappings":"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","names":["dirname","resolve","resolve","dirname"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anfo/nuxt-dialogs-plugin",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Nuxt module that auto-scans a directory for Vue dialog/drawer components and exposes them through a fully type-safe virtual module (virtual:dialogs). Dialog apps automatically inherit the Nuxt app context (Pinia, i18n, UI libraries, global components).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nuxt",
|