From c6e4065b4554cf1b4b68e55e6f2db634f7c4fda1 Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Thu, 7 Dec 2023 15:25:29 +0100 Subject: [PATCH 01/10] chore(release): 4.0.0 --- CHANGELOG.md | 6 ++++++ package.json | 28 +++++++++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9df0ab3..7facf43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# Changelog + +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +## [4.0.0](https://github.com/victorgarciaesgi/nuxt-typed-router/compare/v3.5.0...v4.0.0) (2023-12-07) + Changelog All notable changes to this project will be documented in this file. diff --git a/package.json b/package.json index ee8b400..1b2bdf9 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "nuxt-typed-router", - "version": "3.5.1", - "description": "Provide autocompletion for routes paths, names and params in Nuxt apps", + "version": "4.0.0", + "description": "Provide a type safe router to Nuxt", "type": "module", - "main": "./dist/module.cjs", + "main": "./dist/module.mjs", "types": "./dist/types.d.ts", "exports": { ".": { @@ -15,23 +15,24 @@ "dist" ], "scripts": { - "prepack": "nuxt-module-build build", + "build": "nuxt-module-build build", + "prepack": "pnpm build", "dev": "nuxi dev playground", "dev:build": "nuxi build playground", "prepare:playground": "nuxi prepare playground", "dev:prepare": "nuxt-module-build build --stub && nuxi prepare playground && pnpm run test:prepare-fixtures", - "build:test": "cross-env NUXT_BUILD_TYPE=stub pnpm run prepack && pnpm run dev:build", + "build:test": "cross-env NUXT_BUILD_TYPE=stub pnpm run build && pnpm run dev:build", + "lint": "eslint --ext .ts --ext .vue .", + "docs:dev": "cd docs && pnpm run dev", + "docs:build": "cd docs && nuxt generate", + "typecheck": "tsc --noEmit", + "release": "bumpp && npm publish && git push --follow-tags", + "release:test": "standard-version", "test:prepare-fixtures": "nuxi prepare test/fixtures/simple && nuxi prepare test/fixtures/withOptions && nuxi prepare test/fixtures/complex", "test:fixtures": "vitest run --dir test", "test:types": "pnpm run typecheck && pnpm run test:vue", "test:vue": "vue-tsc -p test/fixtures/simple/tsconfig.json --noEmit && vue-tsc -p test/fixtures/complex/tsconfig.json --noEmit", - "test": "pnpm run dev:prepare && pnpm run test:types && pnpm run test:fixtures", - "lint": "eslint --ext .ts --ext .vue .", - "docs:dev": "cd docs && pnpm run dev", - "docs:prepare": "nuxt-module-build --stub && nuxi prepare playground", - "docs:build": "npm run docs:prepare && cd docs && nuxi generate", - "typecheck": "tsc --noEmit", - "release": "bumpp && npm publish && git push --follow-tags" + "test": "pnpm run dev:prepare && pnpm run test:types && pnpm run test:fixtures" }, "publishConfig": { "access": "public" @@ -111,6 +112,7 @@ "@intlify/core-base": "9.8.0", "@intlify/vue-router-bridge": "1.1.0", "@intlify/vue-i18n-bridge": "1.1.0", - "vue-i18n-routing": "1.2.0" + "vue-i18n-routing": "1.2.0", + "standard-version": "9.5.0" } } From a7a0c416e4517c2bf136161ea72a80a315e52970 Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Thu, 7 Dec 2023 18:18:43 +0100 Subject: [PATCH 02/10] Working sample for tests --- package.json | 14 +- pnpm-lock.yaml | 238 +++++++------ pnpm-workspace.yaml | 2 +- test/e2e/complex/complex.spec.ts | 55 --- test/e2e/sample-project/[classic].spec.ts | 5 + test/e2e/sample-project/[withStrict].spec.ts | 8 + test/e2e/sample-project/utils.ts | 24 ++ test/e2e/simple/simple.spec.ts | 51 --- .../.gitignore | 2 + .../{withOptions => sample-project}/README.md | 0 .../{withOptions => sample-project}/app.vue | 0 test/fixtures/sample-project/nuxt.config.ts | 5 + .../package.json | 4 +- .../src/components/testModule.vue} | 0 .../src/modules/testAddRoute.ts | 14 + .../sample-project/src/pages/[...404].vue | 3 + .../src/pages/admin/[id].vue} | 0 .../src/pages/admin/[id]/action-[slug].vue} | 0 .../src/pages/admin/[id]/index.vue | 1 + .../src/pages/admin/[id]/profile.vue | 1 + .../src/pages/admin/[id]/settings.vue | 1 + .../src/pages/admin/panel/[[blou]].vue | 1 + .../sample-project/src/pages/baguette.vue | 1 + .../sample-project/src/pages/index.vue | 34 ++ .../src}/pages/user/[foo]-[[bar]].vue | 0 .../src}/pages/user/[id].vue | 0 .../src}/pages/user/[id]/[slug].vue | 0 .../src/pages/user/[id]/[slug]/articles.vue | 1 + .../src}/pages/user/[id]/[slug]/index.vue | 0 .../src}/pages/user/[id]/index.vue | 0 .../src}/pages/user/[id]/posts.vue | 0 .../src}/pages/user/[one]-foo-[two].vue | 0 .../src/pages/user/catch/[...slug].vue} | 0 .../sample-project/src/pages/user/index.vue | 1 + .../src/pages/user/test-[[optional]].vue | 1 + .../tests/i18n/NuxtLinkLocale.spec-d.ts | 143 ++++++++ .../tests/i18n/useLocalePath.spec-d.ts | 330 ++++++++++++++++++ .../tests/i18n/useLocaleRoute.spec-d.ts | 159 +++++++++ .../tests/misc/definePageMeta.spec-d.ts | 117 +++++++ .../tests/router/$typedRouter.spec-d.ts | 84 +++++ .../tests/router/NuxtLink.spec-d.ts | 129 +++++++ .../tests/router/navigateTo.spec-d.ts | 237 +++++++++++++ .../tests/router/useRouter.spec-d.ts | 132 +++++++ .../tests/routes/useRoute.spec-d.ts | 87 +++++ test/fixtures/sample-project/tsconfig.json | 4 + test/fixtures/withOptions/nuxt.config.ts | 10 - test/fixtures/withOptions/pages/index.vue | 7 - .../tests/e2e/withPartialStrict.spec.ts | 42 --- .../withOptions/tests/e2e/withStrict.spec.ts | 37 -- test/fixtures/withOptions/tsconfig.json | 6 - test/samples/[classic].config.ts | 3 + test/samples/[withStrict].config.ts | 6 + vercel.json | 5 + 53 files changed, 1675 insertions(+), 330 deletions(-) delete mode 100644 test/e2e/complex/complex.spec.ts create mode 100644 test/e2e/sample-project/[classic].spec.ts create mode 100644 test/e2e/sample-project/[withStrict].spec.ts create mode 100644 test/e2e/sample-project/utils.ts delete mode 100644 test/e2e/simple/simple.spec.ts rename test/fixtures/{withOptions => sample-project}/.gitignore (82%) rename test/fixtures/{withOptions => sample-project}/README.md (100%) rename test/fixtures/{withOptions => sample-project}/app.vue (100%) create mode 100644 test/fixtures/sample-project/nuxt.config.ts rename test/fixtures/{withOptions => sample-project}/package.json (76%) rename test/fixtures/{withOptions/pages/user/[...slug].vue => sample-project/src/components/testModule.vue} (100%) create mode 100644 test/fixtures/sample-project/src/modules/testAddRoute.ts create mode 100644 test/fixtures/sample-project/src/pages/[...404].vue rename test/fixtures/{withOptions/pages/user/[id]/[slug]/articles.vue => sample-project/src/pages/admin/[id].vue} (100%) rename test/fixtures/{withOptions/pages/user/index.vue => sample-project/src/pages/admin/[id]/action-[slug].vue} (100%) create mode 100644 test/fixtures/sample-project/src/pages/admin/[id]/index.vue create mode 100644 test/fixtures/sample-project/src/pages/admin/[id]/profile.vue create mode 100644 test/fixtures/sample-project/src/pages/admin/[id]/settings.vue create mode 100644 test/fixtures/sample-project/src/pages/admin/panel/[[blou]].vue create mode 100644 test/fixtures/sample-project/src/pages/baguette.vue create mode 100644 test/fixtures/sample-project/src/pages/index.vue rename test/fixtures/{withOptions => sample-project/src}/pages/user/[foo]-[[bar]].vue (100%) rename test/fixtures/{withOptions => sample-project/src}/pages/user/[id].vue (100%) rename test/fixtures/{withOptions => sample-project/src}/pages/user/[id]/[slug].vue (100%) create mode 100644 test/fixtures/sample-project/src/pages/user/[id]/[slug]/articles.vue rename test/fixtures/{withOptions => sample-project/src}/pages/user/[id]/[slug]/index.vue (100%) rename test/fixtures/{withOptions => sample-project/src}/pages/user/[id]/index.vue (100%) rename test/fixtures/{withOptions => sample-project/src}/pages/user/[id]/posts.vue (100%) rename test/fixtures/{withOptions => sample-project/src}/pages/user/[one]-foo-[two].vue (100%) rename test/fixtures/{withOptions/pages/user/test-[[optional]].vue => sample-project/src/pages/user/catch/[...slug].vue} (100%) create mode 100644 test/fixtures/sample-project/src/pages/user/index.vue create mode 100644 test/fixtures/sample-project/src/pages/user/test-[[optional]].vue create mode 100644 test/fixtures/sample-project/tests/i18n/NuxtLinkLocale.spec-d.ts create mode 100644 test/fixtures/sample-project/tests/i18n/useLocalePath.spec-d.ts create mode 100644 test/fixtures/sample-project/tests/i18n/useLocaleRoute.spec-d.ts create mode 100644 test/fixtures/sample-project/tests/misc/definePageMeta.spec-d.ts create mode 100644 test/fixtures/sample-project/tests/router/$typedRouter.spec-d.ts create mode 100644 test/fixtures/sample-project/tests/router/NuxtLink.spec-d.ts create mode 100644 test/fixtures/sample-project/tests/router/navigateTo.spec-d.ts create mode 100644 test/fixtures/sample-project/tests/router/useRouter.spec-d.ts create mode 100644 test/fixtures/sample-project/tests/routes/useRoute.spec-d.ts create mode 100644 test/fixtures/sample-project/tsconfig.json delete mode 100644 test/fixtures/withOptions/nuxt.config.ts delete mode 100644 test/fixtures/withOptions/pages/index.vue delete mode 100644 test/fixtures/withOptions/tests/e2e/withPartialStrict.spec.ts delete mode 100644 test/fixtures/withOptions/tests/e2e/withStrict.spec.ts delete mode 100644 test/fixtures/withOptions/tsconfig.json create mode 100644 test/samples/[classic].config.ts create mode 100644 test/samples/[withStrict].config.ts create mode 100644 vercel.json diff --git a/package.json b/package.json index 1b2bdf9..347a601 100644 --- a/package.json +++ b/package.json @@ -16,21 +16,20 @@ ], "scripts": { "build": "nuxt-module-build build", - "prepack": "pnpm build", + "prepack": "pnpm run typecheck && pnpm build", "dev": "nuxi dev playground", "dev:build": "nuxi build playground", "prepare:playground": "nuxi prepare playground", - "dev:prepare": "nuxt-module-build build --stub && nuxi prepare playground && pnpm run test:prepare-fixtures", + "dev:prepare": "nuxt-module-build build --stub && nuxi prepare playground", "build:test": "cross-env NUXT_BUILD_TYPE=stub pnpm run build && pnpm run dev:build", "lint": "eslint --ext .ts --ext .vue .", "docs:dev": "cd docs && pnpm run dev", "docs:build": "cd docs && nuxt generate", "typecheck": "tsc --noEmit", "release": "bumpp && npm publish && git push --follow-tags", - "release:test": "standard-version", - "test:prepare-fixtures": "nuxi prepare test/fixtures/simple && nuxi prepare test/fixtures/withOptions && nuxi prepare test/fixtures/complex", + "test:prepare-fixtures": "nuxi prepare test/fixtures/sample-project", "test:fixtures": "vitest run --dir test", - "test:types": "pnpm run typecheck && pnpm run test:vue", + "test:types": "pnpm run typecheck", "test:vue": "vue-tsc -p test/fixtures/simple/tsconfig.json --noEmit && vue-tsc -p test/fixtures/complex/tsconfig.json --noEmit", "test": "pnpm run dev:prepare && pnpm run test:types && pnpm run test:fixtures" }, @@ -100,7 +99,8 @@ "playwright": "1.40.1", "@playwright/test": "1.40.1", "tsd": "0.29.0", - "typescript": "5.3.2", + "typescript": "5.2.2", + "tslib": "2.6.2", "vitest": "0.34.6", "vue": "3.3.10", "vue-eslint-parser": "9.3.2", @@ -113,6 +113,6 @@ "@intlify/vue-router-bridge": "1.1.0", "@intlify/vue-i18n-bridge": "1.1.0", "vue-i18n-routing": "1.2.0", - "standard-version": "9.5.0" + "globby": "14.0.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f1bed99..b2e3ce6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -59,7 +59,7 @@ importers: version: 1.0.3(nuxt@3.8.2)(rollup@3.29.4)(vite@5.0.6) '@nuxt/module-builder': specifier: 0.5.4 - version: 0.5.4(@nuxt/kit@3.8.2)(nuxi@3.10.0)(typescript@5.3.2) + version: 0.5.4(@nuxt/kit@3.8.2)(nuxi@3.10.0)(typescript@5.2.2) '@nuxt/schema': specifier: 3.8.2 version: 3.8.2(rollup@3.29.4) @@ -71,7 +71,7 @@ importers: version: 2.17.2 '@nuxtjs/eslint-config-typescript': specifier: 12.1.0 - version: 12.1.0(eslint@8.54.0)(typescript@5.3.2) + version: 12.1.0(eslint@8.54.0)(typescript@5.2.2) '@nuxtjs/i18n': specifier: 8.0.0-rc.5 version: 8.0.0-rc.5(rollup@3.29.4)(vue-router@4.2.5)(vue@3.3.10) @@ -89,10 +89,10 @@ importers: version: 20.10.0 '@typescript-eslint/eslint-plugin': specifier: 6.12.0 - version: 6.12.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0)(typescript@5.3.2) + version: 6.12.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0)(typescript@5.2.2) '@typescript-eslint/parser': specifier: 6.12.0 - version: 6.12.0(eslint@8.54.0)(typescript@5.3.2) + version: 6.12.0(eslint@8.54.0)(typescript@5.2.2) '@vue/test-utils': specifier: 2.4.2 version: 2.4.2(vue@3.3.10) @@ -114,9 +114,12 @@ importers: eslint-plugin-vue: specifier: 9.18.1 version: 9.18.1(eslint@8.54.0) + globby: + specifier: 14.0.0 + version: 14.0.0 nuxt: specifier: 3.8.2 - version: 3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.3.2)(vite@5.0.6)(vue-tsc@1.8.22) + version: 3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.2.2)(vite@5.0.6)(vue-tsc@1.8.22) nuxt-seo-kit: specifier: 1.3.13 version: 1.3.13(@unhead/vue@1.8.8)(rollup@3.29.4)(vue@3.3.10) @@ -126,15 +129,18 @@ importers: tsd: specifier: 0.29.0 version: 0.29.0 + tslib: + specifier: 2.6.2 + version: 2.6.2 typescript: - specifier: 5.3.2 - version: 5.3.2 + specifier: 5.2.2 + version: 5.2.2 vitest: specifier: 0.34.6 version: 0.34.6(playwright@1.40.1) vue: specifier: 3.3.10 - version: 3.3.10(typescript@5.3.2) + version: 3.3.10(typescript@5.2.2) vue-eslint-parser: specifier: 9.3.2 version: 9.3.2(eslint@8.54.0) @@ -149,7 +155,7 @@ importers: version: 4.2.5(vue@3.3.10) vue-tsc: specifier: 1.8.22 - version: 1.8.22(typescript@5.3.2) + version: 1.8.22(typescript@5.2.2) docs: devDependencies: @@ -158,7 +164,7 @@ importers: version: 1.14.3(nuxt@3.8.1)(postcss@8.4.32)(rollup@3.29.4)(vue@3.3.10) nuxt: specifier: 3.8.1 - version: 3.8.1(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.3.2)(vite@5.0.6)(vue-tsc@1.8.22) + version: 3.8.1(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.2.2)(vite@5.0.6)(vue-tsc@1.8.22) test/fixtures/complex: devDependencies: @@ -167,34 +173,40 @@ importers: version: 8.0.0-rc.5(rollup@3.29.4)(vue-router@4.2.5)(vue@3.3.10) nuxt: specifier: 3.8.2 - version: 3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.3.2)(vite@5.0.6)(vue-tsc@1.8.22) + version: 3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.2.2)(vite@5.0.6)(vue-tsc@1.8.22) nuxt-typed-router: specifier: workspace:* version: link:../../.. vue: specifier: 3.3.10 - version: 3.3.10(typescript@5.3.2) + version: 3.3.10(typescript@5.2.2) - test/fixtures/simple: + test/fixtures/sample-project: devDependencies: + '@nuxtjs/i18n': + specifier: 8.0.0-rc.5 + version: 8.0.0-rc.5(rollup@3.29.4)(vue-router@4.2.5)(vue@3.3.10) nuxt: - specifier: ^3.8.2 - version: 3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.3.2)(vite@5.0.6)(vue-tsc@1.8.22) + specifier: 3.8.2 + version: 3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.2.2)(vite@5.0.6)(vue-tsc@1.8.22) nuxt-typed-router: specifier: workspace:* version: link:../../.. vue: specifier: 3.3.10 - version: 3.3.10(typescript@5.3.2) + version: 3.3.10(typescript@5.2.2) - test/fixtures/withOptions: + test/fixtures/simple: devDependencies: nuxt: - specifier: 3.8.2 - version: 3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.3.2)(vite@5.0.6)(vue-tsc@1.8.22) + specifier: ^3.8.2 + version: 3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.2.2)(vite@5.0.6)(vue-tsc@1.8.22) nuxt-typed-router: specifier: workspace:* version: link:../../.. + vue: + specifier: 3.3.10 + version: 3.3.10(typescript@5.2.2) packages: @@ -1224,7 +1236,7 @@ packages: vue: '>=3' dependencies: '@iconify/types': 2.0.0 - vue: 3.3.10(typescript@5.3.2) + vue: 3.3.10(typescript@5.2.2) dev: true /@intlify/bundle-utils@7.4.0(vue-i18n@9.5.0): @@ -1805,7 +1817,7 @@ packages: '@nuxt/kit': 3.8.2(rollup@3.29.4) '@nuxt/schema': 3.8.2(rollup@3.29.4) execa: 7.2.0 - nuxt: 3.8.1(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.3.2)(vite@5.0.6)(vue-tsc@1.8.22) + nuxt: 3.8.1(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.2.2)(vite@5.0.6)(vue-tsc@1.8.22) vite: 5.0.6(@types/node@20.10.0) transitivePeerDependencies: - rollup @@ -1821,7 +1833,7 @@ packages: '@nuxt/kit': 3.8.2(rollup@3.29.4) '@nuxt/schema': 3.8.2(rollup@3.29.4) execa: 7.2.0 - nuxt: 3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.3.2)(vite@5.0.6)(vue-tsc@1.8.22) + nuxt: 3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.2.2)(vite@5.0.6)(vue-tsc@1.8.22) vite: 5.0.6(@types/node@20.10.0) transitivePeerDependencies: - rollup @@ -1871,7 +1883,7 @@ packages: local-pkg: 0.5.0 magicast: 0.3.2 nitropack: 2.8.1 - nuxt: 3.8.1(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.3.2)(vite@5.0.6)(vue-tsc@1.8.22) + nuxt: 3.8.1(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.2.2)(vite@5.0.6)(vue-tsc@1.8.22) nypm: 0.3.3 ofetch: 1.3.3 ohash: 1.1.3 @@ -1939,7 +1951,7 @@ packages: local-pkg: 0.5.0 magicast: 0.3.2 nitropack: 2.8.1 - nuxt: 3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.3.2)(vite@5.0.6)(vue-tsc@1.8.22) + nuxt: 3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.2.2)(vite@5.0.6)(vue-tsc@1.8.22) nypm: 0.3.3 ofetch: 1.3.3 ohash: 1.1.3 @@ -2060,7 +2072,7 @@ packages: - rollup - supports-color - /@nuxt/module-builder@0.5.4(@nuxt/kit@3.8.2)(nuxi@3.10.0)(typescript@5.3.2): + /@nuxt/module-builder@0.5.4(@nuxt/kit@3.8.2)(nuxi@3.10.0)(typescript@5.2.2): resolution: {integrity: sha512-lCPh8s8LSfYqHgIMMsctDhz+AX1z6TnATkUes/GXc/No4kApC0zmJkQWrbtDRjmsWjElwl1kE7l7OzYdYc3d4w==} hasBin: true peerDependencies: @@ -2073,7 +2085,7 @@ packages: mlly: 1.4.2 nuxi: 3.10.0 pathe: 1.1.1 - unbuild: 2.0.0(typescript@5.3.2) + unbuild: 2.0.0(typescript@5.2.2) transitivePeerDependencies: - sass - supports-color @@ -2188,7 +2200,7 @@ packages: pathe: 1.1.1 ufo: 1.3.2 vitest: 0.34.6(playwright@1.40.1) - vue: 3.3.10(typescript@5.3.2) + vue: 3.3.10(typescript@5.2.2) transitivePeerDependencies: - rollup - supports-color @@ -2218,7 +2230,7 @@ packages: /@nuxt/ui-templates@1.3.1: resolution: {integrity: sha512-5gc02Pu1HycOVUWJ8aYsWeeXcSTPe8iX8+KIrhyEtEoOSkY0eMBuo0ssljB8wALuEmepv31DlYe5gpiRwkjESA==} - /@nuxt/vite-builder@3.8.1(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.3.2)(vue-tsc@1.8.22)(vue@3.3.10): + /@nuxt/vite-builder@3.8.1(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.2.2)(vue-tsc@1.8.22)(vue@3.3.10): resolution: {integrity: sha512-Ot/twGONxj22T9U4bxp771ibKVFlZxIiYDHY/e6mZsE4Blc0efKo6MzPPPo0W4/tXQbtKKEq41uINN3dMI3mag==} engines: {node: ^14.18.0 || >=16.10.0} peerDependencies: @@ -2255,8 +2267,8 @@ packages: unplugin: 1.5.1 vite: 4.5.1(@types/node@20.10.0) vite-node: 0.33.0(@types/node@20.10.0) - vite-plugin-checker: 0.6.2(eslint@8.54.0)(typescript@5.3.2)(vite@4.5.1)(vue-tsc@1.8.22) - vue: 3.3.10(typescript@5.3.2) + vite-plugin-checker: 0.6.2(eslint@8.54.0)(typescript@5.2.2)(vite@4.5.1)(vue-tsc@1.8.22) + vue: 3.3.10(typescript@5.2.2) vue-bundle-renderer: 2.0.0 transitivePeerDependencies: - '@types/node' @@ -2278,7 +2290,7 @@ packages: - vue-tsc dev: true - /@nuxt/vite-builder@3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.3.2)(vue-tsc@1.8.22)(vue@3.3.10): + /@nuxt/vite-builder@3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.2.2)(vue-tsc@1.8.22)(vue@3.3.10): resolution: {integrity: sha512-l/lzDDTbd3M89BpmWqjhVLgLVRqfkKp0tyYgV5seJQjj3SX+IeqI7k6k8+dMEifdeO34jUajVWptNpITXQryyg==} engines: {node: ^14.18.0 || >=16.10.0} peerDependencies: @@ -2315,8 +2327,8 @@ packages: unplugin: 1.5.1 vite: 4.5.1(@types/node@20.10.0) vite-node: 0.33.0(@types/node@20.10.0) - vite-plugin-checker: 0.6.2(eslint@8.54.0)(typescript@5.3.2)(vite@4.5.1)(vue-tsc@1.8.22) - vue: 3.3.10(typescript@5.3.2) + vite-plugin-checker: 0.6.2(eslint@8.54.0)(typescript@5.2.2)(vite@4.5.1)(vue-tsc@1.8.22) + vue: 3.3.10(typescript@5.2.2) vue-bundle-renderer: 2.0.0 transitivePeerDependencies: - '@types/node' @@ -2365,14 +2377,14 @@ packages: - supports-color dev: true - /@nuxtjs/eslint-config-typescript@12.1.0(eslint@8.54.0)(typescript@5.3.2): + /@nuxtjs/eslint-config-typescript@12.1.0(eslint@8.54.0)(typescript@5.2.2): resolution: {integrity: sha512-l2fLouDYwdAvCZEEw7wGxOBj+i8TQcHFu3zMPTLqKuv1qu6WcZIr0uztkbaa8ND1uKZ9YPqKx6UlSOjM4Le69Q==} peerDependencies: eslint: ^8.48.0 dependencies: '@nuxtjs/eslint-config': 12.0.0(@typescript-eslint/parser@6.12.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0) - '@typescript-eslint/eslint-plugin': 6.12.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0)(typescript@5.3.2) - '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/eslint-plugin': 6.12.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.2.2) eslint: 8.54.0 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.12.0)(eslint-plugin-import@2.29.0)(eslint@8.54.0) eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.12.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0) @@ -3442,7 +3454,7 @@ packages: source-map: 0.6.1 dev: true - /@typescript-eslint/eslint-plugin@6.12.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0)(typescript@5.3.2): + /@typescript-eslint/eslint-plugin@6.12.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0)(typescript@5.2.2): resolution: {integrity: sha512-XOpZ3IyJUIV1b15M7HVOpgQxPPF7lGXgsfcEIu3yDxFPaf/xZKt7s9QO/pbk7vpWQyVulpJbu4E5LwpZiQo4kA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -3454,10 +3466,10 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.2.2) '@typescript-eslint/scope-manager': 6.12.0 - '@typescript-eslint/type-utils': 6.12.0(eslint@8.54.0)(typescript@5.3.2) - '@typescript-eslint/utils': 6.12.0(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/type-utils': 6.12.0(eslint@8.54.0)(typescript@5.2.2) + '@typescript-eslint/utils': 6.12.0(eslint@8.54.0)(typescript@5.2.2) '@typescript-eslint/visitor-keys': 6.12.0 debug: 4.3.4 eslint: 8.54.0 @@ -3465,13 +3477,13 @@ packages: ignore: 5.3.0 natural-compare: 1.4.0 semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.3.2) - typescript: 5.3.2 + ts-api-utils: 1.0.3(typescript@5.2.2) + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@6.12.0(eslint@8.54.0)(typescript@5.3.2): + /@typescript-eslint/parser@6.12.0(eslint@8.54.0)(typescript@5.2.2): resolution: {integrity: sha512-s8/jNFPKPNRmXEnNXfuo1gemBdVmpQsK1pcu+QIvuNJuhFzGrpD7WjOcvDc/+uEdfzSYpNu7U/+MmbScjoQ6vg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -3483,11 +3495,11 @@ packages: dependencies: '@typescript-eslint/scope-manager': 6.12.0 '@typescript-eslint/types': 6.12.0 - '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.3.2) + '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.2.2) '@typescript-eslint/visitor-keys': 6.12.0 debug: 4.3.4 eslint: 8.54.0 - typescript: 5.3.2 + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true @@ -3500,7 +3512,7 @@ packages: '@typescript-eslint/visitor-keys': 6.12.0 dev: true - /@typescript-eslint/type-utils@6.12.0(eslint@8.54.0)(typescript@5.3.2): + /@typescript-eslint/type-utils@6.12.0(eslint@8.54.0)(typescript@5.2.2): resolution: {integrity: sha512-WWmRXxhm1X8Wlquj+MhsAG4dU/Blvf1xDgGaYCzfvStP2NwPQh6KBvCDbiOEvaE0filhranjIlK/2fSTVwtBng==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -3510,12 +3522,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.3.2) - '@typescript-eslint/utils': 6.12.0(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.2.2) + '@typescript-eslint/utils': 6.12.0(eslint@8.54.0)(typescript@5.2.2) debug: 4.3.4 eslint: 8.54.0 - ts-api-utils: 1.0.3(typescript@5.3.2) - typescript: 5.3.2 + ts-api-utils: 1.0.3(typescript@5.2.2) + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true @@ -3525,7 +3537,7 @@ packages: engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@6.12.0(typescript@5.3.2): + /@typescript-eslint/typescript-estree@6.12.0(typescript@5.2.2): resolution: {integrity: sha512-vw9E2P9+3UUWzhgjyyVczLWxZ3GuQNT7QpnIY3o5OMeLO/c8oHljGc8ZpryBMIyympiAAaKgw9e5Hl9dCWFOYw==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -3540,13 +3552,13 @@ packages: globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.3.2) - typescript: 5.3.2 + ts-api-utils: 1.0.3(typescript@5.2.2) + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@6.12.0(eslint@8.54.0)(typescript@5.3.2): + /@typescript-eslint/utils@6.12.0(eslint@8.54.0)(typescript@5.2.2): resolution: {integrity: sha512-LywPm8h3tGEbgfyjYnu3dauZ0U7R60m+miXgKcZS8c7QALO9uWJdvNoP+duKTk2XMWc7/Q3d/QiCuLN9X6SWyQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -3557,7 +3569,7 @@ packages: '@types/semver': 7.5.6 '@typescript-eslint/scope-manager': 6.12.0 '@typescript-eslint/types': 6.12.0 - '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.3.2) + '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.2.2) eslint: 8.54.0 semver: 7.5.4 transitivePeerDependencies: @@ -3637,7 +3649,7 @@ packages: '@unhead/shared': 1.8.8 hookable: 5.5.3 unhead: 1.8.8 - vue: 3.3.10(typescript@5.3.2) + vue: 3.3.10(typescript@5.2.2) dev: true /@unocss/reset@0.50.8: @@ -3676,7 +3688,7 @@ packages: '@babel/plugin-transform-typescript': 7.23.5(@babel/core@7.23.5) '@vue/babel-plugin-jsx': 1.1.5(@babel/core@7.23.5) vite: 4.5.1(@types/node@20.10.0) - vue: 3.3.10(typescript@5.3.2) + vue: 3.3.10(typescript@5.2.2) transitivePeerDependencies: - supports-color dev: true @@ -3689,7 +3701,7 @@ packages: vue: ^3.2.25 dependencies: vite: 4.5.1(@types/node@20.10.0) - vue: 3.3.10(typescript@5.3.2) + vue: 3.3.10(typescript@5.2.2) dev: true /@vitest/expect@0.34.6: @@ -3809,7 +3821,7 @@ packages: ast-kit: 0.11.3(rollup@3.29.4) local-pkg: 0.5.0 magic-string-ast: 0.3.0 - vue: 3.3.10(typescript@5.3.2) + vue: 3.3.10(typescript@5.2.2) transitivePeerDependencies: - rollup dev: true @@ -3879,7 +3891,7 @@ packages: resolution: {integrity: sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==} dev: true - /@vue/language-core@1.8.22(typescript@5.3.2): + /@vue/language-core@1.8.22(typescript@5.2.2): resolution: {integrity: sha512-bsMoJzCrXZqGsxawtUea1cLjUT9dZnDsy5TuZ+l1fxRMzUGQUG9+Ypq4w//CqpWmrx7nIAJpw2JVF/t258miRw==} peerDependencies: typescript: '*' @@ -3894,11 +3906,11 @@ packages: computeds: 0.0.1 minimatch: 9.0.3 muggle-string: 0.3.1 - typescript: 5.3.2 + typescript: 5.2.2 vue-template-compiler: 2.7.15 dev: true - /@vue/language-core@1.8.25(typescript@5.3.2): + /@vue/language-core@1.8.25(typescript@5.2.2): resolution: {integrity: sha512-NJk/5DnAZlpvXX8BdWmHI45bWGLViUaS3R/RMrmFSvFMSbJKuEODpM4kR0F0Ofv5SFzCWuNiMhxameWpVdQsnA==} peerDependencies: typescript: '*' @@ -3914,7 +3926,7 @@ packages: minimatch: 9.0.3 muggle-string: 0.3.1 path-browserify: 1.0.1 - typescript: 5.3.2 + typescript: 5.2.2 vue-template-compiler: 2.7.15 dev: true @@ -3956,7 +3968,7 @@ packages: dependencies: '@vue/compiler-ssr': 3.3.10 '@vue/shared': 3.3.10 - vue: 3.3.10(typescript@5.3.2) + vue: 3.3.10(typescript@5.2.2) dev: true /@vue/shared@3.3.10: @@ -3973,7 +3985,7 @@ packages: optional: true dependencies: js-beautify: 1.14.11 - vue: 3.3.10(typescript@5.3.2) + vue: 3.3.10(typescript@5.2.2) vue-component-type-helpers: 1.8.25 dev: true @@ -4010,7 +4022,7 @@ packages: '@unhead/schema': 1.8.8 '@unhead/ssr': 1.8.8 '@unhead/vue': 1.8.8(vue@3.3.10) - vue: 3.3.10(typescript@5.3.2) + vue: 3.3.10(typescript@5.2.2) dev: true /@vueuse/head@2.0.0(vue@3.3.10): @@ -4022,7 +4034,7 @@ packages: '@unhead/schema': 1.8.8 '@unhead/ssr': 1.8.8 '@unhead/vue': 1.8.8(vue@3.3.10) - vue: 3.3.10(typescript@5.3.2) + vue: 3.3.10(typescript@5.2.2) dev: true /@vueuse/integrations@10.7.0(focus-trap@7.5.4)(fuse.js@6.6.2)(vue@3.3.10): @@ -4093,7 +4105,7 @@ packages: '@vueuse/core': 10.7.0(vue@3.3.10) '@vueuse/metadata': 10.7.0 local-pkg: 0.5.0 - nuxt: 3.8.1(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.3.2)(vite@5.0.6)(vue-tsc@1.8.22) + nuxt: 3.8.1(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.2.2)(vite@5.0.6)(vue-tsc@1.8.22) vue-demi: 0.14.6(vue@3.3.10) transitivePeerDependencies: - '@vue/composition-api' @@ -4111,7 +4123,7 @@ packages: '@vueuse/core': 10.7.0(vue@3.3.10) '@vueuse/metadata': 10.7.0 local-pkg: 0.5.0 - nuxt: 3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.3.2)(vite@5.0.6)(vue-tsc@1.8.22) + nuxt: 3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.2.2)(vite@5.0.6)(vue-tsc@1.8.22) vue-demi: 0.14.6(vue@3.3.10) transitivePeerDependencies: - '@vue/composition-api' @@ -5873,7 +5885,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.2.2) debug: 3.2.7 eslint: 8.54.0 eslint-import-resolver-node: 0.3.9 @@ -5914,7 +5926,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.2.2) array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2 @@ -8658,7 +8670,7 @@ packages: hasBin: true dev: false - /mkdist@1.4.0(typescript@5.3.2): + /mkdist@1.4.0(typescript@5.2.2): resolution: {integrity: sha512-LzzdzWDx6cWWPd8saIoO+kT5jnbijfeDaE6jZfmCYEi3YL2aJSyF23/tCFee/mDuh/ek1UQeSYdLeSa6oesdiw==} hasBin: true peerDependencies: @@ -8683,7 +8695,7 @@ packages: pathe: 1.1.1 postcss: 8.4.32 postcss-nested: 6.0.1(postcss@8.4.32) - typescript: 5.3.2 + typescript: 5.2.2 dev: true /mlly@1.4.2: @@ -9069,8 +9081,8 @@ packages: dependencies: '@nuxt/kit': 3.8.2(rollup@3.29.4) scule: 1.1.1 - typescript: 5.3.2 - vue-component-meta: 1.8.25(typescript@5.3.2) + typescript: 5.2.2 + vue-component-meta: 1.8.25(typescript@5.2.2) transitivePeerDependencies: - rollup - supports-color @@ -9225,7 +9237,7 @@ packages: - vue dev: true - /nuxt@3.8.1(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.3.2)(vite@5.0.6)(vue-tsc@1.8.22): + /nuxt@3.8.1(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.2.2)(vite@5.0.6)(vue-tsc@1.8.22): resolution: {integrity: sha512-RSGO56Gv0x2f6AXWw4o4GoBaVdsD0qkPCjrX7Ud/jzH3cRJoyYMPuq/9AOLvf2o1ecZWl39j5elqJ4QHmggyOA==} engines: {node: ^14.18.0 || >=16.10.0} hasBin: true @@ -9244,7 +9256,7 @@ packages: '@nuxt/schema': 3.8.1(rollup@3.29.4) '@nuxt/telemetry': 2.5.3(rollup@3.29.4) '@nuxt/ui-templates': 1.3.1 - '@nuxt/vite-builder': 3.8.1(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.3.2)(vue-tsc@1.8.22)(vue@3.3.10) + '@nuxt/vite-builder': 3.8.1(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.2.2)(vue-tsc@1.8.22)(vue@3.3.10) '@types/node': 20.10.0 '@unhead/dom': 1.8.8 '@unhead/ssr': 1.8.8 @@ -9290,7 +9302,7 @@ packages: unplugin: 1.5.1 unplugin-vue-router: 0.7.0(rollup@3.29.4)(vue-router@4.2.5)(vue@3.3.10) untyped: 1.4.0 - vue: 3.3.10(typescript@5.3.2) + vue: 3.3.10(typescript@5.2.2) vue-bundle-renderer: 2.0.0 vue-devtools-stub: 0.1.0 vue-router: 4.2.5(vue@3.3.10) @@ -9331,7 +9343,7 @@ packages: - xml2js dev: true - /nuxt@3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.3.2)(vite@5.0.6)(vue-tsc@1.8.22): + /nuxt@3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.2.2)(vite@5.0.6)(vue-tsc@1.8.22): resolution: {integrity: sha512-HUAyifmqTs2zcQBGvcby3KNs2pBAk+l7ZbLjD1oCNqQQ+wBuZ1qgLC4Ebu++y4g3o3Y8WAWSvpafbKRLQZziPw==} engines: {node: ^14.18.0 || >=16.10.0} hasBin: true @@ -9350,7 +9362,7 @@ packages: '@nuxt/schema': 3.8.2(rollup@3.29.4) '@nuxt/telemetry': 2.5.3(rollup@3.29.4) '@nuxt/ui-templates': 1.3.1 - '@nuxt/vite-builder': 3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.3.2)(vue-tsc@1.8.22)(vue@3.3.10) + '@nuxt/vite-builder': 3.8.2(@types/node@20.10.0)(eslint@8.54.0)(rollup@3.29.4)(typescript@5.2.2)(vue-tsc@1.8.22)(vue@3.3.10) '@types/node': 20.10.0 '@unhead/dom': 1.8.8 '@unhead/ssr': 1.8.8 @@ -9396,7 +9408,7 @@ packages: unplugin: 1.5.1 unplugin-vue-router: 0.7.0(rollup@3.29.4)(vue-router@4.2.5)(vue@3.3.10) untyped: 1.4.0 - vue: 3.3.10(typescript@5.3.2) + vue: 3.3.10(typescript@5.2.2) vue-bundle-renderer: 2.0.0 vue-devtools-stub: 0.1.0 vue-router: 4.2.5(vue@3.3.10) @@ -10628,7 +10640,7 @@ packages: glob: 7.2.3 dev: true - /rollup-plugin-dts@5.3.1(rollup@3.29.4)(typescript@5.3.2): + /rollup-plugin-dts@5.3.1(rollup@3.29.4)(typescript@5.2.2): resolution: {integrity: sha512-gusMi+Z4gY/JaEQeXnB0RUdU82h1kF0WYzCWgVmV4p3hWXqelaKuCvcJawfeg+EKn2T1Ie+YWF2OiN1/L8bTVg==} engines: {node: '>=v14.21.3'} peerDependencies: @@ -10637,12 +10649,12 @@ packages: dependencies: magic-string: 0.30.5 rollup: 3.29.4 - typescript: 5.3.2 + typescript: 5.2.2 optionalDependencies: '@babel/code-frame': 7.23.5 dev: true - /rollup-plugin-dts@6.1.0(rollup@3.29.4)(typescript@5.3.2): + /rollup-plugin-dts@6.1.0(rollup@3.29.4)(typescript@5.2.2): resolution: {integrity: sha512-ijSCPICkRMDKDLBK9torss07+8dl9UpY9z1N/zTeA1cIqdzMlpkV3MOOC7zukyvQfDyxa1s3Dl2+DeiP/G6DOw==} engines: {node: '>=16'} peerDependencies: @@ -10651,7 +10663,7 @@ packages: dependencies: magic-string: 0.30.5 rollup: 3.29.4 - typescript: 5.3.2 + typescript: 5.2.2 optionalDependencies: '@babel/code-frame': 7.23.5 dev: true @@ -11487,13 +11499,13 @@ packages: resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} dev: true - /ts-api-utils@1.0.3(typescript@5.3.2): + /ts-api-utils@1.0.3(typescript@5.2.2): resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} engines: {node: '>=16.13.0'} peerDependencies: typescript: '>=4.2.0' dependencies: - typescript: 5.3.2 + typescript: 5.2.2 dev: true /tsconfig-paths@3.14.2: @@ -11627,8 +11639,8 @@ packages: is-typed-array: 1.1.12 dev: true - /typescript@5.3.2: - resolution: {integrity: sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==} + /typescript@5.2.2: + resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} engines: {node: '>=14.17'} hasBin: true dev: true @@ -11667,23 +11679,23 @@ packages: hookable: 5.5.3 jiti: 1.21.0 magic-string: 0.30.5 - mkdist: 1.4.0(typescript@5.3.2) + mkdist: 1.4.0(typescript@5.2.2) mlly: 1.4.2 mri: 1.2.0 pathe: 1.1.1 pkg-types: 1.0.3 pretty-bytes: 6.1.1 rollup: 3.29.4 - rollup-plugin-dts: 5.3.1(rollup@3.29.4)(typescript@5.3.2) + rollup-plugin-dts: 5.3.1(rollup@3.29.4)(typescript@5.2.2) scule: 1.1.1 - typescript: 5.3.2 + typescript: 5.2.2 untyped: 1.4.0 transitivePeerDependencies: - sass - supports-color dev: true - /unbuild@2.0.0(typescript@5.3.2): + /unbuild@2.0.0(typescript@5.2.2): resolution: {integrity: sha512-JWCUYx3Oxdzvw2J9kTAp+DKE8df/BnH/JTSj6JyA4SH40ECdFu7FoJJcrm8G92B7TjofQ6GZGjJs50TRxoH6Wg==} hasBin: true peerDependencies: @@ -11707,15 +11719,15 @@ packages: hookable: 5.5.3 jiti: 1.21.0 magic-string: 0.30.5 - mkdist: 1.4.0(typescript@5.3.2) + mkdist: 1.4.0(typescript@5.2.2) mlly: 1.4.2 pathe: 1.1.1 pkg-types: 1.0.3 pretty-bytes: 6.1.1 rollup: 3.29.4 - rollup-plugin-dts: 6.1.0(rollup@3.29.4)(typescript@5.3.2) + rollup-plugin-dts: 6.1.0(rollup@3.29.4)(typescript@5.2.2) scule: 1.1.1 - typescript: 5.3.2 + typescript: 5.2.2 untyped: 1.4.0 transitivePeerDependencies: - sass @@ -12237,7 +12249,7 @@ packages: - terser dev: true - /vite-plugin-checker@0.6.2(eslint@8.54.0)(typescript@5.3.2)(vite@4.5.1)(vue-tsc@1.8.22): + /vite-plugin-checker@0.6.2(eslint@8.54.0)(typescript@5.2.2)(vite@4.5.1)(vue-tsc@1.8.22): resolution: {integrity: sha512-YvvvQ+IjY09BX7Ab+1pjxkELQsBd4rPhWNw8WLBeFVxu/E7O+n6VYAqNsKdK/a2luFlX/sMpoWdGFfg4HvwdJQ==} engines: {node: '>=14.16'} peerDependencies: @@ -12282,13 +12294,13 @@ packages: semver: 7.5.4 strip-ansi: 6.0.1 tiny-invariant: 1.3.1 - typescript: 5.3.2 + typescript: 5.2.2 vite: 4.5.1(@types/node@20.10.0) vscode-languageclient: 7.0.0 vscode-languageserver: 7.0.0 vscode-languageserver-textdocument: 1.0.11 vscode-uri: 3.0.8 - vue-tsc: 1.8.22(typescript@5.3.2) + vue-tsc: 1.8.22(typescript@5.2.2) dev: true /vite-plugin-inspect@0.7.42(@nuxt/kit@3.8.2)(rollup@3.29.4)(vite@5.0.6): @@ -12519,7 +12531,7 @@ packages: ufo: 1.3.2 dev: true - /vue-component-meta@1.8.25(typescript@5.3.2): + /vue-component-meta@1.8.25(typescript@5.2.2): resolution: {integrity: sha512-CLsDWVJGBpUmdWiNuKaQ74yvCa3kYi17tT0nO7Fdmcd3GpzChpqYl/0M+WmZjwRDJha91ojWHtrBLWBv/XQiIQ==} peerDependencies: typescript: '*' @@ -12528,9 +12540,9 @@ packages: optional: true dependencies: '@volar/typescript': 1.11.1 - '@vue/language-core': 1.8.25(typescript@5.3.2) + '@vue/language-core': 1.8.25(typescript@5.2.2) path-browserify: 1.0.1 - typescript: 5.3.2 + typescript: 5.2.2 vue-component-type-helpers: 1.8.25 dev: true @@ -12550,7 +12562,7 @@ packages: '@vue/composition-api': optional: true dependencies: - vue: 3.3.10(typescript@5.3.2) + vue: 3.3.10(typescript@5.2.2) dev: true /vue-devtools-stub@0.1.0: @@ -12600,7 +12612,7 @@ packages: '@intlify/vue-i18n-bridge': 1.1.0(vue-i18n@9.5.0) '@intlify/vue-router-bridge': 1.1.0(vue-router@4.2.5)(vue@3.3.10) ufo: 1.3.2 - vue: 3.3.10(typescript@5.3.2) + vue: 3.3.10(typescript@5.2.2) vue-demi: 0.14.6(vue@3.3.10) vue-i18n: 9.5.0(vue@3.3.10) vue-router: 4.2.5(vue@3.3.10) @@ -12631,7 +12643,7 @@ packages: '@intlify/vue-i18n-bridge': 1.1.0(vue-i18n@9.8.0) '@intlify/vue-router-bridge': 1.1.0(vue-router@4.2.5)(vue@3.3.10) ufo: 1.3.2 - vue: 3.3.10(typescript@5.3.2) + vue: 3.3.10(typescript@5.2.2) vue-demi: 0.14.6(vue@3.3.10) vue-i18n: 9.8.0(vue@3.3.10) vue-router: 4.2.5(vue@3.3.10) @@ -12646,7 +12658,7 @@ packages: '@intlify/core-base': 9.5.0 '@intlify/shared': 9.5.0 '@vue/devtools-api': 6.5.1 - vue: 3.3.10(typescript@5.3.2) + vue: 3.3.10(typescript@5.2.2) dev: true /vue-i18n@9.8.0(vue@3.3.10): @@ -12658,7 +12670,7 @@ packages: '@intlify/core-base': 9.8.0 '@intlify/shared': 9.8.0 '@vue/devtools-api': 6.5.1 - vue: 3.3.10(typescript@5.3.2) + vue: 3.3.10(typescript@5.2.2) dev: true /vue-router@4.2.5(vue@3.3.10): @@ -12667,7 +12679,7 @@ packages: vue: ^3.2.0 dependencies: '@vue/devtools-api': 6.5.1 - vue: 3.3.10(typescript@5.3.2) + vue: 3.3.10(typescript@5.2.2) dev: true /vue-template-compiler@2.7.15: @@ -12677,19 +12689,19 @@ packages: he: 1.2.0 dev: true - /vue-tsc@1.8.22(typescript@5.3.2): + /vue-tsc@1.8.22(typescript@5.2.2): resolution: {integrity: sha512-j9P4kHtW6eEE08aS5McFZE/ivmipXy0JzrnTgbomfABMaVKx37kNBw//irL3+LlE3kOo63XpnRigyPC3w7+z+A==} hasBin: true peerDependencies: typescript: '*' dependencies: '@volar/typescript': 1.10.10 - '@vue/language-core': 1.8.22(typescript@5.3.2) + '@vue/language-core': 1.8.22(typescript@5.2.2) semver: 7.5.4 - typescript: 5.3.2 + typescript: 5.2.2 dev: true - /vue@3.3.10(typescript@5.3.2): + /vue@3.3.10(typescript@5.2.2): resolution: {integrity: sha512-zg6SIXZdTBwiqCw/1p+m04VyHjLfwtjwz8N57sPaBhEex31ND0RYECVOC1YrRwMRmxFf5T1dabl6SGUbMKKuVw==} peerDependencies: typescript: '*' @@ -12702,7 +12714,7 @@ packages: '@vue/runtime-dom': 3.3.10 '@vue/server-renderer': 3.3.10(vue@3.3.10) '@vue/shared': 3.3.10 - typescript: 5.3.2 + typescript: 5.2.2 dev: true /web-namespaces@2.0.1: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 693cbb0..d40b20c 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,5 +1,5 @@ packages: - test/fixtures/simple - test/fixtures/complex - - test/fixtures/withOptions + - test/fixtures/sample-project - docs \ No newline at end of file diff --git a/test/e2e/complex/complex.spec.ts b/test/e2e/complex/complex.spec.ts deleted file mode 100644 index 62be466..0000000 --- a/test/e2e/complex/complex.spec.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { fileURLToPath } from 'node:url'; -import { describe, it, expect } from 'vitest'; -import { setup, $fetch, createPage } from '@nuxt/test-utils'; -import { expectNoClientErrors } from '../utils'; -import { timeout } from '$$/utils'; - -const TIME = 2000; - -describe('Complex config behaviour', async () => { - await setup({ - rootDir: fileURLToPath(new URL('../../fixtures/complex', import.meta.url)), - setupTimeout: 120000, - }); - - it('should display the root page without error', async () => { - const html = await $fetch('/'); - - expect(html).toContain('Navigate button'); - expect(html).toContain('Navigate link'); - expect(html).toContain('NavigateTo button'); - expect(html).toContain('Navigate plugin'); - - await expectNoClientErrors('/'); - }); - - // Commented for now because of a Nuxt bug still happening to me - - it('should navigate correctly with useRouter', async () => { - const page = await createPage('/'); - await page.click('#useRouter'); - const html = await page.innerHTML('body'); - await timeout(TIME); - - await expectNoClientErrors('/'); - }); - - it('should navigate correctly with nuxtLink', async () => { - const page = await createPage('/'); - await page.click('#nuxtLink'); - - await timeout(TIME); - const html = await page.innerHTML('body'); - - await expectNoClientErrors('/'); - }); - - it('should navigate correctly with navigateTo', async () => { - const page = await createPage('/'); - await page.click('#navigateTo'); - const html = await page.innerHTML('body'); - await timeout(TIME); - - await expectNoClientErrors('/'); - }); -}); diff --git a/test/e2e/sample-project/[classic].spec.ts b/test/e2e/sample-project/[classic].spec.ts new file mode 100644 index 0000000..881919f --- /dev/null +++ b/test/e2e/sample-project/[classic].spec.ts @@ -0,0 +1,5 @@ +import { setupNuxtTestWithConfig } from './utils'; + +setupNuxtTestWithConfig('classic', { + modules: ['nuxt-typed-router'], +}); diff --git a/test/e2e/sample-project/[withStrict].spec.ts b/test/e2e/sample-project/[withStrict].spec.ts new file mode 100644 index 0000000..80208c6 --- /dev/null +++ b/test/e2e/sample-project/[withStrict].spec.ts @@ -0,0 +1,8 @@ +import { setupNuxtTestWithConfig } from './utils'; + +setupNuxtTestWithConfig('withStrict', { + modules: ['nuxt-typed-router'], + nuxtTypedRouter: { + strict: true, + }, +}); diff --git a/test/e2e/sample-project/utils.ts b/test/e2e/sample-project/utils.ts new file mode 100644 index 0000000..ee69559 --- /dev/null +++ b/test/e2e/sample-project/utils.ts @@ -0,0 +1,24 @@ +import { $fetch, setup, setTestContext, stopServer } from '@nuxt/test-utils'; +import { globby } from 'globby'; +import { fileURLToPath } from 'node:url'; +import { describe, expect, it } from 'vitest'; +import { expectNoClientErrors } from '../utils'; + +export async function setupNuxtTestWithConfig(name: string, config: Record) { + describe(`Config: ${name}`, async () => { + await setup({ + rootDir: fileURLToPath(new URL('../../fixtures/sample-project', import.meta.url)), + nuxtConfig: config, + }); + + it('should render base buttons', async () => { + const html = await $fetch('/'); + + expect(html).toContain('Navigate button'); + expect(html).toContain('Navigate link'); + expect(html).toContain('NavigateTo button'); + + await expectNoClientErrors('/'); + }); + }); +} diff --git a/test/e2e/simple/simple.spec.ts b/test/e2e/simple/simple.spec.ts deleted file mode 100644 index c077732..0000000 --- a/test/e2e/simple/simple.spec.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { fileURLToPath } from 'node:url'; -import { describe, it, expect, assertType, expectTypeOf } from 'vitest'; -import { setup, $fetch, createPage } from '@nuxt/test-utils'; -import { expectNoClientErrors } from '../utils'; -import { timeout } from '$$/utils'; - -const TIME = 2000; - -describe('Simple config behaviour', async () => { - await setup({ - rootDir: fileURLToPath(new URL('../../fixtures/simple', import.meta.url)), - setupTimeout: 120000, - }); - - it('should display the root page without error', async () => { - const html = await $fetch('/'); - - expect(html).toContain('Navigate button'); - expect(html).toContain('Navigate link'); - expect(html).toContain('NavigateTo button'); - - await expectNoClientErrors('/'); - }); - - it('should navigate correctly with useRouter', async () => { - const page = await createPage('/'); - await page.click('#useRouter'); - const html = await page.innerHTML('body'); - await timeout(TIME); - - await expectNoClientErrors('/'); - }); - - it('should navigate correctly with nuxtLink', async () => { - const page = await createPage('/'); - await page.click('#nuxtLink'); - await timeout(TIME); - const html = await page.innerHTML('body'); - - await expectNoClientErrors('/'); - }); - - it('should navigate correctly with navigateTo', async () => { - const page = await createPage('/'); - await page.click('#navigateTo'); - const html = await page.innerHTML('body'); - await timeout(TIME); - - await expectNoClientErrors('/'); - }); -}); diff --git a/test/fixtures/withOptions/.gitignore b/test/fixtures/sample-project/.gitignore similarity index 82% rename from test/fixtures/withOptions/.gitignore rename to test/fixtures/sample-project/.gitignore index 438cb08..c8ff9d9 100644 --- a/test/fixtures/withOptions/.gitignore +++ b/test/fixtures/sample-project/.gitignore @@ -6,3 +6,5 @@ node_modules .output .env dist + +src/plugins \ No newline at end of file diff --git a/test/fixtures/withOptions/README.md b/test/fixtures/sample-project/README.md similarity index 100% rename from test/fixtures/withOptions/README.md rename to test/fixtures/sample-project/README.md diff --git a/test/fixtures/withOptions/app.vue b/test/fixtures/sample-project/app.vue similarity index 100% rename from test/fixtures/withOptions/app.vue rename to test/fixtures/sample-project/app.vue diff --git a/test/fixtures/sample-project/nuxt.config.ts b/test/fixtures/sample-project/nuxt.config.ts new file mode 100644 index 0000000..2a00ae5 --- /dev/null +++ b/test/fixtures/sample-project/nuxt.config.ts @@ -0,0 +1,5 @@ +import TestModuleRoute from './src/modules/testAddRoute'; + +export default defineNuxtConfig({ + srcDir: './src', +}); diff --git a/test/fixtures/withOptions/package.json b/test/fixtures/sample-project/package.json similarity index 76% rename from test/fixtures/withOptions/package.json rename to test/fixtures/sample-project/package.json index b856c02..0c7cb67 100644 --- a/test/fixtures/withOptions/package.json +++ b/test/fixtures/sample-project/package.json @@ -1,6 +1,6 @@ { "private": true, - "name": "with-options", + "name": "sample-project", "version": "1.0.0", "scripts": { "build": "nuxt build", @@ -9,7 +9,9 @@ "preview": "nuxt preview" }, "devDependencies": { + "@nuxtjs/i18n": "8.0.0-rc.5", "nuxt": "3.8.2", + "vue": "3.3.10", "nuxt-typed-router": "workspace:*" } } diff --git a/test/fixtures/withOptions/pages/user/[...slug].vue b/test/fixtures/sample-project/src/components/testModule.vue similarity index 100% rename from test/fixtures/withOptions/pages/user/[...slug].vue rename to test/fixtures/sample-project/src/components/testModule.vue diff --git a/test/fixtures/sample-project/src/modules/testAddRoute.ts b/test/fixtures/sample-project/src/modules/testAddRoute.ts new file mode 100644 index 0000000..2582823 --- /dev/null +++ b/test/fixtures/sample-project/src/modules/testAddRoute.ts @@ -0,0 +1,14 @@ +import { createResolver, defineNuxtModule, extendPages } from '@nuxt/kit'; + +export default defineNuxtModule({ + setup() { + const { resolve } = createResolver(import.meta.url); + extendPages((routes) => { + routes.push({ + file: resolve('../components/testModule.vue'), + path: '/testModule/:foo', + name: 'test-module', + }); + }); + }, +}); diff --git a/test/fixtures/sample-project/src/pages/[...404].vue b/test/fixtures/sample-project/src/pages/[...404].vue new file mode 100644 index 0000000..2c78cf3 --- /dev/null +++ b/test/fixtures/sample-project/src/pages/[...404].vue @@ -0,0 +1,3 @@ + diff --git a/test/fixtures/withOptions/pages/user/[id]/[slug]/articles.vue b/test/fixtures/sample-project/src/pages/admin/[id].vue similarity index 100% rename from test/fixtures/withOptions/pages/user/[id]/[slug]/articles.vue rename to test/fixtures/sample-project/src/pages/admin/[id].vue diff --git a/test/fixtures/withOptions/pages/user/index.vue b/test/fixtures/sample-project/src/pages/admin/[id]/action-[slug].vue similarity index 100% rename from test/fixtures/withOptions/pages/user/index.vue rename to test/fixtures/sample-project/src/pages/admin/[id]/action-[slug].vue diff --git a/test/fixtures/sample-project/src/pages/admin/[id]/index.vue b/test/fixtures/sample-project/src/pages/admin/[id]/index.vue new file mode 100644 index 0000000..7dcf98f --- /dev/null +++ b/test/fixtures/sample-project/src/pages/admin/[id]/index.vue @@ -0,0 +1 @@ + diff --git a/test/fixtures/sample-project/src/pages/admin/[id]/profile.vue b/test/fixtures/sample-project/src/pages/admin/[id]/profile.vue new file mode 100644 index 0000000..7dcf98f --- /dev/null +++ b/test/fixtures/sample-project/src/pages/admin/[id]/profile.vue @@ -0,0 +1 @@ + diff --git a/test/fixtures/sample-project/src/pages/admin/[id]/settings.vue b/test/fixtures/sample-project/src/pages/admin/[id]/settings.vue new file mode 100644 index 0000000..7dcf98f --- /dev/null +++ b/test/fixtures/sample-project/src/pages/admin/[id]/settings.vue @@ -0,0 +1 @@ + diff --git a/test/fixtures/sample-project/src/pages/admin/panel/[[blou]].vue b/test/fixtures/sample-project/src/pages/admin/panel/[[blou]].vue new file mode 100644 index 0000000..7dcf98f --- /dev/null +++ b/test/fixtures/sample-project/src/pages/admin/panel/[[blou]].vue @@ -0,0 +1 @@ + diff --git a/test/fixtures/sample-project/src/pages/baguette.vue b/test/fixtures/sample-project/src/pages/baguette.vue new file mode 100644 index 0000000..7dcf98f --- /dev/null +++ b/test/fixtures/sample-project/src/pages/baguette.vue @@ -0,0 +1 @@ + diff --git a/test/fixtures/sample-project/src/pages/index.vue b/test/fixtures/sample-project/src/pages/index.vue new file mode 100644 index 0000000..98b7abc --- /dev/null +++ b/test/fixtures/sample-project/src/pages/index.vue @@ -0,0 +1,34 @@ + + + diff --git a/test/fixtures/withOptions/pages/user/[foo]-[[bar]].vue b/test/fixtures/sample-project/src/pages/user/[foo]-[[bar]].vue similarity index 100% rename from test/fixtures/withOptions/pages/user/[foo]-[[bar]].vue rename to test/fixtures/sample-project/src/pages/user/[foo]-[[bar]].vue diff --git a/test/fixtures/withOptions/pages/user/[id].vue b/test/fixtures/sample-project/src/pages/user/[id].vue similarity index 100% rename from test/fixtures/withOptions/pages/user/[id].vue rename to test/fixtures/sample-project/src/pages/user/[id].vue diff --git a/test/fixtures/withOptions/pages/user/[id]/[slug].vue b/test/fixtures/sample-project/src/pages/user/[id]/[slug].vue similarity index 100% rename from test/fixtures/withOptions/pages/user/[id]/[slug].vue rename to test/fixtures/sample-project/src/pages/user/[id]/[slug].vue diff --git a/test/fixtures/sample-project/src/pages/user/[id]/[slug]/articles.vue b/test/fixtures/sample-project/src/pages/user/[id]/[slug]/articles.vue new file mode 100644 index 0000000..7dcf98f --- /dev/null +++ b/test/fixtures/sample-project/src/pages/user/[id]/[slug]/articles.vue @@ -0,0 +1 @@ + diff --git a/test/fixtures/withOptions/pages/user/[id]/[slug]/index.vue b/test/fixtures/sample-project/src/pages/user/[id]/[slug]/index.vue similarity index 100% rename from test/fixtures/withOptions/pages/user/[id]/[slug]/index.vue rename to test/fixtures/sample-project/src/pages/user/[id]/[slug]/index.vue diff --git a/test/fixtures/withOptions/pages/user/[id]/index.vue b/test/fixtures/sample-project/src/pages/user/[id]/index.vue similarity index 100% rename from test/fixtures/withOptions/pages/user/[id]/index.vue rename to test/fixtures/sample-project/src/pages/user/[id]/index.vue diff --git a/test/fixtures/withOptions/pages/user/[id]/posts.vue b/test/fixtures/sample-project/src/pages/user/[id]/posts.vue similarity index 100% rename from test/fixtures/withOptions/pages/user/[id]/posts.vue rename to test/fixtures/sample-project/src/pages/user/[id]/posts.vue diff --git a/test/fixtures/withOptions/pages/user/[one]-foo-[two].vue b/test/fixtures/sample-project/src/pages/user/[one]-foo-[two].vue similarity index 100% rename from test/fixtures/withOptions/pages/user/[one]-foo-[two].vue rename to test/fixtures/sample-project/src/pages/user/[one]-foo-[two].vue diff --git a/test/fixtures/withOptions/pages/user/test-[[optional]].vue b/test/fixtures/sample-project/src/pages/user/catch/[...slug].vue similarity index 100% rename from test/fixtures/withOptions/pages/user/test-[[optional]].vue rename to test/fixtures/sample-project/src/pages/user/catch/[...slug].vue diff --git a/test/fixtures/sample-project/src/pages/user/index.vue b/test/fixtures/sample-project/src/pages/user/index.vue new file mode 100644 index 0000000..7dcf98f --- /dev/null +++ b/test/fixtures/sample-project/src/pages/user/index.vue @@ -0,0 +1 @@ + diff --git a/test/fixtures/sample-project/src/pages/user/test-[[optional]].vue b/test/fixtures/sample-project/src/pages/user/test-[[optional]].vue new file mode 100644 index 0000000..87ac15c --- /dev/null +++ b/test/fixtures/sample-project/src/pages/user/test-[[optional]].vue @@ -0,0 +1 @@ + diff --git a/test/fixtures/sample-project/tests/i18n/NuxtLinkLocale.spec-d.ts b/test/fixtures/sample-project/tests/i18n/NuxtLinkLocale.spec-d.ts new file mode 100644 index 0000000..fefe4f3 --- /dev/null +++ b/test/fixtures/sample-project/tests/i18n/NuxtLinkLocale.spec-d.ts @@ -0,0 +1,143 @@ +import { assertType, vi } from 'vitest'; +import type { GlobalComponents } from 'vue'; + +const NuxtLinkLocale: GlobalComponents['NuxtLinkLocale'] = vi.fn() as any; + +// ! ------ Should Error ❌ + +// * index.vue +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: { name: 'index', params: { id: 1 } } })); +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: { name: 'index', params: { id: 1 } } })); +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: { name: 'blabla-baguette' } })); + +// * --- [id].vue +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: { name: 'user-id' } })); +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: { name: 'user-id', params: { foo: 'bar' } } })); + +// * --- [foo]-[[bar]].vue +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: { name: 'user-foo-bar' } })); +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: { name: 'user-foo-bar', params: { bar: 1 } } })); + +// * --- [...slug].vue +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: { name: 'user-slug' } })); +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: { name: 'user-slug', params: { slug: 1 } } })); + +// * --- [one]-foo-[two].vue +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: { name: 'user-one-foo-two' } })); +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: { name: 'user-one-foo-two', params: { one: 1 } } })); + +// * --- [id]/[slug].vue +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: { name: 'user-id-slug' } })); +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: { name: 'user-id-slug', params: { id: 1 } } })); + +// * --- Routes added by modules +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: { name: 'test-module' } })); + +// --- Path navigation + +// ! ------ Should Error ❌ + +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: '' })); +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: '/admin ' })); +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: '/admin/ /' })); +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: `/ / // / / eefzr` })); +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: '/elzhlzehflzhef' })); +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: '/admin/foo/bar' })); +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: '/admin/foo/bar/baz' })); +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: `/admin/${id}/action-bar/taz?query` })); +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: '/admin/panel/3O9393/bar' })); +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: '/admin/foo/ profile/ezfje' })); +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: '/admin/3U93U/settings/baz' })); +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: '/admin/panel/?fjzk' })); + +// $ ----- Should be valid ✅ + +const id = '38789803'; +assertType(new NuxtLinkLocale({ to: '/' })); +assertType(new NuxtLinkLocale({ to: '/baguette' })); +assertType(new NuxtLinkLocale({ to: '/admin/foo' })); +assertType(new NuxtLinkLocale({ to: '/admin/foo/' })); +assertType(new NuxtLinkLocale({ to: `/admin/${id}/action-bar#hash` })); +assertType(new NuxtLinkLocale({ to: `/admin/${id}/action-bar?query=bar` })); +assertType(new NuxtLinkLocale({ to: '/admin/foo/profile/' })); +assertType(new NuxtLinkLocale({ to: `/admin/${id}/settings` })); +assertType(new NuxtLinkLocale({ to: '/admin/panel/' })); +assertType(new NuxtLinkLocale({ to: '/admin/panel/938783/' })); +assertType(new NuxtLinkLocale({ to: '/user/38873-' })); +assertType(new NuxtLinkLocale({ to: '/user/38673/bar/#hash' })); +assertType(new NuxtLinkLocale({ to: '/user/ç9737/foo/articles?baz=foo' })); +assertType(new NuxtLinkLocale({ to: '/user/catch/1/2' })); +assertType(new NuxtLinkLocale({ to: '/user/test-' })); +assertType(new NuxtLinkLocale({ to: '/user' })); + +// $ ----- Should be valid ✅ + +assertType(new NuxtLinkLocale({ to: { name: 'index' } })); +assertType(new NuxtLinkLocale({ to: { name: 'user-id', params: { id: 1 }, hash: 'baz' } })); +assertType( + new NuxtLinkLocale({ to: { name: 'user-foo-bar', params: { foo: 'bar' }, force: true } }) +); +assertType( + new NuxtLinkLocale({ + to: { name: 'user-foo-bar', params: { foo: 'bar', bar: 'baz' } }, + }) +); +assertType(new NuxtLinkLocale({ to: { name: 'user-catch-slug', params: { slug: ['foo'] } } })); +assertType(new NuxtLinkLocale({ to: { name: 'user-catch-slug', params: { slug: [1, 2, 3] } } })); +assertType(new NuxtLinkLocale({ to: { name: 'user-one-foo-two', params: { one: 1, two: '2' } } })); +assertType( + new NuxtLinkLocale({ + to: { name: 'user-id-slug', params: { slug: '2' }, query: { foo: 'bar' } }, + }) +); + +assertType( + new NuxtLinkLocale({ + to: { name: 'test-module', params: { foo: 1 }, query: { foo: 'bar' } }, + }) +); + +// - With External prop + +// $ ----- Should be valid ✅ + +assertType(new NuxtLinkLocale({ to: '/admin/:id/', external: false })); +assertType(new NuxtLinkLocale({ to: 'http://google.com', external: true })); + +// - With Locale prop + +// $ ----- Should be valid ✅ + +assertType(new NuxtLinkLocale({ to: '/admin/:id/', locale: 'en' })); +assertType(new NuxtLinkLocale({ to: '/admin/:id/', locale: 'fr' })); + +// ! ------ Should Error ❌ + +// @ts-expect-error +assertType(new NuxtLinkLocale({ to: '/admin/:id/', external: true, locale: 'en' })); diff --git a/test/fixtures/sample-project/tests/i18n/useLocalePath.spec-d.ts b/test/fixtures/sample-project/tests/i18n/useLocalePath.spec-d.ts new file mode 100644 index 0000000..0b3a479 --- /dev/null +++ b/test/fixtures/sample-project/tests/i18n/useLocalePath.spec-d.ts @@ -0,0 +1,330 @@ +import { assertType, expectTypeOf, vi } from 'vitest'; +import type { GlobalComponents } from 'vue'; +import type { HistoryState, LocationQuery, LocationQueryRaw } from 'vue-router'; +import { navigateTo, useLocalePath, useRouter } from '@typed-router'; + +// @ts-expect-error Ensure global imports are disabled +declare const globalDecl: (typeof globalThis)['useLocalePath']; + +// Given +const localePath = useLocalePath(); + +// - Return types + +const localeRouteLocation = localePath({ + name: 'user-foo-bar', + params: { foo: '1' }, + query: { foo: 'bar' }, +}); + +expectTypeOf(localeRouteLocation.name).toMatchTypeOf<'user-foo-bar'>(); +expectTypeOf(localeRouteLocation.params).toMatchTypeOf<{ + foo: string | number; + bar?: string | number | undefined; +}>(); +expectTypeOf(localeRouteLocation.force).toMatchTypeOf(); +expectTypeOf(localeRouteLocation.hash).toMatchTypeOf(); +expectTypeOf(localeRouteLocation.query).toMatchTypeOf(); +expectTypeOf(localeRouteLocation.state).toMatchTypeOf; + +// - Usage of localePath with useRouter + +const router = useRouter(); + +// ! ------ Should Error ❌ + +// * index.vue +// @ts-expect-error +router.push(localePath({ name: 'index' }, 'DE')); +// @ts-expect-error +router.push(localePath({ name: 'index', params: { id: 1 } }, 'es')); +// @ts-expect-error +router.push(localePath({ name: 'index', params: { id: 1 } })); +// @ts-expect-error +router.push(localePath({ name: 'blabla-baguette' })); + +// * --- [id].vue +// @ts-expect-error +router.push(localePath({ name: 'user-id' })); +// @ts-expect-error +router.push(localePath({ name: 'user-id', params: { foo: 'bar' } })); + +// * --- [foo]-[[bar]].vue +// @ts-expect-error +router.push(localePath({ name: 'user-foo-bar' })); +// @ts-expect-error +router.push(localePath({ name: 'user-foo-bar', params: { bar: 1 } })); + +// * --- [...slug].vue +// @ts-expect-error +router.push(localePath({ name: 'user-slug' })); +// @ts-expect-error +router.push(localePath({ name: 'user-slug', params: { slug: 1 } })); + +// * --- [one]-foo-[two].vue +// @ts-expect-error +router.push(localePath({ name: 'user-one-foo-two' })); +// @ts-expect-error +router.push(localePath({ name: 'user-one-foo-two', params: { one: 1 } })); + +// * --- [id]/[slug].vue +// @ts-expect-error +router.push(localePath({ name: 'user-id-slug' })); +// @ts-expect-error +router.push(localePath({ name: 'user-id-slug', params: { id: 1 } })); + +// * --- Routes added by modules +// @ts-expect-error +router.push(localePath({ name: 'test-module' })); + +// * --- Path navigation +// @ts-expect-error +router.push(localePath('/fooooooooooo')); +// @ts-expect-error +router.push(localePath({ path: '/foo' })); + +// $ ----- Should be valid ✅ + +router.push(localePath({ name: 'index' })); +router.push(localePath({ name: 'user-id', params: { id: 1 }, hash: 'baz' }, 'en')); +router.push(localePath({ name: 'user-foo-bar', params: { foo: 'bar' }, force: true })); +router.push(localePath({ name: 'user-foo-bar', params: { foo: 'bar', bar: 'baz' } }, 'fr')); +router.push(localePath({ name: 'user-catch-slug', params: { slug: ['foo'] } })); +router.push(localePath({ name: 'user-catch-slug', params: { slug: [1, 2, 3] } }, 'en')); +router.push(localePath({ name: 'user-one-foo-two', params: { one: 1, two: '2' } })); +router.push(localePath({ name: 'user-id-slug', params: { slug: '2' }, query: { foo: 'bar' } })); +router.push(localePath({ name: 'test-module', params: { foo: 1 }, query: { foo: 'bar' } })); + +router.replace(localePath({ name: 'index' })); +router.replace(localePath({ name: 'user-id', params: { id: 1 }, hash: 'baz' })); + +// --- Path navigation + +// ! ------ Should Error ❌ + +// @ts-expect-error +assertType(router.push(localePath(''))); +// @ts-expect-error +assertType(router.push(localePath('/admin '))); +// @ts-expect-error +assertType(router.push(localePath('/admin/ /'))); +// @ts-expect-error +assertType(router.push(localePath(`/ / // / / eefzr`))); +// @ts-expect-error +assertType(router.push(localePath('/elzhlzehflzhef'))); +// @ts-expect-error +assertType(router.push(localePath('/admin/foo/bar'))); +// @ts-expect-error +assertType(router.push(localePath('/admin/foo/bar/baz'))); +// @ts-expect-error +assertType(router.push(localePath(`/admin/${id}/action-bar/taz?query`))); +// @ts-expect-error +assertType(router.push(localePath('/admin/panel/3O9393/bar'))); +// @ts-expect-error +assertType(router.push(localePath('/admin/foo/ profile/ezfje'))); +// @ts-expect-error +assertType(router.push(localePath('/admin/3U93U/settings/baz'))); +// @ts-expect-error +assertType(router.push(localePath('/admin/panel/?fjzk'))); + +// $ ----- Should be valid ✅ + +const id = '38789803'; +assertType(router.push(localePath('/'))); +assertType(router.push(localePath('/baguette'))); +assertType(router.push(localePath('/admin/foo'))); +assertType(router.push(localePath('/admin/foo/'))); +assertType(router.push(localePath(`/admin/${id}/action-bar#hash`))); +assertType(router.push(localePath(`/admin/${id}/action-bar?query=bar`))); +assertType(router.push(localePath('/admin/foo/profile/'))); +assertType(router.push(localePath(`/admin/${id}/settings`))); +assertType(router.push(localePath('/admin/panel/'))); +assertType(router.push(localePath('/admin/panel/938783/'))); +assertType(router.push(localePath('/user/38873-'))); +assertType(router.push(localePath('/user/38673/bar/#hash'))); +assertType(router.push(localePath('/user/ç9737/foo/articles?baz=foo'))); +assertType(router.push(localePath('/user/catch/1/2'))); +assertType(router.push(localePath('/user/test-'))); +assertType(router.push(localePath('/user'))); + +// * Resolved routes + +const resolved1 = router.resolve(localePath({ name: 'index' })); +assertType<'index'>(resolved1.name); +// @ts-expect-error +assertType<'index'>(resolved1.params); + +const resolved2 = router.resolve(localePath({ name: 'user-id', params: { id: 1 }, hash: 'baz' })); +assertType<'user-id'>(resolved2.name); +assertType<{ id: string }>(resolved2.params); + +// - Usage of localePath with NuxtLink + +const NuxtLink: GlobalComponents['NuxtLink'] = vi.fn() as any; + +// ! ------ Should Error ❌ + +// * index.vue +// @ts-expect-error +assertType(new NuxtLink({ to: localePath({ name: 'index' }, 'DE') })); +// @ts-expect-error +assertType(new NuxtLink({ to: localePath({ name: 'index', params: { id: 1 } }, 'es') })); +// @ts-expect-error +assertType(new NuxtLink({ to: localePath({ name: 'blabla-baguette' }) })); + +// * --- [id].vue +// @ts-expect-error +assertType(new NuxtLink({ to: localePath({ name: 'user-id' }) })); +// @ts-expect-error +assertType(new NuxtLink({ to: localePath({ name: 'user-id', params: { foo: 'bar' } }) })); + +// * --- [foo]-[[bar]].vue +// @ts-expect-error +assertType(new NuxtLink({ to: localePath({ name: 'user-foo-bar' }) })); +// @ts-expect-error +assertType(new NuxtLink({ to: localePath({ name: 'user-foo-bar', params: { bar: 1 } }) })); + +// * --- [...slug].vue +// @ts-expect-error +assertType(new NuxtLink({ to: localePath({ name: 'user-slug' }) })); +// @ts-expect-error +assertType(new NuxtLink({ to: localePath({ name: 'user-slug', params: { slug: 1 } }) })); + +// * --- [one]-foo-[two].vue +// @ts-expect-error +assertType(new NuxtLink({ to: localePath({ name: 'user-one-foo-two' }) })); +// @ts-expect-error +assertType(new NuxtLink({ to: localePath({ name: 'user-one-foo-two', params: { one: 1 } }) })); + +// * --- [id]/[slug].vue +// @ts-expect-error +assertType(new NuxtLink({ to: localePath({ name: 'user-id-slug' }) })); +// @ts-expect-error +assertType(new NuxtLink({ to: localePath({ name: 'user-id-slug', params: { id: 1 } }) })); + +// * --- Routes added by modules +// @ts-expect-error +assertType(new NuxtLink({ to: localePath({ name: 'test-module' }) })); + +// $ ----- Should be valid ✅ + +assertType(new NuxtLink({ to: localePath({ name: 'index' }) })); +assertType( + new NuxtLink({ to: localePath({ name: 'user-id', params: { id: 1 }, hash: 'baz' }, 'en') }) +); +assertType( + new NuxtLink({ to: localePath({ name: 'user-foo-bar', params: { foo: 'bar' }, force: true }) }) +); +assertType( + new NuxtLink({ + to: localePath({ name: 'user-foo-bar', params: { foo: 'bar', bar: 'baz' } }, 'fr'), + }) +); +assertType( + new NuxtLink({ to: localePath({ name: 'user-catch-slug', params: { slug: ['foo'] } }) }) +); +assertType( + new NuxtLink({ to: localePath({ name: 'user-catch-slug', params: { slug: [1, 2, 3] } }, 'en') }) +); +assertType( + new NuxtLink({ to: localePath({ name: 'user-one-foo-two', params: { one: 1, two: '2' } }) }) +); +assertType( + new NuxtLink({ + to: localePath({ name: 'user-id-slug', params: { slug: '2' }, query: { foo: 'bar' } }), + }) +); + +assertType( + new NuxtLink({ + to: localePath({ name: 'test-module', params: { foo: 1 }, query: { foo: 'bar' } }), + }) +); + +// * with path + +assertType( + new NuxtLink({ + to: localePath('/user'), + }) +); + +// - Usage of localePath with navigateTo + +// ! ------ Should Error ❌ + +// * index.vue +// @ts-expect-error +navigateTo(localePath({ name: 'index' }, 'DE')); +// @ts-expect-error +navigateTo(localePath({ name: 'index', params: { id: 1 } }, 'es')); +// @ts-expect-error +navigateTo(localePath({ name: 'index', params: { id: 1 } })); +// @ts-expect-error +navigateTo(localePath({ name: 'blabla-baguette' })); + +// * --- [id].vue +// @ts-expect-error +navigateTo(localePath({ name: 'user-id' })); +// @ts-expect-error +navigateTo(localePath({ name: 'user-id', params: { foo: 'bar' } })); + +// * --- [foo]-[[bar]].vue +// @ts-expect-error +navigateTo(localePath({ name: 'user-foo-bar' })); +// @ts-expect-error +navigateTo(localePath({ name: 'user-foo-bar', params: { bar: 1 } })); + +// * --- [...slug].vue +// @ts-expect-error +navigateTo(localePath({ name: 'user-catch-slug' })); +// @ts-expect-error +navigateTo(localePath({ name: 'user-catch-slug', params: { slug: 1 } })); + +// * --- [one]-foo-[two].vue +// @ts-expect-error +navigateTo(localePath({ name: 'user-one-foo-two' })); +// @ts-expect-error +navigateTo(localePath({ name: 'user-one-foo-two', params: { one: 1 } })); + +// * --- [id]/[slug].vue +// @ts-expect-error +navigateTo(localePath({ name: 'user-id-slug' })); +// @ts-expect-error +navigateTo(localePath({ name: 'user-id-slug', params: { id: 1 } })); + +// * --- Routes added by modules +// @ts-expect-error +navigateTo(localePath({ name: 'test-module' })); + +// $ ----- Should be valid ✅ + +navigateTo(localePath({ name: 'index' })); +navigateTo(localePath({ name: 'user-id', params: { id: 1 }, hash: 'baz' }, 'en')); +navigateTo(localePath({ name: 'user-foo-bar', params: { foo: 'bar' }, force: true })); +navigateTo(localePath({ name: 'user-foo-bar', params: { foo: 'bar', bar: 'baz' } }, 'fr')); +navigateTo(localePath({ name: 'user-catch-slug', params: { slug: ['foo'] } })); +navigateTo(localePath({ name: 'user-catch-slug', params: { slug: [1, 2, 3] } }, 'en')); +navigateTo(localePath({ name: 'user-one-foo-two', params: { one: 1, two: '2' } })); +navigateTo(localePath({ name: 'user-id-slug', params: { slug: '2' }, query: { foo: 'bar' } })); +navigateTo(localePath({ name: 'test-module', params: { foo: 1 }, query: { foo: 'bar' } })); + +navigateTo(localePath('/user')); + +// * --- Resolved types added by modules + +const resolvedNavigateToRoute = await navigateTo( + localePath({ + name: 'user-one-foo-two', + params: { one: 1, two: 2 }, + }) +); + +if (resolvedNavigateToRoute && !(resolvedNavigateToRoute instanceof Error)) { + expectTypeOf(resolvedNavigateToRoute.name).toMatchTypeOf<'user-one-foo-two'>(); + expectTypeOf(resolvedNavigateToRoute.params).toMatchTypeOf<{ + one: string | number; + two: string | number; + }>(); + expectTypeOf(resolvedNavigateToRoute.query).toMatchTypeOf(); +} diff --git a/test/fixtures/sample-project/tests/i18n/useLocaleRoute.spec-d.ts b/test/fixtures/sample-project/tests/i18n/useLocaleRoute.spec-d.ts new file mode 100644 index 0000000..0157be7 --- /dev/null +++ b/test/fixtures/sample-project/tests/i18n/useLocaleRoute.spec-d.ts @@ -0,0 +1,159 @@ +import { assertType, test } from 'vitest'; +import type { RouteLocationMatched } from 'vue-router'; +import type { TypedRouteFromName } from '@typed-router'; +import { useLocaleRoute } from '@typed-router'; + +// @ts-expect-error Ensure global imports are disabled +declare const globalDecl: (typeof globalThis)['useLocaleRoute']; + +const localeRoute = useLocaleRoute(); + +// ! ------ Should Error ❌ + +// @ts-expect-error +assertType(localeRoute({ name: 'index' }, 'DE')); +// * index.vue +// @ts-expect-error +assertType(localeRoute({ name: 'index', params: { id: 1 } }, 'es')); +// @ts-expect-error +assertType(localeRoute({ name: 'index', params: { id: 1 } })); +// @ts-expect-error +assertType(localeRoute({ name: 'blabla-baguette' })); + +// * --- [id].vue +// @ts-expect-error +assertType(localeRoute({ name: 'user-id' })); +// @ts-expect-error +assertType(localeRoute({ name: 'user-id', params: { foo: 'bar' } })); + +// * --- [foo]-[[bar]].vue +// @ts-expect-error +assertType(localeRoute({ name: 'user-foo-bar' })); +// @ts-expect-error +assertType(localeRoute({ name: 'user-foo-bar', params: { bar: 1 } })); + +// * --- [...slug].vue +// @ts-expect-error +assertType(localeRoute({ name: 'user-slug' })); +// @ts-expect-error +assertType(localeRoute({ name: 'user-slug', params: { slug: 1 } })); + +// * --- [one]-foo-[two].vue +// @ts-expect-error +assertType(localeRoute({ name: 'user-one-foo-two' })); +// @ts-expect-error +assertType(localeRoute({ name: 'user-one-foo-two', params: { one: 1 } })); + +// * --- [id]/[slug].vue +// @ts-expect-error +assertType(localeRoute({ name: 'user-id-slug' })); +// @ts-expect-error +assertType(localeRoute({ name: 'user-id-slug', params: { id: 1 } })); + +// * --- Routes added by modules +// @ts-expect-error +assertType(localeRoute({ name: 'test-module' })); + +// * --- Path navigation +// @ts-expect-error +assertType(localeRoute('/fooooo')); +// @ts-expect-error +assertType(localeRoute({ path: '/foooo' })); + +// * Basic types + +test('Basic', () => { + const resolved = localeRoute({ name: 'user-foo-bar', params: { foo: 1 } }, 'fr'); + + assertType>(resolved); + assertType<'user-foo-bar'>(resolved.name); + assertType<{ + foo: string; + bar?: string | undefined; + }>(resolved.params); + assertType(resolved.fullPath); + assertType(resolved.hash); + assertType(resolved.path); + assertType(resolved.matched); +}); + +// * index.vue + +test('index', () => { + const resolved = localeRoute({ name: 'index' }, 'fr'); + + assertType>(resolved); + assertType<'index'>(resolved.name); + // @ts-expect-error + assertType(resolved.params); +}); + +// * --- [id].vue + +test('[id]', () => { + const resolved = localeRoute({ name: 'user-id', params: { id: 1 } }, 'fr'); + + assertType>(resolved); + assertType<'user-id'>(resolved.name); + assertType<{ id: string }>(resolved.params); +}); + +// * --- [foo]-[[bar]].vue +test('[foo]-[[bar]]', () => { + const resolved = localeRoute({ name: 'user-foo-bar', params: { foo: 1, bar: 1 } }, 'fr'); + + assertType>(resolved); + assertType<'user-foo-bar'>(resolved.name); + assertType<{ + foo: string; + bar?: string | undefined; + }>(resolved.params); +}); + +// * --- [...slug].vue +test('[...slug]', () => { + const resolved = localeRoute({ name: 'user-catch-slug', params: { slug: [1, 2] } }, 'fr'); + + assertType>(resolved); + assertType<'user-catch-slug'>(resolved.name); + assertType<{ + slug: string[]; + }>(resolved.params); +}); + +// * --- [one]-foo-[two].vue +test('[one]-foo-[two]', () => { + const resolved = localeRoute({ name: 'user-one-foo-two', params: { one: 1, two: 2 } }, 'fr'); + + assertType>(resolved); + assertType<'user-one-foo-two'>(resolved.name); + assertType<{ + one: string; + two: string; + }>(resolved.params); +}); + +// * --- [id]/[slug].vue + +test('[id]/[slug]', () => { + const resolved = localeRoute({ name: 'user-id-slug', params: { slug: 1, id: '1' } }, 'fr'); + + assertType>(resolved); + assertType<'user-id-slug'>(resolved.name); + assertType<{ + id: string; + slug: string; + }>(resolved.params); +}); + +// * --- Routes added by modules + +test('Routes added by modules', () => { + const resolved = localeRoute({ name: 'test-module', params: { foo: 1 } }, 'fr'); + + assertType>(resolved); + assertType<'test-module'>(resolved.name); + assertType<{ + foo: string; + }>(resolved.params); +}); diff --git a/test/fixtures/sample-project/tests/misc/definePageMeta.spec-d.ts b/test/fixtures/sample-project/tests/misc/definePageMeta.spec-d.ts new file mode 100644 index 0000000..ae2cee4 --- /dev/null +++ b/test/fixtures/sample-project/tests/misc/definePageMeta.spec-d.ts @@ -0,0 +1,117 @@ +import { assertType, expectTypeOf } from 'vitest'; +import { definePageMeta } from '@typed-router'; + +// Given + +// - Usage of useRouter with useRouter + +// ! ------ Should Error ❌ + +// * index.vue +definePageMeta({ redirect: { name: 'index' } }); +// @ts-expect-error +definePageMeta({ redirect: { name: 'index', params: { id: 1 } } }); +// @ts-expect-error +definePageMeta({ redirect: { name: 'blabla-baguette' } }); + +// * --- [id].vue +// @ts-expect-error +definePageMeta({ redirect: { name: 'user-id' } }); +// @ts-expect-error +definePageMeta({ redirect: { name: 'user-id', params: { foo: 'bar' } } }); + +// * --- [foo]-[[bar]].vue +// @ts-expect-error +definePageMeta({ redirect: { name: 'user-foo-bar' } }); +// @ts-expect-error +definePageMeta({ redirect: { name: 'user-foo-bar', params: { bar: 1 } } }); + +// * --- [...slug].vue +// @ts-expect-error +definePageMeta({ redirect: { name: 'user-slug' } }); +// @ts-expect-error +definePageMeta({ redirect: { name: 'user-slug', params: { slug: 1 } } }); + +// * --- [one]-foo-[two].vue +// @ts-expect-error +definePageMeta({ redirect: { name: 'user-one-foo-two' } }); +// @ts-expect-error +definePageMeta({ redirect: { name: 'user-one-foo-two', params: { one: 1 } } }); + +// * --- [id]/[slug].vue +// @ts-expect-error +definePageMeta({ redirect: { name: 'user-id-slug' } }); +// @ts-expect-error +definePageMeta({ redirect: { name: 'user-id-slug', params: { id: 1 } } }); + +// * --- Routes added by modules +// @ts-expect-error +definePageMeta({ redirect: { name: 'test-module' } }); + +// * --- Path navigation +// @ts-expect-error +definePageMeta({ redirect: '/fooooooooooo' }); +// @ts-expect-error +definePageMeta({ redirect: { path: '/foo' } }); + +// $ ----- Should be valid ✅ + +definePageMeta({ redirect: { name: 'index' } }); +definePageMeta({ redirect: { name: 'user-id', params: { id: 1 }, hash: 'baz' } }); +definePageMeta({ redirect: { name: 'user-foo-bar', params: { foo: 'bar' }, force: true } }); +definePageMeta({ redirect: { name: 'user-foo-bar', params: { foo: 'bar', bar: 'baz' } } }); +definePageMeta({ redirect: { name: 'user-catch-slug', params: { slug: ['foo'] } } }); +definePageMeta({ redirect: { name: 'user-catch-slug', params: { slug: [1, 2, 3] } } }); +definePageMeta({ redirect: { name: 'user-one-foo-two', params: { one: 1, two: '2' } } }); +definePageMeta({ + redirect: { name: 'user-id-slug', params: { slug: '2' }, query: { foo: 'bar' } }, +}); + +// --- Path navigation + +// ! ------ Should Error ❌ + +// @ts-expect-error +assertType(definePageMeta({ redirect: '' })); +// @ts-expect-error +assertType(definePageMeta({ redirect: '/admin ' })); +// @ts-expect-error +assertType(definePageMeta({ redirect: '/admin/ /' })); +// @ts-expect-error +assertType(definePageMeta({ redirect: `/ / // / / eefzr` })); +// @ts-expect-error +assertType(definePageMeta({ redirect: '/elzhlzehflzhef' })); +// @ts-expect-error +assertType(definePageMeta({ redirect: '/admin/foo/bar' })); +// @ts-expect-error +assertType(definePageMeta({ redirect: '/admin/foo/bar/baz' })); +// @ts-expect-error +assertType(definePageMeta({ redirect: `/admin/${id}/action-bar/taz?query` })); +// @ts-expect-error +assertType(definePageMeta({ redirect: '/admin/panel/3O9393/bar' })); +// @ts-expect-error +assertType(definePageMeta({ redirect: '/admin/foo/ profile/ezfje' })); +// @ts-expect-error +assertType(definePageMeta({ redirect: '/admin/3U93U/settings/baz' })); +// @ts-expect-error +assertType(definePageMeta({ redirect: '/admin/panel/?fjzk' })); + +// $ ----- Should be valid ✅ + +const id = '38789803'; +assertType(definePageMeta({ redirect: '/' })); +assertType(definePageMeta({ redirect: '/baguette' })); +assertType(definePageMeta({ redirect: '/admin/foo' })); +assertType(definePageMeta({ redirect: '/admin/foo/' })); +assertType(definePageMeta({ redirect: `/admin/${id}/action-bar#hash` })); +assertType(definePageMeta({ redirect: `/admin/${id}/action-bar?query=bar` })); +assertType(definePageMeta({ redirect: '/admin/foo/profile/' })); +assertType(definePageMeta({ redirect: `/admin/${id}/settings` })); +assertType(definePageMeta({ redirect: '/admin/panel/' })); +assertType(definePageMeta({ redirect: '/admin/panel/938783/' })); +assertType(definePageMeta({ redirect: '/user/38873-' })); +assertType(definePageMeta({ redirect: '/user/38673/bar/#hash' })); +assertType(definePageMeta({ redirect: '/user/ç9737/foo/articles?baz=foo' })); +assertType(definePageMeta({ redirect: '/user/catch/1/2' })); +assertType(definePageMeta({ redirect: '/user/test-' })); +assertType(definePageMeta({ redirect: '/user' })); diff --git a/test/fixtures/sample-project/tests/router/$typedRouter.spec-d.ts b/test/fixtures/sample-project/tests/router/$typedRouter.spec-d.ts new file mode 100644 index 0000000..2457cf5 --- /dev/null +++ b/test/fixtures/sample-project/tests/router/$typedRouter.spec-d.ts @@ -0,0 +1,84 @@ +import { useNuxtApp } from '#imports'; +import { assertType } from 'vitest'; +import type { TypedRouter } from '@typed-router'; + +// Given +const { $typedRouter } = useNuxtApp(); + +assertType($typedRouter); + +// - Usage of localePath with useRouter + +// ! ------ Should Error ❌ + +// * index.vue +// @ts-expect-error +$typedRouter.push({ name: 'index', params: { id: 1 } }); +// @ts-expect-error +$typedRouter.push({ name: 'index', params: { id: 1 } }); +// @ts-expect-error +$typedRouter.push({ name: 'blabla-baguette' }); + +// * --- [id].vue +// @ts-expect-error +$typedRouter.push({ name: 'user-id' }); +// @ts-expect-error +$typedRouter.push({ name: 'user-id', params: { foo: 'bar' } }); + +// * --- [foo]-[[bar]].vue +// @ts-expect-error +$typedRouter.push({ name: 'user-foo-bar' }); +// @ts-expect-error +$typedRouter.push({ name: 'user-foo-bar', params: { bar: 1 } }); + +// * --- [...slug].vue +// @ts-expect-error +$typedRouter.push({ name: 'user-slug' }); +// @ts-expect-error +$typedRouter.push({ name: 'user-slug', params: { slug: 1 } }); + +// * --- [one]-foo-[two].vue +// @ts-expect-error +$typedRouter.push({ name: 'user-one-foo-two' }); +// @ts-expect-error +$typedRouter.push({ name: 'user-one-foo-two', params: { one: 1 } }); + +// * --- [id]/[slug].vue +// @ts-expect-error +$typedRouter.push({ name: 'user-id-slug' }); +// @ts-expect-error +$typedRouter.push({ name: 'user-id-slug', params: { id: 1 } }); + +// * --- Routes added by modules +// @ts-expect-error +$typedRouter.push({ name: 'test-module' }); + +// * --- Path navigation +// @ts-expect-error +$typedRouter.push('/admin/:id/foo'); + +// $ ----- Should be valid ✅ + +$typedRouter.push({ name: 'index' }); +$typedRouter.push({ name: 'user-id', params: { id: 1 }, hash: 'baz' }); +$typedRouter.push({ name: 'user-foo-bar', params: { foo: 'bar' }, force: true }); +$typedRouter.push({ name: 'user-foo-bar', params: { foo: 'bar', bar: 'baz' } }); +$typedRouter.push({ name: 'user-catch-slug', params: { slug: ['foo'] } }); +$typedRouter.push({ name: 'user-catch-slug', params: { slug: [1, 2, 3] } }); +$typedRouter.push({ name: 'user-one-foo-two', params: { one: 1, two: '2' } }); +$typedRouter.push({ name: 'user-id-slug', params: { slug: '2' }, query: { foo: 'bar' } }); +$typedRouter.push({ name: 'test-module', params: { foo: 1 }, query: { foo: 'bar' } }); + +$typedRouter.replace({ name: 'index' }); +$typedRouter.replace({ name: 'user-id', params: { id: 1 }, hash: 'baz' }); + +// * Resolved routes + +const resolved1 = $typedRouter.resolve({ name: 'index' }); +assertType<'index'>(resolved1.name); +// @ts-expect-error +assertType<'index'>(resolved1.params); + +const resolved2 = $typedRouter.resolve({ name: 'user-id', params: { id: 1 }, hash: 'baz' }); +assertType<'user-id'>(resolved2.name); +assertType<{ id: string }>(resolved2.params); diff --git a/test/fixtures/sample-project/tests/router/NuxtLink.spec-d.ts b/test/fixtures/sample-project/tests/router/NuxtLink.spec-d.ts new file mode 100644 index 0000000..d04b913 --- /dev/null +++ b/test/fixtures/sample-project/tests/router/NuxtLink.spec-d.ts @@ -0,0 +1,129 @@ +import { assertType, vi } from 'vitest'; +import type { GlobalComponents } from 'vue'; + +const NuxtLink: GlobalComponents['NuxtLink'] = vi.fn() as any; + +// ! ------ Should Error ❌ + +// * index.vue +// @ts-expect-error +assertType(new NuxtLink({ to: { name: 'index', params: { id: 1 } } })); +// @ts-expect-error +assertType(new NuxtLink({ to: { name: 'index', params: { id: 1 } } })); +// @ts-expect-error +assertType(new NuxtLink({ to: { name: 'blabla-baguette' } })); + +// * --- [id].vue +// @ts-expect-error +assertType(new NuxtLink({ to: { name: 'user-id' } })); +// @ts-expect-error +assertType(new NuxtLink({ to: { name: 'user-id', params: { foo: 'bar' } } })); + +// * --- [foo]-[[bar]].vue +// @ts-expect-error +assertType(new NuxtLink({ to: { name: 'user-foo-bar' } })); +// @ts-expect-error +assertType(new NuxtLink({ to: { name: 'user-foo-bar', params: { bar: 1 } } })); + +// * --- [...slug].vue +// @ts-expect-error +assertType(new NuxtLink({ to: { name: 'user-slug' } })); +// @ts-expect-error +assertType(new NuxtLink({ to: { name: 'user-slug', params: { slug: 1 } } })); + +// * --- [one]-foo-[two].vue +// @ts-expect-error +assertType(new NuxtLink({ to: { name: 'user-one-foo-two' } })); +// @ts-expect-error +assertType(new NuxtLink({ to: { name: 'user-one-foo-two', params: { one: 1 } } })); + +// * --- [id]/[slug].vue +// @ts-expect-error +assertType(new NuxtLink({ to: { name: 'user-id-slug' } })); +// @ts-expect-error +assertType(new NuxtLink({ to: { name: 'user-id-slug', params: { id: 1 } } })); + +// * --- Routes added by modules +// @ts-expect-error +assertType(new NuxtLink({ to: { name: 'test-module' } })); + +// --- Path navigation + +// ! ------ Should Error ❌ + +// @ts-expect-error +assertType(new NuxtLink({ to: '' })); +// @ts-expect-error +assertType(new NuxtLink({ to: '/admin ' })); +// @ts-expect-error +assertType(new NuxtLink({ to: '/admin/ /' })); +// @ts-expect-error +assertType(new NuxtLink({ to: `/ / // / / eefzr` })); +// @ts-expect-error +assertType(new NuxtLink({ to: '/elzhlzehflzhef' })); +// @ts-expect-error +assertType(new NuxtLink({ to: '/admin/foo/bar' })); +// @ts-expect-error +assertType(new NuxtLink({ to: '/admin/foo/bar/baz' })); +// @ts-expect-error +assertType(new NuxtLink({ to: `/admin/${id}/action-bar/taz?query` })); +// @ts-expect-error +assertType(new NuxtLink({ to: '/admin/panel/3O9393/bar' })); +// @ts-expect-error +assertType(new NuxtLink({ to: '/admin/foo/ profile/ezfje' })); +// @ts-expect-error +assertType(new NuxtLink({ to: '/admin/3U93U/settings/baz' })); +// @ts-expect-error +assertType(new NuxtLink({ to: '/admin/panel/?fjzk' })); + +// $ ----- Should be valid ✅ + +const id = '38789803'; +assertType(new NuxtLink({ to: '/' })); +assertType(new NuxtLink({ to: '/baguette' })); +assertType(new NuxtLink({ to: '/admin/foo' })); +assertType(new NuxtLink({ to: '/admin/foo/' })); +assertType(new NuxtLink({ to: `/admin/${id}/action-bar#hash` })); +assertType(new NuxtLink({ to: `/admin/${id}/action-bar?query=bar` })); +assertType(new NuxtLink({ to: '/admin/foo/profile/' })); +assertType(new NuxtLink({ to: `/admin/${id}/settings` })); +assertType(new NuxtLink({ to: '/admin/panel/' })); +assertType(new NuxtLink({ to: '/admin/panel/938783/' })); +assertType(new NuxtLink({ to: '/user/38873-' })); +assertType(new NuxtLink({ to: '/user/38673/bar/#hash' })); +assertType(new NuxtLink({ to: '/user/ç9737/foo/articles?baz=foo' })); +assertType(new NuxtLink({ to: '/user/catch/1/2' })); +assertType(new NuxtLink({ to: '/user/test-' })); +assertType(new NuxtLink({ to: '/user' })); + +// $ ----- Should be valid ✅ + +assertType(new NuxtLink({ to: { name: 'index' } })); +assertType(new NuxtLink({ to: { name: 'user-id', params: { id: 1 }, hash: 'baz' } })); +assertType(new NuxtLink({ to: { name: 'user-foo-bar', params: { foo: 'bar' }, force: true } })); +assertType( + new NuxtLink({ + to: { name: 'user-foo-bar', params: { foo: 'bar', bar: 'baz' } }, + }) +); +assertType(new NuxtLink({ to: { name: 'user-catch-slug', params: { slug: ['foo'] } } })); +assertType(new NuxtLink({ to: { name: 'user-catch-slug', params: { slug: [1, 2, 3] } } })); +assertType(new NuxtLink({ to: { name: 'user-one-foo-two', params: { one: 1, two: '2' } } })); +assertType( + new NuxtLink({ + to: { name: 'user-id-slug', params: { slug: '2' }, query: { foo: 'bar' } }, + }) +); + +assertType( + new NuxtLink({ + to: { name: 'test-module', params: { foo: 1 }, query: { foo: 'bar' } }, + }) +); + +// - With External prop + +// $ ----- Should be valid ✅ + +assertType(new NuxtLink({ to: '/admin/:id/', external: false })); +assertType(new NuxtLink({ to: 'http://google.com', external: true })); diff --git a/test/fixtures/sample-project/tests/router/navigateTo.spec-d.ts b/test/fixtures/sample-project/tests/router/navigateTo.spec-d.ts new file mode 100644 index 0000000..647b1d6 --- /dev/null +++ b/test/fixtures/sample-project/tests/router/navigateTo.spec-d.ts @@ -0,0 +1,237 @@ +import { assertType } from 'vitest'; +import type { LocationQuery } from 'vue-router'; +import test from 'node:test'; +import { navigateTo } from '@typed-router'; + +// @ts-expect-error Ensure global imports are disabled +declare const globalDecl: (typeof globalThis)['navigateTo']; + +// ! ------ Should Error ❌ + +// * index.vue +// @ts-expect-error +navigateTo({ name: 'index', params: { id: 1 } }); +// @ts-expect-error +navigateTo({ name: 'index', params: { id: 1 } }); +// @ts-expect-error +navigateTo({ name: 'blabla-baguette' }); + +// * --- [id].vue +// @ts-expect-error +navigateTo({ name: 'user-id' }); +// @ts-expect-error +navigateTo({ name: 'user-id', params: { foo: 'bar' } }); + +// * --- [foo]-[[bar]].vue +// @ts-expect-error +navigateTo({ name: 'user-foo-bar' }); +// @ts-expect-error +navigateTo({ name: 'user-foo-bar', params: { bar: 1 } }); + +// * --- [...slug].vue +// @ts-expect-error +navigateTo({ name: 'user-slug' }); +// @ts-expect-error +navigateTo({ name: 'user-slug', params: { slug: 1 } }); + +// * --- [one]-foo-[two].vue +// @ts-expect-error +navigateTo({ name: 'user-one-foo-two' }); +// @ts-expect-error +navigateTo({ name: 'user-one-foo-two', params: { one: 1 } }); + +// * --- [id]/[slug].vue +// @ts-expect-error +navigateTo({ name: 'user-id-slug' }); +// @ts-expect-error +navigateTo({ name: 'user-id-slug', params: { id: 1 } }); + +// * --- Routes added by modules +// @ts-expect-error +navigateTo({ name: 'test-module' }); + +// $ ----- Should be valid ✅ + +navigateTo({ name: 'index' }, { external: true }); +navigateTo({ name: 'user-id', params: { id: 1 }, hash: 'baz' }); +navigateTo({ name: 'user-foo-bar', params: { foo: 'bar' }, force: true }); +navigateTo({ name: 'user-foo-bar', params: { foo: 'bar', bar: 'baz' } }); +navigateTo({ name: 'user-catch-slug', params: { slug: ['foo'] } }); +navigateTo({ name: 'user-catch-slug', params: { slug: [1, 2, 3] } }); +navigateTo({ name: 'user-one-foo-two', params: { one: 1, two: '2' } }); +navigateTo({ name: 'user-id-slug', params: { slug: '2' }, query: { foo: 'bar' } }); +navigateTo({ name: 'test-module', params: { foo: 1 }, query: { foo: 'bar' } }); + +// --- Path navigation + +// ! ------ Should Error ❌ + +// @ts-expect-error +assertType(navigateTo('')); +// @ts-expect-error +assertType(navigateTo('/admin ')); +// @ts-expect-error +assertType(navigateTo('/admin/ /')); +// @ts-expect-error +assertType(navigateTo(`/ / // / / eefzr`)); +// @ts-expect-error +assertType(navigateTo('/elzhlzehflzhef')); +// @ts-expect-error +assertType(navigateTo('/admin/foo/bar')); +// @ts-expect-error +assertType(navigateTo('/admin/foo/bar/baz')); +// @ts-expect-error +assertType(navigateTo(`/admin/${id}/action-bar/taz?query`)); +// @ts-expect-error +assertType(navigateTo('/admin/panel/3O9393/bar')); +// @ts-expect-error +assertType(navigateTo('/admin/foo/ profile/ezfje')); +// @ts-expect-error +assertType(navigateTo('/admin/3U93U/settings/baz')); +// @ts-expect-error +assertType(navigateTo('/admin/panel/?fjzk')); +// @ts-expect-error +assertType(navigateTo('/admin/panel/938783/ ')); +// @ts-expect-error +assertType(navigateTo('/user/3887/foo/bar/')); +// @ts-expect-error +assertType(navigateTo('/admin/:id//')); + +// $ ----- Should be valid ✅ + +const id = '38789803'; +assertType(navigateTo('/')); +assertType(navigateTo('/baguette')); +assertType(navigateTo('/admin/foo')); +assertType(navigateTo('/admin/foo/')); +assertType(navigateTo(`/admin/${id}/action-bar#hash`)); +assertType(navigateTo(`/admin/${id}/action-bar?query=bar`)); +assertType(navigateTo('/admin/foo/profile/')); +assertType(navigateTo(`/admin/${id}/settings`)); +assertType(navigateTo('/admin/panel/')); +assertType(navigateTo('/admin/panel/938783/')); +assertType(navigateTo('/user/38873-')); +assertType(navigateTo('/user/38673/bar/#hash')); +assertType(navigateTo('/user/ç9737/foo/articles?baz=foo')); +assertType(navigateTo('/user/catch/1/2')); +assertType(navigateTo('/user/test-')); +assertType(navigateTo('/user')); +// - Resolved routes + +// * index.vue +test('', async () => { + const resolvedNavigateToRoute = await navigateTo({ + name: 'index', + }); + + if (resolvedNavigateToRoute && !(resolvedNavigateToRoute instanceof Error)) { + assertType<'index'>(resolvedNavigateToRoute.name); + // @ts-expect-error + assertType(resolvedNavigateToRoute.params); + } +}); + +// * --- [id].vue +test('', async () => { + const resolvedNavigateToRoute = await navigateTo({ + name: 'user-id', + params: { + id: 1, + }, + }); + + if (resolvedNavigateToRoute && !(resolvedNavigateToRoute instanceof Error)) { + assertType<'user-id'>(resolvedNavigateToRoute.name); + assertType<{ + id: string; + }>(resolvedNavigateToRoute.params); + } +}); + +// * --- [foo]-[[bar]].vue +test('', async () => { + const resolvedNavigateToRoute = await navigateTo({ + name: 'user-foo-bar', + params: { + foo: 1, + bar: 1, + }, + }); + + if (resolvedNavigateToRoute && !(resolvedNavigateToRoute instanceof Error)) { + assertType<'user-foo-bar'>(resolvedNavigateToRoute.name); + assertType<{ + foo: string; + bar?: string | undefined; + }>(resolvedNavigateToRoute.params); + } +}); + +// * --- [...slug].vue +test('', async () => { + const resolvedNavigateToRoute = await navigateTo({ + name: 'user-catch-slug', + params: { + slug: [1, 2, 3], + }, + }); + + if (resolvedNavigateToRoute && !(resolvedNavigateToRoute instanceof Error)) { + assertType<'user-catch-slug'>(resolvedNavigateToRoute.name); + assertType<{ + slug: string[]; + }>(resolvedNavigateToRoute.params); + } +}); + +// * --- [one]-foo-[two].vue + +const resolvedNavigateToRoute = await navigateTo({ + name: 'user-one-foo-two', + params: { one: 1, two: 2 }, +}); + +if (resolvedNavigateToRoute && !(resolvedNavigateToRoute instanceof Error)) { + assertType<'user-one-foo-two'>(resolvedNavigateToRoute.name); + assertType<{ + one: string | number; + two: string | number; + }>(resolvedNavigateToRoute.params); + assertType(resolvedNavigateToRoute.query); +} + +// * --- [id]/[slug].vue +test('', async () => { + const resolvedNavigateToRoute = await navigateTo({ + name: 'user-id-slug', + params: { + slug: 1, + id: 1, + }, + }); + + if (resolvedNavigateToRoute && !(resolvedNavigateToRoute instanceof Error)) { + assertType<'user-id-slug'>(resolvedNavigateToRoute.name); + assertType<{ + id: string; + slug: string; + }>(resolvedNavigateToRoute.params); + } +}); + +// * --- Routes added by modules +test('', async () => { + const resolvedNavigateToRoute = await navigateTo({ + name: 'test-module', + params: { + foo: 1, + }, + }); + + if (resolvedNavigateToRoute && !(resolvedNavigateToRoute instanceof Error)) { + assertType<'test-module'>(resolvedNavigateToRoute.name); + assertType<{ + foo: string; + }>(resolvedNavigateToRoute.params); + } +}); diff --git a/test/fixtures/sample-project/tests/router/useRouter.spec-d.ts b/test/fixtures/sample-project/tests/router/useRouter.spec-d.ts new file mode 100644 index 0000000..3d4502b --- /dev/null +++ b/test/fixtures/sample-project/tests/router/useRouter.spec-d.ts @@ -0,0 +1,132 @@ +import { assertType } from 'vitest'; +import type { TypedRouter, } from '@typed-router'; +import { useRouter } from '@typed-router'; + +// @ts-expect-error Ensure global imports are disabled +declare const globalDecl: (typeof globalThis)['useRouter']; + +// Given +const router = useRouter(); + +assertType(router); + +// - Usage of useRouter with useRouter + +// ! ------ Should Error ❌ + +// * index.vue +// @ts-expect-error +router.push({ name: 'index', params: { id: 1 } }); +// @ts-expect-error +router.push({ name: 'index', params: { id: 1 } }); +// @ts-expect-error +router.push({ name: 'blabla-baguette' }); + +// * --- [id].vue +// @ts-expect-error +router.push({ name: 'user-id' }); +// @ts-expect-error +router.push({ name: 'user-id', params: { foo: 'bar' } }); + +// * --- [foo]-[[bar]].vue +// @ts-expect-error +router.push({ name: 'user-foo-bar' }); +// @ts-expect-error +router.push({ name: 'user-foo-bar', params: { bar: 1 } }); + +// * --- [...slug].vue +// @ts-expect-error +router.push({ name: 'user-slug' }); +// @ts-expect-error +router.push({ name: 'user-slug', params: { slug: 1 } }); + +// * --- [one]-foo-[two].vue +// @ts-expect-error +router.push({ name: 'user-one-foo-two' }); +// @ts-expect-error +router.push({ name: 'user-one-foo-two', params: { one: 1 } }); + +// * --- [id]/[slug].vue +// @ts-expect-error +router.push({ name: 'user-id-slug' }); +// @ts-expect-error +router.push({ name: 'user-id-slug', params: { id: 1 } }); + +// * --- Routes added by modules +// @ts-expect-error +router.push({ name: 'test-module' }); + +// $ ----- Should be valid ✅ + +router.push({ name: 'index' }); +router.push({ name: 'user-id', params: { id: 1 }, hash: 'baz' }); +router.push({ name: 'user-foo-bar', params: { foo: 'bar' }, force: true }); +router.push({ name: 'user-foo-bar', params: { foo: 'bar', bar: 'baz' } }); +router.push({ name: 'user-catch-slug', params: { slug: ['foo'] } }); +router.push({ name: 'user-catch-slug', params: { slug: [1, 2, 3] } }); +router.push({ name: 'user-one-foo-two', params: { one: 1, two: '2' } }); +router.push({ name: 'user-id-slug', params: { slug: '2' }, query: { foo: 'bar' } }); +router.push({ name: 'test-module', params: { foo: 1 }, query: { foo: 'bar' } }); + +router.replace({ name: 'index' }); +router.replace({ name: 'user-id', params: { id: 1 }, hash: 'baz' }); + +// --- Path navigation + +// ! ------ Should Error ❌ + +// @ts-expect-error +assertType(router.push('')); +// @ts-expect-error +assertType(router.push('/admin ')); +// @ts-expect-error +assertType(router.push('/admin/ /')); +// @ts-expect-error +assertType(router.push(`/ / // / / eefzr`)); +// @ts-expect-error +assertType(router.push('/elzhlzehflzhef')); +// @ts-expect-error +assertType(router.push('/admin/foo/bar')); +// @ts-expect-error +assertType(router.push('/admin/foo/bar/baz')); +// @ts-expect-error +assertType(router.push(`/admin/${id}/action-bar/taz?query`)); +// @ts-expect-error +assertType(router.push('/admin/panel/3O9393/bar')); +// @ts-expect-error +assertType(router.push('/admin/foo/ profile/ezfje')); +// @ts-expect-error +assertType(router.push('/admin/3U93U/settings/baz')); +// @ts-expect-error +assertType(router.push('/admin/panel/?fjzk')); + +// $ ----- Should be valid ✅ + +const id = '38789803'; +assertType(router.push('/')); +assertType(router.push('/baguette')); +assertType(router.push('/admin/foo')); +assertType(router.push('/admin/foo/')); +assertType(router.push(`/admin/${id}/action-bar#hash`)); +assertType(router.push(`/admin/${id}/action-bar?query=bar`)); +assertType(router.push('/admin/foo/profile/')); +assertType(router.push(`/admin/${id}/settings`)); +assertType(router.push('/admin/panel/')); +assertType(router.push('/admin/panel/938783/')); +assertType(router.push('/user/38873-')); +assertType(router.push('/user/38673/bar/#hash')); +assertType(router.push('/user/ç9737/foo/articles?baz=foo')); +assertType(router.push('/user/catch/1/2')); +assertType(router.push('/user/test-')); +assertType(router.push('/user')); + +// * Resolved routes + +const resolved1 = router.resolve({ name: 'index' }); +assertType<'index'>(resolved1.name); +// @ts-expect-error +assertType<'index'>(resolved1.params); + +const resolved2 = router.resolve({ name: 'user-id', params: { id: 1 }, hash: 'baz' }); +assertType<'user-id'>(resolved2.name); +assertType<{ id: string }>(resolved2.params); diff --git a/test/fixtures/sample-project/tests/routes/useRoute.spec-d.ts b/test/fixtures/sample-project/tests/routes/useRoute.spec-d.ts new file mode 100644 index 0000000..983455f --- /dev/null +++ b/test/fixtures/sample-project/tests/routes/useRoute.spec-d.ts @@ -0,0 +1,87 @@ +import { assertType, test } from 'vitest'; +import type { RouteLocationMatched } from 'vue-router'; +import type { TypedRouteFromName } from '@typed-router'; +import {useRoute} from '@typed-router' + +// @ts-expect-error Ensure global imports are disabled +declare const globalDecl: (typeof globalThis)['useRoute']; + +// Given +const route = useRoute(); + +test('Basic', () => { + const namedRoute = useRoute('user-foo-bar'); + + assertType>(namedRoute); + assertType<'user-foo-bar'>(namedRoute.name); + assertType<{ + foo: string; + bar?: string | undefined; + }>(namedRoute.params); + assertType(namedRoute.fullPath); + assertType(namedRoute.hash); + assertType(namedRoute.path); + assertType(namedRoute.matched); +}); + +// * index.vue + +if (route.name === 'index') { + assertType<'index'>(route.name); + assertType(route.params); +} + +// * --- [id].vue +if (route.name === 'user-id') { + assertType>(route); + assertType<'user-id'>(route.name); + assertType<{ id: string }>(route.params); +} + +// * --- [foo]-[[bar]].vue +if (route.name === 'user-foo-bar') { + assertType>(route); + assertType<'user-foo-bar'>(route.name); + assertType<{ + foo: string; + bar?: string | undefined; + }>(route.params); +} + +// * --- [...slug].vue +if (route.name === 'user-catch-slug') { + assertType>(route); + assertType<'user-catch-slug'>(route.name); + assertType<{ + slug: string[]; + }>(route.params); +} + +// * --- [one]-foo-[two].vue +if (route.name === 'user-one-foo-two') { + assertType>(route); + assertType<'user-one-foo-two'>(route.name); + assertType<{ + one: string; + two: string; + }>(route.params); +} + +// * --- [id]/[slug].vue +if (route.name === 'user-id-slug') { + assertType>(route); + assertType<'user-id-slug'>(route.name); + assertType<{ + id: string; + slug: string; + }>(route.params); +} + +// * --- Routes added by modules +if (route.name === 'test-module') { + assertType>(route); + assertType<'test-module'>(route.name); + assertType<{ + foo: string; + }>(route.params); +} diff --git a/test/fixtures/sample-project/tsconfig.json b/test/fixtures/sample-project/tsconfig.json new file mode 100644 index 0000000..a746f2a --- /dev/null +++ b/test/fixtures/sample-project/tsconfig.json @@ -0,0 +1,4 @@ +{ + // https://nuxt.com/docs/guide/concepts/typescript + "extends": "./.nuxt/tsconfig.json" +} diff --git a/test/fixtures/withOptions/nuxt.config.ts b/test/fixtures/withOptions/nuxt.config.ts deleted file mode 100644 index 658a9f2..0000000 --- a/test/fixtures/withOptions/nuxt.config.ts +++ /dev/null @@ -1,10 +0,0 @@ -import NuxtTypedRouter from '../../..'; - -export default defineNuxtConfig({ - modules: [NuxtTypedRouter], - vite: { - resolve: { - dedupe: ['vue-router'], - }, - }, -}); diff --git a/test/fixtures/withOptions/pages/index.vue b/test/fixtures/withOptions/pages/index.vue deleted file mode 100644 index e3a145e..0000000 --- a/test/fixtures/withOptions/pages/index.vue +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/test/fixtures/withOptions/tests/e2e/withPartialStrict.spec.ts b/test/fixtures/withOptions/tests/e2e/withPartialStrict.spec.ts deleted file mode 100644 index b3dda7e..0000000 --- a/test/fixtures/withOptions/tests/e2e/withPartialStrict.spec.ts +++ /dev/null @@ -1,42 +0,0 @@ -test('empty') - -// import { fileURLToPath } from 'node:url'; -// import { setup } from '@nuxt/test-utils'; -// import { assertType } from 'vitest'; -// import { useRouter } from '../../.nuxt/typed-router'; -// import type { TypedNuxtLink } from '../../.nuxt/typed-router/typed-router'; - -// test.skip('The strict option should behave correctly with partial strict options', async () => { -// await setup({ -// rootDir: fileURLToPath(new URL('../../fixtures/withOptions', import.meta.url)), -// setupTimeout: 120000, -// nuxtConfig: { -// nuxtTypedRouter: { -// strict: { -// NuxtLink: { -// strictRouteLocation: true, -// }, -// router: { -// strictToArgument: true, -// }, -// }, -// }, -// }, -// } as any); - -// // const diagnostic = await runTypesDiagnostics(__dirname, __filename); - -// // expect(diagnostic.length).toBe(0); - -// const NuxtLink: TypedNuxtLink = vi.fn() as any; - -// const router = { push: vi.fn() } as unknown as ReturnType; - -// assertType(router.push('/user')); -// // @ts-expect-error -// assertType(router.push({ path: '/login' })); - -// // @ts-expect-error -// assertType(new NuxtLink('/user')); -// assertType(new NuxtLink({ to: { path: '/user' } })); -// }); diff --git a/test/fixtures/withOptions/tests/e2e/withStrict.spec.ts b/test/fixtures/withOptions/tests/e2e/withStrict.spec.ts deleted file mode 100644 index 2c105e8..0000000 --- a/test/fixtures/withOptions/tests/e2e/withStrict.spec.ts +++ /dev/null @@ -1,37 +0,0 @@ -test('empty') -// import { setup } from '@nuxt/test-utils'; -// import { fileURLToPath } from 'node:url'; -// import { assertType } from 'vitest'; -// import { useRouter } from '../../.nuxt/typed-router'; -// import type { TypedNuxtLink } from '../../.nuxt/typed-router/typed-router'; - -// test.skip('The strict option should behave correctly with strict: true', async () => { -// await setup({ -// rootDir: fileURLToPath(new URL('../../fixtures/withOptions', import.meta.url)), -// setupTimeout: 120000, -// nuxtConfig: { -// nuxtTypedRouter: { -// strict: true, -// }, -// }, -// } as any); - -// // const diagnostic = await runTypesDiagnostics(__dirname, __filename); - -// // expect(diagnostic.length).toBe(0); - -// const NuxtLink: TypedNuxtLink = vi.fn() as any; - -// const router = { push: vi.fn() } as unknown as ReturnType; - -// // @ts-expect-error -// assertType(router.push('/foo')); -// // @ts-expect-error -// assertType(router.push({ path: '/login' })); - -// // @ts-expect-error -// assertType(new NuxtLink('/login')); -// // @ts-expect-error -// assertType(new NuxtLink({ path: '/goooo' })); -// }); - diff --git a/test/fixtures/withOptions/tsconfig.json b/test/fixtures/withOptions/tsconfig.json deleted file mode 100644 index 2c90bb7..0000000 --- a/test/fixtures/withOptions/tsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "./.nuxt/tsconfig.json", - "compilerOptions": { - "types": ["vitest/globals"] - } -} diff --git a/test/samples/[classic].config.ts b/test/samples/[classic].config.ts new file mode 100644 index 0000000..d89e933 --- /dev/null +++ b/test/samples/[classic].config.ts @@ -0,0 +1,3 @@ +export default { + modules: ['nuxt-typed-router'], +}; diff --git a/test/samples/[withStrict].config.ts b/test/samples/[withStrict].config.ts new file mode 100644 index 0000000..e3d8900 --- /dev/null +++ b/test/samples/[withStrict].config.ts @@ -0,0 +1,6 @@ +export default { + modules: ['nuxt-typed-router'], + nuxtTypedRouter: { + strict: true, + }, +}; diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000..7ae9a3d --- /dev/null +++ b/vercel.json @@ -0,0 +1,5 @@ +{ + "github": { + "silent": true + } +} From 68f7927cafb3770d0f68ac7cdf6bbc654266147d Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Thu, 4 Jan 2024 10:49:27 +0100 Subject: [PATCH 03/10] Rewrite tests and types --- CHANGELOG.md | 13 + docs/content/3.options/4.ignoreRoutes.md | 5 +- docs/package.json | 4 +- package.json | 59 +- playground/nuxt.config.ts | 2 +- playground/src/components/TestLink.vue | 8 +- playground/src/pages/ignoreFolder/foo.vue | 0 playground/src/pages/index.vue | 12 +- pnpm-lock.yaml | 3227 +++++++++-------- pnpm-workspace.yaml | 2 - src/core/config/moduleOptions.ts | 21 +- .../generators/files/__i18n-router.file.ts | 2 +- .../output/generators/files/__paths.file.ts | 4 +- .../generators/files/__router.d.file.ts | 8 +- .../output/generators/files/index.file.ts | 2 +- src/module.ts | 16 +- test/e2e/sample-project/[classic].spec.ts | 5 - test/e2e/sample-project/[withStrict].spec.ts | 8 - test/e2e/sample-project/allConfigs.spec.ts | 11 + test/e2e/sample-project/utils.ts | 87 +- test/e2e/utils.ts | 51 - test/fixtures/complex/.gitignore | 10 - test/fixtures/complex/README.md | 42 - test/fixtures/complex/app.vue | 3 - test/fixtures/complex/nuxt.config.ts | 23 - test/fixtures/complex/package.json | 17 - .../complex/src/components/testModule.vue | 1 - .../complex/src/modules/testAddRoute.ts | 14 - test/fixtures/complex/src/pages/[...404].vue | 3 - .../fixtures/complex/src/pages/admin/[id].vue | 1 - .../src/pages/admin/[id]/action-[slug].vue | 1 - .../complex/src/pages/admin/[id]/index.vue | 1 - .../complex/src/pages/admin/[id]/profile.vue | 1 - .../complex/src/pages/admin/[id]/settings.vue | 1 - .../src/pages/admin/panel/[[blou]].vue | 1 - test/fixtures/complex/src/pages/baguette.vue | 1 - .../complex/src/pages/user/[foo]-[[bar]].vue | 1 - test/fixtures/complex/src/pages/user/[id].vue | 1 - .../complex/src/pages/user/[id]/[slug].vue | 1 - .../src/pages/user/[id]/[slug]/articles.vue | 1 - .../src/pages/user/[id]/[slug]/index.vue | 3 - .../complex/src/pages/user/[id]/index.vue | 1 - .../complex/src/pages/user/[id]/posts.vue | 1 - .../src/pages/user/[one]-foo-[two].vue | 1 - .../src/pages/user/catch/[...slug].vue | 1 - .../fixtures/complex/src/pages/user/index.vue | 1 - .../src/pages/user/test-[[optional]].vue | 1 - .../tests/i18n/NuxtLinkLocale.spec-d.ts | 143 - .../tests/i18n/useLocalePath.spec-d.ts | 330 -- .../tests/i18n/useLocaleRoute.spec-d.ts | 159 - test/fixtures/complex/tsconfig.json | 4 - test/fixtures/sample-project/nuxt.config.ts | 29 + test/fixtures/sample-project/package.json | 9 +- .../src/pages/[tests]/[classic].vue} | 7 +- .../src/pages/[tests]/[withPlugin].vue | 30 + .../src/pages/[tests]/[withStrict].vue | 25 + .../sample-project/src/pages/index.vue | 33 +- .../[classic]}/misc/definePageMeta.spec-d.ts | 2 +- .../[classic]}/router/NuxtLink.spec-d.ts | 0 .../[classic]}/router/navigateTo.spec-d.ts | 0 .../[classic]}/router/useRouter.spec-d.ts | 0 .../[classic]}/routes/useRoute.spec-d.ts | 0 .../tests/[classic]/test.vue} | 6 - .../[withPlugin]}/$typedRouter.spec-d.ts | 0 .../misc/definePageMeta.spec-d.ts | 52 +- .../router/NuxtLink.spec-d.ts | 45 +- .../router/navigateTo.spec-d.ts | 53 +- .../router/useRouter.spec-d.ts | 47 +- .../routes/useRoute.spec-d.ts | 4 - .../tests/misc/definePageMeta.spec-d.ts | 117 - .../tests/router/$typedRouter.spec-d.ts | 84 - test/fixtures/simple/.gitignore | 8 - test/fixtures/simple/README.md | 42 - test/fixtures/simple/app.vue | 3 - test/fixtures/simple/nuxt.config.ts | 8 - test/fixtures/simple/package.json | 16 - test/fixtures/simple/pages/admin.vue | 1 - test/fixtures/simple/pages/admin/[id].vue | 1 - .../simple/pages/admin/[id]/action-[slug].vue | 1 - .../simple/pages/admin/[id]/index.vue | 1 - .../simple/pages/admin/[id]/profile.vue | 1 - .../simple/pages/admin/[id]/settings.vue | 1 - .../simple/pages/admin/panel/[[blou]].vue | 1 - test/fixtures/simple/pages/baguette.vue | 1 - .../simple/pages/user/[foo]-[[bar]].vue | 1 - test/fixtures/simple/pages/user/[id].vue | 1 - .../simple/pages/user/[id]/[slug].vue | 1 - .../pages/user/[id]/[slug]/articles.vue | 1 - .../simple/pages/user/[id]/[slug]/index.vue | 3 - .../fixtures/simple/pages/user/[id]/index.vue | 1 - .../fixtures/simple/pages/user/[id]/posts.vue | 1 - .../simple/pages/user/[one]-foo-[two].vue | 1 - .../simple/pages/user/catch/[...slug].vue | 1 - test/fixtures/simple/pages/user/index.vue | 1 - .../simple/pages/user/test-[[optional]].vue | 1 - .../simple/tests/router/NuxtLink.spec-d.ts | 123 - .../simple/tests/router/navigateTo.spec-d.ts | 233 -- .../simple/tests/router/useRouter.spec-d.ts | 153 - .../simple/tests/routes/useLink.spec-d.ts | 245 -- .../simple/tests/routes/useRoute.spec-d.ts | 74 - test/fixtures/simple/tsconfig.json | 7 - test/samples-config/classic.ts | 5 + test/samples-config/withPlugin.ts | 8 + test/samples-config/withStrict.ts | 8 + test/samples/[classic].config.ts | 3 - test/samples/[withStrict].config.ts | 6 - vite.config.ts | 2 +- 107 files changed, 2053 insertions(+), 3771 deletions(-) create mode 100644 playground/src/pages/ignoreFolder/foo.vue delete mode 100644 test/e2e/sample-project/[classic].spec.ts delete mode 100644 test/e2e/sample-project/[withStrict].spec.ts create mode 100644 test/e2e/sample-project/allConfigs.spec.ts delete mode 100644 test/e2e/utils.ts delete mode 100644 test/fixtures/complex/.gitignore delete mode 100644 test/fixtures/complex/README.md delete mode 100644 test/fixtures/complex/app.vue delete mode 100644 test/fixtures/complex/nuxt.config.ts delete mode 100644 test/fixtures/complex/package.json delete mode 100644 test/fixtures/complex/src/components/testModule.vue delete mode 100644 test/fixtures/complex/src/modules/testAddRoute.ts delete mode 100644 test/fixtures/complex/src/pages/[...404].vue delete mode 100644 test/fixtures/complex/src/pages/admin/[id].vue delete mode 100644 test/fixtures/complex/src/pages/admin/[id]/action-[slug].vue delete mode 100644 test/fixtures/complex/src/pages/admin/[id]/index.vue delete mode 100644 test/fixtures/complex/src/pages/admin/[id]/profile.vue delete mode 100644 test/fixtures/complex/src/pages/admin/[id]/settings.vue delete mode 100644 test/fixtures/complex/src/pages/admin/panel/[[blou]].vue delete mode 100644 test/fixtures/complex/src/pages/baguette.vue delete mode 100644 test/fixtures/complex/src/pages/user/[foo]-[[bar]].vue delete mode 100644 test/fixtures/complex/src/pages/user/[id].vue delete mode 100644 test/fixtures/complex/src/pages/user/[id]/[slug].vue delete mode 100644 test/fixtures/complex/src/pages/user/[id]/[slug]/articles.vue delete mode 100644 test/fixtures/complex/src/pages/user/[id]/[slug]/index.vue delete mode 100644 test/fixtures/complex/src/pages/user/[id]/index.vue delete mode 100644 test/fixtures/complex/src/pages/user/[id]/posts.vue delete mode 100644 test/fixtures/complex/src/pages/user/[one]-foo-[two].vue delete mode 100644 test/fixtures/complex/src/pages/user/catch/[...slug].vue delete mode 100644 test/fixtures/complex/src/pages/user/index.vue delete mode 100644 test/fixtures/complex/src/pages/user/test-[[optional]].vue delete mode 100644 test/fixtures/complex/tests/i18n/NuxtLinkLocale.spec-d.ts delete mode 100644 test/fixtures/complex/tests/i18n/useLocalePath.spec-d.ts delete mode 100644 test/fixtures/complex/tests/i18n/useLocaleRoute.spec-d.ts delete mode 100644 test/fixtures/complex/tsconfig.json rename test/fixtures/{simple/pages/index.vue => sample-project/src/pages/[tests]/[classic].vue} (78%) create mode 100644 test/fixtures/sample-project/src/pages/[tests]/[withPlugin].vue create mode 100644 test/fixtures/sample-project/src/pages/[tests]/[withStrict].vue rename test/fixtures/{simple/tests => sample-project/tests/[classic]}/misc/definePageMeta.spec-d.ts (98%) rename test/fixtures/{complex/tests => sample-project/tests/[classic]}/router/NuxtLink.spec-d.ts (100%) rename test/fixtures/{complex/tests => sample-project/tests/[classic]}/router/navigateTo.spec-d.ts (100%) rename test/fixtures/{complex/tests => sample-project/tests/[classic]}/router/useRouter.spec-d.ts (100%) rename test/fixtures/{complex/tests => sample-project/tests/[classic]}/routes/useRoute.spec-d.ts (100%) rename test/fixtures/{complex/src/pages/index.vue => sample-project/tests/[classic]/test.vue} (77%) rename test/fixtures/{complex/tests/router => sample-project/tests/[withPlugin]}/$typedRouter.spec-d.ts (100%) rename test/fixtures/{complex/tests => sample-project/tests/[withStrict]}/misc/definePageMeta.spec-d.ts (50%) rename test/fixtures/sample-project/tests/{ => [withStrict]}/router/NuxtLink.spec-d.ts (60%) rename test/fixtures/sample-project/tests/{ => [withStrict]}/router/navigateTo.spec-d.ts (72%) rename test/fixtures/sample-project/tests/{ => [withStrict]}/router/useRouter.spec-d.ts (61%) rename test/fixtures/sample-project/tests/{ => [withStrict]}/routes/useRoute.spec-d.ts (93%) delete mode 100644 test/fixtures/sample-project/tests/misc/definePageMeta.spec-d.ts delete mode 100644 test/fixtures/sample-project/tests/router/$typedRouter.spec-d.ts delete mode 100644 test/fixtures/simple/.gitignore delete mode 100644 test/fixtures/simple/README.md delete mode 100644 test/fixtures/simple/app.vue delete mode 100644 test/fixtures/simple/nuxt.config.ts delete mode 100644 test/fixtures/simple/package.json delete mode 100644 test/fixtures/simple/pages/admin.vue delete mode 100644 test/fixtures/simple/pages/admin/[id].vue delete mode 100644 test/fixtures/simple/pages/admin/[id]/action-[slug].vue delete mode 100644 test/fixtures/simple/pages/admin/[id]/index.vue delete mode 100644 test/fixtures/simple/pages/admin/[id]/profile.vue delete mode 100644 test/fixtures/simple/pages/admin/[id]/settings.vue delete mode 100644 test/fixtures/simple/pages/admin/panel/[[blou]].vue delete mode 100644 test/fixtures/simple/pages/baguette.vue delete mode 100644 test/fixtures/simple/pages/user/[foo]-[[bar]].vue delete mode 100644 test/fixtures/simple/pages/user/[id].vue delete mode 100644 test/fixtures/simple/pages/user/[id]/[slug].vue delete mode 100644 test/fixtures/simple/pages/user/[id]/[slug]/articles.vue delete mode 100644 test/fixtures/simple/pages/user/[id]/[slug]/index.vue delete mode 100644 test/fixtures/simple/pages/user/[id]/index.vue delete mode 100644 test/fixtures/simple/pages/user/[id]/posts.vue delete mode 100644 test/fixtures/simple/pages/user/[one]-foo-[two].vue delete mode 100644 test/fixtures/simple/pages/user/catch/[...slug].vue delete mode 100644 test/fixtures/simple/pages/user/index.vue delete mode 100644 test/fixtures/simple/pages/user/test-[[optional]].vue delete mode 100644 test/fixtures/simple/tests/router/NuxtLink.spec-d.ts delete mode 100644 test/fixtures/simple/tests/router/navigateTo.spec-d.ts delete mode 100644 test/fixtures/simple/tests/router/useRouter.spec-d.ts delete mode 100644 test/fixtures/simple/tests/routes/useLink.spec-d.ts delete mode 100644 test/fixtures/simple/tests/routes/useRoute.spec-d.ts delete mode 100644 test/fixtures/simple/tsconfig.json create mode 100644 test/samples-config/classic.ts create mode 100644 test/samples-config/withPlugin.ts create mode 100644 test/samples-config/withStrict.ts delete mode 100644 test/samples/[classic].config.ts delete mode 100644 test/samples/[withStrict].config.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 7facf43..278c774 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file. See [standa ## [4.0.0](https://github.com/victorgarciaesgi/nuxt-typed-router/compare/v3.5.0...v4.0.0) (2023-12-07) +New features + +- `ignoreRoutes` option now support Globs pattern +- Simplification of `NuxtRoute` type, removing the need for generics + +Fixs + +- Fixed strict:true errors when using `router.push('xxx')` +- Fixed import of `NuxtLocaleRoute` + + + + Changelog All notable changes to this project will be documented in this file. diff --git a/docs/content/3.options/4.ignoreRoutes.md b/docs/content/3.options/4.ignoreRoutes.md index a07f996..e30df84 100644 --- a/docs/content/3.options/4.ignoreRoutes.md +++ b/docs/content/3.options/4.ignoreRoutes.md @@ -5,12 +5,13 @@ title: ignoreRoutes # ignoreRoutes Allow to ignore selected files to be typed, for exemple 404 routes or catch-all routes. -You can pass an array of file paths (taking base of your `pagesDir`). +You can pass an array of file paths or glob patterns (taking base of your `pagesDir`). + Usage: ```ts -ignoreRoutes: ["[...404].vue", "admin/[...slug].vue"]; +ignoreRoutes: ["[...404].vue", "admin/[...slug].vue", "ignored/**/*"]; ``` ## Type diff --git a/docs/package.json b/docs/package.json index b567f44..f1447a4 100755 --- a/docs/package.json +++ b/docs/package.json @@ -9,7 +9,7 @@ "preview": "nuxi preview" }, "devDependencies": { - "@nuxt-themes/docus": "1.14.3", - "nuxt": "3.8.1" + "@nuxt-themes/docus": "1.15.0", + "nuxt": "3.8.2" } } diff --git a/package.json b/package.json index 347a601..f9a1ec2 100644 --- a/package.json +++ b/package.json @@ -28,10 +28,12 @@ "typecheck": "tsc --noEmit", "release": "bumpp && npm publish && git push --follow-tags", "test:prepare-fixtures": "nuxi prepare test/fixtures/sample-project", + "test:types-fixtures": "nuxi typecheck test/fixtures/sample-project", "test:fixtures": "vitest run --dir test", "test:types": "pnpm run typecheck", "test:vue": "vue-tsc -p test/fixtures/simple/tsconfig.json --noEmit && vue-tsc -p test/fixtures/complex/tsconfig.json --noEmit", - "test": "pnpm run dev:prepare && pnpm run test:types && pnpm run test:fixtures" + "test": "pnpm run test:prepare-fixtures && pnpm run test:types && pnpm run test:fixtures", + "test:debug": "NUXT_ROUTER_CONFIG_NAME=$CONFIG pnpm run test:types-fixtures" }, "publishConfig": { "access": "public" @@ -69,50 +71,51 @@ "lodash-es": "4.17.21", "log-symbols": "6.0.0", "mkdirp": "3.0.1", - "nanoid": "5.0.3", + "nanoid": "5.0.4", "pathe": "1.1.1", - "prettier": "3.1.0" + "globby": "14.0.0" }, "devDependencies": { - "@nuxt/devtools": "1.0.3", - "@nuxt/schema": "3.8.2", + "@intlify/core-base": "9.8.0", + "@intlify/message-compiler": "9.8.0", + "@intlify/shared": "9.8.0", + "@intlify/vue-i18n-bridge": "1.1.0", + "@intlify/vue-router-bridge": "1.1.0", + "@nuxt/content": "2.9.0", + "@nuxt/devtools": "1.0.6", "@nuxt/module-builder": "0.5.4", - "@nuxt/test-utils": "3.8.1", + "@nuxt/schema": "3.8.2", + "@nuxt/test-utils": "3.9.0", "@nuxt/types": "2.17.2", "@nuxtjs/eslint-config-typescript": "12.1.0", - "@nuxt/content": "2.9.0", "@nuxtjs/i18n": "8.0.0-rc.5", "@nuxtjs/web-vitals": "0.2.6", + "@playwright/test": "1.40.1", "@types/lodash-es": "4.17.12", - "@types/node": "20.10.0", - "@typescript-eslint/eslint-plugin": "6.12.0", - "@typescript-eslint/parser": "6.12.0", - "@vue/test-utils": "2.4.2", - "bumpp": "9.2.0", + "@types/node": "20.10.5", + "@typescript-eslint/eslint-plugin": "6.15.0", + "@typescript-eslint/parser": "6.15.0", + "@vue/test-utils": "2.4.3", + "bumpp": "9.2.1", "changelogithub": "0.13.2", "cross-env": "7.0.3", - "eslint": "8.54.0", - "eslint-config-prettier": "9.0.0", - "eslint-plugin-vue": "9.18.1", + "eslint": "8.56.0", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-vue": "9.19.2", "nuxt": "3.8.2", "nuxt-seo-kit": "1.3.13", "playwright": "1.40.1", - "@playwright/test": "1.40.1", - "tsd": "0.29.0", - "typescript": "5.2.2", + "prettier": "3.1.1", + "tsd": "0.30.0", "tslib": "2.6.2", - "vitest": "0.34.6", - "vue": "3.3.10", + "typescript": "5.2.2", + "vitest": "1.1.0", + "vue": "3.3.13", "vue-eslint-parser": "9.3.2", - "vue-router": "4.2.5", - "vue-tsc": "1.8.22", "vue-i18n": "9.8.0", - "@intlify/shared": "9.8.0", - "@intlify/message-compiler": "9.8.0", - "@intlify/core-base": "9.8.0", - "@intlify/vue-router-bridge": "1.1.0", - "@intlify/vue-i18n-bridge": "1.1.0", "vue-i18n-routing": "1.2.0", - "globby": "14.0.0" + "vue-router": "4.2.5", + "vue-tsc": "1.8.25", + "zx": "7.2.3" } } diff --git a/playground/nuxt.config.ts b/playground/nuxt.config.ts index 5f38e4a..98b43d2 100644 --- a/playground/nuxt.config.ts +++ b/playground/nuxt.config.ts @@ -8,7 +8,7 @@ export default defineNuxtConfig({ plugin: true, pathCheck: true, removeNuxtDefs: true, - ignoreRoutes: ['[...404].vue'], + ignoreRoutes: ['[...404].vue', 'ignoreFolder/**/*'], }, content: { documentDriven: false, diff --git a/playground/src/components/TestLink.vue b/playground/src/components/TestLink.vue index 68e6db8..383f0ed 100644 --- a/playground/src/components/TestLink.vue +++ b/playground/src/components/TestLink.vue @@ -2,15 +2,11 @@ - diff --git a/playground/src/pages/ignoreFolder/foo.vue b/playground/src/pages/ignoreFolder/foo.vue new file mode 100644 index 0000000..e69de29 diff --git a/playground/src/pages/index.vue b/playground/src/pages/index.vue index 1ec2f11..98e521f 100644 --- a/playground/src/pages/index.vue +++ b/playground/src/pages/index.vue @@ -17,12 +17,20 @@ diff --git a/test/fixtures/sample-project/src/pages/[tests]/[withStrict].vue b/test/fixtures/sample-project/src/pages/[tests]/[withStrict].vue new file mode 100644 index 0000000..359d077 --- /dev/null +++ b/test/fixtures/sample-project/src/pages/[tests]/[withStrict].vue @@ -0,0 +1,25 @@ + + + diff --git a/test/fixtures/sample-project/src/pages/index.vue b/test/fixtures/sample-project/src/pages/index.vue index 98b7abc..9ed4e76 100644 --- a/test/fixtures/sample-project/src/pages/index.vue +++ b/test/fixtures/sample-project/src/pages/index.vue @@ -1,34 +1,5 @@ - + diff --git a/test/fixtures/simple/tests/misc/definePageMeta.spec-d.ts b/test/fixtures/sample-project/tests/[classic]/misc/definePageMeta.spec-d.ts similarity index 98% rename from test/fixtures/simple/tests/misc/definePageMeta.spec-d.ts rename to test/fixtures/sample-project/tests/[classic]/misc/definePageMeta.spec-d.ts index ae2cee4..4b0b400 100644 --- a/test/fixtures/simple/tests/misc/definePageMeta.spec-d.ts +++ b/test/fixtures/sample-project/tests/[classic]/misc/definePageMeta.spec-d.ts @@ -72,7 +72,7 @@ definePageMeta({ // ! ------ Should Error ❌ // @ts-expect-error -assertType(definePageMeta({ redirect: '' })); +assertType(definePageMeta({ redirect: '/foo' })); // @ts-expect-error assertType(definePageMeta({ redirect: '/admin ' })); // @ts-expect-error diff --git a/test/fixtures/complex/tests/router/NuxtLink.spec-d.ts b/test/fixtures/sample-project/tests/[classic]/router/NuxtLink.spec-d.ts similarity index 100% rename from test/fixtures/complex/tests/router/NuxtLink.spec-d.ts rename to test/fixtures/sample-project/tests/[classic]/router/NuxtLink.spec-d.ts diff --git a/test/fixtures/complex/tests/router/navigateTo.spec-d.ts b/test/fixtures/sample-project/tests/[classic]/router/navigateTo.spec-d.ts similarity index 100% rename from test/fixtures/complex/tests/router/navigateTo.spec-d.ts rename to test/fixtures/sample-project/tests/[classic]/router/navigateTo.spec-d.ts diff --git a/test/fixtures/complex/tests/router/useRouter.spec-d.ts b/test/fixtures/sample-project/tests/[classic]/router/useRouter.spec-d.ts similarity index 100% rename from test/fixtures/complex/tests/router/useRouter.spec-d.ts rename to test/fixtures/sample-project/tests/[classic]/router/useRouter.spec-d.ts diff --git a/test/fixtures/complex/tests/routes/useRoute.spec-d.ts b/test/fixtures/sample-project/tests/[classic]/routes/useRoute.spec-d.ts similarity index 100% rename from test/fixtures/complex/tests/routes/useRoute.spec-d.ts rename to test/fixtures/sample-project/tests/[classic]/routes/useRoute.spec-d.ts diff --git a/test/fixtures/complex/src/pages/index.vue b/test/fixtures/sample-project/tests/[classic]/test.vue similarity index 77% rename from test/fixtures/complex/src/pages/index.vue rename to test/fixtures/sample-project/tests/[classic]/test.vue index 98b7abc..3359064 100644 --- a/test/fixtures/complex/src/pages/index.vue +++ b/test/fixtures/sample-project/tests/[classic]/test.vue @@ -6,7 +6,6 @@ > - @@ -16,7 +15,6 @@ import { useRoute, useRouter, navigateTo } from '@typed-router'; const route = useRoute('user-foo-bar'); const router = useRouter(); -const { $typedRouter, $typedRoute } = useNuxtApp(); function navigate() { router.push({ name: 'user-id-slug', params: { slug: 'bar', id: 1 } }); @@ -27,8 +25,4 @@ function navigate() { function testNavigateTo() { navigateTo({ name: 'user-id-slug', params: { id: '1', slug: 'foo' } }); } - -function testNavigatePlugin() { - $typedRouter.push({ name: 'user-id-slug', params: { slug: 'bar', id: 1 } }); -} diff --git a/test/fixtures/complex/tests/router/$typedRouter.spec-d.ts b/test/fixtures/sample-project/tests/[withPlugin]/$typedRouter.spec-d.ts similarity index 100% rename from test/fixtures/complex/tests/router/$typedRouter.spec-d.ts rename to test/fixtures/sample-project/tests/[withPlugin]/$typedRouter.spec-d.ts diff --git a/test/fixtures/complex/tests/misc/definePageMeta.spec-d.ts b/test/fixtures/sample-project/tests/[withStrict]/misc/definePageMeta.spec-d.ts similarity index 50% rename from test/fixtures/complex/tests/misc/definePageMeta.spec-d.ts rename to test/fixtures/sample-project/tests/[withStrict]/misc/definePageMeta.spec-d.ts index ae2cee4..e58ef18 100644 --- a/test/fixtures/complex/tests/misc/definePageMeta.spec-d.ts +++ b/test/fixtures/sample-project/tests/[withStrict]/misc/definePageMeta.spec-d.ts @@ -1,4 +1,4 @@ -import { assertType, expectTypeOf } from 'vitest'; +import { assertType } from 'vitest'; import { definePageMeta } from '@typed-router'; // Given @@ -48,12 +48,6 @@ definePageMeta({ redirect: { name: 'user-id-slug', params: { id: 1 } } }); // @ts-expect-error definePageMeta({ redirect: { name: 'test-module' } }); -// * --- Path navigation -// @ts-expect-error -definePageMeta({ redirect: '/fooooooooooo' }); -// @ts-expect-error -definePageMeta({ redirect: { path: '/foo' } }); - // $ ----- Should be valid ✅ definePageMeta({ redirect: { name: 'index' } }); @@ -72,46 +66,4 @@ definePageMeta({ // ! ------ Should Error ❌ // @ts-expect-error -assertType(definePageMeta({ redirect: '' })); -// @ts-expect-error -assertType(definePageMeta({ redirect: '/admin ' })); -// @ts-expect-error -assertType(definePageMeta({ redirect: '/admin/ /' })); -// @ts-expect-error -assertType(definePageMeta({ redirect: `/ / // / / eefzr` })); -// @ts-expect-error -assertType(definePageMeta({ redirect: '/elzhlzehflzhef' })); -// @ts-expect-error -assertType(definePageMeta({ redirect: '/admin/foo/bar' })); -// @ts-expect-error -assertType(definePageMeta({ redirect: '/admin/foo/bar/baz' })); -// @ts-expect-error -assertType(definePageMeta({ redirect: `/admin/${id}/action-bar/taz?query` })); -// @ts-expect-error -assertType(definePageMeta({ redirect: '/admin/panel/3O9393/bar' })); -// @ts-expect-error -assertType(definePageMeta({ redirect: '/admin/foo/ profile/ezfje' })); -// @ts-expect-error -assertType(definePageMeta({ redirect: '/admin/3U93U/settings/baz' })); -// @ts-expect-error -assertType(definePageMeta({ redirect: '/admin/panel/?fjzk' })); - -// $ ----- Should be valid ✅ - -const id = '38789803'; -assertType(definePageMeta({ redirect: '/' })); -assertType(definePageMeta({ redirect: '/baguette' })); -assertType(definePageMeta({ redirect: '/admin/foo' })); -assertType(definePageMeta({ redirect: '/admin/foo/' })); -assertType(definePageMeta({ redirect: `/admin/${id}/action-bar#hash` })); -assertType(definePageMeta({ redirect: `/admin/${id}/action-bar?query=bar` })); -assertType(definePageMeta({ redirect: '/admin/foo/profile/' })); -assertType(definePageMeta({ redirect: `/admin/${id}/settings` })); -assertType(definePageMeta({ redirect: '/admin/panel/' })); -assertType(definePageMeta({ redirect: '/admin/panel/938783/' })); -assertType(definePageMeta({ redirect: '/user/38873-' })); -assertType(definePageMeta({ redirect: '/user/38673/bar/#hash' })); -assertType(definePageMeta({ redirect: '/user/ç9737/foo/articles?baz=foo' })); -assertType(definePageMeta({ redirect: '/user/catch/1/2' })); -assertType(definePageMeta({ redirect: '/user/test-' })); -assertType(definePageMeta({ redirect: '/user' })); +definePageMeta({ redirect: '/' }); diff --git a/test/fixtures/sample-project/tests/router/NuxtLink.spec-d.ts b/test/fixtures/sample-project/tests/[withStrict]/router/NuxtLink.spec-d.ts similarity index 60% rename from test/fixtures/sample-project/tests/router/NuxtLink.spec-d.ts rename to test/fixtures/sample-project/tests/[withStrict]/router/NuxtLink.spec-d.ts index d04b913..17967f9 100644 --- a/test/fixtures/sample-project/tests/router/NuxtLink.spec-d.ts +++ b/test/fixtures/sample-project/tests/[withStrict]/router/NuxtLink.spec-d.ts @@ -52,49 +52,9 @@ assertType(new NuxtLink({ to: { name: 'test-module' } })); // ! ------ Should Error ❌ // @ts-expect-error -assertType(new NuxtLink({ to: '' })); -// @ts-expect-error -assertType(new NuxtLink({ to: '/admin ' })); -// @ts-expect-error -assertType(new NuxtLink({ to: '/admin/ /' })); -// @ts-expect-error -assertType(new NuxtLink({ to: `/ / // / / eefzr` })); -// @ts-expect-error -assertType(new NuxtLink({ to: '/elzhlzehflzhef' })); -// @ts-expect-error -assertType(new NuxtLink({ to: '/admin/foo/bar' })); -// @ts-expect-error -assertType(new NuxtLink({ to: '/admin/foo/bar/baz' })); -// @ts-expect-error -assertType(new NuxtLink({ to: `/admin/${id}/action-bar/taz?query` })); -// @ts-expect-error -assertType(new NuxtLink({ to: '/admin/panel/3O9393/bar' })); -// @ts-expect-error -assertType(new NuxtLink({ to: '/admin/foo/ profile/ezfje' })); -// @ts-expect-error -assertType(new NuxtLink({ to: '/admin/3U93U/settings/baz' })); -// @ts-expect-error -assertType(new NuxtLink({ to: '/admin/panel/?fjzk' })); - -// $ ----- Should be valid ✅ - -const id = '38789803'; assertType(new NuxtLink({ to: '/' })); -assertType(new NuxtLink({ to: '/baguette' })); -assertType(new NuxtLink({ to: '/admin/foo' })); -assertType(new NuxtLink({ to: '/admin/foo/' })); -assertType(new NuxtLink({ to: `/admin/${id}/action-bar#hash` })); -assertType(new NuxtLink({ to: `/admin/${id}/action-bar?query=bar` })); -assertType(new NuxtLink({ to: '/admin/foo/profile/' })); -assertType(new NuxtLink({ to: `/admin/${id}/settings` })); -assertType(new NuxtLink({ to: '/admin/panel/' })); -assertType(new NuxtLink({ to: '/admin/panel/938783/' })); -assertType(new NuxtLink({ to: '/user/38873-' })); -assertType(new NuxtLink({ to: '/user/38673/bar/#hash' })); -assertType(new NuxtLink({ to: '/user/ç9737/foo/articles?baz=foo' })); -assertType(new NuxtLink({ to: '/user/catch/1/2' })); -assertType(new NuxtLink({ to: '/user/test-' })); -assertType(new NuxtLink({ to: '/user' })); +// @ts-expect-error +assertType(new NuxtLink({ to: { path: '/' } })); // $ ----- Should be valid ✅ @@ -125,5 +85,4 @@ assertType( // $ ----- Should be valid ✅ -assertType(new NuxtLink({ to: '/admin/:id/', external: false })); assertType(new NuxtLink({ to: 'http://google.com', external: true })); diff --git a/test/fixtures/sample-project/tests/router/navigateTo.spec-d.ts b/test/fixtures/sample-project/tests/[withStrict]/router/navigateTo.spec-d.ts similarity index 72% rename from test/fixtures/sample-project/tests/router/navigateTo.spec-d.ts rename to test/fixtures/sample-project/tests/[withStrict]/router/navigateTo.spec-d.ts index 647b1d6..5235ebe 100644 --- a/test/fixtures/sample-project/tests/router/navigateTo.spec-d.ts +++ b/test/fixtures/sample-project/tests/[withStrict]/router/navigateTo.spec-d.ts @@ -1,10 +1,6 @@ import { assertType } from 'vitest'; import type { LocationQuery } from 'vue-router'; import test from 'node:test'; -import { navigateTo } from '@typed-router'; - -// @ts-expect-error Ensure global imports are disabled -declare const globalDecl: (typeof globalThis)['navigateTo']; // ! ------ Should Error ❌ @@ -67,55 +63,8 @@ navigateTo({ name: 'test-module', params: { foo: 1 }, query: { foo: 'bar' } }); // ! ------ Should Error ❌ // @ts-expect-error -assertType(navigateTo('')); -// @ts-expect-error -assertType(navigateTo('/admin ')); -// @ts-expect-error -assertType(navigateTo('/admin/ /')); -// @ts-expect-error -assertType(navigateTo(`/ / // / / eefzr`)); -// @ts-expect-error -assertType(navigateTo('/elzhlzehflzhef')); -// @ts-expect-error -assertType(navigateTo('/admin/foo/bar')); -// @ts-expect-error -assertType(navigateTo('/admin/foo/bar/baz')); -// @ts-expect-error -assertType(navigateTo(`/admin/${id}/action-bar/taz?query`)); -// @ts-expect-error -assertType(navigateTo('/admin/panel/3O9393/bar')); -// @ts-expect-error -assertType(navigateTo('/admin/foo/ profile/ezfje')); -// @ts-expect-error -assertType(navigateTo('/admin/3U93U/settings/baz')); -// @ts-expect-error -assertType(navigateTo('/admin/panel/?fjzk')); -// @ts-expect-error -assertType(navigateTo('/admin/panel/938783/ ')); -// @ts-expect-error -assertType(navigateTo('/user/3887/foo/bar/')); -// @ts-expect-error -assertType(navigateTo('/admin/:id//')); - -// $ ----- Should be valid ✅ - -const id = '38789803'; assertType(navigateTo('/')); -assertType(navigateTo('/baguette')); -assertType(navigateTo('/admin/foo')); -assertType(navigateTo('/admin/foo/')); -assertType(navigateTo(`/admin/${id}/action-bar#hash`)); -assertType(navigateTo(`/admin/${id}/action-bar?query=bar`)); -assertType(navigateTo('/admin/foo/profile/')); -assertType(navigateTo(`/admin/${id}/settings`)); -assertType(navigateTo('/admin/panel/')); -assertType(navigateTo('/admin/panel/938783/')); -assertType(navigateTo('/user/38873-')); -assertType(navigateTo('/user/38673/bar/#hash')); -assertType(navigateTo('/user/ç9737/foo/articles?baz=foo')); -assertType(navigateTo('/user/catch/1/2')); -assertType(navigateTo('/user/test-')); -assertType(navigateTo('/user')); + // - Resolved routes // * index.vue diff --git a/test/fixtures/sample-project/tests/router/useRouter.spec-d.ts b/test/fixtures/sample-project/tests/[withStrict]/router/useRouter.spec-d.ts similarity index 61% rename from test/fixtures/sample-project/tests/router/useRouter.spec-d.ts rename to test/fixtures/sample-project/tests/[withStrict]/router/useRouter.spec-d.ts index 3d4502b..50d96d6 100644 --- a/test/fixtures/sample-project/tests/router/useRouter.spec-d.ts +++ b/test/fixtures/sample-project/tests/[withStrict]/router/useRouter.spec-d.ts @@ -1,6 +1,6 @@ import { assertType } from 'vitest'; -import type { TypedRouter, } from '@typed-router'; -import { useRouter } from '@typed-router'; +import type { TypedRouter } from '@typed-router'; +import { useRouter } from '@typed-router'; // @ts-expect-error Ensure global imports are disabled declare const globalDecl: (typeof globalThis)['useRouter']; @@ -74,51 +74,8 @@ router.replace({ name: 'user-id', params: { id: 1 }, hash: 'baz' }); // --- Path navigation // ! ------ Should Error ❌ - -// @ts-expect-error -assertType(router.push('')); -// @ts-expect-error -assertType(router.push('/admin ')); -// @ts-expect-error -assertType(router.push('/admin/ /')); -// @ts-expect-error -assertType(router.push(`/ / // / / eefzr`)); -// @ts-expect-error -assertType(router.push('/elzhlzehflzhef')); -// @ts-expect-error -assertType(router.push('/admin/foo/bar')); -// @ts-expect-error -assertType(router.push('/admin/foo/bar/baz')); // @ts-expect-error -assertType(router.push(`/admin/${id}/action-bar/taz?query`)); -// @ts-expect-error -assertType(router.push('/admin/panel/3O9393/bar')); -// @ts-expect-error -assertType(router.push('/admin/foo/ profile/ezfje')); -// @ts-expect-error -assertType(router.push('/admin/3U93U/settings/baz')); -// @ts-expect-error -assertType(router.push('/admin/panel/?fjzk')); - -// $ ----- Should be valid ✅ - -const id = '38789803'; assertType(router.push('/')); -assertType(router.push('/baguette')); -assertType(router.push('/admin/foo')); -assertType(router.push('/admin/foo/')); -assertType(router.push(`/admin/${id}/action-bar#hash`)); -assertType(router.push(`/admin/${id}/action-bar?query=bar`)); -assertType(router.push('/admin/foo/profile/')); -assertType(router.push(`/admin/${id}/settings`)); -assertType(router.push('/admin/panel/')); -assertType(router.push('/admin/panel/938783/')); -assertType(router.push('/user/38873-')); -assertType(router.push('/user/38673/bar/#hash')); -assertType(router.push('/user/ç9737/foo/articles?baz=foo')); -assertType(router.push('/user/catch/1/2')); -assertType(router.push('/user/test-')); -assertType(router.push('/user')); // * Resolved routes diff --git a/test/fixtures/sample-project/tests/routes/useRoute.spec-d.ts b/test/fixtures/sample-project/tests/[withStrict]/routes/useRoute.spec-d.ts similarity index 93% rename from test/fixtures/sample-project/tests/routes/useRoute.spec-d.ts rename to test/fixtures/sample-project/tests/[withStrict]/routes/useRoute.spec-d.ts index 983455f..2287c8e 100644 --- a/test/fixtures/sample-project/tests/routes/useRoute.spec-d.ts +++ b/test/fixtures/sample-project/tests/[withStrict]/routes/useRoute.spec-d.ts @@ -1,10 +1,6 @@ import { assertType, test } from 'vitest'; import type { RouteLocationMatched } from 'vue-router'; import type { TypedRouteFromName } from '@typed-router'; -import {useRoute} from '@typed-router' - -// @ts-expect-error Ensure global imports are disabled -declare const globalDecl: (typeof globalThis)['useRoute']; // Given const route = useRoute(); diff --git a/test/fixtures/sample-project/tests/misc/definePageMeta.spec-d.ts b/test/fixtures/sample-project/tests/misc/definePageMeta.spec-d.ts deleted file mode 100644 index ae2cee4..0000000 --- a/test/fixtures/sample-project/tests/misc/definePageMeta.spec-d.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { assertType, expectTypeOf } from 'vitest'; -import { definePageMeta } from '@typed-router'; - -// Given - -// - Usage of useRouter with useRouter - -// ! ------ Should Error ❌ - -// * index.vue -definePageMeta({ redirect: { name: 'index' } }); -// @ts-expect-error -definePageMeta({ redirect: { name: 'index', params: { id: 1 } } }); -// @ts-expect-error -definePageMeta({ redirect: { name: 'blabla-baguette' } }); - -// * --- [id].vue -// @ts-expect-error -definePageMeta({ redirect: { name: 'user-id' } }); -// @ts-expect-error -definePageMeta({ redirect: { name: 'user-id', params: { foo: 'bar' } } }); - -// * --- [foo]-[[bar]].vue -// @ts-expect-error -definePageMeta({ redirect: { name: 'user-foo-bar' } }); -// @ts-expect-error -definePageMeta({ redirect: { name: 'user-foo-bar', params: { bar: 1 } } }); - -// * --- [...slug].vue -// @ts-expect-error -definePageMeta({ redirect: { name: 'user-slug' } }); -// @ts-expect-error -definePageMeta({ redirect: { name: 'user-slug', params: { slug: 1 } } }); - -// * --- [one]-foo-[two].vue -// @ts-expect-error -definePageMeta({ redirect: { name: 'user-one-foo-two' } }); -// @ts-expect-error -definePageMeta({ redirect: { name: 'user-one-foo-two', params: { one: 1 } } }); - -// * --- [id]/[slug].vue -// @ts-expect-error -definePageMeta({ redirect: { name: 'user-id-slug' } }); -// @ts-expect-error -definePageMeta({ redirect: { name: 'user-id-slug', params: { id: 1 } } }); - -// * --- Routes added by modules -// @ts-expect-error -definePageMeta({ redirect: { name: 'test-module' } }); - -// * --- Path navigation -// @ts-expect-error -definePageMeta({ redirect: '/fooooooooooo' }); -// @ts-expect-error -definePageMeta({ redirect: { path: '/foo' } }); - -// $ ----- Should be valid ✅ - -definePageMeta({ redirect: { name: 'index' } }); -definePageMeta({ redirect: { name: 'user-id', params: { id: 1 }, hash: 'baz' } }); -definePageMeta({ redirect: { name: 'user-foo-bar', params: { foo: 'bar' }, force: true } }); -definePageMeta({ redirect: { name: 'user-foo-bar', params: { foo: 'bar', bar: 'baz' } } }); -definePageMeta({ redirect: { name: 'user-catch-slug', params: { slug: ['foo'] } } }); -definePageMeta({ redirect: { name: 'user-catch-slug', params: { slug: [1, 2, 3] } } }); -definePageMeta({ redirect: { name: 'user-one-foo-two', params: { one: 1, two: '2' } } }); -definePageMeta({ - redirect: { name: 'user-id-slug', params: { slug: '2' }, query: { foo: 'bar' } }, -}); - -// --- Path navigation - -// ! ------ Should Error ❌ - -// @ts-expect-error -assertType(definePageMeta({ redirect: '' })); -// @ts-expect-error -assertType(definePageMeta({ redirect: '/admin ' })); -// @ts-expect-error -assertType(definePageMeta({ redirect: '/admin/ /' })); -// @ts-expect-error -assertType(definePageMeta({ redirect: `/ / // / / eefzr` })); -// @ts-expect-error -assertType(definePageMeta({ redirect: '/elzhlzehflzhef' })); -// @ts-expect-error -assertType(definePageMeta({ redirect: '/admin/foo/bar' })); -// @ts-expect-error -assertType(definePageMeta({ redirect: '/admin/foo/bar/baz' })); -// @ts-expect-error -assertType(definePageMeta({ redirect: `/admin/${id}/action-bar/taz?query` })); -// @ts-expect-error -assertType(definePageMeta({ redirect: '/admin/panel/3O9393/bar' })); -// @ts-expect-error -assertType(definePageMeta({ redirect: '/admin/foo/ profile/ezfje' })); -// @ts-expect-error -assertType(definePageMeta({ redirect: '/admin/3U93U/settings/baz' })); -// @ts-expect-error -assertType(definePageMeta({ redirect: '/admin/panel/?fjzk' })); - -// $ ----- Should be valid ✅ - -const id = '38789803'; -assertType(definePageMeta({ redirect: '/' })); -assertType(definePageMeta({ redirect: '/baguette' })); -assertType(definePageMeta({ redirect: '/admin/foo' })); -assertType(definePageMeta({ redirect: '/admin/foo/' })); -assertType(definePageMeta({ redirect: `/admin/${id}/action-bar#hash` })); -assertType(definePageMeta({ redirect: `/admin/${id}/action-bar?query=bar` })); -assertType(definePageMeta({ redirect: '/admin/foo/profile/' })); -assertType(definePageMeta({ redirect: `/admin/${id}/settings` })); -assertType(definePageMeta({ redirect: '/admin/panel/' })); -assertType(definePageMeta({ redirect: '/admin/panel/938783/' })); -assertType(definePageMeta({ redirect: '/user/38873-' })); -assertType(definePageMeta({ redirect: '/user/38673/bar/#hash' })); -assertType(definePageMeta({ redirect: '/user/ç9737/foo/articles?baz=foo' })); -assertType(definePageMeta({ redirect: '/user/catch/1/2' })); -assertType(definePageMeta({ redirect: '/user/test-' })); -assertType(definePageMeta({ redirect: '/user' })); diff --git a/test/fixtures/sample-project/tests/router/$typedRouter.spec-d.ts b/test/fixtures/sample-project/tests/router/$typedRouter.spec-d.ts deleted file mode 100644 index 2457cf5..0000000 --- a/test/fixtures/sample-project/tests/router/$typedRouter.spec-d.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { useNuxtApp } from '#imports'; -import { assertType } from 'vitest'; -import type { TypedRouter } from '@typed-router'; - -// Given -const { $typedRouter } = useNuxtApp(); - -assertType($typedRouter); - -// - Usage of localePath with useRouter - -// ! ------ Should Error ❌ - -// * index.vue -// @ts-expect-error -$typedRouter.push({ name: 'index', params: { id: 1 } }); -// @ts-expect-error -$typedRouter.push({ name: 'index', params: { id: 1 } }); -// @ts-expect-error -$typedRouter.push({ name: 'blabla-baguette' }); - -// * --- [id].vue -// @ts-expect-error -$typedRouter.push({ name: 'user-id' }); -// @ts-expect-error -$typedRouter.push({ name: 'user-id', params: { foo: 'bar' } }); - -// * --- [foo]-[[bar]].vue -// @ts-expect-error -$typedRouter.push({ name: 'user-foo-bar' }); -// @ts-expect-error -$typedRouter.push({ name: 'user-foo-bar', params: { bar: 1 } }); - -// * --- [...slug].vue -// @ts-expect-error -$typedRouter.push({ name: 'user-slug' }); -// @ts-expect-error -$typedRouter.push({ name: 'user-slug', params: { slug: 1 } }); - -// * --- [one]-foo-[two].vue -// @ts-expect-error -$typedRouter.push({ name: 'user-one-foo-two' }); -// @ts-expect-error -$typedRouter.push({ name: 'user-one-foo-two', params: { one: 1 } }); - -// * --- [id]/[slug].vue -// @ts-expect-error -$typedRouter.push({ name: 'user-id-slug' }); -// @ts-expect-error -$typedRouter.push({ name: 'user-id-slug', params: { id: 1 } }); - -// * --- Routes added by modules -// @ts-expect-error -$typedRouter.push({ name: 'test-module' }); - -// * --- Path navigation -// @ts-expect-error -$typedRouter.push('/admin/:id/foo'); - -// $ ----- Should be valid ✅ - -$typedRouter.push({ name: 'index' }); -$typedRouter.push({ name: 'user-id', params: { id: 1 }, hash: 'baz' }); -$typedRouter.push({ name: 'user-foo-bar', params: { foo: 'bar' }, force: true }); -$typedRouter.push({ name: 'user-foo-bar', params: { foo: 'bar', bar: 'baz' } }); -$typedRouter.push({ name: 'user-catch-slug', params: { slug: ['foo'] } }); -$typedRouter.push({ name: 'user-catch-slug', params: { slug: [1, 2, 3] } }); -$typedRouter.push({ name: 'user-one-foo-two', params: { one: 1, two: '2' } }); -$typedRouter.push({ name: 'user-id-slug', params: { slug: '2' }, query: { foo: 'bar' } }); -$typedRouter.push({ name: 'test-module', params: { foo: 1 }, query: { foo: 'bar' } }); - -$typedRouter.replace({ name: 'index' }); -$typedRouter.replace({ name: 'user-id', params: { id: 1 }, hash: 'baz' }); - -// * Resolved routes - -const resolved1 = $typedRouter.resolve({ name: 'index' }); -assertType<'index'>(resolved1.name); -// @ts-expect-error -assertType<'index'>(resolved1.params); - -const resolved2 = $typedRouter.resolve({ name: 'user-id', params: { id: 1 }, hash: 'baz' }); -assertType<'user-id'>(resolved2.name); -assertType<{ id: string }>(resolved2.params); diff --git a/test/fixtures/simple/.gitignore b/test/fixtures/simple/.gitignore deleted file mode 100644 index 438cb08..0000000 --- a/test/fixtures/simple/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -node_modules -*.log* -.nuxt -.nitro -.cache -.output -.env -dist diff --git a/test/fixtures/simple/README.md b/test/fixtures/simple/README.md deleted file mode 100644 index c699c96..0000000 --- a/test/fixtures/simple/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# Nuxt 3 Minimal Starter - -Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more. - -## Setup - -Make sure to install the dependencies: - -```bash -# yarn -yarn install - -# npm -npm install - -# pnpm -pnpm install -``` - -## Development Server - -Start the development server on http://localhost:3000 - -```bash -npm run dev -``` - -## Production - -Build the application for production: - -```bash -npm run build -``` - -Locally preview production build: - -```bash -npm run preview -``` - -Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. diff --git a/test/fixtures/simple/app.vue b/test/fixtures/simple/app.vue deleted file mode 100644 index 01b7bef..0000000 --- a/test/fixtures/simple/app.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/test/fixtures/simple/nuxt.config.ts b/test/fixtures/simple/nuxt.config.ts deleted file mode 100644 index a278ee6..0000000 --- a/test/fixtures/simple/nuxt.config.ts +++ /dev/null @@ -1,8 +0,0 @@ -export default defineNuxtConfig({ - modules: ['nuxt-typed-router'], - vite: { - resolve: { - dedupe: ['vue-router'], - }, - }, -}); diff --git a/test/fixtures/simple/package.json b/test/fixtures/simple/package.json deleted file mode 100644 index ca2431f..0000000 --- a/test/fixtures/simple/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "private": true, - "name": "simple", - "version": "1.0.0", - "scripts": { - "build": "nuxt build", - "dev": "nuxt dev", - "generate": "nuxt generate", - "preview": "nuxt preview" - }, - "devDependencies": { - "nuxt": "^3.8.2", - "vue": "3.3.10", - "nuxt-typed-router": "workspace:*" - } -} diff --git a/test/fixtures/simple/pages/admin.vue b/test/fixtures/simple/pages/admin.vue deleted file mode 100644 index 7dcf98f..0000000 --- a/test/fixtures/simple/pages/admin.vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/simple/pages/admin/[id].vue b/test/fixtures/simple/pages/admin/[id].vue deleted file mode 100644 index 7dcf98f..0000000 --- a/test/fixtures/simple/pages/admin/[id].vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/simple/pages/admin/[id]/action-[slug].vue b/test/fixtures/simple/pages/admin/[id]/action-[slug].vue deleted file mode 100644 index 7dcf98f..0000000 --- a/test/fixtures/simple/pages/admin/[id]/action-[slug].vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/simple/pages/admin/[id]/index.vue b/test/fixtures/simple/pages/admin/[id]/index.vue deleted file mode 100644 index 7dcf98f..0000000 --- a/test/fixtures/simple/pages/admin/[id]/index.vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/simple/pages/admin/[id]/profile.vue b/test/fixtures/simple/pages/admin/[id]/profile.vue deleted file mode 100644 index 7dcf98f..0000000 --- a/test/fixtures/simple/pages/admin/[id]/profile.vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/simple/pages/admin/[id]/settings.vue b/test/fixtures/simple/pages/admin/[id]/settings.vue deleted file mode 100644 index 7dcf98f..0000000 --- a/test/fixtures/simple/pages/admin/[id]/settings.vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/simple/pages/admin/panel/[[blou]].vue b/test/fixtures/simple/pages/admin/panel/[[blou]].vue deleted file mode 100644 index 7dcf98f..0000000 --- a/test/fixtures/simple/pages/admin/panel/[[blou]].vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/simple/pages/baguette.vue b/test/fixtures/simple/pages/baguette.vue deleted file mode 100644 index 7dcf98f..0000000 --- a/test/fixtures/simple/pages/baguette.vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/simple/pages/user/[foo]-[[bar]].vue b/test/fixtures/simple/pages/user/[foo]-[[bar]].vue deleted file mode 100644 index 87ac15c..0000000 --- a/test/fixtures/simple/pages/user/[foo]-[[bar]].vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/simple/pages/user/[id].vue b/test/fixtures/simple/pages/user/[id].vue deleted file mode 100644 index 094637f..0000000 --- a/test/fixtures/simple/pages/user/[id].vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/simple/pages/user/[id]/[slug].vue b/test/fixtures/simple/pages/user/[id]/[slug].vue deleted file mode 100644 index 094637f..0000000 --- a/test/fixtures/simple/pages/user/[id]/[slug].vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/simple/pages/user/[id]/[slug]/articles.vue b/test/fixtures/simple/pages/user/[id]/[slug]/articles.vue deleted file mode 100644 index 7dcf98f..0000000 --- a/test/fixtures/simple/pages/user/[id]/[slug]/articles.vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/simple/pages/user/[id]/[slug]/index.vue b/test/fixtures/simple/pages/user/[id]/[slug]/index.vue deleted file mode 100644 index 9070ec8..0000000 --- a/test/fixtures/simple/pages/user/[id]/[slug]/index.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/test/fixtures/simple/pages/user/[id]/index.vue b/test/fixtures/simple/pages/user/[id]/index.vue deleted file mode 100644 index 2504a8a..0000000 --- a/test/fixtures/simple/pages/user/[id]/index.vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/simple/pages/user/[id]/posts.vue b/test/fixtures/simple/pages/user/[id]/posts.vue deleted file mode 100644 index 094637f..0000000 --- a/test/fixtures/simple/pages/user/[id]/posts.vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/simple/pages/user/[one]-foo-[two].vue b/test/fixtures/simple/pages/user/[one]-foo-[two].vue deleted file mode 100644 index 87ac15c..0000000 --- a/test/fixtures/simple/pages/user/[one]-foo-[two].vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/simple/pages/user/catch/[...slug].vue b/test/fixtures/simple/pages/user/catch/[...slug].vue deleted file mode 100644 index 87ac15c..0000000 --- a/test/fixtures/simple/pages/user/catch/[...slug].vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/simple/pages/user/index.vue b/test/fixtures/simple/pages/user/index.vue deleted file mode 100644 index 7dcf98f..0000000 --- a/test/fixtures/simple/pages/user/index.vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/simple/pages/user/test-[[optional]].vue b/test/fixtures/simple/pages/user/test-[[optional]].vue deleted file mode 100644 index 87ac15c..0000000 --- a/test/fixtures/simple/pages/user/test-[[optional]].vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/simple/tests/router/NuxtLink.spec-d.ts b/test/fixtures/simple/tests/router/NuxtLink.spec-d.ts deleted file mode 100644 index 30d7c07..0000000 --- a/test/fixtures/simple/tests/router/NuxtLink.spec-d.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { assertType, vi } from 'vitest'; -import type { TypedNuxtLink } from '../../.nuxt/typed-router/typed-router'; - -const NuxtLink: TypedNuxtLink = vi.fn() as any; - -// ! ------ Should Error ❌ - -// * index.vue -// @ts-expect-error -assertType(new NuxtLink({ to: { name: 'index', params: { id: 1 } } })); -// @ts-expect-error -assertType(new NuxtLink({ to: { name: 'index', params: { id: 1 } } })); -// @ts-expect-error -assertType(new NuxtLink({ to: { name: 'blabla-baguette' } })); - -// * --- [id].vue -// @ts-expect-error -assertType(new NuxtLink({ to: { name: 'user-id' } })); -// @ts-expect-error -assertType(new NuxtLink({ to: { name: 'user-id', params: { foo: 'bar' } } })); - -// * --- [foo]-[[bar]].vue -// @ts-expect-error -assertType(new NuxtLink({ to: { name: 'user-foo-bar' } })); -// @ts-expect-error -assertType(new NuxtLink({ to: { name: 'user-foo-bar', params: { bar: 1 } } })); - -// * --- [...slug].vue -// @ts-expect-error -assertType(new NuxtLink({ to: { name: 'user-catch-slug' } })); -// @ts-expect-error -assertType(new NuxtLink({ to: { name: 'user-catch-slug', params: { slug: 1 } } })); - -// * --- [one]-foo-[two].vue -// @ts-expect-error -assertType(new NuxtLink({ to: { name: 'user-one-foo-two' } })); -// @ts-expect-error -assertType(new NuxtLink({ to: { name: 'user-one-foo-two', params: { one: 1 } } })); - -// * --- [id]/[slug].vue -// @ts-expect-error -assertType(new NuxtLink({ to: { name: 'user-id-slug' } })); -// @ts-expect-error -assertType(new NuxtLink({ to: { name: 'user-id-slug', params: { id: 1 } } })); - -// * --- Routes added by modules -// @ts-expect-error -assertType(new NuxtLink({ to: { name: 'test-module' } })); - -// $ ----- Should be valid ✅ - -assertType(new NuxtLink({ to: { name: 'index' } })); -assertType(new NuxtLink({ to: { name: 'user-id', params: { id: 1 }, hash: 'baz' } })); -assertType(new NuxtLink({ to: { name: 'user-foo-bar', params: { foo: 'bar' }, force: true } })); -assertType( - new NuxtLink({ - to: { name: 'user-foo-bar', params: { foo: 'bar', bar: 'baz' } }, - }) -); -assertType(new NuxtLink({ to: { name: 'user-catch-slug', params: { slug: ['foo'] } } })); -assertType(new NuxtLink({ to: { name: 'user-catch-slug', params: { slug: [1, 2, 3] } } })); -assertType(new NuxtLink({ to: { name: 'user-one-foo-two', params: { one: 1, two: '2' } } })); -assertType( - new NuxtLink({ - to: { name: 'user-id-slug', params: { slug: '2' }, query: { foo: 'bar' } }, - }) -); - -// --- Path navigation - -// ! ------ Should Error ❌ - -// @ts-expect-error -assertType(new NuxtLink({ to: '' })); -// @ts-expect-error -assertType(new NuxtLink({ to: '/admin ' })); -// @ts-expect-error -assertType(new NuxtLink({ to: '/admin/ /' })); -// @ts-expect-error -assertType(new NuxtLink({ to: `/ / // / / eefzr` })); -// @ts-expect-error -assertType(new NuxtLink({ to: '/elzhlzehflzhef' })); -// @ts-expect-error -assertType(new NuxtLink({ to: '/admin/foo/bar' })); -// @ts-expect-error -assertType(new NuxtLink({ to: '/admin/foo/bar/baz' })); -// @ts-expect-error -assertType(new NuxtLink({ to: `/admin/${id}/action-bar/taz?query` })); -// @ts-expect-error -assertType(new NuxtLink({ to: '/admin/panel/3O9393/bar' })); -// @ts-expect-error -assertType(new NuxtLink({ to: '/admin/foo/ profile/ezfje' })); -// @ts-expect-error -assertType(new NuxtLink({ to: '/admin/3U93U/settings/baz' })); -// @ts-expect-error -assertType(new NuxtLink({ to: '/admin/panel/?fjzk' })); - -// $ ----- Should be valid ✅ - -const id = '38789803'; -assertType(new NuxtLink({ to: '/' })); -assertType(new NuxtLink({ to: '/baguette' })); -assertType(new NuxtLink({ to: '/admin/foo' })); -assertType(new NuxtLink({ to: '/admin/foo/' })); -assertType(new NuxtLink({ to: `/admin/${id}/action-bar#hash` })); -assertType(new NuxtLink({ to: `/admin/${id}/action-bar?query=bar` })); -assertType(new NuxtLink({ to: '/admin/foo/profile/' })); -assertType(new NuxtLink({ to: `/admin/${id}/settings` })); -assertType(new NuxtLink({ to: '/admin/panel/' })); -assertType(new NuxtLink({ to: '/admin/panel/938783/' })); -assertType(new NuxtLink({ to: '/user/38873-' })); -assertType(new NuxtLink({ to: '/user/38673/bar/#hash' })); -assertType(new NuxtLink({ to: '/user/ç9737/foo/articles?baz=foo' })); -assertType(new NuxtLink({ to: '/user/catch/1/2' })); -assertType(new NuxtLink({ to: '/user/test-' })); -assertType(new NuxtLink({ to: '/user' })); - -// - With External prop - -// $ ----- Should be valid ✅ - -assertType(new NuxtLink({ to: '/admin/:id/', external: false })); -assertType(new NuxtLink({ to: 'http://google.com', external: true })); diff --git a/test/fixtures/simple/tests/router/navigateTo.spec-d.ts b/test/fixtures/simple/tests/router/navigateTo.spec-d.ts deleted file mode 100644 index 37aea62..0000000 --- a/test/fixtures/simple/tests/router/navigateTo.spec-d.ts +++ /dev/null @@ -1,233 +0,0 @@ -import { assertType, test } from 'vitest'; -import type { LocationQuery } from 'vue-router'; - -// ! ------ Should Error ❌ - -// * index.vue -// @ts-expect-error -navigateTo({ name: 'index', params: { id: 1 } }); -// @ts-expect-error -navigateTo({ name: 'index', params: { id: 1 } }); -// @ts-expect-error -navigateTo({ name: 'blabla-baguette' }); - -// * --- [id].vue -// @ts-expect-error -navigateTo({ name: 'user-id' }); -// @ts-expect-error -navigateTo({ name: 'user-id', params: { foo: 'bar' } }); - -// * --- [foo]-[[bar]].vue -// @ts-expect-error -navigateTo({ name: 'user-foo-bar' }); -// @ts-expect-error -navigateTo({ name: 'user-foo-bar', params: { bar: 1 } }); - -// * --- [...slug].vue -// @ts-expect-error -navigateTo({ name: 'user-catch-slug' }); -// @ts-expect-error -navigateTo({ name: 'user-catch-slug', params: { slug: 1 } }); - -// * --- [one]-foo-[two].vue -// @ts-expect-error -navigateTo({ name: 'user-one-foo-two' }); -// @ts-expect-error -navigateTo({ name: 'user-one-foo-two', params: { one: 1 } }); - -// * --- [id]/[slug].vue -// @ts-expect-error -navigateTo({ name: 'user-id-slug' }); -// @ts-expect-error -navigateTo({ name: 'user-id-slug', params: { id: 1 } }); - -// * --- Routes added by modules -// @ts-expect-error -navigateTo({ name: 'test-module' }); - -// $ ----- Should be valid ✅ - -navigateTo({ name: 'index' }, { external: true }); -navigateTo({ name: 'user-id', params: { id: 1 }, hash: 'baz' }); -navigateTo({ name: 'user-foo-bar', params: { foo: 'bar' }, force: true }); -navigateTo({ name: 'user-foo-bar', params: { foo: 'bar', bar: 'baz' } }); -navigateTo({ name: 'user-catch-slug', params: { slug: ['foo'] } }); -navigateTo({ name: 'user-catch-slug', params: { slug: [1, 2, 3] } }); -navigateTo({ name: 'user-one-foo-two', params: { one: 1, two: '2' } }); -navigateTo({ name: 'user-id-slug', params: { slug: '2' }, query: { foo: 'bar' } }); - -// --- Path navigation - -// ! ------ Should Error ❌ - -// @ts-expect-error -assertType(navigateTo('')); -// @ts-expect-error -assertType(navigateTo('/admin ')); -// @ts-expect-error -assertType(navigateTo('/admin/ /')); -// @ts-expect-error -assertType(navigateTo(`/ / // / / eefzr`)); -// @ts-expect-error -assertType(navigateTo('/elzhlzehflzhef')); -// @ts-expect-error -assertType(navigateTo('/admin/foo/bar')); -// @ts-expect-error -assertType(navigateTo('/admin/foo/bar/baz')); -// @ts-expect-error -assertType(navigateTo(`/admin/${id}/action-bar/taz?query`)); -// @ts-expect-error -assertType(navigateTo('/admin/panel/3O9393/bar')); -// @ts-expect-error -assertType(navigateTo('/admin/foo/ profile/ezfje')); -// @ts-expect-error -assertType(navigateTo('/admin/3U93U/settings/baz')); -// @ts-expect-error -assertType(navigateTo('/admin/panel/?fjzk')); -// @ts-expect-error -assertType(navigateTo('/admin/panel/938783/ ')); -// @ts-expect-error -assertType(navigateTo('/user/3887/foo/bar/')); -// @ts-expect-error -assertType(navigateTo('/admin/:id//')); - -// $ ----- Should be valid ✅ - -const id = '38789803'; -assertType(navigateTo('/')); -assertType(navigateTo('/baguette')); -assertType(navigateTo('/admin/foo')); -assertType(navigateTo('/admin/foo/')); -assertType(navigateTo(`/admin/${id}/action-bar#hash`)); -assertType(navigateTo(`/admin/${id}/action-bar?query=bar`)); -assertType(navigateTo('/admin/foo/profile/')); -assertType(navigateTo(`/admin/${id}/settings`)); -assertType(navigateTo('/admin/panel/')); -assertType(navigateTo('/admin/panel/938783/')); -assertType(navigateTo('/user/38873-')); -assertType(navigateTo('/user/38673/bar/#hash')); -assertType(navigateTo('/user/ç9737/foo/articles?baz=foo')); -assertType(navigateTo('/user/catch/1/2')); -assertType(navigateTo('/user/test-')); -assertType(navigateTo('/user')); - -// - Resolved routes - -// * index.vue -test('', async () => { - const resolvedNavigateToRoute = await navigateTo({ - name: 'index', - }); - - if (resolvedNavigateToRoute && !(resolvedNavigateToRoute instanceof Error)) { - assertType<'index'>(resolvedNavigateToRoute.name); - // @ts-expect-error - assertType(resolvedNavigateToRoute.params); - } -}); - -// * --- [id].vue -test('', async () => { - const resolvedNavigateToRoute = await navigateTo({ - name: 'user-id', - params: { - id: 1, - }, - }); - - if (resolvedNavigateToRoute && !(resolvedNavigateToRoute instanceof Error)) { - assertType<'user-id'>(resolvedNavigateToRoute.name); - assertType<{ - id: string; - }>(resolvedNavigateToRoute.params); - } -}); - -// * --- [foo]-[[bar]].vue -test('', async () => { - const resolvedNavigateToRoute = await navigateTo({ - name: 'user-foo-bar', - params: { - foo: 1, - bar: 1, - }, - }); - - if (resolvedNavigateToRoute && !(resolvedNavigateToRoute instanceof Error)) { - assertType<'user-foo-bar'>(resolvedNavigateToRoute.name); - assertType<{ - foo: string; - bar?: string | undefined; - }>(resolvedNavigateToRoute.params); - } -}); - -// * --- [...slug].vue -test('', async () => { - const resolvedNavigateToRoute = await navigateTo({ - name: 'user-catch-slug', - params: { - slug: [1, 2, 3], - }, - }); - - if (resolvedNavigateToRoute && !(resolvedNavigateToRoute instanceof Error)) { - assertType<'user-catch-slug'>(resolvedNavigateToRoute.name); - assertType<{ - slug: string[]; - }>(resolvedNavigateToRoute.params); - } -}); - -// * --- [one]-foo-[two].vue - -const resolvedNavigateToRoute = await navigateTo({ - name: 'user-one-foo-two', - params: { one: 1, two: 2 }, -}); - -if (resolvedNavigateToRoute && !(resolvedNavigateToRoute instanceof Error)) { - assertType<'user-one-foo-two'>(resolvedNavigateToRoute.name); - assertType<{ - one: string | number; - two: string | number; - }>(resolvedNavigateToRoute.params); - assertType(resolvedNavigateToRoute.query); -} - -// * --- [id]/[slug].vue -test('', async () => { - const resolvedNavigateToRoute = await navigateTo({ - name: 'user-id-slug', - params: { - slug: 1, - id: 1, - }, - }); - - if (resolvedNavigateToRoute && !(resolvedNavigateToRoute instanceof Error)) { - assertType<'user-id-slug'>(resolvedNavigateToRoute.name); - assertType<{ - id: string; - slug: string; - }>(resolvedNavigateToRoute.params); - } -}); - -// - With paths - -// * --- [foo]-[[bar]].vue -test('', async () => { - const resolvedNavigateToRoute = await navigateTo('/admin/3883/action-376773'); - - if (resolvedNavigateToRoute && !(resolvedNavigateToRoute instanceof Error)) { - assertType<'admin-id-action-slug'>(resolvedNavigateToRoute.name); - assertType<{ - id: string; - slug: string; - }>(resolvedNavigateToRoute.params); - - // @ts-expect-error - assertType<'admin-id'>(resolvedNavigateToRoute.name); - } -}); diff --git a/test/fixtures/simple/tests/router/useRouter.spec-d.ts b/test/fixtures/simple/tests/router/useRouter.spec-d.ts deleted file mode 100644 index 09aa5a6..0000000 --- a/test/fixtures/simple/tests/router/useRouter.spec-d.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { assertType } from 'vitest'; -import test from 'node:test'; -import type { TypedRouter } from '@typed-router'; - -// Given -const router = useRouter(); - -assertType(router); - -// - Usage of useRouter with useRouter - -// ! ------ Should Error ❌ - -// * index.vue -// @ts-expect-error -router.push({ name: 'index', params: { id: 1 } }); -// @ts-expect-error -router.push({ name: 'index', params: { id: 1 } }); -// @ts-expect-error -router.push({ name: 'blabla-baguette' }); - -// * --- [id].vue -// @ts-expect-error -router.push({ name: 'user-id' }); -// @ts-expect-error -router.push({ name: 'user-id', params: { foo: 'bar' } }); - -// * --- [foo]-[[bar]].vue -// @ts-expect-error -router.push({ name: 'user-foo-bar' }); -// @ts-expect-error -router.push({ name: 'user-foo-bar', params: { bar: 1 } }); - -// * --- [...slug].vue -// @ts-expect-error -router.push({ name: 'user-slug' }); -// @ts-expect-error -router.push({ name: 'user-slug', params: { slug: 1 } }); - -// * --- [one]-foo-[two].vue -// @ts-expect-error -router.push({ name: 'user-one-foo-two' }); -// @ts-expect-error -router.push({ name: 'user-one-foo-two', params: { one: 1 } }); - -// * --- [id]/[slug].vue -// @ts-expect-error -router.push({ name: 'user-id-slug' }); -// @ts-expect-error -router.push({ name: 'user-id-slug', params: { id: 1 } }); - -// * --- Routes added by modules -// @ts-expect-error -router.push({ name: 'test-module' }); - -// * --- Path navigation -// @ts-expect-error -router.push('/fooooooooooo'); -// @ts-expect-error -router.push({ path: '/foo' }); - -// $ ----- Should be valid ✅ - -router.push({ name: 'index' }); -router.push({ name: 'user-id', params: { id: 1 }, hash: 'baz' }); -router.push({ name: 'user-foo-bar', params: { foo: 'bar' }, force: true }); -router.push({ name: 'user-foo-bar', params: { foo: 'bar', bar: 'baz' } }); -router.push({ name: 'user-catch-slug', params: { slug: ['foo'] } }); -router.push({ name: 'user-catch-slug', params: { slug: [1, 2, 3] } }); -router.push({ name: 'user-one-foo-two', params: { one: 1, two: '2' } }); -router.push({ name: 'user-id-slug', params: { slug: '2' }, query: { foo: 'bar' } }); - -router.replace({ name: 'index' }); -router.replace({ name: 'user-id', params: { id: 1 }, hash: 'baz' }); -router.replace('/admin'); - -// --- Path navigation - -// ! ------ Should Error ❌ - -// @ts-expect-error -assertType(router.push('')); -// @ts-expect-error -assertType(router.push('/admin ')); -// @ts-expect-error -assertType(router.push('/admin/ /')); -// @ts-expect-error -assertType(router.push(`/ / // / / eefzr`)); -// @ts-expect-error -assertType(router.push('/elzhlzehflzhef')); -// @ts-expect-error -assertType(router.push('/admin/foo/bar')); -// @ts-expect-error -assertType(router.push('/admin/foo/bar/baz')); -// @ts-expect-error -assertType(router.push(`/admin/${id}/action-bar/taz?query`)); -// @ts-expect-error -assertType(router.push('/admin/panel/3O9393/bar')); -// @ts-expect-error -assertType(router.push('/admin/foo/ profile/ezfje')); -// @ts-expect-error -assertType(router.push('/admin/3U93U/settings/baz')); -// @ts-expect-error -assertType(router.push('/admin/panel/?fjzk')); - -// $ ----- Should be valid ✅ - -const id = '38789803'; -assertType(router.push('/')); -assertType(router.push('/baguette')); -assertType(router.push('/admin/foo')); -assertType(router.push('/admin/foo/')); -assertType(router.push(`/admin/${id}/action-bar#hash`)); -assertType(router.push(`/admin/${id}/action-bar?query=bar`)); -assertType(router.push('/admin/foo/profile/')); -assertType(router.push(`/admin/${id}/settings`)); -assertType(router.push('/admin/panel/')); -assertType(router.push('/admin/panel/938783/')); -assertType(router.push('/user/38873-')); -assertType(router.push('/user/38673/bar/#hash')); -assertType(router.push('/user/ç9737/foo/articles?baz=foo')); -assertType(router.push('/user/catch/1/2')); -assertType(router.push('/user/test-')); -assertType(router.push('/user')); - -// * Resolved routes - -test('', () => { - const resolved = router.resolve({ name: 'index' }); - assertType<'index'>(resolved.name); - // @ts-expect-error - assertType<'index'>(resolved.params); -}); - -test('', () => { - const resolved = router.resolve({ name: 'user-id', params: { id: 1 }, hash: 'baz' }); - assertType<'user-id'>(resolved.name); - assertType<{ id: string }>(resolved.params); - - // @ts-expect-error - assertType<'user-eojzpejfze'>(resolved.name); -}); - -test('', () => { - const resolved = router.resolve('/admin/foo/'); - assertType<'admin-id'>(resolved.name); - assertType<{ id: string }>(resolved.params); - - // @ts-expect-error - assertType<'jzeifjlfej'>(resolved.name); - // @ts-expect-error - assertType<{ foo: string }>(resolved.params); -}); diff --git a/test/fixtures/simple/tests/routes/useLink.spec-d.ts b/test/fixtures/simple/tests/routes/useLink.spec-d.ts deleted file mode 100644 index 04eb3c4..0000000 --- a/test/fixtures/simple/tests/routes/useLink.spec-d.ts +++ /dev/null @@ -1,245 +0,0 @@ -import { assertType, test } from 'vitest'; -import type { LocationQuery } from 'vue-router'; - -// ! ------ Should Error ❌ - -// * index.vue -// @ts-expect-error -useLink({ to: { name: 'index', params: { id: 1 } } }); -// @ts-expect-error -useLink({ to: { name: 'index', params: { id: 1 } } }); -// @ts-expect-error -useLink({ to: { name: 'blabla-baguette' } }); - -// * --- [id].vue -// @ts-expect-error -useLink({ to: { name: 'user-id' } }); -// @ts-expect-error -useLink({ to: { name: 'user-id', params: { foo: 'bar' } } }); - -// * --- [foo]-[[bar]].vue -// @ts-expect-error -useLink({ to: { name: 'user-foo-bar' } }); -// @ts-expect-error -useLink({ to: { name: 'user-foo-bar', params: { bar: 1 } } }); - -// * --- [...slug].vue -// @ts-expect-error -useLink({ to: { name: 'user-catch-slug' } }); -// @ts-expect-error -useLink({ to: { name: 'user-catch-slug', params: { slug: 1 } } }); - -// * --- [one]-foo-[two].vue -// @ts-expect-error -useLink({ to: { name: 'user-one-foo-two' } }); -// @ts-expect-error -useLink({ to: { name: 'user-one-foo-two', params: { one: 1 } } }); - -// * --- [id]/[slug].vue -// @ts-expect-error -useLink({ to: { name: 'user-id-slug' } }); -// @ts-expect-error -useLink({ to: { name: 'user-id-slug', params: { id: 1 } } }); - -// * --- Routes added by modules -// @ts-expect-error -useLink({ to: { name: 'test-module' } }); - -// $ ----- Should be valid ✅ - -useLink({ to: { name: 'index' } }); -useLink({ to: { name: 'user-id', params: { id: 1 }, hash: 'baz' } }); -useLink({ to: { name: 'user-foo-bar', params: { foo: 'bar' }, force: true } }); -useLink({ to: { name: 'user-foo-bar', params: { foo: 'bar', bar: 'baz' } } }); -useLink({ to: { name: 'user-catch-slug', params: { slug: ['foo'] } } }); -useLink({ to: { name: 'user-catch-slug', params: { slug: [1, 2, 3] } } }); -useLink({ to: { name: 'user-one-foo-two', params: { one: 1, two: '2' } } }); -useLink({ to: { name: 'user-id-slug', params: { slug: '2' }, query: { foo: 'bar' } } }); - -// --- Path navigation - -// ! ------ Should Error ❌ - -// @ts-expect-error -assertType(useLink({ to: '' })); -// @ts-expect-error -assertType(useLink({ to: '/admin ' })); -// @ts-expect-error -assertType(useLink({ to: '/admin/ /' })); -// @ts-expect-error -assertType(useLink({ to: `/ / // / / eefzr` })); -// @ts-expect-error -assertType(useLink({ to: '/elzhlzehflzhef' })); -// @ts-expect-error -assertType(useLink({ to: '/admin/foo/bar' })); -// @ts-expect-error -assertType(useLink({ to: '/admin/foo/bar/baz' })); -// @ts-expect-error -assertType(useLink({ to: `/admin/${id}/action-bar/taz?query` })); -// @ts-expect-error -assertType(useLink({ to: '/admin/panel/3O9393/bar' })); -// @ts-expect-error -assertType(useLink({ to: '/admin/foo/ profile/ezfje' })); -// @ts-expect-error -assertType(useLink({ to: '/admin/3U93U/settings/baz' })); -// @ts-expect-error -assertType(useLink({ to: '/admin/panel/?fjzk' })); -// @ts-expect-error -assertType(useLink({ to: '/admin/panel/938783/ ' })); -// @ts-expect-error -assertType(useLink({ to: '/user/3887/foo/bar/' })); -// @ts-expect-error -assertType(useLink({ to: '/admin/:id//' })); - -// $ ----- Should be valid ✅ - -const id = '38789803'; -assertType(useLink({ to: '/' })); -assertType(useLink({ to: '/baguette' })); -assertType(useLink({ to: '/admin/foo' })); -assertType(useLink({ to: '/admin/foo/' })); -assertType(useLink({ to: `/admin/${id}/action-bar#hash` })); -assertType(useLink({ to: `/admin/${id}/action-bar?query=bar` })); -assertType(useLink({ to: '/admin/foo/profile/' })); -assertType(useLink({ to: `/admin/${id}/settings` })); -assertType(useLink({ to: '/admin/panel/' })); -assertType(useLink({ to: '/admin/panel/938783/' })); -assertType(useLink({ to: '/user/38873-' })); -assertType(useLink({ to: '/user/38673/bar/#hash' })); -assertType(useLink({ to: '/user/ç9737/foo/articles?baz=foo' })); -assertType(useLink({ to: '/user/catch/1/2' })); -assertType(useLink({ to: '/user/test-' })); -assertType(useLink({ to: '/user' })); - -// - Resolved routes - -// * index.vue -test('', async () => { - const resolvedNavigateToRoute = useLink({ - to: { - name: 'index', - }, - }); - - if (resolvedNavigateToRoute) { - assertType<'index'>(resolvedNavigateToRoute.route.value.name); - // @ts-expect-error - assertType(resolvedNavigateToRoute.params); - } -}); - -// * --- [id].vue -test('', async () => { - const resolvedNavigateToRoute = await useLink({ - to: { - name: 'user-id', - params: { - id: 1, - }, - }, - }); - - if (resolvedNavigateToRoute) { - assertType<'user-id'>(resolvedNavigateToRoute.route.value.name); - assertType<{ - id: string; - }>(resolvedNavigateToRoute.route.value.params); - } -}); - -// * --- [foo]-[[bar]].vue -test('', async () => { - const resolvedNavigateToRoute = await useLink({ - to: { - name: 'user-foo-bar', - params: { - foo: 1, - bar: 1, - }, - }, - }); - - if (resolvedNavigateToRoute) { - assertType<'user-foo-bar'>(resolvedNavigateToRoute.route.value.name); - assertType<{ - foo: string; - bar?: string | undefined; - }>(resolvedNavigateToRoute.route.value.params); - } -}); - -// * --- [...slug].vue -test('', async () => { - const resolvedNavigateToRoute = await useLink({ - to: { - name: 'user-catch-slug', - params: { - slug: [1, 2, 3], - }, - }, - }); - - if (resolvedNavigateToRoute) { - assertType<'user-catch-slug'>(resolvedNavigateToRoute.route.value.name); - assertType<{ - slug: string[]; - }>(resolvedNavigateToRoute.route.value.params); - } -}); - -// * --- [one]-foo-[two].vue - -const resolvedNavigateToRoute = await useLink({ - to: { - name: 'user-one-foo-two', - params: { one: 1, two: 2 }, - }, -}); - -if (resolvedNavigateToRoute) { - assertType<'user-one-foo-two'>(resolvedNavigateToRoute.route.value.name); - assertType<{ - one: string | number; - two: string | number; - }>(resolvedNavigateToRoute.route.value.params); - assertType(resolvedNavigateToRoute.route.value.query); -} - -// * --- [id]/[slug].vue -test('', async () => { - const resolvedNavigateToRoute = await useLink({ - to: { - name: 'user-id-slug', - params: { - slug: 1, - id: 1, - }, - }, - }); - - if (resolvedNavigateToRoute) { - assertType<'user-id-slug'>(resolvedNavigateToRoute.route.value.name); - assertType<{ - id: string; - slug: string; - }>(resolvedNavigateToRoute.route.value.params); - } -}); - -// - With paths - -// * --- [foo]-[[bar]].vue -test('', async () => { - const resolvedNavigateToRoute = await useLink({ to: '/admin/3883/action-376773' }); - - if (resolvedNavigateToRoute) { - assertType<'admin-id-action-slug'>(resolvedNavigateToRoute.route.value.name); - assertType<{ - id: string; - slug: string; - }>(resolvedNavigateToRoute.route.value.params); - - // @ts-expect-error - assertType<'admin-id'>(resolvedNavigateToRoute.route.value.name); - } -}); diff --git a/test/fixtures/simple/tests/routes/useRoute.spec-d.ts b/test/fixtures/simple/tests/routes/useRoute.spec-d.ts deleted file mode 100644 index 5993a5f..0000000 --- a/test/fixtures/simple/tests/routes/useRoute.spec-d.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { assertType, test } from 'vitest'; -import type { RouteLocationMatched } from 'vue-router'; -import type { TypedRouteFromName } from '@typed-router'; - -// Given -const route = useRoute(); - -test('Basic', () => { - const namedRoute = useRoute('user-foo-bar'); - - assertType>(namedRoute); - assertType<'user-foo-bar'>(namedRoute.name); - assertType<{ - foo: string; - bar?: string | undefined; - }>(namedRoute.params); - assertType(namedRoute.fullPath); - assertType(namedRoute.hash); - assertType(namedRoute.path); - assertType(namedRoute.matched); -}); - -// * index.vue - -if (route.name === 'index') { - assertType<'index'>(route.name); - assertType(route.params); -} - -// * --- [id].vue -if (route.name === 'user-id') { - assertType>(route); - assertType<'user-id'>(route.name); - assertType<{ id: string }>(route.params); -} - -// * --- [foo]-[[bar]].vue -if (route.name === 'user-foo-bar') { - assertType>(route); - assertType<'user-foo-bar'>(route.name); - assertType<{ - foo: string; - bar?: string | undefined; - }>(route.params); -} - -// * --- [...slug].vue -if (route.name === 'user-catch-slug') { - assertType>(route); - assertType<'user-catch-slug'>(route.name); - assertType<{ - slug: string[]; - }>(route.params); -} - -// * --- [one]-foo-[two].vue -if (route.name === 'user-one-foo-two') { - assertType>(route); - assertType<'user-one-foo-two'>(route.name); - assertType<{ - one: string; - two: string; - }>(route.params); -} - -// * --- [id]/[slug].vue -if (route.name === 'user-id-slug') { - assertType>(route); - assertType<'user-id-slug'>(route.name); - assertType<{ - id: string; - slug: string; - }>(route.params); -} diff --git a/test/fixtures/simple/tsconfig.json b/test/fixtures/simple/tsconfig.json deleted file mode 100644 index 3c61969..0000000 --- a/test/fixtures/simple/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // https://nuxt.com/docs/guide/concepts/typescript - "extends": "./.nuxt/tsconfig.json", - "compilerOptions": { - "verbatimModuleSyntax": false - } -} diff --git a/test/samples-config/classic.ts b/test/samples-config/classic.ts new file mode 100644 index 0000000..ccac3ac --- /dev/null +++ b/test/samples-config/classic.ts @@ -0,0 +1,5 @@ +import { NuxtConfig } from '@nuxt/schema'; + +const config: NuxtConfig = {}; + +export default config; diff --git a/test/samples-config/withPlugin.ts b/test/samples-config/withPlugin.ts new file mode 100644 index 0000000..51bada2 --- /dev/null +++ b/test/samples-config/withPlugin.ts @@ -0,0 +1,8 @@ +import { NuxtConfig } from '@nuxt/schema'; + +const config: NuxtConfig = { + nuxtTypedRouter: { + plugin: true, + }, +}; +export default config; diff --git a/test/samples-config/withStrict.ts b/test/samples-config/withStrict.ts new file mode 100644 index 0000000..330156b --- /dev/null +++ b/test/samples-config/withStrict.ts @@ -0,0 +1,8 @@ +import { NuxtConfig } from '@nuxt/schema'; + +const config: NuxtConfig = { + nuxtTypedRouter: { + strict: true, + }, +}; +export default config; diff --git a/test/samples/[classic].config.ts b/test/samples/[classic].config.ts deleted file mode 100644 index d89e933..0000000 --- a/test/samples/[classic].config.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default { - modules: ['nuxt-typed-router'], -}; diff --git a/test/samples/[withStrict].config.ts b/test/samples/[withStrict].config.ts deleted file mode 100644 index e3d8900..0000000 --- a/test/samples/[withStrict].config.ts +++ /dev/null @@ -1,6 +0,0 @@ -export default { - modules: ['nuxt-typed-router'], - nuxtTypedRouter: { - strict: true, - }, -}; diff --git a/vite.config.ts b/vite.config.ts index 71af7e8..fc9a316 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -5,7 +5,7 @@ export default defineConfig({ test: { globals: true, testTimeout: 10000, - threads: false, + passWithNoTests: true, }, resolve: { alias: { From dadcb88f568393c52fa333b05672a5c1b2d49127 Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Thu, 4 Jan 2024 17:25:36 +0100 Subject: [PATCH 04/10] rebase --- docs/package.json | 2 +- package.json | 13 +- playground/nuxt.config.ts | 1 + playground/src/pages/[lang]/post/[slug].vue | 1 + playground/src/pages/index.vue | 8 +- pnpm-lock.yaml | 432 ++++++++++++++++-- src/core/fs/prettierFormat.ts | 11 +- .../output/generators/files/__paths.file.ts | 29 +- src/core/parser/base.ts | 24 + src/core/parser/i18n.modifiers.ts | 41 +- src/core/parser/walkRoutes.ts | 2 +- .../[classic]/router/useRouter.spec-d.ts | 6 +- .../sample-project/tests/[classic]/test.vue | 3 +- 13 files changed, 497 insertions(+), 76 deletions(-) diff --git a/docs/package.json b/docs/package.json index f1447a4..cd24af5 100755 --- a/docs/package.json +++ b/docs/package.json @@ -10,6 +10,6 @@ }, "devDependencies": { "@nuxt-themes/docus": "1.15.0", - "nuxt": "3.8.2" + "nuxt": "3.9.0" } } diff --git a/package.json b/package.json index f9a1ec2..5a00425 100644 --- a/package.json +++ b/package.json @@ -26,14 +26,7 @@ "docs:dev": "cd docs && pnpm run dev", "docs:build": "cd docs && nuxt generate", "typecheck": "tsc --noEmit", - "release": "bumpp && npm publish && git push --follow-tags", - "test:prepare-fixtures": "nuxi prepare test/fixtures/sample-project", - "test:types-fixtures": "nuxi typecheck test/fixtures/sample-project", - "test:fixtures": "vitest run --dir test", - "test:types": "pnpm run typecheck", - "test:vue": "vue-tsc -p test/fixtures/simple/tsconfig.json --noEmit && vue-tsc -p test/fixtures/complex/tsconfig.json --noEmit", - "test": "pnpm run test:prepare-fixtures && pnpm run test:types && pnpm run test:fixtures", - "test:debug": "NUXT_ROUTER_CONFIG_NAME=$CONFIG pnpm run test:types-fixtures" + "release": "pnpm run prepack && bumpp && npm publish && git push --follow-tags" }, "publishConfig": { "access": "public" @@ -65,7 +58,7 @@ "prettier": "^2.5.x || 3.x" }, "dependencies": { - "@nuxt/kit": "3.8.2", + "@nuxt/kit": "3.9.0", "chalk": "5.3.0", "defu": "6.1.3", "lodash-es": "4.17.21", @@ -73,7 +66,7 @@ "mkdirp": "3.0.1", "nanoid": "5.0.4", "pathe": "1.1.1", - "globby": "14.0.0" + "prettier": "3.1.1" }, "devDependencies": { "@intlify/core-base": "9.8.0", diff --git a/playground/nuxt.config.ts b/playground/nuxt.config.ts index 98b43d2..8a0491e 100644 --- a/playground/nuxt.config.ts +++ b/playground/nuxt.config.ts @@ -16,6 +16,7 @@ export default defineNuxtConfig({ srcDir: './src', i18n: { defaultLocale: 'de', + strategy: 'prefix', // dynamicRouteParams: true, locales: [ { diff --git a/playground/src/pages/[lang]/post/[slug].vue b/playground/src/pages/[lang]/post/[slug].vue index e69de29..517134a 100644 --- a/playground/src/pages/[lang]/post/[slug].vue +++ b/playground/src/pages/[lang]/post/[slug].vue @@ -0,0 +1 @@ + diff --git a/playground/src/pages/index.vue b/playground/src/pages/index.vue index 98e521f..58ea183 100644 --- a/playground/src/pages/index.vue +++ b/playground/src/pages/index.vue @@ -1,13 +1,12 @@