napi-rs/src/artifacts.ts
2020-09-04 17:11:23 +08:00

73 lines
2.2 KiB
TypeScript

import { join, parse } from 'path'
import chalk from 'chalk'
import { Command } from 'clipanion'
import { fdir } from 'fdir'
import { debugFactory } from './debug'
import { readFileAsync, writeFileAsync } from './utils'
const debug = debugFactory('artifacts')
export class ArtifactsCommand extends Command {
@Command.String('-d,--dir')
sourceDir = 'artifacts'
@Command.String('-t,--target')
targetDir = '.'
@Command.Path('artifacts')
async execute() {
const api = new fdir()
.withFullPaths()
.exclude((dirPath) => dirPath.includes('node_modules'))
.filter((filePath) => filePath.endsWith('package.json'))
.crawl(join(process.cwd(), this.targetDir))
const sourceApi = new fdir()
.withFullPaths()
.crawl(join(process.cwd(), this.sourceDir))
const distDirs = await api.withPromise().then(
(output) =>
(output as string[])
.map((packageJsonPath) => {
const { dir } = parse(packageJsonPath)
const { napi } = require(packageJsonPath)
if (!napi) {
return null
}
const napiName: string = napi?.name ?? 'index'
debug(
`Scan dir: [${chalk.yellowBright(
dir,
)}], napi name: ${chalk.greenBright(napiName)}`,
)
return {
dir,
name: napiName,
}
})
.filter(Boolean) as {
name: string
dir: string
}[],
)
await sourceApi.withPromise().then((output) =>
Promise.all(
(output as string[]).map(async (filePath) => {
debug(`Read [${chalk.yellowBright(filePath)}]`)
const sourceContent = await readFileAsync(filePath)
const parsedName = parse(filePath)
const [fileName] = parsedName.name.split('.')
const { dir } = distDirs.find(({ name }) => name === fileName) ?? {}
if (!dir) {
throw new TypeError(`No dist dir found for ${filePath}`)
}
const distFilePath = join(dir, parsedName.base)
debug(`Write file content to [${chalk.yellowBright(distFilePath)}]`)
await writeFileAsync(distFilePath, sourceContent)
}),
),
)
}
}