@malloy-publisher/server 0.0.196-dev → 0.0.198-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/api-doc.yaml +213 -214
- package/dist/app/assets/EnvironmentPage-1j6QDWAy.js +1 -0
- package/dist/app/assets/HomePage-DMop21VG.js +1 -0
- package/dist/app/assets/MainPage-BbE8ETz1.js +2 -0
- package/dist/app/assets/ModelPage-D2jvfe3t.js +1 -0
- package/dist/app/assets/PackagePage-BbnhGoD3.js +1 -0
- package/dist/app/assets/{RouteError-DefbDO7F.js → RouteError-D3LGEZ3i.js} +1 -1
- package/dist/app/assets/WorkbookPage-DttVIj4u.js +1 -0
- package/dist/app/assets/{core-BrfQApxh.es-DnvCX4oH.js → core-w79IMXAG.es-Bd0UlzOL.js} +1 -1
- package/dist/app/assets/{index-Bu0ub036.js → index-5K9YjIxF.js} +117 -117
- package/dist/app/assets/{index-CkzK3JIl.js → index-C513UodQ.js} +1 -1
- package/dist/app/assets/{index-CoA6HIGS.js → index-DIgzgp69.js} +1 -1
- package/dist/app/assets/{index.umd-B6Ms2PpL.js → index.umd-BMeMPq_9.js} +1 -1
- package/dist/app/index.html +1 -1
- package/dist/server.mjs +1947 -1317
- package/package.json +1 -1
- package/publisher.config.json +2 -2
- package/src/config.spec.ts +74 -66
- package/src/config.ts +50 -47
- package/src/controller/compile.controller.ts +10 -7
- package/src/controller/connection.controller.ts +79 -58
- package/src/controller/database.controller.ts +10 -7
- package/src/controller/manifest.controller.ts +23 -14
- package/src/controller/materialization.controller.ts +14 -14
- package/src/controller/model.controller.ts +35 -20
- package/src/controller/package.controller.ts +83 -49
- package/src/controller/query.controller.ts +11 -8
- package/src/controller/watch-mode.controller.ts +35 -29
- package/src/errors.ts +2 -2
- package/src/mcp/error_messages.ts +2 -2
- package/src/mcp/handler_utils.ts +23 -20
- package/src/mcp/mcp_constants.ts +1 -1
- package/src/mcp/prompts/handlers.ts +3 -3
- package/src/mcp/prompts/prompt_service.ts +5 -5
- package/src/mcp/prompts/utils.ts +12 -12
- package/src/mcp/resource_metadata.ts +3 -3
- package/src/mcp/resources/environment_resource.ts +187 -0
- package/src/mcp/resources/model_resource.ts +19 -17
- package/src/mcp/resources/notebook_resource.ts +13 -13
- package/src/mcp/resources/package_resource.ts +30 -27
- package/src/mcp/resources/query_resource.ts +15 -10
- package/src/mcp/resources/source_resource.ts +10 -10
- package/src/mcp/resources/view_resource.ts +11 -11
- package/src/mcp/server.ts +16 -14
- package/src/mcp/tools/discovery_tools.ts +67 -49
- package/src/mcp/tools/execute_query_tool.ts +14 -14
- package/src/server-old.ts +1139 -0
- package/src/server.ts +191 -159
- package/src/service/connection.spec.ts +158 -133
- package/src/service/connection.ts +42 -39
- package/src/service/connection_config.spec.ts +13 -11
- package/src/service/connection_config.ts +28 -19
- package/src/service/connection_service.spec.ts +63 -43
- package/src/service/connection_service.ts +106 -89
- package/src/service/{project.ts → environment.ts} +92 -77
- package/src/service/{project_compile.spec.ts → environment_compile.spec.ts} +1 -1
- package/src/service/{project_store.spec.ts → environment_store.spec.ts} +99 -85
- package/src/service/{project_store.ts → environment_store.ts} +368 -326
- package/src/service/manifest_service.spec.ts +15 -15
- package/src/service/manifest_service.ts +26 -21
- package/src/service/materialization_service.spec.ts +93 -59
- package/src/service/materialization_service.ts +71 -62
- package/src/service/materialized_table_gc.spec.ts +15 -15
- package/src/service/materialized_table_gc.ts +3 -3
- package/src/service/model.ts +2 -2
- package/src/service/package.spec.ts +2 -2
- package/src/service/package.ts +23 -21
- package/src/service/resolve_environment.ts +15 -0
- package/src/storage/DatabaseInterface.ts +34 -25
- package/src/storage/StorageManager.mock.ts +3 -3
- package/src/storage/StorageManager.ts +24 -23
- package/src/storage/duckdb/ConnectionRepository.ts +13 -11
- package/src/storage/duckdb/DuckDBConnection.ts +1 -1
- package/src/storage/duckdb/DuckDBManifestStore.ts +6 -6
- package/src/storage/duckdb/DuckDBRepository.ts +47 -47
- package/src/storage/duckdb/{ProjectRepository.ts → EnvironmentRepository.ts} +35 -35
- package/src/storage/duckdb/ManifestRepository.ts +21 -20
- package/src/storage/duckdb/MaterializationRepository.ts +31 -28
- package/src/storage/duckdb/PackageRepository.ts +11 -11
- package/src/storage/duckdb/manifest_store.spec.ts +2 -2
- package/src/storage/duckdb/schema.ts +20 -20
- package/src/storage/ducklake/DuckLakeManifestStore.ts +14 -14
- package/tests/fixtures/publisher.config.json +1 -1
- package/tests/harness/e2e.ts +1 -1
- package/tests/harness/mcp_test_setup.ts +1 -1
- package/tests/harness/mocks.ts +10 -8
- package/tests/integration/materialization/materialization_lifecycle.integration.spec.ts +4 -4
- package/tests/integration/mcp/mcp_execute_query_tool.integration.spec.ts +27 -48
- package/tests/integration/mcp/mcp_resource.integration.spec.ts +26 -35
- package/tests/unit/duckdb/attached_databases.test.ts +51 -33
- package/tests/unit/ducklake/ducklake.test.ts +24 -22
- package/tests/unit/mcp/prompt_happy.test.ts +8 -8
- package/dist/app/assets/HomePage-DbZS0N7G.js +0 -1
- package/dist/app/assets/MainPage-CBuWkbmr.js +0 -2
- package/dist/app/assets/ModelPage-Bt37smot.js +0 -1
- package/dist/app/assets/PackagePage-DLZe50WG.js +0 -1
- package/dist/app/assets/ProjectPage-FQTEPXP4.js +0 -1
- package/dist/app/assets/WorkbookPage-CkAo16ar.js +0 -1
- package/src/mcp/resources/project_resource.ts +0 -184
- package/src/service/resolve_project.ts +0 -13
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{u as V,g as F,r as g,R as _,a as X,b as S,c as M,e as A,j as e,s as m,f as w,h as v,k as I,P as Y,m as R,l as J,n as z,B as K,o as N,p as Z,T as U,q,t as oo,d as ro,v as f,C as j,w as eo,x as to,I as ao,M as so,y as $,S as no,z as lo,A as io,O as co,D as po}from"./index-Bu0ub036.js";function uo(o,r,t,a,n){const[s,i]=g.useState(()=>n&&t?t(o).matches:a?a(o).matches:r);return X(()=>{if(!t)return;const p=t(o),u=()=>{i(p.matches)};return u(),p.addEventListener("change",u),()=>{p.removeEventListener("change",u)}},[o,t]),s}const go={..._},L=go.useSyncExternalStore;function xo(o,r,t,a,n){const s=g.useCallback(()=>r,[r]),i=g.useMemo(()=>{if(n&&t)return()=>t(o).matches;if(a!==null){const{matches:c}=a(o);return()=>c}return s},[s,o,a,n,t]),[p,u]=g.useMemo(()=>{if(t===null)return[s,()=>()=>{}];const c=t(o);return[()=>c.matches,l=>(c.addEventListener("change",l),()=>{c.removeEventListener("change",l)})]},[s,t,o]);return L(u,p,i)}function O(o={}){const{themeId:r}=o;return function(a,n={}){let s=V();s&&r&&(s=s[r]||s);const i=typeof window<"u"&&typeof window.matchMedia<"u",{defaultMatches:p=!1,matchMedia:u=i?window.matchMedia:null,ssrMatchMedia:d=null,noSsr:c=!1}=F({name:"MuiUseMediaQuery",props:n,theme:s});let l=typeof a=="function"?a(s):a;return l=l.replace(/^@media( ?)/m,""),l.includes("print")&&console.warn(["MUI: You have provided a `print` query to the `useMediaQuery` hook.","Using the print media query to modify print styles can lead to unexpected results.","Consider using the `displayPrint` field in the `sx` prop instead.","More information about `displayPrint` on our docs: https://mui.com/system/display/#display-in-print."].join(`
|
|
2
|
-
`)),(L!==void 0?xo:uo)(l,p,u,d,c)}}O();function mo(o){return S("MuiAppBar",o)}M("MuiAppBar",["root","positionFixed","positionAbsolute","positionSticky","positionStatic","positionRelative","colorDefault","colorPrimary","colorSecondary","colorInherit","colorTransparent","colorError","colorInfo","colorSuccess","colorWarning"]);const fo=o=>{const{color:r,position:t,classes:a}=o,n={root:["root",`color${v(r)}`,`position${v(t)}`]};return I(n,mo,a)},D=(o,r)=>o?`${o?.replace(")","")}, ${r})`:r,bo=m(Y,{name:"MuiAppBar",slot:"Root",overridesResolver:(o,r)=>{const{ownerState:t}=o;return[r.root,r[`position${v(t.position)}`],r[`color${v(t.color)}`]]}})(R(({theme:o})=>({display:"flex",flexDirection:"column",width:"100%",boxSizing:"border-box",flexShrink:0,variants:[{props:{position:"fixed"},style:{position:"fixed",zIndex:(o.vars||o).zIndex.appBar,top:0,left:"auto",right:0,"@media print":{position:"absolute"}}},{props:{position:"absolute"},style:{position:"absolute",zIndex:(o.vars||o).zIndex.appBar,top:0,left:"auto",right:0}},{props:{position:"sticky"},style:{position:"sticky",zIndex:(o.vars||o).zIndex.appBar,top:0,left:"auto",right:0}},{props:{position:"static"},style:{position:"static"}},{props:{position:"relative"},style:{position:"relative"}},{props:{color:"inherit"},style:{"--AppBar-color":"inherit"}},{props:{color:"default"},style:{"--AppBar-background":o.vars?o.vars.palette.AppBar.defaultBg:o.palette.grey[100],"--AppBar-color":o.vars?o.vars.palette.text.primary:o.palette.getContrastText(o.palette.grey[100]),...o.applyStyles("dark",{"--AppBar-background":o.vars?o.vars.palette.AppBar.defaultBg:o.palette.grey[900],"--AppBar-color":o.vars?o.vars.palette.text.primary:o.palette.getContrastText(o.palette.grey[900])})}},...Object.entries(o.palette).filter(J(["contrastText"])).map(([r])=>({props:{color:r},style:{"--AppBar-background":(o.vars??o).palette[r].main,"--AppBar-color":(o.vars??o).palette[r].contrastText}})),{props:r=>r.enableColorOnDark===!0&&!["inherit","transparent"].includes(r.color),style:{backgroundColor:"var(--AppBar-background)",color:"var(--AppBar-color)"}},{props:r=>r.enableColorOnDark===!1&&!["inherit","transparent"].includes(r.color),style:{backgroundColor:"var(--AppBar-background)",color:"var(--AppBar-color)",...o.applyStyles("dark",{backgroundColor:o.vars?D(o.vars.palette.AppBar.darkBg,"var(--AppBar-background)"):null,color:o.vars?D(o.vars.palette.AppBar.darkColor,"var(--AppBar-color)"):null})}},{props:{color:"transparent"},style:{"--AppBar-background":"transparent","--AppBar-color":"inherit",backgroundColor:"var(--AppBar-background)",color:"var(--AppBar-color)",...o.applyStyles("dark",{backgroundImage:"none"})}}]}))),ho=g.forwardRef(function(r,t){const a=A({props:r,name:"MuiAppBar"}),{className:n,color:s="primary",enableColorOnDark:i=!1,position:p="fixed",...u}=a,d={...a,color:s,position:p,enableColorOnDark:i},c=fo(d);return e.jsx(bo,{square:!0,component:"header",ownerState:d,elevation:4,className:w(c.root,n,p==="fixed"&&"mui-fixed"),ref:t,...u})}),yo=z(e.jsx("path",{d:"M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"})),vo=m(K,{name:"MuiBreadcrumbCollapsed"})(R(({theme:o})=>({display:"flex",marginLeft:`calc(${o.spacing(1)} * 0.5)`,marginRight:`calc(${o.spacing(1)} * 0.5)`,...o.palette.mode==="light"?{backgroundColor:o.palette.grey[100],color:o.palette.grey[700]}:{backgroundColor:o.palette.grey[700],color:o.palette.grey[100]},borderRadius:2,"&:hover, &:focus":{...o.palette.mode==="light"?{backgroundColor:o.palette.grey[200]}:{backgroundColor:o.palette.grey[600]}},"&:active":{boxShadow:o.shadows[0],...o.palette.mode==="light"?{backgroundColor:N(o.palette.grey[200],.12)}:{backgroundColor:N(o.palette.grey[600],.12)}}}))),ko=m(yo)({width:24,height:16});function Bo(o){const{slots:r={},slotProps:t={},...a}=o,n=o;return e.jsx("li",{children:e.jsx(vo,{focusRipple:!0,...a,ownerState:n,children:e.jsx(ko,{as:r.CollapsedIcon,ownerState:n,...t.collapsedIcon})})})}function Co(o){return S("MuiBreadcrumbs",o)}const jo=M("MuiBreadcrumbs",["root","ol","li","separator"]),So=o=>{const{classes:r}=o;return I({root:["root"],li:["li"],ol:["ol"],separator:["separator"]},Co,r)},Mo=m(U,{name:"MuiBreadcrumbs",slot:"Root",overridesResolver:(o,r)=>[{[`& .${jo.li}`]:r.li},r.root]})({}),Ao=m("ol",{name:"MuiBreadcrumbs",slot:"Ol"})({display:"flex",flexWrap:"wrap",alignItems:"center",padding:0,margin:0,listStyle:"none"}),wo=m("li",{name:"MuiBreadcrumbs",slot:"Separator"})({display:"flex",userSelect:"none",marginLeft:8,marginRight:8});function Io(o,r,t,a){return o.reduce((n,s,i)=>(i<o.length-1?n=n.concat(s,e.jsx(wo,{"aria-hidden":!0,className:r,ownerState:a,children:t},`separator-${i}`)):n.push(s),n),[])}const Ro=g.forwardRef(function(r,t){const a=A({props:r,name:"MuiBreadcrumbs"}),{children:n,className:s,component:i="nav",slots:p={},slotProps:u={},expandText:d="Show path",itemsAfterCollapse:c=1,itemsBeforeCollapse:l=1,maxItems:h=8,separator:k="/",...Q}=a,[T,W]=g.useState(!1),b={...a,component:i,expanded:T,expandText:d,itemsAfterCollapse:c,itemsBeforeCollapse:l,maxItems:h,separator:k},y=So(b),H=Z({elementType:p.CollapsedIcon,externalSlotProps:u.collapsedIcon,ownerState:b}),P=g.useRef(null),G=x=>{const C=()=>{W(!0);const E=P.current.querySelector("a[href],button,[tabindex]");E&&E.focus()};return l+c>=x.length?x:[...x.slice(0,l),e.jsx(Bo,{"aria-label":d,slots:{CollapsedIcon:p.CollapsedIcon},slotProps:{collapsedIcon:H},onClick:C},"ellipsis"),...x.slice(x.length-c,x.length)]},B=g.Children.toArray(n).filter(x=>g.isValidElement(x)).map((x,C)=>e.jsx("li",{className:y.li,children:x},`child-${C}`));return e.jsx(Mo,{ref:t,component:i,color:"textSecondary",className:w(y.root,s),ownerState:b,...Q,children:e.jsx(Ao,{className:y.ol,ref:P,ownerState:b,children:Io(T||h&&B.length<=h?B:G(B),y.separator,k,b)})})});function zo(o){return S("MuiToolbar",o)}M("MuiToolbar",["root","gutters","regular","dense"]);const To=o=>{const{classes:r,disableGutters:t,variant:a}=o;return I({root:["root",!t&&"gutters",a]},zo,r)},Po=m("div",{name:"MuiToolbar",slot:"Root",overridesResolver:(o,r)=>{const{ownerState:t}=o;return[r.root,!t.disableGutters&&r.gutters,r[t.variant]]}})(R(({theme:o})=>({position:"relative",display:"flex",alignItems:"center",variants:[{props:({ownerState:r})=>!r.disableGutters,style:{paddingLeft:o.spacing(2),paddingRight:o.spacing(2),[o.breakpoints.up("sm")]:{paddingLeft:o.spacing(3),paddingRight:o.spacing(3)}}},{props:{variant:"dense"},style:{minHeight:48}},{props:{variant:"regular"},style:o.mixins.toolbar}]}))),Eo=g.forwardRef(function(r,t){const a=A({props:r,name:"MuiToolbar"}),{className:n,component:s="div",disableGutters:i=!1,variant:p="regular",...u}=a,d={...a,component:s,disableGutters:i,variant:p},c=To(d);return e.jsx(Po,{as:s,className:w(c.root,n),ref:t,ownerState:d,...u})}),No=O({themeId:q}),$o=z(e.jsx("path",{d:"M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"})),Do=z(e.jsx("path",{d:"M3 18h18v-2H3zm0-5h18v-2H3zm0-7v2h18V6z"}));function Uo(){const o=oo(),r=o["*"],t=ro();return e.jsx(f,{sx:{display:"flex",alignItems:"center"},children:e.jsxs(Ro,{"aria-label":"breadcrumb",separator:e.jsx($o,{sx:{fontSize:14,color:"text.secondary"}}),sx:{"& .MuiBreadcrumbs-separator":{margin:"0 6px"}},children:[o.projectName&&e.jsx(j,{onClick:a=>t(`/${o.projectName}/`,a),label:o.projectName,size:"medium",sx:{backgroundColor:"background.paper",color:"primary.main",fontWeight:500,height:"32px",fontSize:"1rem",cursor:"pointer","&:hover":{backgroundColor:"primary.100"}}}),o.packageName&&e.jsx(j,{onClick:a=>t(`/${o.projectName}/${o.packageName}/`,a),label:o.packageName,size:"medium",sx:{backgroundColor:"background.paper",color:"primary.main",fontWeight:500,height:"32px",fontSize:"1rem",cursor:"pointer","&:hover":{backgroundColor:"secondary.100"}}}),r&&e.jsx(j,{onClick:a=>t(`/${o.projectName}/${o.packageName}/${r}`,a),label:r,size:"medium",sx:{backgroundColor:"background.paper",color:"primary.main",fontWeight:500,height:"32px",fontSize:"1rem",cursor:"pointer","&:hover":{backgroundColor:"grey.200"}}})]})})}function Lo({logoHeader:o,endCap:r}){const t=eo(),a=to(),n=No(a.breakpoints.down("sm")),[s,i]=g.useState(null),p=!!s,u=l=>{i(l.currentTarget)},d=()=>i(null),c=[{label:"Malloy Docs",link:"https://docs.malloydata.dev/documentation/",sx:{color:"primary.main"}},{label:"Publisher Docs",link:"https://github.com/malloydata/publisher/blob/main/README.md",sx:{color:"primary.main"}},{label:"Publisher API",link:"/api-doc.html",sx:{color:"primary.main"}}];return e.jsxs(ho,{position:"sticky",elevation:0,sx:{backgroundColor:"background.paper",borderBottom:"1px solid",borderColor:"divider"},children:[e.jsxs(Eo,{sx:{justifyContent:"space-between",flexWrap:"nowrap",minHeight:44},children:[o||e.jsxs(f,{sx:{display:"flex",alignItems:"center",gap:1,cursor:"pointer"},onClick:()=>t("/"),children:[e.jsx(f,{component:"img",src:"/logo.svg",alt:"Malloy",sx:{width:28,height:28}}),e.jsx(U,{variant:"h6",sx:{color:"text.primary",fontWeight:700,letterSpacing:"-0.025em",fontSize:{xs:"1.1rem",sm:"1.25rem"}},children:"Malloy Publisher"})]}),n?e.jsxs(e.Fragment,{children:[e.jsx(ao,{color:"inherit",onClick:u,children:e.jsx(Do,{})}),e.jsxs(so,{anchorEl:s,open:p,onClose:d,anchorOrigin:{vertical:"bottom",horizontal:"right"},children:[c.map(l=>e.jsx($,{onClick:()=>{d(),window.location.href=l.link},sx:l.sx,children:l.label},l.label)),r&&e.jsx($,{children:r})]})]}):e.jsxs(no,{direction:"row",spacing:2,alignItems:"center",children:[c.map(l=>e.jsx(lo,{href:l.link,sx:l.sx,children:l.label},l.label)),r]})]}),e.jsx(f,{sx:{borderTop:"1px solid white",paddingLeft:"16px",paddingRight:"16px",marginBottom:"1px",overflowX:"auto"},children:e.jsx(Uo,{})})]})}function Qo({headerProps:o}){return e.jsxs(f,{sx:{display:"flex",flexDirection:"column",minHeight:"100vh"},children:[e.jsx(Lo,{...o}),e.jsx(io,{maxWidth:"xl",component:"main",sx:{flex:1,display:"flex",flexDirection:"column",py:2,gap:2},children:e.jsx(f,{sx:{flex:1},children:e.jsx(g.Suspense,{fallback:e.jsx(po,{}),children:e.jsx(co,{})})})})]})}export{Qo as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as n,j as e,E as i,F as t,G as c}from"./index-Bu0ub036.js";function o(){const a=n(),r=a["*"];if(!a.projectName)return e.jsx("div",{children:e.jsx("h2",{children:"Missing project name"})});if(!a.packageName)return e.jsx("div",{children:e.jsx("h2",{children:"Missing package name"})});const s=i({projectName:a.projectName,packageName:a.packageName,modelPath:r});return r?.endsWith(".malloy")?e.jsx(t,{resourceUri:s,runOnDemand:!0,maxResultSize:512*1024}):r?.endsWith(".malloynb")?e.jsx(c,{resourceUri:s,maxResultSize:1024*1024}):e.jsx("div",{children:e.jsxs("h2",{children:["Unrecognized file type: ",r]})})}export{o as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as n,d as c,j as e,E as t,H as o}from"./index-Bu0ub036.js";function l(){const{projectName:s,packageName:a}=n(),r=c();if(s)if(a){const i=t({projectName:s,packageName:a});return e.jsx(o,{onClickPackageFile:r,resourceUri:i})}else return e.jsx("div",{children:e.jsx("h2",{children:"Missing package name"})});else return e.jsx("div",{children:e.jsx("h2",{children:"Missing project name"})})}export{l as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{d as a,t as n,j as e,E as o,J as c}from"./index-Bu0ub036.js";function u(){const r=a(),{projectName:s}=n();if(s){const t=o({projectName:s});return e.jsx(c,{onSelectPackage:r,resourceUri:t})}else return e.jsx("div",{children:e.jsx("h2",{children:"Missing project name"})})}export{u as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as a,j as e,E as t,Z as c}from"./index-Bu0ub036.js";function d(){const{workspace:r,workbookPath:s,projectName:i,packageName:n}=a();if(r)if(s)if(i)if(n){const o=t({projectName:i,packageName:n});return e.jsx(c,{workbookPath:{path:s,workspace:r},resourceUri:o},`${s}`)}else return e.jsx("div",{children:e.jsx("h2",{children:"Missing package name"})});else return e.jsx("div",{children:e.jsx("h2",{children:"Missing project name"})});else return e.jsx("div",{children:e.jsx("h2",{children:"Missing workbook path"})});else return e.jsx("div",{children:e.jsx("h2",{children:"Missing workspace"})})}export{d as default};
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
McpServer,
|
|
3
|
-
ResourceTemplate,
|
|
4
|
-
} from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
|
-
import type { ListResourcesResult } from "@modelcontextprotocol/sdk/types.js"; // Needed for list return type
|
|
6
|
-
import { logger } from "../../logger";
|
|
7
|
-
import { ProjectStore } from "../../service/project_store";
|
|
8
|
-
import { getInternalError, getNotFoundError } from "../error_messages"; // Needed for error handling in list AND get
|
|
9
|
-
import { handleResourceGet, McpGetResourceError } from "../handler_utils";
|
|
10
|
-
import { RESOURCE_METADATA } from "../resource_metadata";
|
|
11
|
-
|
|
12
|
-
// Define an interface for the package object augmented with project name
|
|
13
|
-
interface PackageWithProject {
|
|
14
|
-
name?: string;
|
|
15
|
-
// Add other relevant package properties if needed
|
|
16
|
-
projectName: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Registers the Malloy Project resource type with the MCP server.
|
|
21
|
-
* Handles getting details for the hardcoded 'home' project and listing packages within it.
|
|
22
|
-
*/
|
|
23
|
-
export function registerProjectResource(
|
|
24
|
-
mcpServer: McpServer,
|
|
25
|
-
projectStore: ProjectStore,
|
|
26
|
-
): void {
|
|
27
|
-
mcpServer.resource(
|
|
28
|
-
"project",
|
|
29
|
-
new ResourceTemplate("malloy://project/{projectName}", {
|
|
30
|
-
/**
|
|
31
|
-
* Handles ListResources requests.
|
|
32
|
-
* If projectName is specified, lists packages for that project (only 'home' supported).
|
|
33
|
-
* If projectName is not specified (general ListResources call), lists packages for the default 'home' project.
|
|
34
|
-
*/
|
|
35
|
-
list: async (/* extra: ListProjectExtra - Deleted */): Promise<ListResourcesResult> => {
|
|
36
|
-
logger.info(
|
|
37
|
-
"[MCP LOG] Entering ListResources (project) handler (listing ALL packages)...",
|
|
38
|
-
);
|
|
39
|
-
// Ignore parameters from 'extra' as URI path params aren't passed to list handlers.
|
|
40
|
-
|
|
41
|
-
try {
|
|
42
|
-
const allProjects = await projectStore.listProjects();
|
|
43
|
-
logger.info(
|
|
44
|
-
`[MCP LOG] Found ${allProjects.length} projects defined.`,
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
const packagePromises = allProjects.map(async (proj) => {
|
|
48
|
-
try {
|
|
49
|
-
logger.info(
|
|
50
|
-
`[MCP LOG] Getting project '${proj.name}' to list its packages...`,
|
|
51
|
-
);
|
|
52
|
-
const projectInstance = await projectStore.getProject(
|
|
53
|
-
proj.name!,
|
|
54
|
-
false,
|
|
55
|
-
); // Use proj.name
|
|
56
|
-
const packages = await projectInstance.listPackages();
|
|
57
|
-
logger.info(
|
|
58
|
-
`[MCP LOG] Found ${packages.length} packages in project '${proj.name}'.`,
|
|
59
|
-
);
|
|
60
|
-
// Return packages along with their project name for URI construction
|
|
61
|
-
return packages.map((pkg) => ({
|
|
62
|
-
...pkg,
|
|
63
|
-
projectName: proj.name,
|
|
64
|
-
}));
|
|
65
|
-
} catch (projectError) {
|
|
66
|
-
logger.error(
|
|
67
|
-
`[MCP Server Error] Error getting/listing packages for project ${proj.name}:`,
|
|
68
|
-
{ error: projectError },
|
|
69
|
-
);
|
|
70
|
-
return []; // Return empty array for this project on error
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
const results = await Promise.allSettled(packagePromises);
|
|
75
|
-
const allPackagesWithProjectName = results
|
|
76
|
-
.filter((result) => result.status === "fulfilled")
|
|
77
|
-
// Use the specific interface instead of any[]
|
|
78
|
-
.flatMap(
|
|
79
|
-
(result) =>
|
|
80
|
-
(result as PromiseFulfilledResult<PackageWithProject[]>)
|
|
81
|
-
.value,
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
logger.info(
|
|
85
|
-
`[MCP LOG] Total packages found across all projects: ${allPackagesWithProjectName.length}`,
|
|
86
|
-
);
|
|
87
|
-
|
|
88
|
-
const packageMetadata = RESOURCE_METADATA.package;
|
|
89
|
-
const mappedResources = allPackagesWithProjectName.map((pkg) => {
|
|
90
|
-
const name = pkg.name || "unknown";
|
|
91
|
-
// Construct URI using the package's specific projectName
|
|
92
|
-
const uri = `malloy://project/${pkg.projectName}/package/${name}`;
|
|
93
|
-
return {
|
|
94
|
-
uri: uri,
|
|
95
|
-
name: name,
|
|
96
|
-
type: "package",
|
|
97
|
-
description: packageMetadata?.description as
|
|
98
|
-
| string
|
|
99
|
-
| undefined,
|
|
100
|
-
metadata: packageMetadata,
|
|
101
|
-
};
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
logger.info(
|
|
105
|
-
`[MCP LOG] ListResources (project): Returning ${mappedResources.length} package resources.`,
|
|
106
|
-
);
|
|
107
|
-
return {
|
|
108
|
-
resources: mappedResources,
|
|
109
|
-
};
|
|
110
|
-
} catch (error) {
|
|
111
|
-
// Catch errors from projectStore.listProjects() itself
|
|
112
|
-
logger.error(`[MCP Server Error] Error listing projects:`, {
|
|
113
|
-
error,
|
|
114
|
-
});
|
|
115
|
-
const errorDetails = getInternalError(
|
|
116
|
-
`ListResources (project - initial list)`,
|
|
117
|
-
error,
|
|
118
|
-
);
|
|
119
|
-
logger.error("MCP ListResources (project) error:", {
|
|
120
|
-
error: errorDetails.message,
|
|
121
|
-
});
|
|
122
|
-
logger.info(
|
|
123
|
-
"[MCP LOG] ListResources (project): Returning empty on error listing projects.",
|
|
124
|
-
);
|
|
125
|
-
return { resources: [] };
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
|
-
}),
|
|
129
|
-
/** Handles GetResource requests for Malloy Projects */
|
|
130
|
-
(uri, params) =>
|
|
131
|
-
handleResourceGet(
|
|
132
|
-
uri,
|
|
133
|
-
params,
|
|
134
|
-
"project",
|
|
135
|
-
async ({ projectName }: { projectName?: unknown }) => {
|
|
136
|
-
logger.info(
|
|
137
|
-
`[MCP LOG] Entering GetResource (project) handler for projectName: ${projectName}`,
|
|
138
|
-
);
|
|
139
|
-
// Validate project name parameter
|
|
140
|
-
if (typeof projectName !== "string") {
|
|
141
|
-
logger.error(
|
|
142
|
-
"[MCP LOG] GetResource (project): Invalid project name param.",
|
|
143
|
-
);
|
|
144
|
-
throw new Error("Invalid project name parameter.");
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
try {
|
|
148
|
-
logger.info(
|
|
149
|
-
`[MCP LOG] GetResource: Getting project '${projectName}'...`,
|
|
150
|
-
);
|
|
151
|
-
// Get the project instance, but we might not need its metadata directly
|
|
152
|
-
await projectStore.getProject(projectName, false);
|
|
153
|
-
// Construct the definition object expected by the test
|
|
154
|
-
const definition = { name: projectName };
|
|
155
|
-
logger.info(
|
|
156
|
-
`[MCP LOG] GetResource (project): Returning definition for '${projectName}'.`,
|
|
157
|
-
);
|
|
158
|
-
// Return the explicit definition structure
|
|
159
|
-
return definition;
|
|
160
|
-
} catch (error) {
|
|
161
|
-
logger.error(
|
|
162
|
-
`[MCP LOG] GetResource (project): Error caught for '${projectName}':`,
|
|
163
|
-
{ error },
|
|
164
|
-
);
|
|
165
|
-
// Catch expected errors from this specific resource logic
|
|
166
|
-
if (error instanceof Error) {
|
|
167
|
-
// Use getNotFoundError for the specific project not found case
|
|
168
|
-
// or a generic message for the invalid param case.
|
|
169
|
-
const errorDetails = getNotFoundError(
|
|
170
|
-
error.message.includes("not found")
|
|
171
|
-
? `Project '${projectName}'` // More specific context
|
|
172
|
-
: `Invalid project identifier provided for URI ${uri.href}`, // Generic but informative
|
|
173
|
-
);
|
|
174
|
-
// Re-throw structured error for handleResourceGet to catch
|
|
175
|
-
throw new McpGetResourceError(errorDetails);
|
|
176
|
-
}
|
|
177
|
-
// Re-throw unexpected errors to be caught by handleResourceGet's generic handler
|
|
178
|
-
throw error;
|
|
179
|
-
}
|
|
180
|
-
},
|
|
181
|
-
RESOURCE_METADATA.project,
|
|
182
|
-
),
|
|
183
|
-
);
|
|
184
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { ProjectNotFoundError } from "../errors";
|
|
2
|
-
import { ResourceRepository } from "../storage/DatabaseInterface";
|
|
3
|
-
|
|
4
|
-
export async function resolveProjectId(
|
|
5
|
-
repository: ResourceRepository,
|
|
6
|
-
projectName: string,
|
|
7
|
-
): Promise<string> {
|
|
8
|
-
const dbProject = await repository.getProjectByName(projectName);
|
|
9
|
-
if (!dbProject) {
|
|
10
|
-
throw new ProjectNotFoundError(`Project '${projectName}' not found`);
|
|
11
|
-
}
|
|
12
|
-
return dbProject.id;
|
|
13
|
-
}
|