From fd30cc1e89dc2059499bd5aff43cb7ea40f1b371 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Mon, 22 May 2023 20:44:03 +0100 Subject: [PATCH] test: refactor type tests into a separate fixture (#21007) --- package.json | 4 +- pnpm-lock.yaml | 25 ++++++ test/fixtures/basic-types/.gitignore | 1 + test/fixtures/basic-types/app.config.ts | 6 ++ .../basic-types/components/WithTypes.vue | 28 +++++++ .../basic-types/extends/bar/app.config.ts | 3 + .../basic-types/extends/bar/index.d.ts | 5 ++ .../extends/bar/layouts/override.vue | 6 ++ .../extends/bar/middleware/override.ts | 3 + .../basic-types/extends/bar/nuxt.config.ts | 1 + .../extends/bar/pages/override.vue | 14 ++++ .../node_modules/foo/layouts/default.vue | 6 ++ .../node_modules/foo/layouts/override.vue | 3 + .../node_modules/foo/middleware/foo.ts | 3 + .../node_modules/foo/middleware/override.ts | 3 + .../extends/node_modules/foo/nuxt.config.ts | 3 + .../extends/node_modules/foo/pages/foo.vue | 19 +++++ .../node_modules/foo/pages/override.vue | 3 + .../extends/node_modules/foo/plugins/foo.ts | 7 ++ .../node_modules/foo/server/api/foo.ts | 3 + .../basic-types/layouts/PascalCase.ts | 0 test/fixtures/basic-types/layouts/custom.vue | 6 ++ .../basic-types/middleware/global.global.ts | 7 ++ test/fixtures/basic-types/middleware/named.ts | 3 + .../modules/auto-registered/index.ts | 15 ++++ .../auto-registered/runtime/handler.ts | 1 + test/fixtures/basic-types/modules/example.ts | 23 ++++++ .../basic-types/modules/page-extend.ts | 19 +++++ .../basic-types/modules/runtime/middleware.ts | 4 + .../basic-types/modules/runtime/page.vue | 17 +++++ .../basic-types/modules/runtime/plugin.ts | 4 + .../basic-types/modules/test/index.ts | 7 ++ test/fixtures/basic-types/nuxt.config.ts | 76 +++++++++++++++++++ .../{basic => basic-types}/nuxt.schema.ts | 0 test/fixtures/basic-types/package.json | 16 ++++ test/fixtures/basic-types/pages/page.vue | 5 ++ .../fixtures/basic-types/pages/param/[id].vue | 5 ++ .../fixtures/basic-types/plugins/injection.ts | 7 ++ test/fixtures/basic-types/server/api/hello.ts | 1 + .../basic-types/server/api/hey/index.get.ts | 4 + .../basic-types/server/api/hey/index.post.ts | 3 + test/fixtures/basic-types/server/api/union.ts | 4 + .../fixtures/basic-types/server/tsconfig.json | 3 + test/fixtures/basic-types/tsconfig.json | 3 + test/fixtures/{basic => basic-types}/types.ts | 58 +++++++++----- test/fixtures/basic/modules/example.ts | 4 - test/fixtures/basic/nuxt.config.ts | 40 +--------- test/fixtures/minimal-types/app.vue | 3 + test/fixtures/minimal-types/nuxt.config.ts | 1 + test/fixtures/minimal-types/package.json | 10 +++ test/fixtures/minimal-types/tsconfig.json | 3 + test/fixtures/minimal-types/types.ts | 48 ++++++++++++ 52 files changed, 483 insertions(+), 63 deletions(-) create mode 100644 test/fixtures/basic-types/.gitignore create mode 100644 test/fixtures/basic-types/app.config.ts create mode 100644 test/fixtures/basic-types/components/WithTypes.vue create mode 100644 test/fixtures/basic-types/extends/bar/app.config.ts create mode 100644 test/fixtures/basic-types/extends/bar/index.d.ts create mode 100644 test/fixtures/basic-types/extends/bar/layouts/override.vue create mode 100644 test/fixtures/basic-types/extends/bar/middleware/override.ts create mode 100644 test/fixtures/basic-types/extends/bar/nuxt.config.ts create mode 100644 test/fixtures/basic-types/extends/bar/pages/override.vue create mode 100644 test/fixtures/basic-types/extends/node_modules/foo/layouts/default.vue create mode 100644 test/fixtures/basic-types/extends/node_modules/foo/layouts/override.vue create mode 100644 test/fixtures/basic-types/extends/node_modules/foo/middleware/foo.ts create mode 100644 test/fixtures/basic-types/extends/node_modules/foo/middleware/override.ts create mode 100644 test/fixtures/basic-types/extends/node_modules/foo/nuxt.config.ts create mode 100644 test/fixtures/basic-types/extends/node_modules/foo/pages/foo.vue create mode 100644 test/fixtures/basic-types/extends/node_modules/foo/pages/override.vue create mode 100644 test/fixtures/basic-types/extends/node_modules/foo/plugins/foo.ts create mode 100644 test/fixtures/basic-types/extends/node_modules/foo/server/api/foo.ts create mode 100644 test/fixtures/basic-types/layouts/PascalCase.ts create mode 100644 test/fixtures/basic-types/layouts/custom.vue create mode 100644 test/fixtures/basic-types/middleware/global.global.ts create mode 100644 test/fixtures/basic-types/middleware/named.ts create mode 100644 test/fixtures/basic-types/modules/auto-registered/index.ts create mode 100644 test/fixtures/basic-types/modules/auto-registered/runtime/handler.ts create mode 100644 test/fixtures/basic-types/modules/example.ts create mode 100644 test/fixtures/basic-types/modules/page-extend.ts create mode 100644 test/fixtures/basic-types/modules/runtime/middleware.ts create mode 100644 test/fixtures/basic-types/modules/runtime/page.vue create mode 100644 test/fixtures/basic-types/modules/runtime/plugin.ts create mode 100644 test/fixtures/basic-types/modules/test/index.ts create mode 100644 test/fixtures/basic-types/nuxt.config.ts rename test/fixtures/{basic => basic-types}/nuxt.schema.ts (100%) create mode 100644 test/fixtures/basic-types/package.json create mode 100644 test/fixtures/basic-types/pages/page.vue create mode 100644 test/fixtures/basic-types/pages/param/[id].vue create mode 100644 test/fixtures/basic-types/plugins/injection.ts create mode 100644 test/fixtures/basic-types/server/api/hello.ts create mode 100644 test/fixtures/basic-types/server/api/hey/index.get.ts create mode 100644 test/fixtures/basic-types/server/api/hey/index.post.ts create mode 100644 test/fixtures/basic-types/server/api/union.ts create mode 100644 test/fixtures/basic-types/server/tsconfig.json create mode 100644 test/fixtures/basic-types/tsconfig.json rename test/fixtures/{basic => basic-types}/types.ts (91%) create mode 100644 test/fixtures/minimal-types/app.vue create mode 100644 test/fixtures/minimal-types/nuxt.config.ts create mode 100644 test/fixtures/minimal-types/package.json create mode 100644 test/fixtures/minimal-types/tsconfig.json create mode 100644 test/fixtures/minimal-types/types.ts diff --git a/package.json b/package.json index ebfbf5efab..74d42c6599 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,9 @@ "test:fixtures:payload": "TEST_PAYLOAD=js pnpm test:fixtures", "test:fixtures:dev": "TEST_ENV=dev pnpm test:fixtures", "test:fixtures:webpack": "TEST_BUILDER=webpack pnpm test:fixtures", - "test:types": "nuxi prepare test/fixtures/basic && cd test/fixtures/basic && npx vue-tsc --noEmit", + "test:types": "pnpm test:types:basic && pnpm test:types:minimal", + "test:types:basic": "nuxi prepare test/fixtures/basic-types && cd test/fixtures/basic-types && npx vue-tsc --noEmit", + "test:types:minimal": "nuxi prepare test/fixtures/minimal-types && cd test/fixtures/minimal-types && npx vue-tsc --noEmit", "test:unit": "vitest run --dir packages", "typecheck": "tsc --noEmit" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fa09eef0c3..4df0c06b22 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -913,12 +913,37 @@ importers: specifier: latest version: 4.2.1(vue@3.3.4) + test/fixtures/basic-types: + dependencies: + nuxt: + specifier: workspace:* + version: link:../../../packages/nuxt + devDependencies: + ofetch: + specifier: latest + version: 1.0.1 + unplugin: + specifier: latest + version: 1.3.1 + vitest: + specifier: latest + version: 0.31.1(playwright@1.34.0) + vue-router: + specifier: latest + version: 4.2.1(vue@3.3.4) + test/fixtures/minimal: dependencies: nuxt: specifier: workspace:* version: link:../../../packages/nuxt + test/fixtures/minimal-types: + dependencies: + nuxt: + specifier: workspace:* + version: link:../../../packages/nuxt + test/fixtures/runtime-compiler: dependencies: nuxt: diff --git a/test/fixtures/basic-types/.gitignore b/test/fixtures/basic-types/.gitignore new file mode 100644 index 0000000000..2a0469def7 --- /dev/null +++ b/test/fixtures/basic-types/.gitignore @@ -0,0 +1 @@ +!extends/node_modules diff --git a/test/fixtures/basic-types/app.config.ts b/test/fixtures/basic-types/app.config.ts new file mode 100644 index 0000000000..2bb6b31bd5 --- /dev/null +++ b/test/fixtures/basic-types/app.config.ts @@ -0,0 +1,6 @@ +export default defineAppConfig({ + userConfig: 123, + nested: { + val: 2 + } +}) diff --git a/test/fixtures/basic-types/components/WithTypes.vue b/test/fixtures/basic-types/components/WithTypes.vue new file mode 100644 index 0000000000..c3f4b271fc --- /dev/null +++ b/test/fixtures/basic-types/components/WithTypes.vue @@ -0,0 +1,28 @@ + + + diff --git a/test/fixtures/basic-types/extends/bar/app.config.ts b/test/fixtures/basic-types/extends/bar/app.config.ts new file mode 100644 index 0000000000..92e47a3736 --- /dev/null +++ b/test/fixtures/basic-types/extends/bar/app.config.ts @@ -0,0 +1,3 @@ +export default { + fromLayer: true +} diff --git a/test/fixtures/basic-types/extends/bar/index.d.ts b/test/fixtures/basic-types/extends/bar/index.d.ts new file mode 100644 index 0000000000..3d1121c544 --- /dev/null +++ b/test/fixtures/basic-types/extends/bar/index.d.ts @@ -0,0 +1,5 @@ +declare module 'bing' { + interface BingInterface { + foo: 'bar' + } +} diff --git a/test/fixtures/basic-types/extends/bar/layouts/override.vue b/test/fixtures/basic-types/extends/bar/layouts/override.vue new file mode 100644 index 0000000000..7397c7ad63 --- /dev/null +++ b/test/fixtures/basic-types/extends/bar/layouts/override.vue @@ -0,0 +1,6 @@ + diff --git a/test/fixtures/basic-types/extends/bar/middleware/override.ts b/test/fixtures/basic-types/extends/bar/middleware/override.ts new file mode 100644 index 0000000000..00edf78124 --- /dev/null +++ b/test/fixtures/basic-types/extends/bar/middleware/override.ts @@ -0,0 +1,3 @@ +export default defineNuxtRouteMiddleware((to) => { + to.meta.override = 'Injected by extended middleware from bar' +}) diff --git a/test/fixtures/basic-types/extends/bar/nuxt.config.ts b/test/fixtures/basic-types/extends/bar/nuxt.config.ts new file mode 100644 index 0000000000..268da7f8c1 --- /dev/null +++ b/test/fixtures/basic-types/extends/bar/nuxt.config.ts @@ -0,0 +1 @@ +export default defineNuxtConfig({}) diff --git a/test/fixtures/basic-types/extends/bar/pages/override.vue b/test/fixtures/basic-types/extends/bar/pages/override.vue new file mode 100644 index 0000000000..d104ece7bf --- /dev/null +++ b/test/fixtures/basic-types/extends/bar/pages/override.vue @@ -0,0 +1,14 @@ + + + diff --git a/test/fixtures/basic-types/extends/node_modules/foo/layouts/default.vue b/test/fixtures/basic-types/extends/node_modules/foo/layouts/default.vue new file mode 100644 index 0000000000..1627862189 --- /dev/null +++ b/test/fixtures/basic-types/extends/node_modules/foo/layouts/default.vue @@ -0,0 +1,6 @@ + diff --git a/test/fixtures/basic-types/extends/node_modules/foo/layouts/override.vue b/test/fixtures/basic-types/extends/node_modules/foo/layouts/override.vue new file mode 100644 index 0000000000..b10cfadd9a --- /dev/null +++ b/test/fixtures/basic-types/extends/node_modules/foo/layouts/override.vue @@ -0,0 +1,3 @@ + diff --git a/test/fixtures/basic-types/extends/node_modules/foo/middleware/foo.ts b/test/fixtures/basic-types/extends/node_modules/foo/middleware/foo.ts new file mode 100644 index 0000000000..53963c7703 --- /dev/null +++ b/test/fixtures/basic-types/extends/node_modules/foo/middleware/foo.ts @@ -0,0 +1,3 @@ +export default defineNuxtRouteMiddleware((to) => { + to.meta.foo = 'Injected by extended middleware from foo' +}) diff --git a/test/fixtures/basic-types/extends/node_modules/foo/middleware/override.ts b/test/fixtures/basic-types/extends/node_modules/foo/middleware/override.ts new file mode 100644 index 0000000000..fbbfd73091 --- /dev/null +++ b/test/fixtures/basic-types/extends/node_modules/foo/middleware/override.ts @@ -0,0 +1,3 @@ +export default defineNuxtRouteMiddleware((to) => { + to.meta.override = 'This middleware should be overriden by bar' +}) diff --git a/test/fixtures/basic-types/extends/node_modules/foo/nuxt.config.ts b/test/fixtures/basic-types/extends/node_modules/foo/nuxt.config.ts new file mode 100644 index 0000000000..f716d9f9da --- /dev/null +++ b/test/fixtures/basic-types/extends/node_modules/foo/nuxt.config.ts @@ -0,0 +1,3 @@ +import { defineNuxtConfig } from 'nuxt/config' + +export default defineNuxtConfig({}) diff --git a/test/fixtures/basic-types/extends/node_modules/foo/pages/foo.vue b/test/fixtures/basic-types/extends/node_modules/foo/pages/foo.vue new file mode 100644 index 0000000000..9599ea6eac --- /dev/null +++ b/test/fixtures/basic-types/extends/node_modules/foo/pages/foo.vue @@ -0,0 +1,19 @@ + + + diff --git a/test/fixtures/basic-types/extends/node_modules/foo/pages/override.vue b/test/fixtures/basic-types/extends/node_modules/foo/pages/override.vue new file mode 100644 index 0000000000..81a97ed0f2 --- /dev/null +++ b/test/fixtures/basic-types/extends/node_modules/foo/pages/override.vue @@ -0,0 +1,3 @@ + diff --git a/test/fixtures/basic-types/extends/node_modules/foo/plugins/foo.ts b/test/fixtures/basic-types/extends/node_modules/foo/plugins/foo.ts new file mode 100644 index 0000000000..23534da003 --- /dev/null +++ b/test/fixtures/basic-types/extends/node_modules/foo/plugins/foo.ts @@ -0,0 +1,7 @@ +export default defineNuxtPlugin(() => { + return { + provide: { + foo: () => 'String generated from foo plugin!' + } + } +}) diff --git a/test/fixtures/basic-types/extends/node_modules/foo/server/api/foo.ts b/test/fixtures/basic-types/extends/node_modules/foo/server/api/foo.ts new file mode 100644 index 0000000000..4529f02639 --- /dev/null +++ b/test/fixtures/basic-types/extends/node_modules/foo/server/api/foo.ts @@ -0,0 +1,3 @@ +import { eventHandler } from 'h3' + +export default eventHandler(() => 'foo') diff --git a/test/fixtures/basic-types/layouts/PascalCase.ts b/test/fixtures/basic-types/layouts/PascalCase.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/fixtures/basic-types/layouts/custom.vue b/test/fixtures/basic-types/layouts/custom.vue new file mode 100644 index 0000000000..e7938d8f69 --- /dev/null +++ b/test/fixtures/basic-types/layouts/custom.vue @@ -0,0 +1,6 @@ + diff --git a/test/fixtures/basic-types/middleware/global.global.ts b/test/fixtures/basic-types/middleware/global.global.ts new file mode 100644 index 0000000000..efc4f51753 --- /dev/null +++ b/test/fixtures/basic-types/middleware/global.global.ts @@ -0,0 +1,7 @@ +export default defineNuxtRouteMiddleware((to) => { + if ('abort' in to.query) { + return abortNavigation({ + statusCode: 401 + }) + } +}) diff --git a/test/fixtures/basic-types/middleware/named.ts b/test/fixtures/basic-types/middleware/named.ts new file mode 100644 index 0000000000..30801347ae --- /dev/null +++ b/test/fixtures/basic-types/middleware/named.ts @@ -0,0 +1,3 @@ +export default defineNuxtRouteMiddleware((to) => { + to.meta.auth = 'Injected by injectAuth middleware' +}) diff --git a/test/fixtures/basic-types/modules/auto-registered/index.ts b/test/fixtures/basic-types/modules/auto-registered/index.ts new file mode 100644 index 0000000000..60406e1126 --- /dev/null +++ b/test/fixtures/basic-types/modules/auto-registered/index.ts @@ -0,0 +1,15 @@ +import { addServerHandler, createResolver, defineNuxtModule } from 'nuxt/kit' + +export default defineNuxtModule({ + meta: { + name: 'auto-registered-module' + }, + setup () { + const resolver = createResolver(import.meta.url) + + addServerHandler({ + handler: resolver.resolve('./runtime/handler'), + route: '/auto-registered-module' + }) + } +}) diff --git a/test/fixtures/basic-types/modules/auto-registered/runtime/handler.ts b/test/fixtures/basic-types/modules/auto-registered/runtime/handler.ts new file mode 100644 index 0000000000..563d40e0b9 --- /dev/null +++ b/test/fixtures/basic-types/modules/auto-registered/runtime/handler.ts @@ -0,0 +1 @@ +export default defineEventHandler(() => 'handler added by auto-registered module') diff --git a/test/fixtures/basic-types/modules/example.ts b/test/fixtures/basic-types/modules/example.ts new file mode 100644 index 0000000000..94365f629f --- /dev/null +++ b/test/fixtures/basic-types/modules/example.ts @@ -0,0 +1,23 @@ +import { addPlugin, createResolver, defineNuxtModule, useNuxt } from 'nuxt/kit' + +export default defineNuxtModule({ + defaults: { + enabled: true, + typeTest: (value: boolean) => typeof value === 'boolean' + }, + meta: { + name: 'my-module', + configKey: 'sampleModule' + }, + setup () { + const resolver = createResolver(import.meta.url) + + addPlugin(resolver.resolve('./runtime/plugin')) + useNuxt().hook('app:resolve', (app) => { + app.middleware.push({ + name: 'unctx-test', + path: resolver.resolve('./runtime/middleware') + }) + }) + } +}) diff --git a/test/fixtures/basic-types/modules/page-extend.ts b/test/fixtures/basic-types/modules/page-extend.ts new file mode 100644 index 0000000000..1f794eeee6 --- /dev/null +++ b/test/fixtures/basic-types/modules/page-extend.ts @@ -0,0 +1,19 @@ +import { createResolver, defineNuxtModule, useNuxt } from 'nuxt/kit' + +export default defineNuxtModule({ + meta: { + name: 'page-extend' + }, + setup () { + const nuxt = useNuxt() + const resolver = createResolver(import.meta.url) + + nuxt.hook('pages:extend', (pages) => { + pages.push({ + name: 'page-extend', + path: '/page-extend', + file: resolver.resolve('./runtime/page.vue') + }) + }) + } +}) diff --git a/test/fixtures/basic-types/modules/runtime/middleware.ts b/test/fixtures/basic-types/modules/runtime/middleware.ts new file mode 100644 index 0000000000..7ddcb23d82 --- /dev/null +++ b/test/fixtures/basic-types/modules/runtime/middleware.ts @@ -0,0 +1,4 @@ +export default defineNuxtRouteMiddleware(async () => { + await new Promise(resolve => setTimeout(resolve, 1)) + useNuxtApp() +}) diff --git a/test/fixtures/basic-types/modules/runtime/page.vue b/test/fixtures/basic-types/modules/runtime/page.vue new file mode 100644 index 0000000000..5174b019cb --- /dev/null +++ b/test/fixtures/basic-types/modules/runtime/page.vue @@ -0,0 +1,17 @@ + + + diff --git a/test/fixtures/basic-types/modules/runtime/plugin.ts b/test/fixtures/basic-types/modules/runtime/plugin.ts new file mode 100644 index 0000000000..61a24ed6d2 --- /dev/null +++ b/test/fixtures/basic-types/modules/runtime/plugin.ts @@ -0,0 +1,4 @@ +export default defineNuxtPlugin(async () => { + await new Promise(resolve => setTimeout(resolve, 1)) + useNuxtApp() +}) diff --git a/test/fixtures/basic-types/modules/test/index.ts b/test/fixtures/basic-types/modules/test/index.ts new file mode 100644 index 0000000000..b3c385cda4 --- /dev/null +++ b/test/fixtures/basic-types/modules/test/index.ts @@ -0,0 +1,7 @@ +import { defineNuxtModule } from 'nuxt/kit' + +export default defineNuxtModule({ + meta: { + name: 'test' + } +}) diff --git a/test/fixtures/basic-types/nuxt.config.ts b/test/fixtures/basic-types/nuxt.config.ts new file mode 100644 index 0000000000..164fdd0fcc --- /dev/null +++ b/test/fixtures/basic-types/nuxt.config.ts @@ -0,0 +1,76 @@ +export default defineNuxtConfig({ + experimental: { + typedPages: true + }, + typescript: { + strict: true, + tsConfig: { + compilerOptions: { + moduleResolution: process.env.MODULE_RESOLUTION + } + } + }, + buildDir: process.env.NITRO_BUILD_DIR, + builder: process.env.TEST_BUILDER as 'webpack' | 'vite' ?? 'vite', + theme: './extends/bar', + extends: [ + './extends/node_modules/foo' + ], + runtimeConfig: { + baseURL: '', + baseAPIToken: '', + privateConfig: 'secret_key', + public: { + ids: [1, 2, 3], + needsFallback: undefined, + testConfig: 123 + } + }, + appConfig: { + fromNuxtConfig: true, + nested: { + val: 1 + } + }, + modules: [ + './modules/test', + [ + '~/modules/example', + { + typeTest (val) { + // @ts-expect-error module type defines val as boolean + const b: string = val + return !!b + } + } + ], + function (_options, nuxt) { + nuxt.hook('pages:extend', (pages) => { + pages.push({ + name: 'internal-async-parent', + path: '/internal-async-parent' + }) + }) + } + ], + telemetry: false, // for testing telemetry types - it is auto-disabled in tests + hooks: { + 'schema:extend' (schemas) { + schemas.push({ + appConfig: { + someThing: { + value: { + $default: 'default', + $schema: { + tsType: 'string | false' + } + } + } + } + }) + }, + 'prepare:types' ({ tsConfig }) { + tsConfig.include = tsConfig.include!.filter(i => i !== '../../../../**/*') + } + } +}) diff --git a/test/fixtures/basic/nuxt.schema.ts b/test/fixtures/basic-types/nuxt.schema.ts similarity index 100% rename from test/fixtures/basic/nuxt.schema.ts rename to test/fixtures/basic-types/nuxt.schema.ts diff --git a/test/fixtures/basic-types/package.json b/test/fixtures/basic-types/package.json new file mode 100644 index 0000000000..aa52bcae27 --- /dev/null +++ b/test/fixtures/basic-types/package.json @@ -0,0 +1,16 @@ +{ + "private": true, + "name": "fixture-basic-types", + "scripts": { + "build": "nuxi build" + }, + "dependencies": { + "nuxt": "workspace:*" + }, + "devDependencies": { + "ofetch": "latest", + "unplugin": "latest", + "vitest": "latest", + "vue-router": "latest" + } +} diff --git a/test/fixtures/basic-types/pages/page.vue b/test/fixtures/basic-types/pages/page.vue new file mode 100644 index 0000000000..41b642051a --- /dev/null +++ b/test/fixtures/basic-types/pages/page.vue @@ -0,0 +1,5 @@ + diff --git a/test/fixtures/basic-types/pages/param/[id].vue b/test/fixtures/basic-types/pages/param/[id].vue new file mode 100644 index 0000000000..41b642051a --- /dev/null +++ b/test/fixtures/basic-types/pages/param/[id].vue @@ -0,0 +1,5 @@ + diff --git a/test/fixtures/basic-types/plugins/injection.ts b/test/fixtures/basic-types/plugins/injection.ts new file mode 100644 index 0000000000..70726e2ade --- /dev/null +++ b/test/fixtures/basic-types/plugins/injection.ts @@ -0,0 +1,7 @@ +export default defineNuxtPlugin(() => { + return { + provide: { + pluginInjection: () => '' + } + } +}) diff --git a/test/fixtures/basic-types/server/api/hello.ts b/test/fixtures/basic-types/server/api/hello.ts new file mode 100644 index 0000000000..569613d6f7 --- /dev/null +++ b/test/fixtures/basic-types/server/api/hello.ts @@ -0,0 +1 @@ +export default defineEventHandler(() => 'Hello API') diff --git a/test/fixtures/basic-types/server/api/hey/index.get.ts b/test/fixtures/basic-types/server/api/hey/index.get.ts new file mode 100644 index 0000000000..7ae4e47bf9 --- /dev/null +++ b/test/fixtures/basic-types/server/api/hey/index.get.ts @@ -0,0 +1,4 @@ +export default defineEventHandler(() => ({ + foo: 'bar', + baz: 'qux' +})) diff --git a/test/fixtures/basic-types/server/api/hey/index.post.ts b/test/fixtures/basic-types/server/api/hey/index.post.ts new file mode 100644 index 0000000000..b09599aed3 --- /dev/null +++ b/test/fixtures/basic-types/server/api/hey/index.post.ts @@ -0,0 +1,3 @@ +export default defineEventHandler(() => ({ + method: 'post' as const +})) diff --git a/test/fixtures/basic-types/server/api/union.ts b/test/fixtures/basic-types/server/api/union.ts new file mode 100644 index 0000000000..9358a00ecc --- /dev/null +++ b/test/fixtures/basic-types/server/api/union.ts @@ -0,0 +1,4 @@ +export default defineEventHandler(() => ({ + type: 'a', + foo: 'bar' +}) as { type: 'a', foo: string } | { type: 'b', baz: string }) diff --git a/test/fixtures/basic-types/server/tsconfig.json b/test/fixtures/basic-types/server/tsconfig.json new file mode 100644 index 0000000000..b9ed69c19e --- /dev/null +++ b/test/fixtures/basic-types/server/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../.nuxt/tsconfig.server.json" +} diff --git a/test/fixtures/basic-types/tsconfig.json b/test/fixtures/basic-types/tsconfig.json new file mode 100644 index 0000000000..4b34df1571 --- /dev/null +++ b/test/fixtures/basic-types/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "./.nuxt/tsconfig.json" +} diff --git a/test/fixtures/basic/types.ts b/test/fixtures/basic-types/types.ts similarity index 91% rename from test/fixtures/basic/types.ts rename to test/fixtures/basic-types/types.ts index cd3b1386dd..8714207a83 100644 --- a/test/fixtures/basic/types.ts +++ b/test/fixtures/basic-types/types.ts @@ -7,7 +7,7 @@ import type { AppConfig, RuntimeValue } from 'nuxt/schema' import { defineNuxtConfig } from 'nuxt/config' import { callWithNuxt, isVue3 } from '#app' import type { NavigateToOptions } from '#app/composables/router' -import { NuxtLink, NuxtPage } from '#components' +import { NuxtLink, NuxtPage, WithTypes } from '#components' import { useRouter } from '#imports' interface TestResponse { message: string } @@ -15,6 +15,10 @@ interface TestResponse { message: string } describe('API routes', () => { it('generates types for routes', () => { expectTypeOf($fetch('/api/hello')).toEqualTypeOf>() + // registered in extends + expectTypeOf($fetch('/api/foo')).toEqualTypeOf>() + // registered in module + expectTypeOf($fetch('/auto-registered-module')).toEqualTypeOf>() expectTypeOf($fetch('/api/hey')).toEqualTypeOf>() expectTypeOf($fetch('/api/hey', { method: 'get' })).toEqualTypeOf>() expectTypeOf($fetch('/api/hey', { method: 'post' })).toEqualTypeOf>() @@ -90,11 +94,14 @@ describe('aliases', () => { describe('middleware', () => { it('recognizes named middleware', () => { - definePageMeta({ middleware: 'inject-auth' }) + definePageMeta({ middleware: 'named' }) + // provided by layer + definePageMeta({ middleware: 'override' }) + definePageMeta({ middleware: 'foo' }) // @ts-expect-error ignore global middleware - definePageMeta({ middleware: 'redirect' }) + definePageMeta({ middleware: 'global' }) // @ts-expect-error Invalid middleware - definePageMeta({ middleware: 'invalid-middleware' }) + definePageMeta({ middleware: 'nonexistent' }) }) it('handles adding middleware', () => { addRouteMiddleware('example', (to, from) => { @@ -117,14 +124,14 @@ describe('typed router integration', () => { // @ts-expect-error this named route does not exist router.push({ name: 'some-thing' }) // this one does - router.push({ name: 'fixed-keyed-child-parent' }) + router.push({ name: 'page' }) // @ts-expect-error this is an invalid param - router.push({ name: 'random-id', params: { bob: 23 } }) - router.push({ name: 'random-id', params: { id: 4 } }) + router.push({ name: 'param-id', params: { bob: 23 } }) + router.push({ name: 'param-id', params: { id: 4 } }) }) it('allows typing useRoute', () => { - const route = useRoute('random-id') + const route = useRoute('param-id') // @ts-expect-error this param does not exist const _invalid = route.params.something // this param does @@ -135,36 +142,40 @@ describe('typed router integration', () => { // @ts-expect-error this named route does not exist navigateTo({ name: 'some-thing' }) // this one does - navigateTo({ name: 'fixed-keyed-child-parent' }) + navigateTo({ name: 'page' }) // @ts-expect-error this is an invalid param - navigateTo({ name: 'random-id', params: { bob: 23 } }) - navigateTo({ name: 'random-id', params: { id: 4 } }) + navigateTo({ name: 'param-id', params: { bob: 23 } }) + navigateTo({ name: 'param-id', params: { id: 4 } }) }) it('allows typing middleware', () => { defineNuxtRouteMiddleware((to) => { expectTypeOf(to.name).not.toBeAny() // @ts-expect-error this route does not exist - expectTypeOf(to.name === 'bob').toMatchTypeOf() - expectTypeOf(to.name === 'assets').toMatchTypeOf() + expectTypeOf(to.name === 'bob').toEqualTypeOf() + expectTypeOf(to.name === 'page').toEqualTypeOf() }) }) it('respects pages:extend augmentation', () => { // added via pages:extend - expectTypeOf(useRoute().name === 'internal-async-parent').toMatchTypeOf() + expectTypeOf(useRoute().name === 'internal-async-parent').toEqualTypeOf() // @ts-expect-error this route does not exist - expectTypeOf(useRoute().name === 'invalid').toMatchTypeOf() + expectTypeOf(useRoute().name === 'invalid').toEqualTypeOf() + }) + + it('respects pages added via layer', () => { + expectTypeOf(useRoute().name === 'override').toEqualTypeOf() }) it('allows typing NuxtLink', () => { // @ts-expect-error this named route does not exist h(NuxtLink, { to: { name: 'some-thing' } }) // this one does - h(NuxtLink, { to: { name: 'fixed-keyed-child-parent' } }) + h(NuxtLink, { to: { name: 'page' } }) // @ts-expect-error this is an invalid param - h(NuxtLink, { to: { name: 'random-id', params: { bob: 23 } } }) - h(NuxtLink, { to: { name: 'random-id', params: { id: 4 } } }) + h(NuxtLink, { to: { name: 'param-id', params: { bob: 23 } } }) + h(NuxtLink, { to: { name: 'param-id', params: { id: 4 } } }) }) }) @@ -172,6 +183,7 @@ describe('layouts', () => { it('recognizes named layouts', () => { definePageMeta({ layout: 'custom' }) definePageMeta({ layout: 'pascal-case' }) + definePageMeta({ layout: 'override' }) // @ts-expect-error Invalid layout definePageMeta({ layout: 'invalid-layout' }) }) @@ -189,7 +201,8 @@ describe('modules', () => { describe('nuxtApp', () => { it('types injections provided by plugins', () => { - expectTypeOf(useNuxtApp().$asyncPlugin).toEqualTypeOf<() => string>() + expectTypeOf(useNuxtApp().$pluginInjection).toEqualTypeOf<() => ''>() + expectTypeOf(useNuxtApp().$foo).toEqualTypeOf<() => 'String generated from foo plugin!'>() expectTypeOf(useNuxtApp().$router).toEqualTypeOf() }) it('marks unknown injections as unknown', () => { @@ -264,6 +277,13 @@ describe('components', () => { it('includes types for NuxtPage', () => { expectTypeOf(NuxtPage).not.toBeAny() }) + it('includes types for other components', () => { + h(WithTypes) + // @ts-expect-error wrong prop type for this component + h(WithTypes, { aProp: '40' }) + + // TODO: assert typed slots, exposed, generics, etc. + }) }) describe('composables', () => { diff --git a/test/fixtures/basic/modules/example.ts b/test/fixtures/basic/modules/example.ts index 7b770f65f0..861b7726c5 100644 --- a/test/fixtures/basic/modules/example.ts +++ b/test/fixtures/basic/modules/example.ts @@ -1,10 +1,6 @@ import { addPlugin, createResolver, defineNuxtModule, useNuxt } from 'nuxt/kit' export default defineNuxtModule({ - defaults: { - enabled: true, - typeTest: (value: boolean) => typeof value === 'boolean' - }, meta: { name: 'my-module', configKey: 'sampleModule' diff --git a/test/fixtures/basic/nuxt.config.ts b/test/fixtures/basic/nuxt.config.ts index c4b074af61..a00baee16b 100644 --- a/test/fixtures/basic/nuxt.config.ts +++ b/test/fixtures/basic/nuxt.config.ts @@ -11,14 +11,6 @@ declare module 'nitropack' { } export default defineNuxtConfig({ - typescript: { - strict: true, - tsConfig: { - compilerOptions: { - moduleResolution: process.env.MODULE_RESOLUTION - } - } - }, app: { pageTransition: true, layoutTransition: true, @@ -70,27 +62,14 @@ export default defineNuxtConfig({ ] }, runtimeConfig: { - baseURL: '', - baseAPIToken: '', - privateConfig: 'secret_key', public: { - ids: [1, 2, 3], needsFallback: undefined, testConfig: 123 } }, modules: [ './modules/test', - [ - '~/modules/example', - { - typeTest (val) { - // @ts-expect-error module type defines val as boolean - const b: string = val - return !!b - } - } - ], + '~/modules/example', function (_, nuxt) { if (typeof nuxt.options.builder === 'string' && nuxt.options.builder.includes('webpack')) { return } @@ -143,23 +122,6 @@ export default defineNuxtConfig({ }, telemetry: false, // for testing telemetry types - it is auto-disabled in tests hooks: { - 'schema:extend' (schemas) { - schemas.push({ - appConfig: { - someThing: { - value: { - $default: 'default', - $schema: { - tsType: 'string | false' - } - } - } - } - }) - }, - 'prepare:types' ({ tsConfig }) { - tsConfig.include = tsConfig.include!.filter(i => i !== '../../../../**/*') - }, 'modules:done' () { addComponent({ name: 'CustomComponent', diff --git a/test/fixtures/minimal-types/app.vue b/test/fixtures/minimal-types/app.vue new file mode 100644 index 0000000000..585f495151 --- /dev/null +++ b/test/fixtures/minimal-types/app.vue @@ -0,0 +1,3 @@ + diff --git a/test/fixtures/minimal-types/nuxt.config.ts b/test/fixtures/minimal-types/nuxt.config.ts new file mode 100644 index 0000000000..268da7f8c1 --- /dev/null +++ b/test/fixtures/minimal-types/nuxt.config.ts @@ -0,0 +1 @@ +export default defineNuxtConfig({}) diff --git a/test/fixtures/minimal-types/package.json b/test/fixtures/minimal-types/package.json new file mode 100644 index 0000000000..bcba9c9e14 --- /dev/null +++ b/test/fixtures/minimal-types/package.json @@ -0,0 +1,10 @@ +{ + "private": true, + "name": "fixture-minimal-types", + "scripts": { + "build": "nuxi build" + }, + "dependencies": { + "nuxt": "workspace:*" + } +} diff --git a/test/fixtures/minimal-types/tsconfig.json b/test/fixtures/minimal-types/tsconfig.json new file mode 100644 index 0000000000..4b34df1571 --- /dev/null +++ b/test/fixtures/minimal-types/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "./.nuxt/tsconfig.json" +} diff --git a/test/fixtures/minimal-types/types.ts b/test/fixtures/minimal-types/types.ts new file mode 100644 index 0000000000..fd39ed7c5a --- /dev/null +++ b/test/fixtures/minimal-types/types.ts @@ -0,0 +1,48 @@ +import { describe, expectTypeOf, it } from 'vitest' + +describe('routing utilities', () => { + it('allows using route composables', () => { + const router = useRouter() + router.push('/test') + + expectTypeOf(useRouter()).not.toBeAny() + expectTypeOf(useRoute()).not.toBeAny() + + navigateTo('/thing') + }) +}) + +describe('auto-imports', () => { + it('defineNuxtConfig', () => { + defineNuxtConfig({ + modules: [], + // @ts-expect-error Should show error on unknown properties + unknownProp: '' + }) + }) + it('core composables', () => { + ref() + useHead({ + script: [], + // @ts-expect-error Should show error on unknown properties + unknown: [] + }) + }) +}) + +describe('config typings', () => { + it('runtimeConfig', () => { + expectTypeOf(useRuntimeConfig()).toMatchTypeOf<{ + app: { + baseURL: string + buildAssetsDir: string + cdnURL: string + } + public: Record + }>() + }) + + it('appConfig', () => { + expectTypeOf(useAppConfig()).toEqualTypeOf<{ [key: string]: unknown }>() + }) +})