|
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