UNPKG

prisma-markdown

Version:

Prisma Markdown documents generator including ERD diagrams and comment descriptions

75 lines (61 loc) 2.44 kB
import { DMMF } from "@prisma/client/runtime/library"; import { PrismaUtil } from "../utils/PrismaUtil"; export namespace DescriptionWriter { export const table = (model: DMMF.Model): string => { const description: string = writeDescription(model); return [ `### \`${model.dbName ?? model.name}\``, ...(description.length ? [description] : []), "", "**Properties**", ...model.fields.filter((f) => f.kind !== "object").map(writeField), ].join("\n"); }; const writeField = (field: DMMF.Field): string => { const description: string = writeDescription(field); const lines: string[] = description.split("\n"); const head = ` - \`${field.dbName ?? field.name}\``; if (lines.length === 0) return head; else if (lines.length === 1) return `${head}: ${lines[0]}`; return [head, ...lines.map((line) => ` > ${line}`)].join("\n"); }; const writeDescription = (target: DMMF.Model | DMMF.Field): string => { const content: string[] = (target.documentation ?? "") .split("\r\n") .join("\n") .split("\n"); let first: number = 0; let last: number = content.length - 1; const empty = (str: string) => str.trim() === "" || str.trim()[0] === "@"; while (first < content.length && empty(content[first])) ++first; while (last >= 0 && empty(content[last])) --last; const summary: string[] = PrismaUtil.tagValues("summary")(target); const body: string[] = content.slice(first, last + 1).map(replaceLinks); return summary.length ? body.length ? [summary[0], "", ...body].join("\n") : summary[0] : body.join("\n"); }; const replaceLinks = (content: string): string => { const rejoined: string[] = []; let i: number = 0; while (true) { const first: number = content.indexOf("{@link ", i); if (first === -1) break; const last: number = content.indexOf("}", first + 7); if (last === -1) break; const part: string = content.slice(first + 7, last).trim(); const space: number = part.indexOf(" "); rejoined.push(content.slice(i, first)); if (space === -1) rejoined.push(`[${part}](#${part.split(".")[0]})`); else rejoined.push( `[${part.slice(space + 1)}](#${part.slice(0, space).split(".")[0]})`, ); i = last + 1; } rejoined.push(content.slice(i)); return rejoined.join(""); }; }