diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 02b3ac4f2..7d36450ef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,7 +38,7 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile - - name: Setup develoment + - name: Setup development run: pnpm dev:prepare - name: Linting diff --git a/.nuxtrc b/.nuxtrc index 0c79f29a7..66e1a6a3d 100644 --- a/.nuxtrc +++ b/.nuxtrc @@ -1,2 +1,3 @@ # enable TypeScript bundler module resolution - https://www.typescriptlang.org/docs/handbook/modules/reference.html#bundler -experimental.typescriptBundlerResolution=true \ No newline at end of file + +future.typescriptBundlerResolution=true diff --git a/eslint.config.js b/eslint.config.js index eb953ec5f..e778be4eb 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -11,10 +11,22 @@ import eslintConfigPrettier from 'eslint-config-prettier' export default [ // ignores { - ignores: ['.nuxt', 'dist', 'playground', 'specs', 'test/fixtures', 'coverage', 'src/runtime/templates/**', 'docs'] + ignores: [ + '.nuxt', + 'dist', + 'playground', + 'specs', + 'test', + 'coverage', + 'docs', + // TODO: figure out how to get eslint to work in these files + // eslint parsing errors in these files, possibly due to generated tsconfig in .nuxt? + 'src/runtime/server', + 'src/runtime/composables/server.ts' + ] }, - // for global and envrionment + // for global and environment { languageOptions: { globals: { diff --git a/internals.d.ts b/internals.d.ts new file mode 100644 index 000000000..2ff92bf1a --- /dev/null +++ b/internals.d.ts @@ -0,0 +1,76 @@ +declare module '#build/i18n.options.mjs' { + import type { DeepRequired } from 'ts-essentials' + /** + * stub type definition for @nuxtjs/i18n internally + */ + + type VueI18nConfig = import('./dist/types').VueI18nConfig + type NuxtI18nOptions = import('./dist/types').NuxtI18nOptions + type LocaleObject = import('./dist/types').LocaleObject + + type LocaleLoader = { + key: string + // eslint-disable-next-line @typescript-eslint/no-explicit-any + load: () => Promise + cache: boolean + } + + export const localeLoaders: Record + + export const vueI18nConfigs: VueI18nConfig[] + + export const localeCodes: string[] + export const nuxtI18nOptions: DeepRequired> + export const normalizedLocales: LocaleObject[] + export const isSSG = false + export const parallelPlugin: boolean + + export const NUXT_I18N_MODULE_ID = '' + export const DEFAULT_DYNAMIC_PARAMS_KEY: string + export const DEFAULT_COOKIE_KEY: string + export const SWITCH_LOCALE_PATH_LINK_IDENTIFIER: string +} + +declare module '#internal/i18n/options.mjs' { + import type { DeepRequired } from 'ts-essentials' + + type VueI18nConfig = import('./dist/types').VueI18nConfig + type NuxtI18nOptions = import('./dist/types').NuxtI18nOptions + type LocaleObject = import('./dist/types').LocaleObject + + /** + * stub type definition for @nuxtjs/i18n internally + */ + + type LocaleLoader = { + key: string + // eslint-disable-next-line @typescript-eslint/no-explicit-any + load: () => Promise + cache: boolean + } + + export const localeLoaders: Record + + export const vueI18nConfigs: VueI18nConfig[] + + export const localeCodes: string[] + export const nuxtI18nOptions: DeepRequired> + export const normalizedLocales: LocaleObject[] + export const isSSG = false + export const parallelPlugin: boolean + + export const NUXT_I18N_MODULE_ID = '' + export const DEFAULT_DYNAMIC_PARAMS_KEY: string + export const DEFAULT_COOKIE_KEY: string + export const SWITCH_LOCALE_PATH_LINK_IDENTIFIER: string +} + +declare module '#internal/i18n/locale.detector.mjs' { + export const localeDetector: import('./dist/runtime/composables/server').LocaleDetector +} + +declare module 'virtual:nuxt-i18n-logger' { + import type { ConsolaInstance } from 'consola' + + export function createLogger(label: string): ConsolaInstance +} diff --git a/package.json b/package.json index 08013787a..f1b9f94f6 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,9 @@ "require": "./dist/module.cjs", "types": "./dist/types.d.ts" }, + "./internals": { + "types": "./internals.d.ts" + }, "./package.json": "./package.json" }, "imports": { @@ -47,17 +50,18 @@ "types": "./dist/types.d.ts", "type": "module", "files": [ - "dist" + "dist", + "internals.d.ts" ], "scripts": { "prepare": "git config --local core.hooksPath .githooks", - "build": "nuxi build-module .", - "stub": "nuxi build-module --stub .", + "build": "nuxt-module-build prepare && nuxt-module-build build .", + "stub": "nuxt-module-build build --stub .", "prepack": "pnpm build", "release": "bumpp --commit \"release: v%s\" --push --tag", "changelog": "gh-changelogen --repo=nuxt-community/i18n-module", "dev": "pnpm dev:prepare && pnpm build --sourcemap && nuxi dev playground", - "dev:prepare": "nuxi prepare", + "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare", "dev:build": "nuxi build playground", "dev:generate": "nuxi generate playground", "dev:preview": "nuxi preview playground", @@ -73,7 +77,7 @@ "lint:prettier": "prettier . --check", "lint:eslint": "eslint .", "test": "pnpm dev:prepare && run-s test:types test:unit test:spec", - "test:types": "tsc --noEmit --project tsconfig.test.json", + "test:types": "tsc --noEmit", "test:unit": "vitest run test", "test:spec": "vitest run specs" }, diff --git a/specs/basic_usage_compat_4.spec.ts b/specs/basic_usage_compat_4.spec.ts index 44b54a9b2..e80fc8a63 100644 --- a/specs/basic_usage_compat_4.spec.ts +++ b/specs/basic_usage_compat_4.spec.ts @@ -14,7 +14,7 @@ import { waitForTransition, waitForURL } from './helper' -import { RouteLocation } from 'vue-router' +import type { RouteLocation } from 'vue-router' describe('basic usage - compatibilityVersion: 4', async () => { await setup({ diff --git a/src/logger.d.ts b/src/logger.d.ts deleted file mode 100644 index 37ccae036..000000000 --- a/src/logger.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare module 'virtual:nuxt-i18n-logger' { - import type { ConsolaInstance } from 'consola' - - export function createLogger(label: string): ConsolaInstance -} diff --git a/src/module.ts b/src/module.ts index b81644e65..9f03e3f66 100644 --- a/src/module.ts +++ b/src/module.ts @@ -6,7 +6,8 @@ import { addTemplate, addTypeTemplate, addImports, - useLogger + useLogger, + createResolver } from '@nuxt/kit' import { resolve, relative } from 'pathe' import { defu } from 'defu' @@ -33,7 +34,7 @@ import { getLocaleFiles, filterLocales } from './utils' -import { distDir, runtimeDir } from './dirs' +import { runtimeDir } from './dirs' import { applyLayerOptions, checkLayerOptions, resolveLayerVueI18nConfigInfo } from './layers' import { generateTemplateNuxtI18nOptions } from './template' import { i18nVirtualLoggerPlugin, RESOLVED_VIRTUAL_NUXT_I18N_LOGGER, VIRTUAL_NUXT_I18N_LOGGER } from './virtual-logger' @@ -59,6 +60,10 @@ export default defineNuxtModule({ async setup(i18nOptions, nuxt) { const logger = useLogger(NUXT_I18N_MODULE_ID) + nuxt.hook('prepare:types', ({ references }) => { + references.push({ types: `${NUXT_I18N_MODULE_ID}/internals` }) + }) + const options = i18nOptions as Required applyOptionOverrides(options, nuxt) debug('options', options) @@ -180,8 +185,9 @@ export default defineNuxtModule({ addPlugin(resolve(runtimeDir, 'plugins/i18n')) addPlugin(resolve(runtimeDir, 'plugins/switch-locale-path-ssr')) + const resolver = createResolver(import.meta.url) // for composables - nuxt.options.alias['#i18n'] = resolve(distDir, 'runtime/composables/index.js') + nuxt.options.alias['#i18n'] = resolver.resolve('./runtime/composables/index') nuxt.options.build.transpile.push('#i18n') nuxt.options.build.transpile.push(VIRTUAL_NUXT_I18N_LOGGER) @@ -206,7 +212,6 @@ export default defineNuxtModule({ }) } - // @ts-expect-error type error nuxt.options.runtimeConfig.public.i18n.locales = simplifyLocaleOptions(nuxt, defu({}, options)) addTemplate({ @@ -448,7 +453,7 @@ declare module '@nuxt/schema' { ['i18n']?: Partial } interface NuxtOptions { - ['i18n']?: UserNuxtI18nOptions + ['i18n']: UserNuxtI18nOptions } interface NuxtHooks extends ModuleHooks {} interface PublicRuntimeConfig extends ModulePublicRuntimeConfig {} diff --git a/src/options.d.ts b/src/options.d.ts deleted file mode 100644 index 4145c9403..000000000 --- a/src/options.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -import type { NuxtI18nOptions, VueI18nConfig, LocaleObject } from './types' -import type { DeepRequired } from 'ts-essentials' - -export type * from './types' - -/** - * stub type definition for @nuxtjs/i18n internally - */ - -type LocaleLoader = { - key: string - // eslint-disable-next-line @typescript-eslint/no-explicit-any - load: () => Promise - cache: boolean -} - -export const localeLoaders: Record = {} - -export const vueI18nConfigs: VueI18nConfig[] - -export const localeCodes: string[] = [] -export const nuxtI18nOptions: DeepRequired> = {} -export const normalizedLocales: LocaleObject[] = [] -export const isSSG = false -export const parallelPlugin: boolean - -export const NUXT_I18N_MODULE_ID = '' -export const DEFAULT_DYNAMIC_PARAMS_KEY: string -export const DEFAULT_COOKIE_KEY: string -export const SWITCH_LOCALE_PATH_LINK_IDENTIFIER: string - -export { NuxtI18nOptions, DetectBrowserLanguageOptions, RootRedirectOptions } from './types' diff --git a/src/runtime/composables/index.ts b/src/runtime/composables/index.ts index d7aaa9cc4..1e9fb1aed 100644 --- a/src/runtime/composables/index.ts +++ b/src/runtime/composables/index.ts @@ -23,7 +23,7 @@ import { getLocale, getLocales, getComposer } from '../compatibility' import type { Ref } from 'vue' import type { Locale } from 'vue-i18n' import type { RouteLocation, RouteLocationNormalizedLoaded, RouteLocationRaw, Router } from 'vue-router' -import type { I18nHeadMetaInfo, I18nHeadOptions, SeoAttributesOptions } from '#build/i18n.options.mjs' +import type { I18nHeadMetaInfo, I18nHeadOptions, SeoAttributesOptions } from '../../types' import type { HeadParam } from '../utils' export * from 'vue-i18n' @@ -246,7 +246,7 @@ export function useLocalePath(): LocalePathFunction { * The parameter signature of this function is same as {@link localeRoute}. * * @param route - A route location. The path or name of the route or an object for more complex routes. - * @param locale - A locale optinal, if not specified, uses the current locale. + * @param locale - A locale optional, if not specified, uses the current locale. * * @returns the route object for a given route, the route object is resolved by vue-router rather than just a full route path. * @@ -305,7 +305,7 @@ export function useLocaleLocation(): LocaleLocationFunction { } /** - * The functin that swtich locale path. + * The function that switch locale path. * * @remarks * The parameter signature of this function is same as {@link switchLocalePath}. diff --git a/src/runtime/composables/server.ts b/src/runtime/composables/server.ts index 9bfdfcf33..a4f8ea19b 100644 --- a/src/runtime/composables/server.ts +++ b/src/runtime/composables/server.ts @@ -18,7 +18,7 @@ export type LocaleConfig = { * @remarks * That is set by `fallbackLocale` option that is loaded with `vueI18n` option (i18n.config). If these do not resolve the fallback locale, use as default `false */ - fallbackLocale: FallbackLocale + fallbackLocale?: FallbackLocale } /** @@ -35,7 +35,7 @@ export type LocaleDetector = (event: H3Event, config: LocaleConfig) => string * Define locale detector for server-side locale detection * * @remarks - * The locale detector fucntion is used to detect the locale on server-side. It's called per request on the server. + * The locale detector function is used to detect the locale on server-side. It's called per request on the server. * * @param detector - The {@link LocaleDetector | locale detector} * diff --git a/src/runtime/internal.ts b/src/runtime/internal.ts index cd386c2d3..70f74e046 100644 --- a/src/runtime/internal.ts +++ b/src/runtime/internal.ts @@ -17,7 +17,7 @@ import { initCommonComposableOptions, type CommonComposableOptions } from './uti import { createLogger } from 'virtual:nuxt-i18n-logger' import type { Locale } from 'vue-i18n' -import type { DetectBrowserLanguageOptions, LocaleObject } from '#build/i18n.options.mjs' +import type { DetectBrowserLanguageOptions, LocaleObject } from '../types' import type { RouteLocationNormalized, RouteLocationNormalizedLoaded } from 'vue-router' import type { CookieRef, NuxtApp } from 'nuxt/app' import type { ModulePublicRuntimeConfig } from '../module' @@ -350,7 +350,7 @@ export function getDomainFromLocale(localeCode: Locale): string | undefined { const nuxtApp = useNuxtApp() const host = getHost() // lookup the `differentDomain` origin associated with given locale. - const config = runtimeConfig.public.i18n + const config = runtimeConfig.public.i18n as ModulePublicRuntimeConfig['i18n'] const lang = normalizedLocales.find(locale => locale.code === localeCode) const domain = config?.domainLocales?.[localeCode]?.domain || lang?.domain || lang?.domains?.find(v => v === host) @@ -374,7 +374,7 @@ export function getDomainFromLocale(localeCode: Locale): string | undefined { } export const runtimeDetectBrowserLanguage = ( - opts: ModulePublicRuntimeConfig['i18n'] = useRuntimeConfig().public.i18n + opts: ModulePublicRuntimeConfig['i18n'] = useRuntimeConfig().public.i18n as ModulePublicRuntimeConfig['i18n'] ) => { if (opts?.detectBrowserLanguage === false) return false @@ -385,8 +385,8 @@ export const runtimeDetectBrowserLanguage = ( * Removes default routes depending on domain */ export function setupMultiDomainLocales(nuxtContext: NuxtApp, defaultLocaleDomain: string) { - const { multiDomainLocales, strategy, routesNameSeparator, defaultLocaleRouteNameSuffix } = - nuxtContext.$config.public.i18n + const { multiDomainLocales, strategy, routesNameSeparator, defaultLocaleRouteNameSuffix } = nuxtContext.$config.public + .i18n as ModulePublicRuntimeConfig['i18n'] // feature disabled if (!multiDomainLocales) return @@ -419,7 +419,8 @@ export function setupMultiDomainLocales(nuxtContext: NuxtApp, defaultLocaleDomai * Returns default locale for the current domain, returns `defaultLocale` by default */ export function getDefaultLocaleForDomain(nuxtContext: NuxtApp) { - const { locales, defaultLocale, multiDomainLocales } = nuxtContext.$config.public.i18n + const { locales, defaultLocale, multiDomainLocales } = nuxtContext.$config.public + .i18n as ModulePublicRuntimeConfig['i18n'] let defaultLocaleDomain: string = defaultLocale || '' diff --git a/src/runtime/plugins/i18n.ts b/src/runtime/plugins/i18n.ts index de2d43ded..9ed33fdec 100644 --- a/src/runtime/plugins/i18n.ts +++ b/src/runtime/plugins/i18n.ts @@ -7,8 +7,7 @@ import { isSSG, localeLoaders, parallelPlugin, - normalizedLocales, - type LocaleObject + normalizedLocales } from '#build/i18n.options.mjs' import { loadVueI18nOptions, loadInitialMessages, loadLocale } from '../messages' import { loadAndSetLocale, detectLocale, detectRedirect, navigate, injectNuxtHelpers, extendBaseUrl } from '../utils' @@ -30,6 +29,8 @@ import { createLogger } from 'virtual:nuxt-i18n-logger' import type { NuxtI18nPluginInjections } from '../injections' import type { Locale, I18nOptions } from 'vue-i18n' import type { NuxtApp } from '#app' +import type { LocaleObject } from '../../types' +import type { ModulePublicRuntimeConfig } from '../../module' // from https://github.com/nuxt/nuxt/blob/2466af53b0331cdb8b17c2c3b08675c5985deaf3/packages/nuxt/src/core/templates.ts#L152 type Decorate> = { [K in keyof T as K extends string ? `$${K}` : never]: T[K] } @@ -57,7 +58,10 @@ export default defineNuxtPlugin({ setupMultiDomainLocales(nuxtContext, defaultLocaleDomain) // Fresh copy per request to prevent reusing mutated options - const runtimeI18n = { ...nuxtContext.$config.public.i18n, defaultLocale: defaultLocaleDomain } + const runtimeI18n = { + ...(nuxtContext.$config.public.i18n as ModulePublicRuntimeConfig['i18n']), + defaultLocale: defaultLocaleDomain + } // @ts-expect-error type incompatible runtimeI18n.baseUrl = extendBaseUrl() @@ -144,10 +148,11 @@ export default defineNuxtPlugin({ extendI18n(i18n, { extendComposer(composer) { const route = useRoute() - const _locales = ref(runtimeI18n.locales) - const _localeCodes = ref(localeCodes) + const _locales = ref(runtimeI18n.locales) + const _localeCodes = ref(localeCodes) const _baseUrl = ref('') + // @ts-expect-error type mismatch composer.locales = computed(() => _locales.value) composer.localeCodes = computed(() => _localeCodes.value) composer.baseUrl = computed(() => _baseUrl.value) diff --git a/src/runtime/routing/compatibles/head.ts b/src/runtime/routing/compatibles/head.ts index 894816e6b..649421eee 100644 --- a/src/runtime/routing/compatibles/head.ts +++ b/src/runtime/routing/compatibles/head.ts @@ -7,7 +7,7 @@ import { getRouteBaseName, localeRoute, switchLocalePath } from './routing' import { getComposer, getLocale, getLocales } from '../../compatibility' import type { I18n } from 'vue-i18n' -import type { I18nHeadMetaInfo, MetaAttrs, LocaleObject, I18nHeadOptions } from '#build/i18n.options.mjs' +import type { I18nHeadMetaInfo, MetaAttrs, LocaleObject, I18nHeadOptions } from '../../../types' import type { CommonComposableOptions } from '../../utils' /** @@ -73,7 +73,7 @@ export function localeHead( function getBaseUrl() { const nuxtApp = useNuxtApp() - const i18n = getComposer(nuxtApp.$i18n as I18n) + const i18n = getComposer(nuxtApp.$i18n as unknown as I18n) return joinURL(unref(i18n.baseUrl), nuxtApp.$config.app.baseURL) } @@ -211,11 +211,11 @@ export function getAlternateOgLocales( return alternateLocales.map(locale => ({ [key]: `i18n-og-alt-${locale.language}`, property: 'og:locale:alternate', - content: hypenToUnderscore(locale.language!) + content: hypenToUnderscore(locale.language) })) } -function hypenToUnderscore(str: string) { +function hypenToUnderscore(str?: string) { return (str || '').replace(/-/g, '_') } diff --git a/src/runtime/routing/compatibles/routing.ts b/src/runtime/routing/compatibles/routing.ts index 5ee25f315..d457cadd7 100644 --- a/src/runtime/routing/compatibles/routing.ts +++ b/src/runtime/routing/compatibles/routing.ts @@ -9,7 +9,7 @@ import { resolve, routeToObject } from './utils' import { getLocaleRouteName, getRouteName } from '../utils' import { extendPrefixable, extendSwitchLocalePathIntercepter, type CommonComposableOptions } from '../../utils' -import type { Strategies, PrefixableOptions, SwitchLocalePathIntercepter } from '#build/i18n.options.mjs' +import type { Strategies, PrefixableOptions, SwitchLocalePathIntercepter } from '../../../types' import type { Locale } from 'vue-i18n' import type { RouteLocation, @@ -20,6 +20,7 @@ import type { RouteLocationNormalizedLoaded, RouteLocationNormalized } from 'vue-router' +import type { ModulePublicRuntimeConfig } from '~/src/module' const RESOLVED_PREFIXED = new Set(['prefix_and_default', 'prefix_except_default']) @@ -132,7 +133,8 @@ export function localeLocation( export function resolveRoute(common: CommonComposableOptions, route: RouteLocationRaw, locale: Locale | undefined) { const { router, i18n } = common const _locale = locale || getLocale(i18n) - const { defaultLocale, strategy, trailingSlash } = common.runtimeConfig.public.i18n + const { defaultLocale, strategy, trailingSlash } = common.runtimeConfig.public + .i18n as ModulePublicRuntimeConfig['i18n'] const prefixable = extendPrefixable(common.runtimeConfig) // if route parameter is a string, check if it's a path or name of route. let _route: RouteLocationPathRaw | RouteLocationNamedRaw diff --git a/src/runtime/routing/compatibles/utils.ts b/src/runtime/routing/compatibles/utils.ts index 902891bf6..cf83ec487 100644 --- a/src/runtime/routing/compatibles/utils.ts +++ b/src/runtime/routing/compatibles/utils.ts @@ -2,7 +2,7 @@ import { assign } from '@intlify/shared' import type { Locale } from 'vue-i18n' import type { RouteLocationNormalizedLoaded, RouteLocationPathRaw } from 'vue-router' -import type { Strategies } from '#build/i18n.options.mjs' +import type { Strategies } from '../../../types' import type { CommonComposableOptions } from '../../utils' function split(str: string, index: number) { diff --git a/src/runtime/routing/utils.ts b/src/runtime/routing/utils.ts index d675493f0..e40205fd5 100644 --- a/src/runtime/routing/utils.ts +++ b/src/runtime/routing/utils.ts @@ -1,6 +1,6 @@ import { isString, isSymbol, isFunction } from '@intlify/shared' -import type { LocaleObject, Strategies, BaseUrlResolveHandler } from '#build/i18n.options.mjs' +import type { LocaleObject, Strategies, BaseUrlResolveHandler } from '../../types' import type { Locale } from 'vue-i18n' export const inBrowser = typeof window !== 'undefined' diff --git a/src/runtime/utils.ts b/src/runtime/utils.ts index 0a64c33a8..4d4284413 100644 --- a/src/runtime/utils.ts +++ b/src/runtime/utils.ts @@ -44,16 +44,16 @@ import type { Router } from '#vue-router' import type { DetectLocaleContext } from './internal' import type { HeadSafe } from '@unhead/vue' import type { RouteLocationNormalized, RouteLocationNormalizedLoaded } from 'vue-router' -import type { RuntimeConfig } from '@nuxt/schema' +import type { RuntimeConfig } from 'nuxt/schema' import type { ModulePublicRuntimeConfig } from '../module' import type { RootRedirectOptions, PrefixableOptions, SwitchLocalePathIntercepter, BaseUrlResolveHandler, - LocaleObject, - Strategies -} from '#build/i18n.options.mjs' + Strategies, + LocaleObject +} from '../types' /** * Common options used internally by composable functions, these @@ -64,14 +64,14 @@ import type { export type CommonComposableOptions = { router: Router i18n: I18n - runtimeConfig: RuntimeConfig + runtimeConfig: RuntimeConfig & { public: { i18n: ModulePublicRuntimeConfig['i18n'] } } metaState: Ref> } export function initCommonComposableOptions(i18n?: I18n): CommonComposableOptions { return { - i18n: i18n ?? (useNuxtApp().$i18n as I18n), + i18n: i18n ?? (useNuxtApp().$i18n as unknown as I18n), router: useRouter(), - runtimeConfig: useRuntimeConfig(), + runtimeConfig: useRuntimeConfig() as RuntimeConfig & { public: { i18n: ModulePublicRuntimeConfig['i18n'] } }, metaState: useState>('nuxt-i18n-meta', () => ({})) } } @@ -282,8 +282,8 @@ export async function navigate( { status = 302, enableNavigate = false }: { status?: number; enableNavigate?: boolean } = {} ) { const { nuxtApp, i18n, locale, route } = args - const { rootRedirect, differentDomains, multiDomainLocales, skipSettingLocaleOnNavigate, locales, strategy } = - nuxtApp.$config.public.i18n + const { rootRedirect, differentDomains, multiDomainLocales, skipSettingLocaleOnNavigate, locales, strategy } = nuxtApp + .$config.public.i18n as ModulePublicRuntimeConfig['i18n'] const logger = /*#__PURE__*/ createLogger('navigate') let { redirectPath } = args @@ -419,7 +419,7 @@ export function extendBaseUrl(): BaseUrlResolveHandler { const logger = /*#__PURE__*/ createLogger('extendBaseUrl') return (): string => { const ctx = useNuxtApp() - const { baseUrl, defaultLocale, differentDomains } = ctx.$config.public.i18n + const { baseUrl, defaultLocale, differentDomains } = ctx.$config.public.i18n as ModulePublicRuntimeConfig['i18n'] if (isFunction(baseUrl)) { const baseUrlResult = baseUrl(ctx) @@ -441,7 +441,8 @@ export function extendBaseUrl(): BaseUrlResolveHandler { return baseUrl } - return baseUrl! + // @ts-expect-error all cases are already handled + return baseUrl } } diff --git a/src/server.d.ts b/src/server.d.ts deleted file mode 100644 index 3a08813c5..000000000 --- a/src/server.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export type LocaleDetector = (event: H3Event, config: LocaleConfig) => string -export const localeDetector: LocaleDetector diff --git a/test/gen.test.ts b/test/gen.test.ts index f0c459b16..66cbe2ee6 100644 --- a/test/gen.test.ts +++ b/test/gen.test.ts @@ -1,5 +1,6 @@ import { generateLoaderOptions } from '../src/gen' import { resolveLocales, resolveVueI18nConfigInfo } from '../src/utils' +import { vi, beforeEach, afterEach, test, expect } from 'vitest' import type { LocaleInfo, NuxtI18nOptions, VueI18nConfigPathInfo } from '../src/types' import type { Nuxt } from '@nuxt/schema' @@ -61,7 +62,7 @@ const makeNuxtOptions = (localeInfo: LocaleInfo[]) => { } ] } - } as Nuxt + } as unknown as Nuxt } test('basic', async () => { diff --git a/test/pages/custom_route.test.ts b/test/pages/custom_route.test.ts index 364dee726..150011d59 100644 --- a/test/pages/custom_route.test.ts +++ b/test/pages/custom_route.test.ts @@ -1,9 +1,9 @@ -import { vi, test, expect } from 'vitest' import fs from 'node:fs' import { resolve } from 'node:path' import { localizeRoutes } from '../../src/routing' import { getRouteOptionsResolver, analyzeNuxtPages } from '../../src/pages' import { getNuxtOptions, stripFilePropertyFromPages } from './utils' +import { vi, afterAll, describe, test, expect } from 'vitest' import type { NuxtPage } from '@nuxt/schema' import type { NuxtPageAnalyzeContext, AnalyzedNuxtPageMeta } from '../../src/pages' diff --git a/test/utils.test.ts b/test/utils.test.ts index 8364ee788..1720cd5b5 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -1,5 +1,6 @@ import { parseSegment, getRoutePath, resolveLocales } from '../src/utils' import type { LocaleObject } from '../src/types' +import { vi, beforeEach, afterEach, test, expect } from 'vitest' vi.mock('pathe', async () => { const mod = await vi.importActual('pathe') diff --git a/tsconfig.json b/tsconfig.json index 78e4a1d6d..ae535c755 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,117 +1,4 @@ { - "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - - /* Projects */ - // "incremental": true, /* Enable incremental compilation */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - - /* Language and Environment */ - "target": "esnext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ - // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - - /* Modules */ - "module": "esnext" /* Specify what module code is generated. */, - // "rootDir": "./", /* Specify the root folder within your source files. */ - "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */, - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - "paths": { - "#app": ["./node_modules/nuxt/dist/app"], - "#app/*": ["./node_modules/nuxt/dist/app/*"], - "#components": ["./.nuxt/components"], - "#imports": ["./.nuxt/imports.d.ts"], - "#pages": ["./node_modules/nuxt/dist/pages/runtime/index.d.ts"], - "#head": ["./node_modules/nuxt/dist/index.d.ts"], - "#i18n": ["./src/runtime/composables/index.ts"], - "#vue-router": ["./node_modules/vue-router"], - "#build/i18n.options.mjs": ["./src/options.d.ts"], - "#internal/i18n/options.mjs": ["./src/options.d.ts"], - "#internal/i18n/locale.detector.mjs": ["./src/server.d.ts"] - } /* Specify a set of entries that re-map imports to additional lookup locations. */, - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ - "types": [ - "vitest/globals" - ] /* Specify type package names to be included without being referenced in a source file. */, - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "resolveJsonModule": true, /* Enable importing .json files */ - // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ - - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ - - /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ - // "outDir": "./", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, - - /* Type Checking */ - "strict": true /* Enable all strict type-checking options. */, - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ - // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ - // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */, - "verbatimModuleSyntax": true - }, - "exclude": ["**/.nuxt/**", "**/*/dist/*", "docs/**", "playground/**", "specs/**.spec*", "src/runtime/templates/**"] + "extends": "./.nuxt/tsconfig.json", + "exclude": ["node_modules", "playground", "specs/**", "test/**", "docs/**"] } diff --git a/tsconfig.test.json b/tsconfig.test.json deleted file mode 100644 index ccaaee2f1..000000000 --- a/tsconfig.test.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./tsconfig.json", - "exclude": [ - "**/.nuxt/**", - "**/*/dist/*", - "dist/**", - "docs/**", - "playground/**", - "specs/**", - "src/runtime/templates/**" - ] -}