generated from garrettmills/template-npm-typescript
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
2.3 KiB
79 lines
2.3 KiB
import {Phase} from './Phase'
|
|
import {ExtolloCompileConfig} from '../types'
|
|
import * as rimraf from 'rimraf'
|
|
import * as fse from 'fs-extra'
|
|
import * as path from 'path'
|
|
import {Logger} from '../Logger'
|
|
|
|
async function* walk(dir: string): any {
|
|
for await (const d of await fse.promises.opendir(dir)) {
|
|
const entry = path.join(dir, d.name)
|
|
if (d.isDirectory()) {
|
|
yield* walk(entry)
|
|
} else if (d.isFile()) {
|
|
yield entry
|
|
}
|
|
}
|
|
}
|
|
|
|
export class ZodifyPhase extends Phase {
|
|
constructor(
|
|
config: ExtolloCompileConfig,
|
|
tsconfig: any,
|
|
protected readonly zodPath: string,
|
|
) {
|
|
super(config, tsconfig)
|
|
}
|
|
|
|
public async run(): Promise<void> {
|
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
const tsz = require('ts-to-zod')
|
|
const dir = this.config.compileDir || 'exbuild'
|
|
await new Promise<void>((res, rej) => {
|
|
rimraf(path.resolve(dir, this.zodPath), e => e ? rej(e) : res())
|
|
})
|
|
|
|
await fse.mkdirp(path.resolve(dir, this.zodPath))
|
|
|
|
for await ( const file of walk(this.zodPath) ) {
|
|
if ( !file.endsWith('.ts') ) {
|
|
continue
|
|
}
|
|
|
|
Logger.verb('zod', file)
|
|
|
|
const sourceText = (await fse.readFile(file)).toString('utf-8')
|
|
const gen = tsz.generate({
|
|
sourceText,
|
|
getSchemaName: () => 'exZodifiedSchema',
|
|
})
|
|
|
|
const zodSource = gen.getZodSchemasFile(file)
|
|
const augmentedSource = this.getAugmentedSourceText(sourceText, zodSource)
|
|
|
|
await fse.writeFile(path.resolve(dir, file), augmentedSource)
|
|
}
|
|
}
|
|
|
|
protected getAugmentedSourceText(originalSource: string, zodSource: string): string {
|
|
const lines = originalSource.split('\n')
|
|
let line = 0
|
|
if ( lines[line].startsWith('#!') ) {
|
|
if ( lines[line + 1] ) {
|
|
line = line + 1
|
|
}
|
|
}
|
|
|
|
const newlines: string[] = []
|
|
lines.forEach((lineVal, idx) => {
|
|
if ( idx === line ) {
|
|
newlines.push('import { z } from "zod";')
|
|
}
|
|
|
|
newlines.push(lineVal)
|
|
})
|
|
|
|
return [...newlines, ...zodSource.split('\n').slice(2)].join('\n')
|
|
}
|
|
}
|