naive-ui/scripts/gen-component-declaration.js
2024-07-12 02:19:13 +08:00

66 lines
1.7 KiB
JavaScript

// The file is not designed to run directly. `cwd` should be project root.
import path from 'node:path'
import process from 'node:process'
import fs from 'fs-extra'
import * as globalComponents from '../src/components'
const TYPE_ROOT = process.cwd()
// XButton is for tsx type checking, shouldn't be exported
const excludeComponents = ['NxButton']
function exist(path) {
return fs.existsSync(path)
}
function parseComponentsDeclaration(code) {
if (!code) {
return {}
}
return Object.fromEntries(
Array.from(code.matchAll(/(?<!\/\/)\s+\s+['"]?(.+?)['"]?:\s(.+?)\n/g)).map(
i => [i[1], i[2]]
)
)
}
async function generateComponentsType() {
const components = {}
Object.keys(globalComponents).forEach((key) => {
const entry = `(typeof import('naive-ui'))['${key}']`
if (key.startsWith('N') && !excludeComponents.includes(key)) {
components[key] = entry
}
})
const originalContent = exist(path.resolve(TYPE_ROOT, 'volar.d.ts'))
? await fs.readFile(path.resolve(TYPE_ROOT, 'volar.d.ts'), 'utf-8')
: ''
const originImports = parseComponentsDeclaration(originalContent)
const lines = Object.entries({
...originImports,
...components
})
.filter(([name]) => {
return components[name]
})
.map(([name, v]) => {
if (!/^\w+$/.test(name)) {
name = `'${name}'`
}
return `${name}: ${v}`
})
const code = `// Auto generated component declarations
declare module 'vue' {
export interface GlobalComponents {
${lines.join('\n ')}
}
}
export {}
`
if (code !== originalContent) {
await fs.writeFile(path.resolve(TYPE_ROOT, 'volar.d.ts'), code, 'utf-8')
}
}
generateComponentsType()