prisma-erd-generator
Version:
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --> [](#contributors-) <!-- ALL-CONTRIBUTORS-BADGE:END -->
36 lines (32 loc) • 7.43 kB
JavaScript
;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(i=>i.name));b=b.filter(i=>!r.has(i.name))}p.length>0&&(b=b.filter(r=>!T(r.name,p)));let $=b.concat(n.types),P=e||s?"":n.enums.map(r=>`
${r.dbName||r.name} {
${r.values.map(i=>`${i.name||i.dbName} ${i.dbName||i.name}`).join(`
`)}
}
`).join(`
`),w=h?'"PK"':'"\u{1F5DD}\uFE0F"',D=h?'"nullable"':'"\u2753"',f=$.map(r=>` "${r.dbName||r.name}" {
${e?"":r.fields.filter(W(r,S)).map(i=>` ${i.type.trimStart()} ${i.name.replace(/^_/,"z_")} ${i.isId||r.primaryKey?.fields?.includes(i.name)?w:""}${i.isRequired?"":D}`).join(`
`)}
}
`).join(`
`),x="";for(let r of $)for(let i of r.fields){let F=i.kind==="enum";if(F&&(e||s))continue;let N=`${F?"enum:":""}${i.name}`,E=`"${r.dbName||r.name}"`,y=`"${$.find(m=>m.name===i.type)?.dbName||i.type}"`;if(i.relationFromFields&&i.relationFromFields.length>0||F){let m=$.find(u=>u.name===i.type||u.dbName===i.type),t=m?.fields.find(({relationName:u})=>u===i.relationName),d="||";t?.isList?d="}o":t?.isRequired||(d="|o");let g="||";i.isList?g="}o":i.isRequired||(g="|o"),x+=` ${E} ${d}--${g} ${m?.dbName||y} : "${N}"
`}else if($.find(m=>m.name===i.type||m.dbName===i.type)&&i.relationFromFields?.length===0){let m=$.find(t=>t.name===i.type||t.dbName===i.type);if(m){let t=m.fields.find(({relationName:g})=>g===i.relationName);if(!(t?.relationFromFields&&t.relationFromFields.length>0)){let g=$.indexOf(r),u=$.indexOf(m);g<u&&(x+=` ${E} o{--}o ${y} : ""
`)}}}else if(i.kind==="object"){let m=n.types.find(t=>t.name.replace(/^_/,"z_").replace(/\s/g,""));if(console.log(y,m),m){let t="||";i.isList?t="}o":i.isRequired||(t="|o");let d=m?.fields.find(({relationName:u})=>u===i.relationName),g=t;d?.isList?t="o{":d?.isRequired||(t="o|"),x+=` ${E} ${t}--${g} ${m.dbName||y} : "${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(t=>t.trim()):[],$=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 t=l.resolve("prisma/debug/1-datamodel.json");c.default.writeFileSync(t,JSON.stringify(f,null,2)),console.log(`data model written to ${t}`)}f.models=J(f.models,n.datamodel),f.types||(f.types=[]);let x=_(n.datamodel);if(f.views=f.models.filter(t=>x.includes(t.name)),w&&f.models){let t=l.resolve("prisma/debug/2-datamodel-map-applied.json");c.default.writeFileSync(t,JSON.stringify(f,null,2)),console.log(`applied @map to fields written to ${t}`)}let r=K(f,{tableOnly:p,ignoreEnums:h,ignoreViews:M,ignorePattern:b,includeRelationFromFields:$,disableEmoji:S});if(w&&r){let t=l.resolve("prisma/debug/3-mermaid.mmd");c.default.writeFileSync(t,r),console.log(`mermaid written to ${t}`)}if(!r)throw new Error("failed to construct mermaid instance from dml");if(o.endsWith(".md"))return c.default.writeFileSync(o,`\`\`\`mermaid
${r}\`\`\`
`);let i=l.resolve(l.join(D,"prisma.mmd"));c.default.writeFileSync(i,r);let F={deterministicIds:!0,maxTextSize:9e4,er:{useMaxWidth:!0},theme:s},N=F;if(e?.mermaidConfig){let t=l.resolve(e.mermaidConfig),d=await import((0,j.pathToFileURL)(t).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 y=e.puppeteerConfig;if(y&&!c.default.existsSync(y))throw new Error(`Puppeteer config file "${y}" does not exist`);if(!y){let t=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(t,JSON.stringify(g)),y=t}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 t=R.execSync("find ../.. -name mmdc").toString().split(`
`).filter(d=>d).pop();if(!t||!c.default.existsSync(t))throw new Error(`Expected mermaid CLI at
${a}
or
${t}
but this package was not found.`);a=l.resolve(t)}let m=`"${a}" -i "${i}" -o "${o}" -c "${E}" -p "${y}"`;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});