mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 13:45:18 +00:00
test: refactor type tests into a separate fixture (#21007)
This commit is contained in:
parent
397c54c9db
commit
fd30cc1e89
@ -21,7 +21,9 @@
|
|||||||
"test:fixtures:payload": "TEST_PAYLOAD=js pnpm test:fixtures",
|
"test:fixtures:payload": "TEST_PAYLOAD=js pnpm test:fixtures",
|
||||||
"test:fixtures:dev": "TEST_ENV=dev pnpm test:fixtures",
|
"test:fixtures:dev": "TEST_ENV=dev pnpm test:fixtures",
|
||||||
"test:fixtures:webpack": "TEST_BUILDER=webpack 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",
|
"test:unit": "vitest run --dir packages",
|
||||||
"typecheck": "tsc --noEmit"
|
"typecheck": "tsc --noEmit"
|
||||||
},
|
},
|
||||||
|
@ -913,12 +913,37 @@ importers:
|
|||||||
specifier: latest
|
specifier: latest
|
||||||
version: 4.2.1(vue@3.3.4)
|
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:
|
test/fixtures/minimal:
|
||||||
dependencies:
|
dependencies:
|
||||||
nuxt:
|
nuxt:
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../../packages/nuxt
|
version: link:../../../packages/nuxt
|
||||||
|
|
||||||
|
test/fixtures/minimal-types:
|
||||||
|
dependencies:
|
||||||
|
nuxt:
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../../../packages/nuxt
|
||||||
|
|
||||||
test/fixtures/runtime-compiler:
|
test/fixtures/runtime-compiler:
|
||||||
dependencies:
|
dependencies:
|
||||||
nuxt:
|
nuxt:
|
||||||
|
1
test/fixtures/basic-types/.gitignore
vendored
Normal file
1
test/fixtures/basic-types/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
!extends/node_modules
|
6
test/fixtures/basic-types/app.config.ts
vendored
Normal file
6
test/fixtures/basic-types/app.config.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export default defineAppConfig({
|
||||||
|
userConfig: 123,
|
||||||
|
nested: {
|
||||||
|
val: 2
|
||||||
|
}
|
||||||
|
})
|
28
test/fixtures/basic-types/components/WithTypes.vue
vendored
Normal file
28
test/fixtures/basic-types/components/WithTypes.vue
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
defineProps({
|
||||||
|
aProp: Number
|
||||||
|
})
|
||||||
|
defineSlots<{
|
||||||
|
fallback: { id: string }
|
||||||
|
}>()
|
||||||
|
defineExpose<{
|
||||||
|
_exposedValue: boolean
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const _exposedValue = 42
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
'some-event': [id: string]
|
||||||
|
}>()
|
||||||
|
emit('some-event', '42')
|
||||||
|
// @ts-expect-error an invalid argument
|
||||||
|
emit('some-event', 42)
|
||||||
|
// @ts-expect-error an unknown event
|
||||||
|
emit('unknown-event', 42)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- -->
|
||||||
|
</div>
|
||||||
|
</template>
|
3
test/fixtures/basic-types/extends/bar/app.config.ts
vendored
Normal file
3
test/fixtures/basic-types/extends/bar/app.config.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default {
|
||||||
|
fromLayer: true
|
||||||
|
}
|
5
test/fixtures/basic-types/extends/bar/index.d.ts
vendored
Normal file
5
test/fixtures/basic-types/extends/bar/index.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
declare module 'bing' {
|
||||||
|
interface BingInterface {
|
||||||
|
foo: 'bar'
|
||||||
|
}
|
||||||
|
}
|
6
test/fixtures/basic-types/extends/bar/layouts/override.vue
vendored
Normal file
6
test/fixtures/basic-types/extends/bar/layouts/override.vue
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div>Extended layout from bar</div>
|
||||||
|
<NuxtPage />
|
||||||
|
</div>
|
||||||
|
</template>
|
3
test/fixtures/basic-types/extends/bar/middleware/override.ts
vendored
Normal file
3
test/fixtures/basic-types/extends/bar/middleware/override.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default defineNuxtRouteMiddleware((to) => {
|
||||||
|
to.meta.override = 'Injected by extended middleware from bar'
|
||||||
|
})
|
1
test/fixtures/basic-types/extends/bar/nuxt.config.ts
vendored
Normal file
1
test/fixtures/basic-types/extends/bar/nuxt.config.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
export default defineNuxtConfig({})
|
14
test/fixtures/basic-types/extends/bar/pages/override.vue
vendored
Normal file
14
test/fixtures/basic-types/extends/bar/pages/override.vue
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<script setup>
|
||||||
|
definePageMeta({
|
||||||
|
layout: 'override',
|
||||||
|
middleware: 'override'
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div>Extended page from bar</div>
|
||||||
|
<div>Middleware | override: {{ $route.meta.override }}</div>
|
||||||
|
<ExtendsOverride />
|
||||||
|
</div>
|
||||||
|
</template>
|
6
test/fixtures/basic-types/extends/node_modules/foo/layouts/default.vue
generated
vendored
Normal file
6
test/fixtures/basic-types/extends/node_modules/foo/layouts/default.vue
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div>Extended layout from foo</div>
|
||||||
|
<NuxtPage />
|
||||||
|
</div>
|
||||||
|
</template>
|
3
test/fixtures/basic-types/extends/node_modules/foo/layouts/override.vue
generated
vendored
Normal file
3
test/fixtures/basic-types/extends/node_modules/foo/layouts/override.vue
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<template>
|
||||||
|
<div>This layout should be overriden by bar</div>
|
||||||
|
</template>
|
3
test/fixtures/basic-types/extends/node_modules/foo/middleware/foo.ts
generated
vendored
Normal file
3
test/fixtures/basic-types/extends/node_modules/foo/middleware/foo.ts
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default defineNuxtRouteMiddleware((to) => {
|
||||||
|
to.meta.foo = 'Injected by extended middleware from foo'
|
||||||
|
})
|
3
test/fixtures/basic-types/extends/node_modules/foo/middleware/override.ts
generated
vendored
Normal file
3
test/fixtures/basic-types/extends/node_modules/foo/middleware/override.ts
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default defineNuxtRouteMiddleware((to) => {
|
||||||
|
to.meta.override = 'This middleware should be overriden by bar'
|
||||||
|
})
|
3
test/fixtures/basic-types/extends/node_modules/foo/nuxt.config.ts
generated
vendored
Normal file
3
test/fixtures/basic-types/extends/node_modules/foo/nuxt.config.ts
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { defineNuxtConfig } from 'nuxt/config'
|
||||||
|
|
||||||
|
export default defineNuxtConfig({})
|
19
test/fixtures/basic-types/extends/node_modules/foo/pages/foo.vue
generated
vendored
Normal file
19
test/fixtures/basic-types/extends/node_modules/foo/pages/foo.vue
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<script setup>
|
||||||
|
import { test } from '~/alias/test'
|
||||||
|
definePageMeta({
|
||||||
|
middleware: 'foo'
|
||||||
|
})
|
||||||
|
|
||||||
|
const foo = useExtendsFoo()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div>{{ test }}</div>
|
||||||
|
<div>Extended page from foo</div>
|
||||||
|
<div>Middleware | foo: {{ $route.meta.foo }}</div>
|
||||||
|
<div>Composable | useExtendsFoo: {{ foo }}</div>
|
||||||
|
<div>Plugin | foo: {{ $foo() }}</div>
|
||||||
|
<ExtendsFoo />
|
||||||
|
</div>
|
||||||
|
</template>
|
3
test/fixtures/basic-types/extends/node_modules/foo/pages/override.vue
generated
vendored
Normal file
3
test/fixtures/basic-types/extends/node_modules/foo/pages/override.vue
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<template>
|
||||||
|
<div>This page should be overriden by bar</div>
|
||||||
|
</template>
|
7
test/fixtures/basic-types/extends/node_modules/foo/plugins/foo.ts
generated
vendored
Normal file
7
test/fixtures/basic-types/extends/node_modules/foo/plugins/foo.ts
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export default defineNuxtPlugin(() => {
|
||||||
|
return {
|
||||||
|
provide: {
|
||||||
|
foo: () => 'String generated from foo plugin!'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
3
test/fixtures/basic-types/extends/node_modules/foo/server/api/foo.ts
generated
vendored
Normal file
3
test/fixtures/basic-types/extends/node_modules/foo/server/api/foo.ts
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { eventHandler } from 'h3'
|
||||||
|
|
||||||
|
export default eventHandler(() => 'foo')
|
0
test/fixtures/basic-types/layouts/PascalCase.ts
vendored
Normal file
0
test/fixtures/basic-types/layouts/PascalCase.ts
vendored
Normal file
6
test/fixtures/basic-types/layouts/custom.vue
vendored
Normal file
6
test/fixtures/basic-types/layouts/custom.vue
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
Custom Layout:
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
7
test/fixtures/basic-types/middleware/global.global.ts
vendored
Normal file
7
test/fixtures/basic-types/middleware/global.global.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export default defineNuxtRouteMiddleware((to) => {
|
||||||
|
if ('abort' in to.query) {
|
||||||
|
return abortNavigation({
|
||||||
|
statusCode: 401
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
3
test/fixtures/basic-types/middleware/named.ts
vendored
Normal file
3
test/fixtures/basic-types/middleware/named.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default defineNuxtRouteMiddleware((to) => {
|
||||||
|
to.meta.auth = 'Injected by injectAuth middleware'
|
||||||
|
})
|
15
test/fixtures/basic-types/modules/auto-registered/index.ts
vendored
Normal file
15
test/fixtures/basic-types/modules/auto-registered/index.ts
vendored
Normal file
@ -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'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
1
test/fixtures/basic-types/modules/auto-registered/runtime/handler.ts
vendored
Normal file
1
test/fixtures/basic-types/modules/auto-registered/runtime/handler.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
export default defineEventHandler(() => 'handler added by auto-registered module')
|
23
test/fixtures/basic-types/modules/example.ts
vendored
Normal file
23
test/fixtures/basic-types/modules/example.ts
vendored
Normal file
@ -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')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
19
test/fixtures/basic-types/modules/page-extend.ts
vendored
Normal file
19
test/fixtures/basic-types/modules/page-extend.ts
vendored
Normal file
@ -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')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
4
test/fixtures/basic-types/modules/runtime/middleware.ts
vendored
Normal file
4
test/fixtures/basic-types/modules/runtime/middleware.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export default defineNuxtRouteMiddleware(async () => {
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1))
|
||||||
|
useNuxtApp()
|
||||||
|
})
|
17
test/fixtures/basic-types/modules/runtime/page.vue
vendored
Normal file
17
test/fixtures/basic-types/modules/runtime/page.vue
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { setResponseHeader } from 'h3'
|
||||||
|
|
||||||
|
definePageMeta({
|
||||||
|
value: 'added in pages:extend'
|
||||||
|
})
|
||||||
|
|
||||||
|
if (process.server) {
|
||||||
|
setResponseHeader(useRequestEvent(), 'x-extend', useRoute().meta.value as string)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
added in pages:extend
|
||||||
|
</div>
|
||||||
|
</template>
|
4
test/fixtures/basic-types/modules/runtime/plugin.ts
vendored
Normal file
4
test/fixtures/basic-types/modules/runtime/plugin.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export default defineNuxtPlugin(async () => {
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1))
|
||||||
|
useNuxtApp()
|
||||||
|
})
|
7
test/fixtures/basic-types/modules/test/index.ts
vendored
Normal file
7
test/fixtures/basic-types/modules/test/index.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { defineNuxtModule } from 'nuxt/kit'
|
||||||
|
|
||||||
|
export default defineNuxtModule({
|
||||||
|
meta: {
|
||||||
|
name: 'test'
|
||||||
|
}
|
||||||
|
})
|
76
test/fixtures/basic-types/nuxt.config.ts
vendored
Normal file
76
test/fixtures/basic-types/nuxt.config.ts
vendored
Normal file
@ -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 !== '../../../../**/*')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
16
test/fixtures/basic-types/package.json
vendored
Normal file
16
test/fixtures/basic-types/package.json
vendored
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
}
|
5
test/fixtures/basic-types/pages/page.vue
vendored
Normal file
5
test/fixtures/basic-types/pages/page.vue
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- -->
|
||||||
|
</div>
|
||||||
|
</template>
|
5
test/fixtures/basic-types/pages/param/[id].vue
vendored
Normal file
5
test/fixtures/basic-types/pages/param/[id].vue
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- -->
|
||||||
|
</div>
|
||||||
|
</template>
|
7
test/fixtures/basic-types/plugins/injection.ts
vendored
Normal file
7
test/fixtures/basic-types/plugins/injection.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export default defineNuxtPlugin(() => {
|
||||||
|
return {
|
||||||
|
provide: {
|
||||||
|
pluginInjection: () => ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
1
test/fixtures/basic-types/server/api/hello.ts
vendored
Normal file
1
test/fixtures/basic-types/server/api/hello.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
export default defineEventHandler(() => 'Hello API')
|
4
test/fixtures/basic-types/server/api/hey/index.get.ts
vendored
Normal file
4
test/fixtures/basic-types/server/api/hey/index.get.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export default defineEventHandler(() => ({
|
||||||
|
foo: 'bar',
|
||||||
|
baz: 'qux'
|
||||||
|
}))
|
3
test/fixtures/basic-types/server/api/hey/index.post.ts
vendored
Normal file
3
test/fixtures/basic-types/server/api/hey/index.post.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default defineEventHandler(() => ({
|
||||||
|
method: 'post' as const
|
||||||
|
}))
|
4
test/fixtures/basic-types/server/api/union.ts
vendored
Normal file
4
test/fixtures/basic-types/server/api/union.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export default defineEventHandler(() => ({
|
||||||
|
type: 'a',
|
||||||
|
foo: 'bar'
|
||||||
|
}) as { type: 'a', foo: string } | { type: 'b', baz: string })
|
3
test/fixtures/basic-types/server/tsconfig.json
vendored
Normal file
3
test/fixtures/basic-types/server/tsconfig.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"extends": "../.nuxt/tsconfig.server.json"
|
||||||
|
}
|
3
test/fixtures/basic-types/tsconfig.json
vendored
Normal file
3
test/fixtures/basic-types/tsconfig.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"extends": "./.nuxt/tsconfig.json"
|
||||||
|
}
|
@ -7,7 +7,7 @@ import type { AppConfig, RuntimeValue } from 'nuxt/schema'
|
|||||||
import { defineNuxtConfig } from 'nuxt/config'
|
import { defineNuxtConfig } from 'nuxt/config'
|
||||||
import { callWithNuxt, isVue3 } from '#app'
|
import { callWithNuxt, isVue3 } from '#app'
|
||||||
import type { NavigateToOptions } from '#app/composables/router'
|
import type { NavigateToOptions } from '#app/composables/router'
|
||||||
import { NuxtLink, NuxtPage } from '#components'
|
import { NuxtLink, NuxtPage, WithTypes } from '#components'
|
||||||
import { useRouter } from '#imports'
|
import { useRouter } from '#imports'
|
||||||
|
|
||||||
interface TestResponse { message: string }
|
interface TestResponse { message: string }
|
||||||
@ -15,6 +15,10 @@ interface TestResponse { message: string }
|
|||||||
describe('API routes', () => {
|
describe('API routes', () => {
|
||||||
it('generates types for routes', () => {
|
it('generates types for routes', () => {
|
||||||
expectTypeOf($fetch('/api/hello')).toEqualTypeOf<Promise<string>>()
|
expectTypeOf($fetch('/api/hello')).toEqualTypeOf<Promise<string>>()
|
||||||
|
// registered in extends
|
||||||
|
expectTypeOf($fetch('/api/foo')).toEqualTypeOf<Promise<string>>()
|
||||||
|
// registered in module
|
||||||
|
expectTypeOf($fetch('/auto-registered-module')).toEqualTypeOf<Promise<string>>()
|
||||||
expectTypeOf($fetch('/api/hey')).toEqualTypeOf<Promise<{ foo: string, baz: string }>>()
|
expectTypeOf($fetch('/api/hey')).toEqualTypeOf<Promise<{ foo: string, baz: string }>>()
|
||||||
expectTypeOf($fetch('/api/hey', { method: 'get' })).toEqualTypeOf<Promise<{ foo: string, baz: string }>>()
|
expectTypeOf($fetch('/api/hey', { method: 'get' })).toEqualTypeOf<Promise<{ foo: string, baz: string }>>()
|
||||||
expectTypeOf($fetch('/api/hey', { method: 'post' })).toEqualTypeOf<Promise<{ method: 'post' }>>()
|
expectTypeOf($fetch('/api/hey', { method: 'post' })).toEqualTypeOf<Promise<{ method: 'post' }>>()
|
||||||
@ -90,11 +94,14 @@ describe('aliases', () => {
|
|||||||
|
|
||||||
describe('middleware', () => {
|
describe('middleware', () => {
|
||||||
it('recognizes named 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
|
// @ts-expect-error ignore global middleware
|
||||||
definePageMeta({ middleware: 'redirect' })
|
definePageMeta({ middleware: 'global' })
|
||||||
// @ts-expect-error Invalid middleware
|
// @ts-expect-error Invalid middleware
|
||||||
definePageMeta({ middleware: 'invalid-middleware' })
|
definePageMeta({ middleware: 'nonexistent' })
|
||||||
})
|
})
|
||||||
it('handles adding middleware', () => {
|
it('handles adding middleware', () => {
|
||||||
addRouteMiddleware('example', (to, from) => {
|
addRouteMiddleware('example', (to, from) => {
|
||||||
@ -117,14 +124,14 @@ describe('typed router integration', () => {
|
|||||||
// @ts-expect-error this named route does not exist
|
// @ts-expect-error this named route does not exist
|
||||||
router.push({ name: 'some-thing' })
|
router.push({ name: 'some-thing' })
|
||||||
// this one does
|
// this one does
|
||||||
router.push({ name: 'fixed-keyed-child-parent' })
|
router.push({ name: 'page' })
|
||||||
// @ts-expect-error this is an invalid param
|
// @ts-expect-error this is an invalid param
|
||||||
router.push({ name: 'random-id', params: { bob: 23 } })
|
router.push({ name: 'param-id', params: { bob: 23 } })
|
||||||
router.push({ name: 'random-id', params: { id: 4 } })
|
router.push({ name: 'param-id', params: { id: 4 } })
|
||||||
})
|
})
|
||||||
|
|
||||||
it('allows typing useRoute', () => {
|
it('allows typing useRoute', () => {
|
||||||
const route = useRoute('random-id')
|
const route = useRoute('param-id')
|
||||||
// @ts-expect-error this param does not exist
|
// @ts-expect-error this param does not exist
|
||||||
const _invalid = route.params.something
|
const _invalid = route.params.something
|
||||||
// this param does
|
// this param does
|
||||||
@ -135,36 +142,40 @@ describe('typed router integration', () => {
|
|||||||
// @ts-expect-error this named route does not exist
|
// @ts-expect-error this named route does not exist
|
||||||
navigateTo({ name: 'some-thing' })
|
navigateTo({ name: 'some-thing' })
|
||||||
// this one does
|
// this one does
|
||||||
navigateTo({ name: 'fixed-keyed-child-parent' })
|
navigateTo({ name: 'page' })
|
||||||
// @ts-expect-error this is an invalid param
|
// @ts-expect-error this is an invalid param
|
||||||
navigateTo({ name: 'random-id', params: { bob: 23 } })
|
navigateTo({ name: 'param-id', params: { bob: 23 } })
|
||||||
navigateTo({ name: 'random-id', params: { id: 4 } })
|
navigateTo({ name: 'param-id', params: { id: 4 } })
|
||||||
})
|
})
|
||||||
|
|
||||||
it('allows typing middleware', () => {
|
it('allows typing middleware', () => {
|
||||||
defineNuxtRouteMiddleware((to) => {
|
defineNuxtRouteMiddleware((to) => {
|
||||||
expectTypeOf(to.name).not.toBeAny()
|
expectTypeOf(to.name).not.toBeAny()
|
||||||
// @ts-expect-error this route does not exist
|
// @ts-expect-error this route does not exist
|
||||||
expectTypeOf(to.name === 'bob').toMatchTypeOf<boolean>()
|
expectTypeOf(to.name === 'bob').toEqualTypeOf<boolean>()
|
||||||
expectTypeOf(to.name === 'assets').toMatchTypeOf<boolean>()
|
expectTypeOf(to.name === 'page').toEqualTypeOf<boolean>()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('respects pages:extend augmentation', () => {
|
it('respects pages:extend augmentation', () => {
|
||||||
// added via pages:extend
|
// added via pages:extend
|
||||||
expectTypeOf(useRoute().name === 'internal-async-parent').toMatchTypeOf<boolean>()
|
expectTypeOf(useRoute().name === 'internal-async-parent').toEqualTypeOf<boolean>()
|
||||||
// @ts-expect-error this route does not exist
|
// @ts-expect-error this route does not exist
|
||||||
expectTypeOf(useRoute().name === 'invalid').toMatchTypeOf<boolean>()
|
expectTypeOf(useRoute().name === 'invalid').toEqualTypeOf<boolean>()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('respects pages added via layer', () => {
|
||||||
|
expectTypeOf(useRoute().name === 'override').toEqualTypeOf<boolean>()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('allows typing NuxtLink', () => {
|
it('allows typing NuxtLink', () => {
|
||||||
// @ts-expect-error this named route does not exist
|
// @ts-expect-error this named route does not exist
|
||||||
h(NuxtLink, { to: { name: 'some-thing' } })
|
h(NuxtLink, { to: { name: 'some-thing' } })
|
||||||
// this one does
|
// this one does
|
||||||
h(NuxtLink, { to: { name: 'fixed-keyed-child-parent' } })
|
h(NuxtLink, { to: { name: 'page' } })
|
||||||
// @ts-expect-error this is an invalid param
|
// @ts-expect-error this is an invalid param
|
||||||
h(NuxtLink, { to: { name: 'random-id', params: { bob: 23 } } })
|
h(NuxtLink, { to: { name: 'param-id', params: { bob: 23 } } })
|
||||||
h(NuxtLink, { to: { name: 'random-id', params: { id: 4 } } })
|
h(NuxtLink, { to: { name: 'param-id', params: { id: 4 } } })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -172,6 +183,7 @@ describe('layouts', () => {
|
|||||||
it('recognizes named layouts', () => {
|
it('recognizes named layouts', () => {
|
||||||
definePageMeta({ layout: 'custom' })
|
definePageMeta({ layout: 'custom' })
|
||||||
definePageMeta({ layout: 'pascal-case' })
|
definePageMeta({ layout: 'pascal-case' })
|
||||||
|
definePageMeta({ layout: 'override' })
|
||||||
// @ts-expect-error Invalid layout
|
// @ts-expect-error Invalid layout
|
||||||
definePageMeta({ layout: 'invalid-layout' })
|
definePageMeta({ layout: 'invalid-layout' })
|
||||||
})
|
})
|
||||||
@ -189,7 +201,8 @@ describe('modules', () => {
|
|||||||
|
|
||||||
describe('nuxtApp', () => {
|
describe('nuxtApp', () => {
|
||||||
it('types injections provided by plugins', () => {
|
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<Router>()
|
expectTypeOf(useNuxtApp().$router).toEqualTypeOf<Router>()
|
||||||
})
|
})
|
||||||
it('marks unknown injections as unknown', () => {
|
it('marks unknown injections as unknown', () => {
|
||||||
@ -264,6 +277,13 @@ describe('components', () => {
|
|||||||
it('includes types for NuxtPage', () => {
|
it('includes types for NuxtPage', () => {
|
||||||
expectTypeOf(NuxtPage).not.toBeAny()
|
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', () => {
|
describe('composables', () => {
|
4
test/fixtures/basic/modules/example.ts
vendored
4
test/fixtures/basic/modules/example.ts
vendored
@ -1,10 +1,6 @@
|
|||||||
import { addPlugin, createResolver, defineNuxtModule, useNuxt } from 'nuxt/kit'
|
import { addPlugin, createResolver, defineNuxtModule, useNuxt } from 'nuxt/kit'
|
||||||
|
|
||||||
export default defineNuxtModule({
|
export default defineNuxtModule({
|
||||||
defaults: {
|
|
||||||
enabled: true,
|
|
||||||
typeTest: (value: boolean) => typeof value === 'boolean'
|
|
||||||
},
|
|
||||||
meta: {
|
meta: {
|
||||||
name: 'my-module',
|
name: 'my-module',
|
||||||
configKey: 'sampleModule'
|
configKey: 'sampleModule'
|
||||||
|
40
test/fixtures/basic/nuxt.config.ts
vendored
40
test/fixtures/basic/nuxt.config.ts
vendored
@ -11,14 +11,6 @@ declare module 'nitropack' {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
typescript: {
|
|
||||||
strict: true,
|
|
||||||
tsConfig: {
|
|
||||||
compilerOptions: {
|
|
||||||
moduleResolution: process.env.MODULE_RESOLUTION
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
app: {
|
app: {
|
||||||
pageTransition: true,
|
pageTransition: true,
|
||||||
layoutTransition: true,
|
layoutTransition: true,
|
||||||
@ -70,27 +62,14 @@ export default defineNuxtConfig({
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
runtimeConfig: {
|
runtimeConfig: {
|
||||||
baseURL: '',
|
|
||||||
baseAPIToken: '',
|
|
||||||
privateConfig: 'secret_key',
|
|
||||||
public: {
|
public: {
|
||||||
ids: [1, 2, 3],
|
|
||||||
needsFallback: undefined,
|
needsFallback: undefined,
|
||||||
testConfig: 123
|
testConfig: 123
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
modules: [
|
modules: [
|
||||||
'./modules/test',
|
'./modules/test',
|
||||||
[
|
'~/modules/example',
|
||||||
'~/modules/example',
|
|
||||||
{
|
|
||||||
typeTest (val) {
|
|
||||||
// @ts-expect-error module type defines val as boolean
|
|
||||||
const b: string = val
|
|
||||||
return !!b
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
function (_, nuxt) {
|
function (_, nuxt) {
|
||||||
if (typeof nuxt.options.builder === 'string' && nuxt.options.builder.includes('webpack')) { return }
|
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
|
telemetry: false, // for testing telemetry types - it is auto-disabled in tests
|
||||||
hooks: {
|
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' () {
|
'modules:done' () {
|
||||||
addComponent({
|
addComponent({
|
||||||
name: 'CustomComponent',
|
name: 'CustomComponent',
|
||||||
|
3
test/fixtures/minimal-types/app.vue
vendored
Normal file
3
test/fixtures/minimal-types/app.vue
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<template>
|
||||||
|
<div>Hello World!</div>
|
||||||
|
</template>
|
1
test/fixtures/minimal-types/nuxt.config.ts
vendored
Normal file
1
test/fixtures/minimal-types/nuxt.config.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
export default defineNuxtConfig({})
|
10
test/fixtures/minimal-types/package.json
vendored
Normal file
10
test/fixtures/minimal-types/package.json
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"private": true,
|
||||||
|
"name": "fixture-minimal-types",
|
||||||
|
"scripts": {
|
||||||
|
"build": "nuxi build"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"nuxt": "workspace:*"
|
||||||
|
}
|
||||||
|
}
|
3
test/fixtures/minimal-types/tsconfig.json
vendored
Normal file
3
test/fixtures/minimal-types/tsconfig.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"extends": "./.nuxt/tsconfig.json"
|
||||||
|
}
|
48
test/fixtures/minimal-types/types.ts
vendored
Normal file
48
test/fixtures/minimal-types/types.ts
vendored
Normal file
@ -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<string, any>
|
||||||
|
}>()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('appConfig', () => {
|
||||||
|
expectTypeOf(useAppConfig()).toEqualTypeOf<{ [key: string]: unknown }>()
|
||||||
|
})
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user