2021-11-21 16:14:46 +00:00
|
|
|
import satisfies from 'semver/functions/satisfies.js' // npm/node-semver#381
|
2024-05-09 08:28:33 +00:00
|
|
|
import { readPackageJSON } from 'pkg-types'
|
2021-12-21 13:57:26 +00:00
|
|
|
import type { Nuxt, NuxtCompatibility, NuxtCompatibilityIssues } from '@nuxt/schema'
|
2021-11-21 16:14:46 +00:00
|
|
|
import { useNuxt } from './context'
|
|
|
|
|
2023-06-06 22:36:35 +00:00
|
|
|
export function normalizeSemanticVersion (version: string) {
|
2024-05-14 17:54:37 +00:00
|
|
|
return version.replace(/-\d+\.[0-9a-f]+/, '') // Remove edge prefix
|
2023-06-06 22:36:35 +00:00
|
|
|
}
|
|
|
|
|
2024-05-09 08:28:33 +00:00
|
|
|
const builderMap = {
|
|
|
|
'@nuxt/vite-builder': 'vite',
|
|
|
|
'@nuxt/webpack-builder': 'webpack',
|
|
|
|
}
|
|
|
|
|
2021-11-21 16:14:46 +00:00
|
|
|
/**
|
|
|
|
* Check version constraints and return incompatibility issues as an array
|
|
|
|
*/
|
2021-12-21 13:57:26 +00:00
|
|
|
export async function checkNuxtCompatibility (constraints: NuxtCompatibility, nuxt: Nuxt = useNuxt()): Promise<NuxtCompatibilityIssues> {
|
2021-11-21 16:14:46 +00:00
|
|
|
const issues: NuxtCompatibilityIssues = []
|
2021-12-21 13:57:26 +00:00
|
|
|
|
|
|
|
// Nuxt version check
|
2021-11-21 16:14:46 +00:00
|
|
|
if (constraints.nuxt) {
|
|
|
|
const nuxtVersion = getNuxtVersion(nuxt)
|
2023-06-06 22:36:35 +00:00
|
|
|
if (!satisfies(normalizeSemanticVersion(nuxtVersion), constraints.nuxt, { includePrerelease: true })) {
|
2021-11-21 16:14:46 +00:00
|
|
|
issues.push({
|
|
|
|
name: 'nuxt',
|
2024-04-05 18:08:32 +00:00
|
|
|
message: `Nuxt version \`${constraints.nuxt}\` is required but currently using \`${nuxtVersion}\``,
|
2021-11-21 16:14:46 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2021-12-21 13:57:26 +00:00
|
|
|
|
2024-05-09 08:28:33 +00:00
|
|
|
// Builder compatibility check
|
|
|
|
if (constraints.builder && typeof nuxt.options.builder === 'string') {
|
|
|
|
const currentBuilder = builderMap[nuxt.options.builder] || nuxt.options.builder
|
|
|
|
if (currentBuilder in constraints.builder) {
|
|
|
|
const constraint = constraints.builder[currentBuilder]!
|
|
|
|
if (constraint === false) {
|
|
|
|
issues.push({
|
|
|
|
name: 'builder',
|
|
|
|
message: `Not compatible with \`${nuxt.options.builder}\`.`,
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
const builderVersion = await readPackageJSON(nuxt.options.builder, { url: nuxt.options.modulesDir }).then(r => r.version).catch(() => undefined)
|
|
|
|
if (builderVersion && !satisfies(normalizeSemanticVersion(builderVersion), constraint, { includePrerelease: true })) {
|
|
|
|
issues.push({
|
|
|
|
name: 'builder',
|
|
|
|
message: `Not compatible with \`${builderVersion}\` of \`${currentBuilder}\`. This module requires \`${constraint}\`.`,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-21 13:57:26 +00:00
|
|
|
// Allow extending compatibility checks
|
|
|
|
await nuxt.callHook('kit:compatibility', constraints, issues)
|
|
|
|
|
|
|
|
// Issues formatter
|
|
|
|
issues.toString = () =>
|
|
|
|
issues.map(issue => ` - [${issue.name}] ${issue.message}`).join('\n')
|
|
|
|
|
2021-11-21 16:14:46 +00:00
|
|
|
return issues
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check version constraints and throw a detailed error if has any, otherwise returns true
|
|
|
|
*/
|
2021-12-21 13:57:26 +00:00
|
|
|
export async function assertNuxtCompatibility (constraints: NuxtCompatibility, nuxt: Nuxt = useNuxt()): Promise<true> {
|
|
|
|
const issues = await checkNuxtCompatibility(constraints, nuxt)
|
2021-11-21 16:14:46 +00:00
|
|
|
if (issues.length) {
|
|
|
|
throw new Error('Nuxt compatibility issues found:\n' + issues.toString())
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check version constraints and return true if passed, otherwise returns false
|
|
|
|
*/
|
2021-12-21 13:57:26 +00:00
|
|
|
export async function hasNuxtCompatibility (constraints: NuxtCompatibility, nuxt: Nuxt = useNuxt()): Promise<boolean> {
|
|
|
|
const issues = await checkNuxtCompatibility(constraints, nuxt)
|
|
|
|
return !issues.length
|
2021-11-21 16:14:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2024-06-20 22:20:49 +00:00
|
|
|
* Check if current Nuxt instance is of specified major version
|
2021-11-21 16:14:46 +00:00
|
|
|
*/
|
2024-06-20 22:20:49 +00:00
|
|
|
export function isNuxtMajorVersion (majorVersion: 2 | 3 | 4, nuxt: Nuxt = useNuxt()) {
|
2023-12-29 08:47:11 +00:00
|
|
|
const version = getNuxtVersion(nuxt)
|
2024-06-20 22:20:49 +00:00
|
|
|
|
|
|
|
return version[0] === majorVersion.toString() && version[1] === '.'
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated Use `isNuxtMajorVersion(2, nuxt)` instead. This may be removed in \@nuxt/kit v5 or a future major version.
|
|
|
|
*/
|
|
|
|
export function isNuxt2 (nuxt: Nuxt = useNuxt()) {
|
|
|
|
return isNuxtMajorVersion(2, nuxt)
|
2021-11-21 16:14:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2024-06-20 22:20:49 +00:00
|
|
|
* @deprecated Use `isNuxtMajorVersion(3, nuxt)` instead. This may be removed in \@nuxt/kit v5 or a future major version.
|
2021-11-21 16:14:46 +00:00
|
|
|
*/
|
|
|
|
export function isNuxt3 (nuxt: Nuxt = useNuxt()) {
|
2024-06-20 22:20:49 +00:00
|
|
|
return isNuxtMajorVersion(3, nuxt)
|
2021-11-21 16:14:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get nuxt version
|
|
|
|
*/
|
|
|
|
export function getNuxtVersion (nuxt: Nuxt | any = useNuxt() /* TODO: LegacyNuxt */) {
|
2024-02-26 16:08:45 +00:00
|
|
|
const rawVersion = nuxt?._version || nuxt?.version || nuxt?.constructor?.version
|
2024-07-12 12:14:39 +00:00
|
|
|
if (typeof rawVersion !== 'string') {
|
|
|
|
throw new TypeError('Cannot determine nuxt version! Is current instance passed?')
|
2021-11-21 16:14:46 +00:00
|
|
|
}
|
2024-02-26 16:08:45 +00:00
|
|
|
return rawVersion.replace(/^v/g, '')
|
2021-11-21 16:14:46 +00:00
|
|
|
}
|