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 -->

37 lines (33 loc) 7.49 kB
#!/usr/bin/env node "use strict";var q=Object.create;var P=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var z=Object.getPrototypeOf,B=Object.prototype.hasOwnProperty;var V=(n,o,i,s)=>{if(o&&typeof o=="object"||typeof o=="function")for(let a of G(o))!B.call(n,a)&&a!==i&&P(n,a,{get:()=>o[a],enumerable:!(s=A(o,a))||s.enumerable});return n};var v=(n,o,i)=>(i=n!=null?q(z(n)):{},V(o||!n||!n.__esModule?P(i,"default",{value:n,enumerable:!0}):i,n));var J=require("@prisma/generator-helper");var l=v(require("path")),C=v(require("child_process")),c=v(require("fs")),R=v(require("os")),j=require("url"),k=v(require("dotenv"));k.config();function U(n,o){let{tableOnly:i=!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=>!Q(r.name,p)));let $=b.concat(n.types),L=i||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=$.map(r=>` "${r.dbName||r.name}" { ${i?"":r.fields.filter(K(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 $)for(let t of r.fields){let E=t.kind==="enum";if(E&&(i||s))continue;let N=`${E?"enum:":""}${t.name}`,F=`"${r.dbName||r.name}"`,y=`"${$.find(m=>m.name===t.type)?.dbName||t.type}"`;if(t.relationFromFields&&t.relationFromFields.length>0||E){let m=$.find(u=>u.name===t.type||u.dbName===t.type),e=m?.fields.find(({relationName:u})=>u===t.relationName),d="||";e?.isList?d="}o":e?.isRequired||(d="|o");let g="||";t.isList?g="}o":t.isRequired||(g="|o"),x+=` ${F} ${d}--${g} ${m?.dbName||y} : "${N}" `}else if($.find(m=>m.name===t.type||m.dbName===t.type)&&t.relationFromFields?.length===0){let m=$.find(e=>e.name===t.type||e.dbName===t.type);if(m){let e=m.fields.find(({relationName:g})=>g===t.relationName);if(!(e?.relationFromFields&&e.relationFromFields.length>0)){let g=$.indexOf(r),u=$.indexOf(m);g<u&&(x+=` ${F} o{--}o ${y} : "" `)}}}else if(t.kind==="object"){let m=n.types.find(e=>e.name.replace(/^_/,"z_").replace(/\s/g,""));if(console.log(y,m),m){let e="||";t.isList?e="}o":t.isRequired||(e="|o");let d=m?.fields.find(({relationName:u})=>u===t.relationName),g=e;d?.isList?e="o{":d?.isRequired||(e="o|"),x+=` ${F} ${e}--${g} ${m.dbName||y} : "${N}" `}}}return`${M} ${L} ${f} ${x}`}var K=(n,o)=>i=>o?i.kind!=="object":i.kind!=="object"&&!n.fields.find(({relationFromFields:s})=>s?.includes(i.name)),W=n=>{let o=[],i=n?.split(` `)||[];for(let s=0;s<i.length;s++){let a=i[s]?.trim();if(!a)continue;let p=a.match(/^view\s+(\w+)\s*{/);p&&p[1]&&o.push(p[1])}return o},H=n=>{let o=n.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".");return new RegExp(`^${o}$`)},Q=(n,o)=>o.some(i=>H(i).test(n)),X=(n,o)=>{let i=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=i.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})}))},_=async n=>{try{let o=n.generator.output?.value||"./prisma/ERD.svg",i=n.generator.config,s=i.theme??"forest",a=l.resolve(l.join(i.mmdcPath||"node_modules/.bin","mmdc")),p=i.tableOnly==="true",S=i.disableEmoji==="true",h=i.ignoreEnums==="true",M=i.ignoreViews==="true",b=i.ignorePattern?i.ignorePattern.split(",").map(e=>e.trim()):[],$=i.includeRelationFromFields==="true",L=process.env.DISABLE_ERD==="true"||i.disabled==="true",w=i.erdDebug==="true"||!!process.env.ERD_DEBUG;if(w&&(console.log("debug mode enabled"),console.log("config",i)),L)return console.log("ERD generator is disabled");let D=c.default.mkdtempSync(`${R.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 e=l.resolve("prisma/debug/1-datamodel.json");c.default.writeFileSync(e,JSON.stringify(f,null,2)),console.log(`data model written to ${e}`)}f.models=X(f.models,n.datamodel),f.types||(f.types=[]);let x=W(n.datamodel);if(f.views=f.models.filter(e=>x.includes(e.name)),w&&f.models){let e=l.resolve("prisma/debug/2-datamodel-map-applied.json");c.default.writeFileSync(e,JSON.stringify(f,null,2)),console.log(`applied @map to fields written to ${e}`)}let r=U(f,{tableOnly:p,ignoreEnums:h,ignoreViews:M,ignorePattern:b,includeRelationFromFields:$,disableEmoji:S});if(w&&r){let e=l.resolve("prisma/debug/3-mermaid.mmd");c.default.writeFileSync(e,r),console.log(`mermaid written to ${e}`)}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 E={deterministicIds:!0,maxTextSize:9e4,er:{useMaxWidth:!0},theme:s},N=E;if(i?.mermaidConfig){let e=l.resolve(i.mermaidConfig),d=await import((0,j.pathToFileURL)(e).href);w&&console.log("imported mermaid config: ",d),N={...E,...d}}let F=l.resolve(l.join(D,"config.json"));c.default.writeFileSync(F,JSON.stringify(N));let y=i.puppeteerConfig;if(y&&!c.default.existsSync(y))throw new Error(`Puppeteer config file "${y}" does not exist`);if(!y){let e=l.resolve(l.join(D,"puppeteerConfig.json")),d,g={logLevel:w?"warn":"error",executablePath:d};if(R.default.platform()==="darwin"&&R.default.arch()==="arm64")try{let u=C.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(e,JSON.stringify(g)),y=e}if(i.mmdcPath){if(!c.default.existsSync(a))throw new Error(` Mermaid CLI provided path does not exist. ${a}`)}else if(!c.default.existsSync(a)){let e=C.execSync("find ../.. -name mmdc").toString().split(` `).filter(d=>d).pop();if(!e||!c.default.existsSync(e))throw new Error(`Expected mermaid CLI at ${a} or ${e} but this package was not found.`);a=l.resolve(e)}let m=`"${a}" -i "${t}" -o "${o}" -c "${F}" -p "${y}"`;if(w&&m&&console.log("mermaid command: ",m),C.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}};var T=require("fs"),I=process.env.DISABLE_ERD==="true",O;try{O=JSON.parse((0,T.readFileSync)("package.json","utf-8"))}catch(n){console.error(n),O={version:"1.0.0"}}(0,J.generatorHandler)({onManifest:()=>({defaultOutput:I?"N/A":"ERD.svg",prettyName:I?"No ERD":"Entity-relationship-diagram",version:O?.version}),onGenerate:_});