prisma-markdown
Version:
Prisma Markdown documents generator including ERD diagrams and comment descriptions
229 lines • 9.33 kB
JavaScript
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
;