mongoku
Version:
[](https://github.com/huggingface/Mongoku/actions/workflows/ci.yml)
66 lines (56 loc) • 16.5 kB
JavaScript
import{f as d,a as s}from"../chunks/DaMh_eeB.js";import{p as Xe,a8 as Ye,f as ve,a as Ze,t as F,c as a,s as o,d as i,b as N,r as e,n as Pe,g as t,u as _e}from"../chunks/IwGwbOe7.js";import{d as $e,s as he,a as v}from"../chunks/BDGd1aqF.js";import{i as C}from"../chunks/CCOVnadf.js";import{e as ye,i as Re,n as z}from"../chunks/DqxUmOYD.js";import{r as et,s as tt,a as ee}from"../chunks/CmI1igJD.js";import{b as te}from"../chunks/ChWGK2Ce.js";import{i as at,s as ot,b as Ae}from"../chunks/CQE8d3kg.js";import{P as lt,u as rt}from"../chunks/YMZQSnF3.js";const it=async xe=>({...xe.data,categories:[{key:"documents",label:"Documents"},{key:"indexes",label:"Indexes"},{key:"mappings",label:"Mappings"},{key:"schema",label:"Schema"}]}),Rt=Object.freeze(Object.defineProperty({__proto__:null,load:it},Symbol.toStringTag,{value:"Module"}));var nt=d('<button class="btn btn-success btn-sm -my-2">Save</button>'),st=d('<button class="btn btn-outline-light btn-sm -my-2 hover:bg-[var(--color-3)]">🤖 AI Helper</button> <!>',1),dt=d('<button class="btn btn-outline-danger btn-sm mt-6 hover:bg-[rgba(255,59,48,0.1)]">Remove Mapping</button>'),ct=d("<option> </option>"),vt=d('<div class="flex-1"><label class="block text-xs mb-1">Target Collection <select class="w-full px-3 py-2 bg-[var(--color-1)] border border-[var(--border-color)] rounded text-sm mt-1"><option>Select collection...</option><!></select></label></div> <div class="flex-1"><label class="block text-xs mb-1">Target Field <input type="text" placeholder="_id" class="w-full px-3 py-2 bg-[var(--color-1)] border border-[var(--border-color)] rounded text-sm mt-1"/></label></div>',1),ut=d('<div class="flex-[2]"><label class="block text-xs mb-1">URL Template (use {value} for interpolation) <input type="text" placeholder="https://example.com/{value}" class="w-full px-3 py-2 bg-[var(--color-1)] border border-[var(--border-color)] rounded text-sm mt-1"/></label></div>'),bt=d('<button class="btn btn-outline-danger btn-sm mt-5 hover:bg-[rgba(255,59,48,0.1)]">×</button>'),pt=d('<div class="flex items-start gap-2 pl-4 border-l-2 border-[var(--color-3)]"><div class="flex-1"><label class="block text-xs mb-1">Type <select class="w-full px-3 py-2 bg-[var(--color-1)] border border-[var(--border-color)] rounded text-sm mt-1"><option>Document</option><option>URL</option></select></label></div> <!> <!></div>'),mt=d('<div class="flex gap-2 mt-2 ml-4"><button class="btn btn-outline-light btn-sm hover:bg-[var(--color-3)]">+ Add Document Target</button> <button class="btn btn-outline-light btn-sm hover:bg-[var(--color-3)]">+ Add URL Target</button></div>'),gt=d('<div class="border border-[var(--border-color)] rounded p-4"><div class="flex items-start gap-4 mb-3"><div class="flex-1"><label class="block text-sm font-medium mb-1">Field Path <input type="text" placeholder="e.g., authorId or comments.authorId" class="w-full px-3 py-2 bg-[var(--color-1)] border border-[var(--border-color)] rounded text-sm mt-1"/></label></div> <!></div> <div class="space-y-2"></div> <!></div>'),ft=d('<div class="space-y-4"></div>'),_t=d('<div class="text-center py-8" style="color: var(--text-secondary);">No mappings defined yet.</div>'),ht=d('<button class="btn btn-success">+ Add New Mapping</button>'),yt=d("<option> </option>"),xt=d('<label class="block text-sm font-medium mb-1">Target Collection <select class="w-full px-3 py-2 bg-[var(--color-1)] border border-[var(--border-color)] rounded mt-1"><option>Select collection...</option><!></select></label> <label class="block text-sm font-medium mb-1">Target Field <input type="text" placeholder="_id" class="w-full px-3 py-2 bg-[var(--color-1)] border border-[var(--border-color)] rounded mt-1"/></label>',1),kt=d(`<label class="block text-sm font-medium mb-1">URL Template <input type="text" placeholder="https://hf.co/datasets/{value}" class="w-full px-3 py-2 bg-[var(--color-1)] border border-[var(--border-color)] rounded mt-1"/></label> <p class="text-xs" style="color: var(--text-secondary);">Use <code class="px-1 bg-[var(--color-2)] rounded">{value}</code> as a placeholder for the field
value. Example: if the field is "abc/glue", and template is "https://hf.co/datasets/{value}",
the result will be "https://hf.co/datasets/abc/glue"</p>`,1),wt=d('<div class="border border-[var(--border-color)] rounded p-4 bg-[var(--light-background)]"><h3 class="text-lg font-medium mb-3">New Mapping</h3> <div class="space-y-3"><label class="block text-sm font-medium mb-1">Field Path <input type="text" placeholder="e.g., authorId or comments.authorId" class="w-full px-3 py-2 bg-[var(--color-1)] border border-[var(--border-color)] rounded mt-1"/></label> <label class="block text-sm font-medium mb-1">Mapping Type <select class="w-full px-3 py-2 bg-[var(--color-1)] border border-[var(--border-color)] rounded mt-1"><option>Document</option><option>URL</option></select></label> <!> <div class="flex gap-2"><button class="btn btn-success">Add</button> <button class="btn btn-default hover:bg-[var(--color-3)]">Cancel</button></div></div></div>'),Tt=d('<div class="mt-4"><!></div>'),Ct=d(`<div class="p-4"><div class="mb-4"><p class="mb-3">Define relationships between collections or external URLs to enable hover tooltips, navigation on foreign key
fields, and clickable external links. This will be stored in the <code class="px-1 bg-[var(--light-background)] rounded">mongoku.mappings</code> collection as a document with <a class="text-blue-500"> </a>.</p> <details class="mb-2" style="color: var(--text-secondary);"><summary class="cursor-pointer font-medium mb-2">Examples</summary> <div class="mt-2 space-y-3"><div><div class="font-medium mb-1">Document Mapping Example:</div> <div class="mb-1">Document in collection <code class="px-1 bg-[var(--light-background)] rounded">posts</code>:</div> <code class="block px-2 py-1 bg-[var(--light-background)] rounded text-xs mb-2">{ _id: "post1", title: "Hello", authorId: "user123", comments: [{authorId: "user456", text:
"Nice!"}] }</code> <div class="text space-y-1"><div>→ Mapping 1: Field path <code class="px-1 bg-[var(--light-background)] rounded">authorId</code>, type <strong>document</strong>, target collection <code class="px-1 bg-[var(--light-background)] rounded">users</code>, target field <code class="px-1 bg-[var(--light-background)] rounded">_id</code></div> <div>→ Mapping 2: Field path <code class="px-1 bg-[var(--light-background)] rounded">comments.authorId</code>, type <strong>document</strong>, target collection <code class="px-1 bg-[var(--light-background)] rounded">users</code>, target field <code class="px-1 bg-[var(--light-background)] rounded">_id</code></div></div></div> <div><div class="font-medium mb-1">URL Mapping Example:</div> <div class="mb-1">Document in collection <code class="px-1 bg-[var(--light-background)] rounded">dataset_info_cache</code>:</div> <code class="block px-2 py-1 bg-[var(--light-background)] rounded text-xs mb-2">{ _id: "abc/glue", name: "GLUE Benchmark", ... }</code> <div class="text space-y-1"><div>→ Mapping: Field path <code class="px-1 bg-[var(--light-background)] rounded">_id</code>, type <strong>URL</strong>, template <code class="px-1 bg-[var(--light-background)] rounded">https://hf.co/datasets/{value}</code></div> <div class="ml-4">Result: Clicking the _id will open "https://hf.co/datasets/abc/glue" in a new tab</div></div></div></div></details></div> <!> <!></div>`),It=d(`<div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4" role="button" tabindex="0"><div class="bg-[var(--color-1)] border border-[var(--border-color)] rounded-lg max-w-4xl w-full max-h-[80vh] overflow-hidden flex flex-col" role="dialog" tabindex="-1"><div class="p-4 border-b border-[var(--border-color)] flex justify-between items-center"><h2 class="text-xl font-semibold">AI Mapping Generator Prompt</h2> <button class="btn btn-outline-light btn-sm hover:bg-[var(--color-3)]">Close</button></div> <div class="p-4 overflow-auto flex-1"><p class="mb-3 text-sm" style="color: var(--text-secondary);">Copy this prompt and paste it into your IDE's AI assistant (Cursor, GitHub Copilot, etc.) to automatically
generate mappings for this collection.</p> <pre class="bg-[var(--color-2)] border border-[var(--border-color)] rounded p-4 text-sm whitespace-pre-wrap overflow-auto"> </pre></div> <div class="p-4 border-t border-[var(--border-color)] flex justify-end gap-2"><button class="btn btn-default hover:bg-[var(--color-3)]">Close</button> <button class="btn btn-primary hover:brightness-110">Copy to Clipboard</button></div></div></div>`),Mt=d("<!> <!>",1);function St(xe,l){Xe(l,!0);function Se(r){return"type"in r?r:{type:"document",collection:r.collection,on:r.on}}let ae=Ye(Object.entries(l.data.mappings).map(([r,n])=>({fieldPath:r,targets:(Array.isArray(n)?n:[n]).map(Se)}))),q=N(""),G=N("document"),B=N(""),oe=N("_id"),H=N(""),ue=N(!1),Q=N(!1);const Fe=_e(()=>`I need help generating MongoDB collection mappings for my database.
**Context:**
- Database: ${l.data.database}
- Collection: ${l.data.collection}
- Available collections: ${l.data.availableCollections.join(", ")}
**Task:**
Please analyze my codebase to identify relationships between the "${l.data.collection}" collection and other collections. Look for:
1. Fields that reference documents in other collections (foreign keys)
2. Nested fields within arrays or objects that reference other documents
3. Common patterns like userId, authorId, etc.
If you have access to the MongoDB MCP server, use it to:
1. Query sample documents from the "${l.data.collection}" collection
2. Analyze the schema and field types
3. Identify potential foreign key relationships
**Output Format:**
Create a file named \`${l.data.collection}.mappings.json\` with the following structure:
\`\`\`json
{
"_id": "${l.data.collection}",
"mappings": {
"fieldPath": { "type": "document", "collection": "targetCollection", "on": "targetField" },
"nested.fieldPath": { "type": "document", "collection": "targetCollection", "on": "targetField" }
}
}
\`\`\`
**Example:**
If the collection has documents like:
\`\`\`json
{
"_id": "post1",
"authorId": "user123",
"comments": [
{ "authorId": "user456", "text": "Great post!" }
]
}
\`\`\`
The mappings would be:
\`\`\`json
{
"_id": "${l.data.collection}",
"mappings": {
"authorId": { "type": "document", "collection": "users", "on": "_id" },
"comments.authorId": { "type": "document", "collection": "users", "on": "_id" }
}
}
\`\`\`
**Notes:**
- Use dot notation for nested fields (e.g., "comments.authorId")
- Multiple mappings for the same field can be expressed as an array
- Target field is usually "_id" but can be any unique field
Please analyze the codebase and database, then generate the appropriate mappings file.`);async function Ne(){try{await navigator.clipboard.writeText(t(Fe)),z.notifySuccess("AI prompt copied to clipboard")}catch(r){z.notifyError(r,"Failed to copy to clipboard")}}function Oe(r,n="document"){n==="document"?r.targets.push({type:"document",collection:"",on:"_id"}):r.targets.push({type:"url",template:""})}function ze(r,n){r.targets.splice(n,1)}function qe(r){ae.splice(r,1)}function Ge(){if(!t(q).trim()){z.notifyError("Field path is required");return}let r;if(t(G)==="document"){if(!t(B).trim()){z.notifyError("Target collection is required");return}r={type:"document",collection:t(B).trim(),on:t(oe).trim()||"_id"}}else{if(!t(H).trim()){z.notifyError("URL template is required");return}r={type:"url",template:t(H).trim()}}ae.push({fieldPath:t(q).trim(),targets:[r]}),i(q,""),i(G,"document"),i(B,""),i(oe,"_id"),i(H,""),i(ue,!1)}function Be(){i(q,""),i(G,"document"),i(B,""),i(oe,"_id"),i(H,""),i(ue,!1)}async function He(){try{const r={};for(const n of ae)if(n.fieldPath.trim()){const g=n.targets.filter(c=>{if("type"in c){if(c.type==="document")return c.collection.trim()&&c.on.trim();if(c.type==="url")return c.template.trim()}else return c.collection.trim()&&c.on.trim();return!1});g.length>0&&(r[n.fieldPath]=g.length===1?g[0]:g)}await rt({server:l.data.server,database:l.data.database,collection:"mongoku.mappings",document:l.data.collection,value:{mappings:r,_id:l.data.collection},partial:!1,upsert:!0}),z.notifySuccess("Mappings saved successfully")}catch(r){console.error("Error saving mappings:",r),z.notifyError(r,"Failed to save mappings")}}var Ee=Mt(),je=ve(Ee);lt(je,{get title(){return`Mappings for ${l.data.collection??""}`},titleClass:"py-2",actions:n=>{var g=st(),c=ve(g),D=o(c,2);{var O=x=>{var J=nt();v("click",J,He),s(x,J)};C(D,x=>{l.data.readOnly||x(O)})}v("click",c,()=>i(Q,!0)),s(n,g)},children:(n,g)=>{var c=Ct(),D=a(c),O=a(D),x=o(a(O),3),J=a(x);e(x),Pe(),e(O),Pe(2),e(D);var le=o(D,2);{var be=h=>{var I=ft();ye(I,21,()=>ae,Re,(we,y,Te)=>{var k=gt(),w=a(k),K=a(w),V=a(K),W=o(a(V));ee(W),e(V),e(K);var re=o(K,2);{var ie=f=>{var _=dt();v("click",_,()=>qe(Te)),s(f,_)};C(re,f=>{l.data.readOnly||f(ie)})}e(w);var L=o(w,2);ye(L,21,()=>t(y).targets,Re,(f,_,M)=>{const P=_e(()=>"type"in t(_)?t(_).type:"document");var ne=pt(),p=a(ne),E=a(p),u=o(a(E)),T=a(u);T.value=T.__value="document";var j=o(T);j.value=j.__value="url",e(u);var ge;at(u),e(E),e(p);var se=o(p,2);{var fe=m=>{const b=_e(()=>t(_));var X=vt(),Y=ve(X),Z=a(Y),$=o(a(Z)),Ce=a($);Ce.value=Ce.__value="";var Ve=o(Ce);ye(Ve,16,()=>l.data.availableCollections,S=>S,(S,Me)=>{var ce=ct(),We=a(ce,!0);e(ce);var Le={};F(()=>{he(We,Me),Le!==(Le=Me)&&(ce.value=(ce.__value=Me)??"")}),s(S,ce)}),e($),e(Z),e(Y);var De=o(Y,2),Ue=a(De),Ie=o(a(Ue));ee(Ie),e(Ue),e(De),F(()=>{$.disabled=l.data.readOnly,Ie.disabled=l.data.readOnly}),Ae($,()=>t(b).collection,S=>t(b).collection=S),te(Ie,()=>t(b).on,S=>t(b).on=S),s(m,X)},A=m=>{const b=_e(()=>t(_));var X=ut(),Y=a(X),Z=o(a(Y));ee(Z),e(Y),e(X),F(()=>Z.disabled=l.data.readOnly),te(Z,()=>t(b).template,$=>t(b).template=$),s(m,X)};C(se,m=>{t(P)==="document"?m(fe):m(A,-1)})}var de=o(se,2);{var R=m=>{var b=bt();F(()=>b.disabled=t(y).targets.length===1),v("click",b,()=>ze(t(y),M)),s(m,b)};C(de,m=>{l.data.readOnly||m(R)})}e(ne),F(()=>{u.disabled=l.data.readOnly,ge!==(ge=t(P))&&(u.value=(u.__value=t(P))??"",ot(u,t(P)))}),v("change",u,m=>{m.currentTarget.value==="document"?t(y).targets[M]={type:"document",collection:"",on:"_id"}:t(y).targets[M]={type:"url",template:""}}),s(f,ne)}),e(L);var pe=o(L,2);{var me=f=>{var _=mt(),M=a(_),P=o(M,2);e(_),v("click",M,()=>Oe(t(y),"document")),v("click",P,()=>Oe(t(y),"url")),s(f,_)};C(pe,f=>{l.data.readOnly||f(me)})}e(k),F(()=>W.disabled=l.data.readOnly),te(W,()=>t(y).fieldPath,f=>t(y).fieldPath=f),s(we,k)}),e(I),s(h,I)},ke=h=>{var I=_t();s(h,I)};C(le,h=>{ae.length>0?h(be):h(ke,-1)})}var U=o(le,2);{var Ke=h=>{var I=Tt(),we=a(I);{var y=k=>{var w=ht();v("click",w,()=>i(ue,!0)),s(k,w)},Te=k=>{var w=wt(),K=o(a(w),2),V=a(K),W=o(a(V));ee(W),e(V);var re=o(V,2),ie=o(a(re)),L=a(ie);L.value=L.__value="document";var pe=o(L);pe.value=pe.__value="url",e(ie),e(re);var me=o(re,2);{var f=p=>{var E=xt(),u=ve(E),T=o(a(u)),j=a(T);j.value=j.__value="";var ge=o(j);ye(ge,16,()=>l.data.availableCollections,A=>A,(A,de)=>{var R=yt(),m=a(R,!0);e(R);var b={};F(()=>{he(m,de),b!==(b=de)&&(R.value=(R.__value=de)??"")}),s(A,R)}),e(T),e(u);var se=o(u,2),fe=o(a(se));ee(fe),e(se),Ae(T,()=>t(B),A=>i(B,A)),te(fe,()=>t(oe),A=>i(oe,A)),s(p,E)},_=p=>{var E=kt(),u=ve(E),T=o(a(u));ee(T),e(u),Pe(2),te(T,()=>t(H),j=>i(H,j)),s(p,E)};C(me,p=>{t(G)==="document"?p(f):p(_,-1)})}var M=o(me,2),P=a(M),ne=o(P,2);e(M),e(K),e(w),te(W,()=>t(q),p=>i(q,p)),Ae(ie,()=>t(G),p=>i(G,p)),v("click",P,Ge),v("click",ne,Be),s(k,w)};C(we,k=>{t(ue)?k(Te,-1):k(y)})}e(I),s(h,I)};C(U,h=>{l.data.readOnly||h(Ke)})}e(c),F(h=>{tt(x,"href",h),he(J,`_id: "${l.data.collection??""}"`)},[()=>et(`/servers/${l.data.server}/databases/${l.data.database}/collections/mongoku.mappings/documents/${l.data.collection}`)]),s(n,c)},$$slots:{actions:!0,default:!0}});var Qe=o(je,2);{var Je=r=>{var n=It(),g=a(n),c=a(g),D=o(a(c),2);e(c);var O=o(c,2),x=o(a(O),2),J=a(x,!0);e(x),e(O);var le=o(O,2),be=a(le),ke=o(be,2);e(le),e(g),e(n),F(()=>he(J,t(Fe))),v("click",n,()=>i(Q,!1)),v("keydown",n,U=>{U.key==="Escape"&&i(Q,!1)}),v("click",g,U=>U.stopPropagation()),v("keydown",g,U=>U.stopPropagation()),v("click",D,()=>i(Q,!1)),v("click",be,()=>i(Q,!1)),v("click",ke,Ne),s(r,n)};C(Qe,r=>{t(Q)&&r(Je)})}s(xe,Ee),Ze()}$e(["click","change","keydown"]);export{St as component,Rt as universal};