UNPKG

prisma-markdown

Version:

Prisma Markdown documents generator including ERD diagrams and comment descriptions

229 lines 9.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MarkdownWriter = void 0; const MermaidWriter_1 = require("./MermaidWriter"); const DescriptionWriter_1 = require("./DescriptionWriter"); const MapUtil_1 = require("../utils/MapUtil"); const PrismaUtil_1 = require("../utils/PrismaUtil"); var MarkdownWriter; (function (MarkdownWriter) { MarkdownWriter.write = (schema, config) => { // LIST UP MODELS const dict = new Map(); const modelList = schema.models.filter((model) => !isHidden(model)); findImplicits(modelList); const emplace = (name) => MapUtil_1.MapUtil.take(dict)(name, () => ({ name, descriptions: new Set(), diagrams: new Set(), })); // TOP NAMESPACE for (const model of modelList) { const namespaces = takeTags("namespace")(model); if (namespaces.length === 0) continue; const top = namespaces[0]; const chapter = emplace(top); chapter.descriptions.add(model); chapter.diagrams.add(model); } // REMAINING NAMESPACES for (const model of modelList) { const namespaces = takeTags("namespace")(model); for (const name of namespaces.slice(1)) { const section = emplace(name); section.descriptions.add(model); section.diagrams.add(model); } } // DESCRIPTIONS for (const model of modelList) { const describes = takeTags("describe")(model); for (const name of describes) { const chapter = MapUtil_1.MapUtil.take(dict)(name, () => ({ name, descriptions: new Set(), diagrams: new Set(), })); chapter.descriptions.add(model); } } // ERD ONLY for (const model of modelList) { const erdList = takeTags("erd")(model); for (const erd of erdList) { const chapter = MapUtil_1.MapUtil.take(dict)(erd, () => ({ name: erd, descriptions: new Set(), diagrams: new Set(), })); chapter.diagrams.add(model); } } // DEFAULTS for (const model of modelList) { const keywords = [ ...takeTags("namespace")(model), ...takeTags("describe")(model), ...takeTags("erd")(model), ]; if (keywords.length !== 0) continue; const basic = MapUtil_1.MapUtil.take(dict)("default", () => ({ name: "default", descriptions: new Set(), diagrams: new Set(), })); basic.descriptions.add(model); basic.diagrams.add(model); } // DO WRITE const title = typeof (config === null || config === void 0 ? void 0 : config.title) === "string" ? config.title : "Prisma Markdown"; const preface = [ `# ${title}`, "> Generated by [`prisma-markdown`](https://github.com/samchon/prisma-markdown)", "", ...[...dict.keys()].map((name) => `- [${name}](#${name.toLowerCase()})`), ].join("\n"); return (preface + "\n\n" + [...dict.values()] .filter((s) => !!s.descriptions.size) .map(writeChapter) .join("\n\n\n")); }; const takeTags = (kind) => (model) => [ ...new Set(PrismaUtil_1.PrismaUtil.tagValues(kind)(model).map((str) => str.split(" ")[0])), ]; const isHidden = (model) => { var _a, _b; return (_b = (_a = model.documentation) === null || _a === void 0 ? void 0 : _a.includes("@hidden")) !== null && _b !== void 0 ? _b : false; }; const writeChapter = (chapter) => [ `## ${chapter.name}`, MermaidWriter_1.MermaidWriter.write([...chapter.diagrams]), "", [...chapter.descriptions].map(DescriptionWriter_1.DescriptionWriter.table).join("\n\n"), ].join("\n"); const findImplicits = (modelList) => { const dict = new Map(); for (const model of modelList) for (const field of model.fields) { if (field.kind !== "object" || field.isList !== true || field.isUnique !== false) continue; const opposite = modelList.find((model) => model.name === field.type); const oppositeField = opposite === null || opposite === void 0 ? void 0 : opposite.fields.find((field) => field.kind === "object" && field.isList && field.type === model.name); if (opposite === undefined || oppositeField === undefined || model === opposite) continue; const relations = [model, opposite].sort((x, y) => x.name.localeCompare(y.name)); const table = `_${relations[0].name}To${relations[1].name}`; if (dict.has(table)) continue; const newbie = implicitToExplicit(relations[0])(relations[1]); modelList.push(newbie); dict.set(table, newbie); } }; const implicitToExplicit = (x) => (y) => { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; const name = `_${x.name}To${y.name}`; const tagger = (kind) => [...new Set([...takeTags(kind)(x), ...takeTags(kind)(y)])].map((value) => `@${kind} ${value}`); const description = [ `Pair relationship table between {@link ${(_a = x.dbName) !== null && _a !== void 0 ? _a : x.name}} and {@link ${(_b = y.dbName) !== null && _b !== void 0 ? _b : y.name}}`, "", ...tagger("describe"), ...tagger("erd"), ...tagger("namespace"), ]; if (description.length === 2) description.splice(1, 1); const newbie = { name, dbName: null, schema: null, fields: [ { kind: "scalar", name: "A", type: (_d = (_c = x.primaryKey) === null || _c === void 0 ? void 0 : _c.fields[0]) !== null && _d !== void 0 ? _d : "String", isRequired: true, isList: false, isUnique: false, isId: false, isReadOnly: false, hasDefaultValue: false, }, { kind: "scalar", name: "B", type: (_f = (_e = y.primaryKey) === null || _e === void 0 ? void 0 : _e.fields[0]) !== null && _f !== void 0 ? _f : "String", isRequired: true, isList: false, isUnique: false, isId: false, isReadOnly: false, hasDefaultValue: false, }, { kind: "object", name: x.name, type: x.name, isRequired: true, isList: false, isUnique: false, isId: false, isReadOnly: false, hasDefaultValue: false, relationToFields: [(_h = (_g = x.primaryKey) === null || _g === void 0 ? void 0 : _g.fields[0]) !== null && _h !== void 0 ? _h : "id"], relationFromFields: ["A"], }, { kind: "object", name: y.name, type: y.name, isRequired: true, isList: false, isUnique: false, isId: false, isReadOnly: false, hasDefaultValue: false, relationToFields: [(_k = (_j = y.primaryKey) === null || _j === void 0 ? void 0 : _j.fields[0]) !== null && _k !== void 0 ? _k : "id"], relationFromFields: ["B"], }, ], uniqueFields: [["A", "B"]], uniqueIndexes: [], primaryKey: null, documentation: description.join("\n"), }; x.fields.push({ kind: "object", name, type: name, isRequired: true, isList: true, isUnique: false, isId: false, isReadOnly: false, hasDefaultValue: false, relationToFields: ["A"], }); y.fields.push({ kind: "object", name, type: name, isRequired: true, isList: true, isUnique: false, isId: false, isReadOnly: false, hasDefaultValue: false, relationToFields: ["B"], }); return newbie; }; })(MarkdownWriter || (exports.MarkdownWriter = MarkdownWriter = {})); //# sourceMappingURL=MarkdownWriter.js.map