prisma-frontend
Version:
A Prisma generator for creating frontend-friendly exports (types and enums).
93 lines (92 loc) • 3.44 kB
JavaScript
import { extractErrorMessage, log } from '@augment-vir/common';
import { createReadStream, createWriteStream } from 'node:fs';
import { mkdir } from 'node:fs/promises';
import { dirname, join } from 'node:path';
import { createInterface } from 'node:readline';
var ParseMode;
(function (ParseMode) {
ParseMode["Models"] = "models";
ParseMode["Enum"] = "enum";
})(ParseMode || (ParseMode = {}));
async function openFileWriteStream(filePath) {
await mkdir(dirname(filePath), { recursive: true });
const writeStream = createWriteStream(filePath);
writeStream.on('error', (error) => {
log.error(`Stream to types file failed: ${extractErrorMessage(error)}`);
process.exit(1);
});
return writeStream;
}
async function perFileLine(filePath, callback) {
const readLine = createInterface({
input: createReadStream(filePath),
crlfDelay: Infinity,
});
for await (const rawLine of readLine) {
if (callback(rawLine)) {
break;
}
}
}
/**
* Reads inputs from a the generated JS client and then generates and writes the frontend output.
*
* @category Prisma Generator
*/
export async function generate(jsClientPath, outputDir) {
const typesStream = await openFileWriteStream(join(outputDir, 'index.d.ts'));
const jsStream = await openFileWriteStream(join(outputDir, 'index.js'));
const generatedComment = `// generated at ${Date.now()}\n\n`;
typesStream.write(generatedComment);
typesStream.write("import type {Prisma} from '../client/index'");
jsStream.write(generatedComment);
let currentParseMode = ParseMode.Models;
await perFileLine(join(jsClientPath, 'index.d.ts'), (rawLine) => {
const line = rawLine.trim();
if (currentParseMode === ParseMode.Models) {
if (line.startsWith('import * as runtime')) {
typesStream.write(rawLine.replace('import *', 'import type *') + '\n');
}
else if (removeLineStarts.some((removeLineStart) => line.startsWith(removeLineStart))) {
// skip these lines
return;
}
else if (line.startsWith('export namespace $Enums {')) {
currentParseMode = ParseMode.Enum;
}
else {
typesStream.write(rawLine.replace('$Result.', 'runtime.Types.Result.') + '\n');
}
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
}
else if (currentParseMode === ParseMode.Enum) {
if (line === '}') {
return true;
}
else if (line.startsWith('export type')) {
return;
}
else {
// types enum output
if (line.startsWith('export const')) {
typesStream.write(rawLine.replace(' const ', ' enum ').replace(': {', ' {') + '\n');
}
else {
typesStream.write(rawLine.replace(": '", " = '") + '\n');
}
// js enum output
jsStream.write(rawLine.replace(': {', ' = {') + '\n');
}
}
});
typesStream.end();
jsStream.end();
}
const removeLineStarts = [
'import $Types =',
'import $Public =',
'import $Utils =',
'import $Extensions =',
'import $Result =',
'export type PrismaPromise<T>',
];