Skip to content

Commit

Permalink
fix: API type completion (#1682)
Browse files Browse the repository at this point in the history
  • Loading branch information
kazupon committed Nov 26, 2022
1 parent a7fc4de commit bdf0d55
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 47 deletions.
9 changes: 7 additions & 2 deletions package.json
Expand Up @@ -26,8 +26,13 @@
"exports": {
".": {
"import": "./dist/module.mjs",
"require": "./dist/module.cjs"
}
"require": "./dist/module.cjs",
"types": "./dist/types.d.ts"
},
"./package.json": "./package.json"
},
"imports": {
"#i18n": "./dist/runtime/composables.mjs"
},
"main": "./dist/module.cjs",
"module": "./dist/module.mjs",
Expand Down
40 changes: 11 additions & 29 deletions src/alias.ts
@@ -1,11 +1,11 @@
import createDebug from 'debug'
import { resolvePath } from '@nuxt/kit'
import { resolveVueI18nPkgPath, pkgModulesDir } from './dirs'
import { resolveVueI18nPkgPath, pkgModulesDir, getPackageManagerType } from './dirs'
import { resolve, parse as parsePath } from 'pathe'
import { resolveLockfile } from 'pkg-types'
import { VUE_I18N_PKG, VUE_I18N_BRIDGE_PKG, VUE_ROUTER_BRIDGE_PKG, VUE_I18N_ROUTING_PKG } from './constants'

import type { Nuxt } from '@nuxt/schema'
import type { PackageManager } from './dirs'

const debug = createDebug('@nuxtjs/i18n:alias')

Expand Down Expand Up @@ -39,60 +39,42 @@ export async function setupAlias(nuxt: Nuxt) {
debug('vue-i18n-routing alias', nuxt.options.alias[VUE_I18N_ROUTING_PKG])
}

const PackageManagerLockFiles = {
'npm-shrinkwrap.json': 'npm-legacy',
'package-lock.json': 'npm',
'yarn.lock': 'yarn',
'pnpm-lock.yaml': 'pnpm'
} as const

type LockFile = keyof typeof PackageManagerLockFiles
type _PackageManager = typeof PackageManagerLockFiles[LockFile]
type PackageManager = _PackageManager | 'unknown'

async function getPackageManagerType(): Promise<PackageManager> {
try {
const parsed = parsePath(await resolveLockfile())
const lockfile = `${parsed.name}${parsed.ext}` as LockFile
debug('getPackageManagerType: lockfile', lockfile)
if (lockfile == null) {
return 'unknown'
}
const type = PackageManagerLockFiles[lockfile]
return type == null ? 'unknown' : type
} catch (e) {
debug('getPackageManagerType: resolveLockfile error', e)
throw e
}
}

async function resolveVueI18nAlias(nuxt: Nuxt) {
return resolve(await resolveVueI18nPkgPath(), nuxt.options.dev ? 'dist/vue-i18n.mjs' : 'dist/vue-i18n.runtime.mjs')
}

async function resolveVueI18nBridgeAlias(pkgModuleDir: string, pkgMgr: PackageManager) {
if (pkgMgr === 'npm') {
debug(
'resolveVueI18nBridgeAlias on npm',
`${VUE_I18N_ROUTING_PKG}/node_modules/${VUE_I18N_BRIDGE_PKG}/lib/index.mjs`
)
return resolve(pkgModuleDir, `${VUE_I18N_ROUTING_PKG}/node_modules/${VUE_I18N_BRIDGE_PKG}/lib/index.mjs`)
} else {
const parsed = parsePath(await resolvePath(VUE_I18N_BRIDGE_PKG))
debug(`resolveVueI18nBridgeAlias on ${pkgMgr}`, parsed)
return `${parsed.dir}/${parsed.name}.mjs`
}
}

async function resolveVueRouterBridgeAlias(pkgModuleDir: string, pkgMgr: PackageManager) {
if (pkgMgr === 'npm') {
debug('resolveVueRouterBridgeAlias on npm', `${VUE_ROUTER_BRIDGE_PKG}/lib/index.mjs`)
return resolve(pkgModuleDir, `${VUE_ROUTER_BRIDGE_PKG}/lib/index.mjs`)
} else {
const parsed = parsePath(await resolvePath(VUE_ROUTER_BRIDGE_PKG))
debug(`resolveVueRouterBridgeAlias on ${pkgMgr}`, parsed)
return `${parsed.dir}/${parsed.name}.mjs`
}
}

async function resolveVueI18nRoutingAlias(pkgModuleDir: string, pkgMgr: PackageManager) {
if (pkgMgr === 'npm') {
debug('resolveVueI18nRoutingAlias on npm', `${VUE_I18N_ROUTING_PKG}/dist/vue-i18n-routing.mjs`)
return resolve(pkgModuleDir, `${VUE_I18N_ROUTING_PKG}/dist/vue-i18n-routing.mjs`)
} else if (pkgMgr === 'pnpm' || pkgMgr === 'yarn') {
const parsed = parsePath(await resolvePath(VUE_I18N_ROUTING_PKG))
debug(`resolveVueI18nRoutingAlias on ${pkgMgr}`, parsed)
return `${parsed.dir}/dist/vue-i18n-routing.mjs`
} else {
return await resolvePath(VUE_I18N_ROUTING_PKG)
Expand Down
47 changes: 42 additions & 5 deletions src/dirs.ts
@@ -1,7 +1,9 @@
import createDebug from 'debug'
import { fileURLToPath } from 'node:url'
import { dirname, resolve } from 'pathe'
import { dirname, resolve, parse as parsePath } from 'pathe'
import { resolvePath } from '@nuxt/kit'
import { resolveLockfile } from 'pkg-types'
import { VUE_I18N_ROUTING_PKG } from './constants'

const debug = createDebug('@nuxtjs/i18n:dirs')

Expand All @@ -10,19 +12,54 @@ export const runtimeDir = fileURLToPath(new URL('./runtime', import.meta.url))
const pkgDir = resolve(distDir, '..')
export const pkgModulesDir = resolve(pkgDir, './node_modules')

const PackageManagerLockFiles = {
'npm-shrinkwrap.json': 'npm-legacy',
'package-lock.json': 'npm',
'yarn.lock': 'yarn',
'pnpm-lock.yaml': 'pnpm'
} as const

type LockFile = keyof typeof PackageManagerLockFiles
type _PackageManager = typeof PackageManagerLockFiles[LockFile]
export type PackageManager = _PackageManager | 'unknown'

debug('distDir', distDir)
debug('runtimeDir', runtimeDir)
debug('pkgDir', pkgDir)
debug('pkgModulesDir', pkgModulesDir)

export async function getPackageManagerType(): Promise<PackageManager> {
try {
const parsed = parsePath(await resolveLockfile())
const lockfile = `${parsed.name}${parsed.ext}` as LockFile
debug('getPackageManagerType: lockfile', lockfile)
if (lockfile == null) {
return 'unknown'
}
const type = PackageManagerLockFiles[lockfile]
return type == null ? 'unknown' : type
} catch (e) {
debug('getPackageManagerType: resolveLockfile error', e)
throw e
}
}

export async function resolveVueI18nPkgPath() {
const p = await resolvePath('vue-i18n')
debug('vue-i18n resolved path', p)
return resolve(p, '../..')
}

export async function resolveVueI18nRoutingPkgPath() {
const p = await resolvePath('vue-i18n-routing')
debug('vue-i18n-routing resolved path', p)
return resolve(p, '..')
export async function resolveVueI18nRoutingDtsPath(id: string) {
const pkgMgr = await getPackageManagerType()
if (pkgMgr === 'npm') {
debug('resolveVueI18nRoutingDtsPath on npm', `${VUE_I18N_ROUTING_PKG}/dist/${id}`)
return resolve(pkgModulesDir, `${VUE_I18N_ROUTING_PKG}/dist/${id}`)
} else if (pkgMgr === 'pnpm' || pkgMgr === 'yarn') {
const parsed = parsePath(await resolvePath(VUE_I18N_ROUTING_PKG))
debug(`resolveVueI18nRoutingDtsPath on ${pkgMgr}`, parsed)
return `${parsed.dir}/${id}`
} else {
throw new Error(`Not supported package manager`)
}
}
25 changes: 14 additions & 11 deletions src/module.ts
Expand Up @@ -9,7 +9,7 @@ import { extendBundler } from './bundler'
import { generateLoaderOptions } from './gen'
import { NUXT_I18N_MODULE_ID, DEFAULT_OPTIONS } from './constants'
import { formatMessage, getNormalizedLocales, resolveLocales } from './utils'
import { distDir, runtimeDir, resolveVueI18nPkgPath, resolveVueI18nRoutingPkgPath } from './dirs'
import { distDir, runtimeDir, resolveVueI18nPkgPath, resolveVueI18nRoutingDtsPath } from './dirs'

import type { NuxtI18nOptions } from './types'
import type { DefineLocaleMessage, LocaleMessages } from 'vue-i18n'
Expand Down Expand Up @@ -116,12 +116,7 @@ export default defineNuxtModule<NuxtI18nOptions>({
addPlugin(resolve(runtimeDir, 'plugin'))

// for compoables
const i18nPath = addTemplate({
filename: 'i18n.mjs',
src: resolve(distDir, 'runtime/composables.mjs')
})
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
nuxt.options.alias['#i18n'] = i18nPath.dst!
nuxt.options.alias['#i18n'] = resolve(distDir, 'runtime/composables.mjs')
nuxt.options.build.transpile.push('#i18n')

// TODO: We don't want to resolve the following as a template,
Expand Down Expand Up @@ -204,22 +199,29 @@ export default defineNuxtModule<NuxtI18nOptions>({
: false
}
const nuxtAppExtendFilename = 'types/i18n-nuxt-app.d.ts'
const vueI18nDir = await resolveVueI18nPkgPath()
const vueI18nRoutingDir = await resolveVueI18nRoutingPkgPath()
const vueI18nRoutingVueI18nDtsPath = await resolveVueI18nRoutingDtsPath('vue-i18n')
const vueI18nRoutingMixinDtsPath = await resolveVueI18nRoutingDtsPath('vue')
addTemplate({
filename: nuxtAppExtendFilename,
getContents: () => {
return [
`import type { ${isLegacyMode() ? 'VueI18n' : 'ExportedGlobalComposer'} } from 'vue-i18n'`,
// prettier-ignore
`import type { NuxtI18nRoutingCustomProperties } from '${resolve(runtimeDir, 'types')}'`,
`import type { I18nRoutingCustomProperties } from 'vue-i18n-routing/dist/vue-i18n'`,
isLegacyMode() ? `import '${resolve(vueI18nRoutingDir, 'dist/vue')}'` : '',
`import type { I18nRoutingCustomProperties } from '${vueI18nRoutingVueI18nDtsPath}'`,
// import legacy mixins
isLegacyMode() ? `import '${vueI18nRoutingMixinDtsPath}'` : '',
`declare module '#app' {`,
' interface NuxtApp {',
// prettier-ignore
` $i18n: ${isLegacyMode() ? 'VueI18n' : 'ExportedGlobalComposer'} & NuxtI18nRoutingCustomProperties & I18nRoutingCustomProperties`,
' }',
'}',
`declare module 'nuxt/dist/app/nuxt' {`,
' interface NuxtApp {',
// prettier-ignore
` $i18n: ${isLegacyMode() ? 'VueI18n' : 'ExportedGlobalComposer'} & NuxtI18nRoutingCustomProperties & I18nRoutingCustomProperties`,
' }',
'}'
].join('\n')
}
Expand All @@ -244,6 +246,7 @@ export default defineNuxtModule<NuxtI18nOptions>({
* auto imports
*/

const vueI18nDir = await resolveVueI18nPkgPath()
await addImports([
{ name: 'useI18n', from: resolve(vueI18nDir, 'dist/vue-i18n') },
...[
Expand Down
11 changes: 11 additions & 0 deletions src/runtime/plugin.ts
Expand Up @@ -401,3 +401,14 @@ declare module '#app' {
$switchLocalePath: (...args: Parameters<SwitchLocalePath>) => ReturnType<SwitchLocalePath>
}
}

// @ts-ignore
declare module 'nuxt/dist/app/nuxt' {
interface NuxtApp {
$getRouteBaseName: (...args: Parameters<GetRouteBaseName>) => ReturnType<GetRouteBaseName>
$localePath: (...args: Parameters<LocalePath>) => ReturnType<LocalePath>
$localeRoute: (...args: Parameters<LocaleRoute>) => ReturnType<LocaleRoute>
$localeHead: (...args: Parameters<LocaleHead>) => ReturnType<LocaleHead>
$switchLocalePath: (...args: Parameters<SwitchLocalePath>) => ReturnType<SwitchLocalePath>
}
}

0 comments on commit bdf0d55

Please sign in to comment.