prisma-class-generator
Version:
Class generator from Prisma schema
133 lines (111 loc) • 3.33 kB
text/typescript
import { pascalCase, snakeCase } from 'change-case'
import { ClassComponent } from './class.component'
import * as path from 'path'
import { getRelativeTSPath, prettierFormat, writeTSFile } from '../util'
import { PrismaClassGenerator } from '../generator'
import { Echoable } from '../interfaces/echoable'
import { ImportComponent } from './import.component'
export class FileComponent implements Echoable {
private _dir?: string
private _filename?: string
private _imports?: ImportComponent[] = []
private _prismaClass: ClassComponent
static TEMP_PREFIX = '__TEMPORARY_CLASS_PATH__'
public get dir() {
return this._dir
}
public set dir(value) {
this._dir = value
}
public get filename() {
return this._filename
}
public set filename(value) {
this._filename = value
}
public get imports() {
return this._imports
}
public set imports(value) {
this._imports = value
}
public get prismaClass() {
return this._prismaClass
}
public set prismaClass(value) {
this._prismaClass = value
}
constructor(input: { classComponent: ClassComponent; output: string }) {
const { classComponent, output } = input
this._prismaClass = classComponent
this.dir = path.resolve(output)
this.filename = `${snakeCase(classComponent.name)}.ts`
this.resolveImports()
}
echoImports = () => {
return this.imports
.reduce((result, importRow) => {
result.push(importRow.echo())
return result
}, [])
.join('\r\n')
}
echo = () => {
return this.prismaClass
.echo()
.replace('#!{IMPORTS}', this.echoImports())
}
registerImport(item: string, from: string) {
const oldIndex = this.imports.findIndex(
(_import) => _import.from === from,
)
if (oldIndex > -1) {
this.imports[oldIndex].add(item)
return
}
this.imports.push(new ImportComponent(from, item))
}
resolveImports() {
const generator = PrismaClassGenerator.getInstance()
this.prismaClass.relationTypes.forEach((relationClassName) => {
this.registerImport(
`${relationClassName}`,
FileComponent.TEMP_PREFIX + relationClassName,
)
})
this.prismaClass.enumTypes.forEach((enumName) => {
this.registerImport(enumName, generator.getClientImportPath())
})
this.prismaClass.decorators.forEach((decorator) => {
this.registerImport(decorator.name, decorator.importFrom)
})
this.prismaClass.fields.forEach((field) => {
field.decorators.forEach((decorator) => {
this.registerImport(decorator.name, decorator.importFrom)
})
})
if (this.prismaClass.types) {
this.prismaClass.types.forEach((type) => {
this.registerImport(type, './' + type.toLowerCase())
})
}
if (generator.getConfig().useGraphQL) {
this.registerImport('ID', '@nestjs/graphql')
this.registerImport('Int', '@nestjs/graphql')
this.registerImport('registerEnumType', '@nestjs/graphql')
this.registerImport('GraphQLJSONObject', 'graphql-type-json')
}
}
write(dryRun: boolean) {
const generator = PrismaClassGenerator.getInstance()
const filePath = path.resolve(this.dir, this.filename)
const content = prettierFormat(this.echo(), generator.prettierOptions)
writeTSFile(filePath, content, dryRun)
}
getRelativePath(to: string): string {
return getRelativeTSPath(this.getPath(), to)
}
getPath() {
return path.resolve(this.dir, this.filename)
}
}