Nuxt/packages/nitro/src/utils/index.ts

143 lines
3.8 KiB
TypeScript
Raw Normal View History

import { createRequire } from 'module'
import { relative, dirname, resolve } from 'pathe'
import fse from 'fs-extra'
2020-11-01 23:17:44 +00:00
import jiti from 'jiti'
import defu from 'defu'
import { mergeHooks } from 'hookable'
import consola from 'consola'
2020-11-20 00:16:31 +00:00
import chalk from 'chalk'
import { get } from 'dot-prop'
2021-01-22 19:55:59 +00:00
import type { NitroPreset, NitroInput } from '../context'
2020-11-01 23:17:44 +00:00
export function hl (str: string) {
2020-11-20 00:16:31 +00:00
return chalk.cyan(str)
}
2020-11-01 23:17:44 +00:00
export function prettyPath (p: string, highlight = true) {
p = relative(process.cwd(), p)
2020-11-01 23:17:44 +00:00
return highlight ? hl(p) : p
}
export function compileTemplate (contents: string) {
2020-11-20 00:16:31 +00:00
return (params: Record<string, any>) => contents.replace(/{{ ?([\w.]+) ?}}/g, (_, match) => {
const val = get(params, match)
if (!val) {
consola.warn(`cannot resolve template param '${match}' in ${contents.substr(0, 20)}`)
}
return val as string || `${match}`
})
2020-11-03 22:14:32 +00:00
}
export function serializeTemplate (contents: string) {
2020-11-03 22:14:32 +00:00
// eslint-disable-next-line no-template-curly-in-string
return `(params) => \`${contents.replace(/{{ (\w+) }}/g, '${params.$1}')}\``
}
export function jitiImport (dir: string, path: string) {
return jiti(dir, { interopDefault: true })(path)
}
export function tryImport (dir: string, path: string) {
try {
return jitiImport(dir, path)
} catch (_err) { }
}
2020-11-04 13:15:38 +00:00
export async function writeFile (file: string, contents: string, log = false) {
await fse.mkdirp(dirname(file))
await fse.writeFile(file, contents, 'utf-8')
2021-01-20 14:37:21 +00:00
if (log) {
consola.info('Generated', prettyPath(file))
}
}
export function resolvePath (nitroContext: NitroInput, path: string | ((nitroContext: NitroInput) => string), resolveBase: string = ''): string {
if (typeof path === 'function') {
2021-01-22 19:55:59 +00:00
path = path(nitroContext)
}
2020-11-06 13:46:17 +00:00
if (typeof path !== 'string') {
throw new TypeError('Invalid path: ' + path)
}
2021-01-22 19:55:59 +00:00
path = compileTemplate(path)(nitroContext)
return resolve(resolveBase, path)
}
export function detectTarget () {
if (process.env.NETLIFY || process.env.NETLIFY_LOCAL) {
return 'netlify'
}
2020-11-06 14:05:11 +00:00
if (process.env.NOW_BUILDER) {
return 'vercel'
}
if (process.env.INPUT_AZURE_STATIC_WEB_APPS_API_TOKEN) {
return 'azure'
}
}
2020-12-07 12:48:29 +00:00
export async function isDirectory (path: string) {
try {
return (await fse.stat(path)).isDirectory()
} catch (_err) {
return false
}
}
2021-01-22 19:55:59 +00:00
export function extendPreset (base: NitroPreset, preset: NitroPreset): NitroPreset {
return (config: NitroInput) => {
2020-11-20 00:16:31 +00:00
if (typeof preset === 'function') {
preset = preset(config)
}
if (typeof base === 'function') {
2020-11-06 13:46:17 +00:00
base = base(config)
}
return defu({
hooks: mergeHooks(base.hooks, preset.hooks)
2020-11-20 00:16:31 +00:00
}, preset, base)
}
}
const _getDependenciesMode = {
dev: ['devDependencies'],
prod: ['dependencies'],
all: ['devDependencies', 'dependencies']
}
const _require = createRequire(import.meta.url)
export function getDependencies (dir: string, mode: keyof typeof _getDependenciesMode = 'all') {
const fields = _getDependenciesMode[mode]
const pkg = _require(resolve(dir, 'package.json'))
const dependencies = []
for (const field of fields) {
if (pkg[field]) {
for (const name in pkg[field]) {
dependencies.push(name)
}
}
}
return dependencies
}
// TODO: Refactor to scule (https://github.com/unjs/scule/issues/6)
export function serializeImportName (id: string) {
return '_' + id.replace(/[^a-zA-Z0-9_$]/g, '_')
}
export function readPackageJson (
packageName: string,
_require: NodeRequire = createRequire(import.meta.url)
) {
try {
return _require(`${packageName}/package.json`)
} catch (error) {
if (error.code === 'ERR_PACKAGE_PATH_NOT_EXPORTED') {
const [pkgModulePath] = /^(.*\/node_modules\/).*$/.exec(_require.resolve(packageName))
return fse.readJSONSync(resolve(pkgModulePath, packageName, 'package.json'))
}
throw error
}
}