|
1 | 1 | import { fileURLToPath } from 'node:url' |
2 | | -import { readFile, readdir } from 'node:fs/promises' |
| 2 | +import { cp, mkdir, readFile, readdir, rm, writeFile } from 'node:fs/promises' |
3 | 3 | import { beforeAll, describe, it, expect } from 'vitest' |
4 | 4 | import { execaCommand } from 'execa' |
5 | 5 | import { readPackageJSON } from 'pkg-types' |
6 | | -import { join } from 'pathe' |
| 6 | +import { dirname, join } from 'pathe' |
7 | 7 | import { findStaticImports } from 'mlly' |
8 | 8 | import { version } from '../package.json' |
9 | 9 |
|
10 | 10 | describe('module builder', () => { |
11 | 11 | const rootDir = fileURLToPath(new URL('../example', import.meta.url)) |
| 12 | + const secondRootDir = rootDir.replace('example', '.temp-example-without-options') |
12 | 13 | const distDir = join(rootDir, 'dist') |
| 14 | + const secondDistDir = join(secondRootDir, 'dist') |
13 | 15 | const runtimeDir = join(distDir, 'runtime') |
14 | 16 |
|
15 | 17 | beforeAll(async () => { |
16 | | - await execaCommand('pnpm dev:prepare', { cwd: rootDir }) |
17 | | - await execaCommand('pnpm prepack', { cwd: rootDir }) |
| 18 | + // Prepare second root directory without type export |
| 19 | + await mkdir(dirname(secondRootDir), { recursive: true }) |
| 20 | + await rm(secondRootDir, { force: true, recursive: true }) |
| 21 | + await cp(rootDir, secondRootDir, { recursive: true }) |
| 22 | + const moduleSrc = join(secondRootDir, 'src/module.ts') |
| 23 | + const contents = await readFile(moduleSrc, 'utf-8').then(r => r.replace('export interface ModuleOptions', 'interface ModuleOptions')) |
| 24 | + await writeFile(moduleSrc, contents) |
| 25 | + |
| 26 | + await Promise.all([ |
| 27 | + execaCommand('pnpm dev:prepare', { cwd: rootDir }).then(() => execaCommand('pnpm prepack', { cwd: rootDir })), |
| 28 | + execaCommand('pnpm dev:prepare', { cwd: secondRootDir }).then(() => execaCommand('pnpm prepack', { cwd: secondRootDir })), |
| 29 | + ]) |
18 | 30 | }, 120 * 1000) |
19 | 31 |
|
20 | 32 | it('should generate all files', async () => { |
@@ -47,32 +59,55 @@ describe('module builder', () => { |
47 | 59 | it('should write types to output directory', async () => { |
48 | 60 | const types = await readFile(join(distDir, 'types.d.ts'), 'utf-8') |
49 | 61 | expect(types).toMatchInlineSnapshot(` |
| 62 | + "import type { ModuleHooks, ModuleRuntimeHooks, ModuleRuntimeConfig, ModulePublicRuntimeConfig } from './module' |
| 63 | +
|
| 64 | + declare module '#app' { |
| 65 | + interface RuntimeNuxtHooks extends ModuleRuntimeHooks {} |
| 66 | + } |
| 67 | +
|
| 68 | + declare module '@nuxt/schema' { |
| 69 | + interface NuxtHooks extends ModuleHooks {} |
| 70 | + interface RuntimeConfig extends ModuleRuntimeConfig {} |
| 71 | + interface PublicRuntimeConfig extends ModulePublicRuntimeConfig {} |
| 72 | + } |
| 73 | +
|
| 74 | + declare module 'nuxt/schema' { |
| 75 | + interface NuxtHooks extends ModuleHooks {} |
| 76 | + interface RuntimeConfig extends ModuleRuntimeConfig {} |
| 77 | + interface PublicRuntimeConfig extends ModulePublicRuntimeConfig {} |
| 78 | + } |
| 79 | +
|
| 80 | + export type { ModuleHooks, ModuleOptions, ModulePublicRuntimeConfig, ModuleRuntimeConfig, ModuleRuntimeHooks, default } from './module' |
50 | 81 | " |
51 | | - import type { ModuleOptions, ModuleHooks, ModuleRuntimeHooks, ModuleRuntimeConfig, ModulePublicRuntimeConfig } from './module' |
| 82 | + `) |
| 83 | + }) |
52 | 84 |
|
| 85 | + it('should generate types when no ModuleOptions are exported', async () => { |
| 86 | + const types = await readFile(join(secondDistDir, 'types.d.ts'), 'utf-8') |
| 87 | + expect(types).toMatchInlineSnapshot(` |
| 88 | + "import type { NuxtModule } from '@nuxt/schema' |
| 89 | +
|
| 90 | + import type { default as Module, ModuleHooks, ModuleRuntimeHooks, ModuleRuntimeConfig, ModulePublicRuntimeConfig } from './module' |
53 | 91 |
|
54 | 92 | declare module '#app' { |
55 | 93 | interface RuntimeNuxtHooks extends ModuleRuntimeHooks {} |
56 | 94 | } |
57 | 95 |
|
58 | 96 | declare module '@nuxt/schema' { |
59 | | - interface NuxtConfig { ['myModule']?: Partial<ModuleOptions> } |
60 | | - interface NuxtOptions { ['myModule']?: ModuleOptions } |
61 | 97 | interface NuxtHooks extends ModuleHooks {} |
62 | 98 | interface RuntimeConfig extends ModuleRuntimeConfig {} |
63 | 99 | interface PublicRuntimeConfig extends ModulePublicRuntimeConfig {} |
64 | 100 | } |
65 | 101 |
|
66 | 102 | declare module 'nuxt/schema' { |
67 | | - interface NuxtConfig { ['myModule']?: Partial<ModuleOptions> } |
68 | | - interface NuxtOptions { ['myModule']?: ModuleOptions } |
69 | 103 | interface NuxtHooks extends ModuleHooks {} |
70 | 104 | interface RuntimeConfig extends ModuleRuntimeConfig {} |
71 | 105 | interface PublicRuntimeConfig extends ModulePublicRuntimeConfig {} |
72 | 106 | } |
73 | 107 |
|
| 108 | + export type ModuleOptions = typeof Module extends NuxtModule<infer O> ? Partial<O> : Record<string, any> |
74 | 109 |
|
75 | | - export type { ModuleHooks, ModuleOptions, ModulePublicRuntimeConfig, ModuleRuntimeConfig, ModuleRuntimeHooks, default } from './module' |
| 110 | + export type { ModuleHooks, ModulePublicRuntimeConfig, ModuleRuntimeConfig, ModuleRuntimeHooks, default } from './module' |
76 | 111 | " |
77 | 112 | `) |
78 | 113 | }) |
|
0 commit comments