UNPKG

prisma-erd-generator

Version:

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --> [![All Contributors](https://img.shields.io/badge/all_contributors-23-orange.svg?style=flat-square)](#contributors-) <!-- ALL-CONTRIBUTORS-BADGE:END -->

36 lines (32 loc) 7.42 kB
"use strict";var q=Object.create;var v=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var V=Object.getPrototypeOf,A=Object.prototype.hasOwnProperty;var B=(n,o)=>{for(var e in o)v(n,e,{get:o[e],enumerable:!0})},O=(n,o,e,s)=>{if(o&&typeof o=="object"||typeof o=="function")for(let a of G(o))!A.call(n,a)&&a!==e&&v(n,a,{get:()=>o[a],enumerable:!(s=z(o,a))||s.enumerable});return n};var C=(n,o,e)=>(e=n!=null?q(V(n)):{},O(o||!n||!n.__esModule?v(e,"default",{value:n,enumerable:!0}):e,n)),U=n=>O(v({},"__esModule",{value:!0}),n);var Q={};B(Q,{default:()=>H,extractViewNames:()=>_,mapPrismaToDb:()=>J,matchesIgnorePattern:()=>T,patternToRegex:()=>I});module.exports=U(Q);var l=C(require("path")),R=C(require("child_process")),c=C(require("fs")),L=C(require("os")),j=require("url"),k=C(require("dotenv"));k.config();function K(n,o){let{tableOnly:e=!1,ignoreEnums:s=!1,ignoreViews:a=!1,ignorePattern:p=[],includeRelationFromFields:S=!1,disableEmoji:h=!1}=o??{},M="erDiagram",b=n.models;if(a&&n.views){let r=new Set(n.views.map(t=>t.name));b=b.filter(t=>!r.has(t.name))}p.length>0&&(b=b.filter(r=>!T(r.name,p)));let y=b.concat(n.types),P=e||s?"":n.enums.map(r=>` ${r.dbName||r.name} { ${r.values.map(t=>`${t.name||t.dbName} ${t.dbName||t.name}`).join(` `)} } `).join(` `),w=h?'"PK"':'"\u{1F5DD}\uFE0F"',D=h?'"nullable"':'"\u2753"',f=y.map(r=>` "${r.dbName||r.name}" { ${e?"":r.fields.filter(W(r,S)).map(t=>` ${t.type.trimStart()} ${t.name.replace(/^_/,"z_")} ${t.isId||r.primaryKey?.fields?.includes(t.name)?w:""}${t.isRequired?"":D}`).join(` `)} } `).join(` `),x="";for(let r of y)for(let t of r.fields){let F=t.kind==="enum";if(F&&(e||s))continue;let N=`${F?"enum:":""}${t.name}`,E=`"${r.dbName||r.name}"`,$=`"${y.find(m=>m.name===t.type)?.dbName||t.type}"`;if(t.relationFromFields&&t.relationFromFields.length>0||F){let m=y.find(u=>u.name===t.type||u.dbName===t.type),i=m?.fields.find(({relationName:u})=>u===t.relationName),d="||";i?.isList?d="}o":i?.isRequired||(d="|o");let g="||";t.isList?g="}o":t.isRequired||(g="|o"),x+=` ${E} ${d}--${g} ${m?.dbName||$} : "${N}" `}else if(y.find(m=>m.name===t.type||m.dbName===t.type)&&t.relationFromFields?.length===0){let m=y.find(i=>i.name===t.type||i.dbName===t.type);if(m){let i=m.fields.find(({relationName:g})=>g===t.relationName);if(!(i?.relationFromFields&&i.relationFromFields.length>0)){let g=y.indexOf(r),u=y.indexOf(m);g<u&&(x+=` ${E} o{--}o ${$} : "" `)}}}else if(t.kind==="object"){let m=n.types.find(i=>i.name.replace(/^_/,"z_").replace(/\s/g,"")===t.type);if(m){let i="||";t.isList?i="}o":t.isRequired||(i="|o");let d=m?.fields.find(({relationName:u})=>u===t.relationName),g=i;d?.isList?i="o{":d?.isRequired||(i="o|"),x+=` ${E} ${i}--${g} ${m.dbName||$} : "${N}" `}}}return`${M} ${P} ${f} ${x}`}var W=(n,o)=>e=>o?e.kind!=="object":e.kind!=="object"&&!n.fields.find(({relationFromFields:s})=>s?.includes(e.name)),_=n=>{let o=[],e=n?.split(` `)||[];for(let s=0;s<e.length;s++){let a=e[s]?.trim();if(!a)continue;let p=a.match(/^view\s+(\w+)\s*{/);p&&p[1]&&o.push(p[1])}return o},I=n=>{let o=n.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".");return new RegExp(`^${o}$`)},T=(n,o)=>o.some(e=>I(e).test(n)),J=(n,o)=>{let e=o?.split(` `).filter(s=>s.includes("@map")||s.includes("model ")).map(s=>s.trim());return n.map(s=>({...s,fields:s.fields.map(a=>{let p="None",S=e.filter(h=>(p==="Match"&&h.includes("model ")&&(p="End"),p==="None"&&h.includes(`model ${s.name} `)&&(p="Match"),p==="Match")).find(h=>h.includes(`${a.name} `)&&h.includes("@map"));if(S){let M=new RegExp(/@map\(\"(.*?)\"\)/,"g").exec(S);if(M?.[1]){let b=M[1].replace(/^_/,"z_").replace(/\s/g,"");a.name=b}}return a})}))},H=async n=>{try{let o=n.generator.output?.value||"./prisma/ERD.svg",e=n.generator.config,s=e.theme??"forest",a=l.resolve(l.join(e.mmdcPath||"node_modules/.bin","mmdc")),p=e.tableOnly==="true",S=e.disableEmoji==="true",h=e.ignoreEnums==="true",M=e.ignoreViews==="true",b=e.ignorePattern?e.ignorePattern.split(",").map(i=>i.trim()):[],y=e.includeRelationFromFields==="true",P=process.env.DISABLE_ERD==="true"||e.disabled==="true",w=e.erdDebug==="true"||!!process.env.ERD_DEBUG;if(w&&(console.log("debug mode enabled"),console.log("config",e)),P)return console.log("ERD generator is disabled");let D=c.default.mkdtempSync(`${L.default.tmpdir()+l.sep}prisma-erd-`);if(!n.dmmf?.datamodel)throw new Error("Datamodel is missing from generator options");let f=JSON.parse(JSON.stringify(n.dmmf.datamodel));if(w&&f){c.default.mkdirSync(l.resolve("prisma/debug"),{recursive:!0});let i=l.resolve("prisma/debug/1-datamodel.json");c.default.writeFileSync(i,JSON.stringify(f,null,2)),console.log(`data model written to ${i}`)}f.models=J(f.models,n.datamodel),f.types||(f.types=[]);let x=_(n.datamodel);if(f.views=f.models.filter(i=>x.includes(i.name)),w&&f.models){let i=l.resolve("prisma/debug/2-datamodel-map-applied.json");c.default.writeFileSync(i,JSON.stringify(f,null,2)),console.log(`applied @map to fields written to ${i}`)}let r=K(f,{tableOnly:p,ignoreEnums:h,ignoreViews:M,ignorePattern:b,includeRelationFromFields:y,disableEmoji:S});if(w&&r){let i=l.resolve("prisma/debug/3-mermaid.mmd");c.default.writeFileSync(i,r),console.log(`mermaid written to ${i}`)}if(!r)throw new Error("failed to construct mermaid instance from dml");if(o.endsWith(".md"))return c.default.writeFileSync(o,`\`\`\`mermaid ${r}\`\`\` `);let t=l.resolve(l.join(D,"prisma.mmd"));c.default.writeFileSync(t,r);let F={deterministicIds:!0,maxTextSize:9e4,er:{useMaxWidth:!0},theme:s},N=F;if(e?.mermaidConfig){let i=l.resolve(e.mermaidConfig),d=await import((0,j.pathToFileURL)(i).href);w&&console.log("imported mermaid config: ",d),N={...F,...d}}let E=l.resolve(l.join(D,"config.json"));c.default.writeFileSync(E,JSON.stringify(N));let $=e.puppeteerConfig;if($&&!c.default.existsSync($))throw new Error(`Puppeteer config file "${$}" does not exist`);if(!$){let i=l.resolve(l.join(D,"puppeteerConfig.json")),d,g={logLevel:w?"warn":"error",executablePath:d};if(L.default.platform()==="darwin"&&L.default.arch()==="arm64")try{let u=R.execSync("which chromium").toString().replace(` `,"");if(!u)throw new Error("Could not find chromium executable. Refer to https://github.com/keonik/prisma-erd-generator#issues for next steps.");g.executablePath=u,g.args=["--no-sandbox"]}catch(u){console.error(u),console.log(` Prisma ERD Generator: Unable to find chromium path for you MacOS arm64 machine. Attempting to use the default at ${d}. To learn more visit https://github.com/keonik/prisma-erd-generator#-arm64-users- `),d="/usr/bin/chromium-browser"}c.default.writeFileSync(i,JSON.stringify(g)),$=i}if(e.mmdcPath){if(!c.default.existsSync(a))throw new Error(` Mermaid CLI provided path does not exist. ${a}`)}else if(!c.default.existsSync(a)){let i=R.execSync("find ../.. -name mmdc").toString().split(` `).filter(d=>d).pop();if(!i||!c.default.existsSync(i))throw new Error(`Expected mermaid CLI at ${a} or ${i} but this package was not found.`);a=l.resolve(i)}let m=`"${a}" -i "${t}" -o "${o}" -c "${E}" -p "${$}"`;if(w&&m&&console.log("mermaid command: ",m),R.execSync(m),!c.default.existsSync(o))throw new Error(`Issue generating ER Diagram. Expected ${o} to be created`)}catch(o){throw console.error(o),o}};0&&(module.exports={extractViewNames,mapPrismaToDb,matchesIgnorePattern,patternToRegex});