ec.fdk 0.8.5 → 0.8.7
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/README.md +24 -10
- package/dist/cli.cjs +27 -12
- package/dist/mcp.cjs +4 -0
- package/package.json +11 -6
package/README.md
CHANGED
|
@@ -105,15 +105,18 @@ ec.fdk <command> [options]
|
|
|
105
105
|
|
|
106
106
|
### Commands
|
|
107
107
|
|
|
108
|
-
| Command
|
|
109
|
-
|
|
|
110
|
-
| `login`
|
|
111
|
-
| `
|
|
112
|
-
| `
|
|
113
|
-
| `
|
|
114
|
-
| `
|
|
115
|
-
| `
|
|
116
|
-
| `
|
|
108
|
+
| Command | Description |
|
|
109
|
+
| ---------------- | ---------------------------------------------- |
|
|
110
|
+
| `login` | Login with ec credentials (interactive prompt) |
|
|
111
|
+
| `dmList` | List datamanagers |
|
|
112
|
+
| `modelList` | List models of a datamanager |
|
|
113
|
+
| `getDatamanager` | Get a single datamanager |
|
|
114
|
+
| `entryList` | List entries |
|
|
115
|
+
| `getEntry` | Get a single entry |
|
|
116
|
+
| `createEntry` | Create an entry |
|
|
117
|
+
| `editEntry` | Edit an entry |
|
|
118
|
+
| `deleteEntry` | Delete an entry |
|
|
119
|
+
| `getSchema` | Get model schema |
|
|
117
120
|
|
|
118
121
|
### Options
|
|
119
122
|
|
|
@@ -122,12 +125,14 @@ ec.fdk <command> [options]
|
|
|
122
125
|
| `-e, --env <env>` | Environment: `stage` \| `live` (default: `stage`) |
|
|
123
126
|
| `-d, --dm <shortID>` | DataManager short ID |
|
|
124
127
|
| `-m, --model <name>` | Model name |
|
|
125
|
-
| `-i, --id <id>` | Entry ID (
|
|
128
|
+
| `-i, --id <id>` | Entry ID or DataManager UUID (context-dependent) |
|
|
126
129
|
| `--data <json>` | JSON data (for create/edit) |
|
|
127
130
|
| `-s, --size <n>` | Page size for list |
|
|
128
131
|
| `-p, --page <n>` | Page number for list |
|
|
129
132
|
| `--sort <field>` | Sort field for list |
|
|
130
133
|
| `--raw` | Include `_links` and `_embedded` in output |
|
|
134
|
+
| `--md` | Output entries as readable markdown table |
|
|
135
|
+
| `-v, --version` | Show version |
|
|
131
136
|
| `-h, --help` | Show help |
|
|
132
137
|
|
|
133
138
|
### Examples
|
|
@@ -136,6 +141,15 @@ ec.fdk <command> [options]
|
|
|
136
141
|
# Login to stage (stores token in ~/.ec-fdk/auth.json)
|
|
137
142
|
ec.fdk login -e stage
|
|
138
143
|
|
|
144
|
+
# List datamanagers
|
|
145
|
+
ec.fdk dmList -e stage
|
|
146
|
+
|
|
147
|
+
# Get a single datamanager
|
|
148
|
+
ec.fdk getDatamanager -e stage --id 73538731-4ac3-4a1a-b3b5-e31d09e94d42
|
|
149
|
+
|
|
150
|
+
# List models of a datamanager
|
|
151
|
+
ec.fdk modelList -e stage --id 73538731-4ac3-4a1a-b3b5-e31d09e94d42
|
|
152
|
+
|
|
139
153
|
# List entries
|
|
140
154
|
ec.fdk entryList -d 83cc6374 -m muffin
|
|
141
155
|
|
package/dist/cli.cjs
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";const
|
|
2
|
+
"use strict";const W=require("node:util"),X=require("node:module"),w=require("node:fs"),M=require("node:path"),Y=require("node:os"),Q=require("node:readline");async function f(t,e={},n={}){const{token:s,rawRes:r}=e;s&&(n.headers={...n.headers||{},Authorization:`Bearer ${s}`});const i=await fetch(t,n);if(!i.ok){if(i.headers.get("content-type")?.includes("application/json")){const o=await i.json(),a=`${o.title}
|
|
3
3
|
${o.detail}
|
|
4
|
-
${o.verbose}`;throw new Error(a)}throw new Error(`unexpected fetch error: ${i.statusText}`)}return r?i:await i.json()}const E={datamanager:{live:"https://datamanager.entrecode.de/",stage:"https://datamanager.cachena.entrecode.de/"},accounts:{live:"https://accounts.entrecode.de/",stage:"https://accounts.cachena.entrecode.de/"},appserver:{live:"https://appserver.entrecode.de/",stage:"https://appserver.cachena.entrecode.de/"},"dm-history":{live:"https://dm-history.entrecode.de/",stage:"https://dm-history.cachena.entrecode.de/"}};function g(n,t="stage",e="datamanager"){const s=E[e];if(!s)throw new Error(`subdomain "${e}" not found. Try one of ${Object.keys(E).join(", ")}`);const r=s[t];if(!r)throw new Error(`env "${t}" not found. Try one of ${Object.keys(s[t]).join(", ")}`);return r+n}function m(n,t=!0){return Object.entries(n).sort((e,s)=>e[0].localeCompare(s[0])).map(([e,s])=>`${e}=${s}`).join("&")}function l(n){Object.entries(n).forEach(([t,e])=>{if(e===void 0)throw new Error(`expected ${t} to be set!`)})}const B={stage:"https://accounts.cachena.entrecode.de/",live:"https://accounts.entrecode.de/"};async function K(n){let{env:t,dmShortID:e,email:s,password:r}=n;l({env:t,dmShortID:e,email:s,password:r});const i=g(`api/${e}/_auth/login?clientID=rest`,t);return await h(i,{},{method:"POST",body:JSON.stringify({email:s,password:r}),headers:{"Content-Type":"application/json"}})}async function V(n){let{env:t,email:e,password:s}=n;l({env:t,email:e,password:s});const r=`${B[t]}auth/login?clientID=rest`;return await h(r,{},{method:"POST",body:JSON.stringify({email:e,password:s}),headers:{"Content-Type":"application/json"}})}async function G(n){let{dmShortID:t,env:e,token:s}=n;l({dmShortID:t,env:e,token:s});const r=g(`api/${t}/_auth/logout?clientID=rest&token=${s}`,e);return await h(r,{rawRes:!0},{method:"POST"})}async function H(n){let{env:t,token:e}=n;l({env:t,token:e});const s=`${B[t]}auth/logout?clientID=rest`;return await h(s,{rawRes:!0,token:e},{method:"POST"})}function Y({dmShortID:n}){return l({dmShortID:n}),n}function Q({env:n}){return l({env:n}),n}let W=["created","creator","id","modified","private","_created","_creator","_embedded","_entryTitle","_id","_links","_modelTitle","_modelTitleField","_modified"];function N(n){let t={};for(let e in n)W.includes(e)||(t[e]=n[e]);return t}function X(n){return JSON.parse(JSON.stringify(n))}async function Z(n){let{env:t,dmShortID:e}=n;l({env:t,dmShortID:e});const s=g(`api/${e}`,t);return h(s,n)}async function J(n){let{env:t,dmShortID:e,model:s,options:r={}}=n;l({env:t,dmShortID:e,model:s}),r={size:50,page:1,_list:!0,...r};const i=m(r),o=g(`api/${e}/${s}?${i}`,t),{count:a,total:c,_embedded:u}=await h(o,n);let d=u?u[`${e}:${s}`]:[];return d=Array.isArray(d)?d:[d],{count:a,total:c,items:d}}function tt({env:n,dmShortID:t,model:e,entryID:s,token:r}){l({env:n,dmShortID:t,model:e,entryID:s});const i=m({_id:s}),o=g(`api/${t}/${e}?${i}`,n);return h(o,{token:r})}async function et({env:n,dmShortID:t,model:e,value:s,token:r}){l({env:n,dmShortID:t,model:e,value:s});const i=g(`api/${t}/${e}`,n);return await h(i,{token:r},{method:"POST",body:JSON.stringify(s),headers:{"Content-Type":"application/json"}})}async function x({env:n,dmShortID:t,model:e,entryID:s,value:r,token:i,safePut:o=!1}){l({env:n,dmShortID:t,model:e,entryID:s,value:r});const a={"Content-Type":"application/json"};if(o){if(!("_modified"in r))throw new Error("expected _modified to be set!");a["If-Unmodified-Since"]=new Date(r._modified).toUTCString()}const c=g(`api/${t}/${e}?_id=${s}`,n);return r=X(r),r=N(r),await h(c,{token:i},{method:"PUT",headers:a,body:JSON.stringify(r)})}function C({env:n,dmShortID:t,model:e,entryID:s,token:r}){l({env:n,dmShortID:t,model:e,entryID:s});const i=g(`api/${t}/${e}?_id=${s}`,n);return h(i,{token:r,rawRes:!0},{method:"DELETE",headers:{"Content-Type":"application/json"}})}async function nt(n,t){let{env:e,dmShortID:s,model:r,options:i={}}=n;l({env:e,dmShortID:s,model:r}),n.options={size:50,page:1,_list:!0,...i};let o=0,a,c=[];for(;a===void 0||o<a;){const u=await J(n);for(let d of u.items)c.push(await t(d));o+=u.items.length,a=u.total,n.options.page++}return c}async function st({env:n,dmShortID:t,model:e,withMetadata:s}){l({env:n,dmShortID:t,model:e});const r=g(`api/schema/${t}/${e}`,n),i=await h(r),o=i?.allOf?.[1];if(typeof o.properties!="object")throw new Error(`getSchema: ${r} returned unexpected format: ${JSON.stringify(i)}`);const{properties:a}=o,c=N(a);for(let u in c){let d=c[u];if(d.required=o.required.includes(u),c[u]?.oneOf&&delete c[u]?.oneOf,d.title?.includes("<")&&d.title?.includes(">")){const f=d.title.split("<")[1].slice(0,-1),y=d.title.split("<")[0];d.type=y,f.includes(":")?d.resource=f.split(":")[1]:d.resource=f}else["asset","entry","assets","entries"].includes(d.title)?(d.type=d.title,d.resource=null):d.type=d.title;delete c[u].title}if(s){const u=a._modelTitle.title,d=a._modelTitleField.title;return{properties:c,meta:{modelTitleField:d,modelTitle:u}}}return c}function I(n){return Object.entries(n).map(([t,e])=>typeof e!="object"?{[t]:String(e)}:{...e.sort&&{sort:Array.isArray(e)?e.join(","):e},...e.search&&{[t+"~"]:e.search},...e.notNull&&{[t+"!"]:""},...e.null&&{[t]:""},...e.any&&{[t]:e.any.join(",")},...e.from&&{[t+"From"]:e.from},...e.to&&{[t+"To"]:e.to}}).reduce((t,e)=>({...t,...e}),{})}const rt=I;function S(n){return n._links.collection.href.split("/").slice(-2)[0]}function z(n){const t=n._links.collection.href.split("api/")[0];return Object.keys(E.datamanager).find(s=>E.datamanager[s]===t)}const F=n=>{const t=S(n),e=z(n),s=n._modelTitle,r=n.id;return{dmShortID:t,env:e,model:s,entryID:r}},it=n=>C(F(n)),ot=(n,t)=>x({...F(n),value:t});function at(n,t){const e=S(t);return t._embedded[`${e}:${t._modelTitle}/${n}/asset`]}async function ct({env:n,dmShortID:t,assetGroup:e,assetID:s,token:r}){l({env:n,dmShortID:t,assetGroup:e,assetID:s});const i=m({assetID:s}),o=g(`a/${t}/${e}?${i}`,n),{_embedded:a}=await h(o,{token:r});return a?a["ec:dm-asset"]:void 0}async function dt(n){let{env:t,dmShortID:e,assetGroup:s,token:r,options:i={}}=n;l({env:t,dmShortID:e,assetGroup:s}),i={size:50,page:1,_list:!0,...i};const o=m(i),a=g(`a/${e}/${s}?${o}`,t),{count:c,total:u,_embedded:d}=await h(a,{token:r});let f=d?d["ec:dm-asset"]:[];return f=Array.isArray(f)?f:[f],{count:c,total:u,items:f}}async function ut({env:n,dmShortID:t,assetGroup:e,token:s,file:r,name:i,options:o}){l({env:n,dmShortID:t,assetGroup:e,file:r});const a=g(`a/${t}/${e}`,n),c=new FormData;return c.append("file",r,i),o&&Object.keys(o).forEach(d=>{c.append(d,o[d])}),(await h(a,{token:s},{method:"POST",body:c}))._embedded["ec:dm-asset"]}async function lt({env:n,dmShortID:t,assetGroup:e,files:s,options:r}){l({env:n,dmShortID:t,assetGroup:e,files:s});const i=g(`a/${t}/${e}`,n),o=new FormData;s.forEach(c=>{o.append("file",c)}),r&&Object.keys(r).forEach(c=>{o.append(c,r[c])});const a=await h(i,{},{method:"POST",body:o});return Array.isArray(a._embedded["ec:dm-asset"])?a._embedded["ec:dm-asset"]:[a._embedded["ec:dm-asset"]]}async function ht({env:n,dmShortID:t,assetGroup:e,assetID:s,token:r}){l({env:n,dmShortID:t,assetGroup:e,assetID:s});const i=g(`a/${t}/${e}/${s}`,n);await h(i,{token:r,rawRes:!0},{method:"DELETE"})}function gt(n,t,e=!1){let s,r;return(e?n?.thumbnails:n?.fileVariants)?.forEach(o=>{const{resolution:{width:a,height:c}}=o,u=Math.abs(Math.max(a,c)-t);(!r||u<r)&&(r=u,s=o)}),s?.url??n?.file?.url??null}function ft(n="stage",t,e,s,r=!1){const i=Math.max(s.file.resolution.width,s.file.resolution.height),o=e.filter(c=>c<i),a=`https://datamanager${n==="stage"?".cachena":""}.entrecode.de`;return r?o.map(c=>{const u=s.thumbnails.find(y=>c===y.dimension),d=`${a}/t/${t}/${s.assetID}/${c}`,f=u?u.url:d;return{size:c,url:f,generated:u}}):o.map(c=>{const u=s.fileVariants.find(y=>c===Math.max(y.resolution.width,y.resolution.height)),d=`${a}/f/${t}/${s.assetID}/${c}`,f=u?u.url:d;return{size:c,url:f,generated:u}})}async function pt(n){let{env:t,dmID:e,token:s}=n;l({env:t,dmID:e});const r=g(`?dataManagerID=${e}`,t);return h(r,{token:s})}async function mt(n){let{env:t,options:e={}}=n;l({env:t}),e={size:25,page:1,_list:!0,...e};const s=m(e),r=g(`?${s}`,t),{count:i,total:o,_embedded:a}=await h(r,n);let c=a?a["ec:datamanager"]:[];return c=Array.isArray(c)?c:[c],{count:i,total:o,items:c}}async function yt(n){let{env:t,dmID:e,options:s={}}=n;l({env:t,dmID:e}),s={size:25,dataManagerID:e,page:1,_list:!0,...s};const r=m(s),i=g(`model?${r}`,t),{count:o,total:a,_embedded:c}=await h(i,n);let u=c?c["ec:model"]:[];return u=Array.isArray(u)?u:[u],{count:o,total:a,items:u}}async function wt(n){let{env:t,resource:e,options:s={},subdomain:r="datamanager"}=n;l({env:t,subdomain:r,resource:e}),s={size:25,page:1,_list:!0,...s};const i=m(s),o=g(`${e}?${i}`,t,r),{count:a,total:c,_embedded:u}=await h(o,n);let d=u?u[Object.keys(u)[0]]:[];return d=Array.isArray(d)?d:[d],{count:a,total:c,items:d}}async function $t(n,t={}){let{env:e,route:s,options:r={},subdomain:i="datamanager"}=n;l({env:e,subdomain:i,route:s}),r={...r};const o=m(r),a=g(`${s}?${o}`,e,i);return h(a,n,t)}const bt=Object.freeze(Object.defineProperty({__proto__:null,assetList:dt,createAsset:ut,createAssets:lt,createEntry:et,deleteAsset:ht,deleteEntry:C,deleteEntryObject:it,dmList:mt,editEntry:x,editEntryObject:ot,entryList:J,fileVariant:gt,filterOptions:rt,getAsset:ct,getDatamanager:pt,getEcAuthKey:Q,getEntry:tt,getEntryAsset:at,getEntryEnv:z,getEntryShortID:S,getFileVariants:ft,getPublicAuthKey:Y,getSchema:st,loginEc:V,loginPublic:K,logoutEc:H,logoutPublic:G,mapEntries:nt,modelList:yt,publicApi:Z,raw:$t,resourceList:wt,sdkOptions:I},Symbol.toStringTag,{value:"Module"})),{entryList:v,mapEntries:Et,getEntry:kt,getAsset:Tt,assetList:O,createAsset:At,createAssets:St,deleteAsset:_t,createEntry:vt,editEntry:P,deleteEntry:Ot,getSchema:Pt,loginPublic:jt,loginEc:Lt,logoutEc:Dt,logoutPublic:qt,getEcAuthKey:$,getPublicAuthKey:b,dmList:Bt,modelList:Nt,publicApi:Jt,getDatamanager:xt,resourceList:Ct,raw:It}=bt;function j(n){if(!n||typeof n!="object")return n;const{_links:t,_embedded:e,...s}=n;return s}function zt(n){return!n||typeof n!="object"?n:Array.isArray(n.items)?{...n,items:n.items.map(j)}:j(n)}class _{constructor(t={}){if(!t.storageAdapter){let e=new Map;t.storageAdapter={get:s=>e.get(s),set:(s,r)=>e.set(s,r),remove:s=>e.delete(s)}}this.config=t}set(t){return new _({...this.config,...t})}async entries(t={}){const e=await this.getBestToken();return v({...this.config,options:t,token:e})}async entryList(t){const e=await this.getBestToken();return v({...this.config,options:t,token:e}).then(s=>this.maybeClean(s))}async mapEntries(t,e={}){const s=await this.getBestToken();return Et({...this.config,options:e,token:s},t)}async getEntry(t){const e=await this.getBestToken();return kt({...this.config,entryID:t,token:e}).then(s=>this.maybeClean(s))}async editEntrySafe(t,e){const s=await this.getBestToken();return P({...this.config,entryID:t,token:s,value:e,safePut:!0}).then(r=>this.maybeClean(r))}async getSchema(){return Pt(this.config)}async assets(t){const e=await this.getBestToken();return O({...this.config,options:t,token:e})}async assetList(t){const e=await this.getBestToken();return O({...this.config,options:t,token:e})}async createAsset(t){const{file:e,name:s,options:r}=t,i=await this.getBestToken();return At({...this.config,file:e,name:s,options:r,token:i})}async createAssets(t){const{files:e,options:s}=t,r=await this.getBestToken();return St({...this.config,files:e,options:s,token:r})}async deleteAsset(t){const e=await this.getBestToken();return _t({...this.config,token:e,assetID:t})}async getAsset(t){const e=await this.getBestToken();return Tt({...this.config,assetID:t,token:e})}async createEntry(t){const e=await this.getBestToken();return vt({...this.config,token:e,value:t}).then(s=>this.maybeClean(s))}async editEntry(t,e){const s=await this.getBestToken();return P({...this.config,entryID:t,token:s,value:e}).then(r=>this.maybeClean(r))}async deleteEntry(t){const e=await this.getBestToken();return Ot({...this.config,token:e,entryID:t})}async resourceList(t){const e=await this.getBestToken();return Ct({...this.config,options:t,token:e})}async raw(t,e){const s=await this.getBestToken();return It({...this.config,options:t,token:s},e)}storageAdapter(t){return this.set({storageAdapter:t})}removeToken(t){if(!this.config.storageAdapter)throw new Error("cannot removeToken: no storageAdapter defined!");const{remove:e}=this.config.storageAdapter;e(t)}getToken(t){if(!this.config.storageAdapter)throw new Error("cannot getAuth: no storageAdapter defined!");const{get:e}=this.config.storageAdapter;return e(t)}getPublicToken(){return this.config.token||this.getToken(b(this.config))}getEcToken(){return this.config.token||this.getToken($(this.config))}setToken(t,e){if(!this.config.storageAdapter)throw new Error("cannot setEcToken: no storageAdapter defined!");return this.config.storageAdapter.set(t,e)}setEcToken(t){this.setToken($(this.config),t)}setPublicToken(t){this.setToken(b(this.config),t)}loginEc(t){return Lt({...this.config,...t}).then(e=>this.setToken($(this.config),e.token))}loginPublic(t){return jt({...this.config,...t}).then(e=>this.setToken(b(this.config),e.token))}logoutPublic(){const t=this.getPublicToken();return qt({...this.config,token:t}).then(()=>this.removeToken(b(this.config)))}logoutEc(){const t=this.getEcToken();return Dt({...this.config,token:t}).then(()=>this.removeToken($(this.config)))}hasPublicToken(){return!!this.getPublicToken()}hasEcToken(){return!!this.getEcToken()}hasAnyToken(){return!!this.getEcToken()||!!this.getPublicToken()}getBestToken(){try{return this.getEcToken()||this.getPublicToken()}catch{return}}clean(t=!0){return this.set({_clean:t})}maybeClean(t){return this.config._clean?zt(t):t}model(t){return this.set({model:t})}token(t){return this.set({token:t})}dmShortID(t){return this.set({dmShortID:t})}dm(t){return this.dmShortID(t)}dmID(t){return this.set({dmID:t})}assetGroup(t){return this.set({assetGroup:t})}assetgroup(t){return this.assetGroup(t)}subdomain(t){return this.set({subdomain:t})}resource(t){return this.set({resource:t})}route(t){return this.set({route:t})}publicApi(){return Jt(this.config)}async getDatamanager(t){const e=await this.getBestToken();return xt({...this.config,dmID:t,token:e})}async dmList(t={}){const e=await this.getBestToken();return Bt({...this.config,options:t,token:e})}async modelList(t={}){const e=await this.getBestToken();return Nt({...this.config,options:t,token:e})}}const T=q.join(R.homedir(),".ec-fdk"),A=q.join(T,"auth.json");function k(){try{return w.existsSync(A)?JSON.parse(w.readFileSync(A,"utf-8")):{}}catch{return{}}}function L(n){w.existsSync(T)||w.mkdirSync(T,{recursive:!0,mode:448}),w.writeFileSync(A,JSON.stringify(n,null,2),{mode:384})}const Ft={get(n){return k()[n]},set(n,t){const e=k();e[n]=t,L(e)},remove(n){const t=k();delete t[n],L(t)}};function Mt(n){const t=U.createInterface({input:process.stdin,output:process.stderr});return new Promise(e=>{t.question(n,s=>{t.close(),e(s)})})}function Rt(n){return new Promise(t=>{process.stderr.write(n);const e=process.stdin;e.setRawMode(!0),e.resume(),e.setEncoding("utf-8");let s="";const r=i=>{if(i===""&&(process.stderr.write(`
|
|
4
|
+
${o.verbose}`;throw new Error(a)}throw new Error(`unexpected fetch error: ${i.statusText}`)}return r?i:await i.json()}const k={datamanager:{live:"https://datamanager.entrecode.de/",stage:"https://datamanager.cachena.entrecode.de/"},accounts:{live:"https://accounts.entrecode.de/",stage:"https://accounts.cachena.entrecode.de/"},appserver:{live:"https://appserver.entrecode.de/",stage:"https://appserver.cachena.entrecode.de/"},"dm-history":{live:"https://dm-history.entrecode.de/",stage:"https://dm-history.cachena.entrecode.de/"}};function g(t,e="stage",n="datamanager"){const s=k[n];if(!s)throw new Error(`subdomain "${n}" not found. Try one of ${Object.keys(k).join(", ")}`);const r=s[e];if(!r)throw new Error(`env "${e}" not found. Try one of ${Object.keys(s[e]).join(", ")}`);return r+t}function m(t,e=!0){return Object.entries(t).sort((n,s)=>n[0].localeCompare(s[0])).map(([n,s])=>`${n}=${s}`).join("&")}function l(t){Object.entries(t).forEach(([e,n])=>{if(n===void 0)throw new Error(`expected ${e} to be set!`)})}const U={stage:"https://accounts.cachena.entrecode.de/",live:"https://accounts.entrecode.de/"};async function Z(t){let{env:e,dmShortID:n,email:s,password:r}=t;l({env:e,dmShortID:n,email:s,password:r});const i=g(`api/${n}/_auth/login?clientID=rest`,e);return await f(i,{},{method:"POST",body:JSON.stringify({email:s,password:r}),headers:{"Content-Type":"application/json"}})}async function ee(t){let{env:e,email:n,password:s}=t;l({env:e,email:n,password:s});const r=`${U[e]}auth/login?clientID=rest`;return await f(r,{},{method:"POST",body:JSON.stringify({email:n,password:s}),headers:{"Content-Type":"application/json"}})}async function te(t){let{dmShortID:e,env:n,token:s}=t;l({dmShortID:e,env:n,token:s});const r=g(`api/${e}/_auth/logout?clientID=rest&token=${s}`,n);return await f(r,{rawRes:!0},{method:"POST"})}async function ne(t){let{env:e,token:n}=t;l({env:e,token:n});const s=`${U[e]}auth/logout?clientID=rest`;return await f(s,{rawRes:!0,token:n},{method:"POST"})}function se({dmShortID:t}){return l({dmShortID:t}),t}function re({env:t}){return l({env:t}),t}let ie=["created","creator","id","modified","private","_created","_creator","_embedded","_entryTitle","_id","_links","_modelTitle","_modelTitleField","_modified"];function z(t){let e={};for(let n in t)ie.includes(n)||(e[n]=t[n]);return e}function oe(t){return JSON.parse(JSON.stringify(t))}async function ae(t){let{env:e,dmShortID:n}=t;l({env:e,dmShortID:n});const s=g(`api/${n}`,e);return f(s,t)}async function J(t){let{env:e,dmShortID:n,model:s,options:r={}}=t;l({env:e,dmShortID:n,model:s}),r={size:50,page:1,_list:!0,...r};const i=m(r),o=g(`api/${n}/${s}?${i}`,e),{count:a,total:c,_embedded:d}=await f(o,t);let u=d?d[`${n}:${s}`]:[];return u=Array.isArray(u)?u:[u],{count:a,total:c,items:u}}function ce({env:t,dmShortID:e,model:n,entryID:s,token:r}){l({env:t,dmShortID:e,model:n,entryID:s});const i=m({_id:s}),o=g(`api/${e}/${n}?${i}`,t);return f(o,{token:r})}async function de({env:t,dmShortID:e,model:n,value:s,token:r}){l({env:t,dmShortID:e,model:n,value:s});const i=g(`api/${e}/${n}`,t);return await f(i,{token:r},{method:"POST",body:JSON.stringify(s),headers:{"Content-Type":"application/json"}})}async function C({env:t,dmShortID:e,model:n,entryID:s,value:r,token:i,safePut:o=!1}){l({env:t,dmShortID:e,model:n,entryID:s,value:r});const a={"Content-Type":"application/json"};if(o){if(!("_modified"in r))throw new Error("expected _modified to be set!");a["If-Unmodified-Since"]=new Date(r._modified).toUTCString()}const c=g(`api/${e}/${n}?_id=${s}`,t);return r=oe(r),r=z(r),await f(c,{token:i},{method:"PUT",headers:a,body:JSON.stringify(r)})}function R({env:t,dmShortID:e,model:n,entryID:s,token:r}){l({env:t,dmShortID:e,model:n,entryID:s});const i=g(`api/${e}/${n}?_id=${s}`,t);return f(i,{token:r,rawRes:!0},{method:"DELETE",headers:{"Content-Type":"application/json"}})}async function ue(t,e){let{env:n,dmShortID:s,model:r,options:i={}}=t;l({env:n,dmShortID:s,model:r}),t.options={size:50,page:1,_list:!0,...i};let o=0,a,c=[];for(;a===void 0||o<a;){const d=await J(t);for(let u of d.items)c.push(await e(u));o+=d.items.length,a=d.total,t.options.page++}return c}async function le({env:t,dmShortID:e,model:n,withMetadata:s}){l({env:t,dmShortID:e,model:n});const r=g(`api/schema/${e}/${n}`,t),i=await f(r),o=i?.allOf?.[1];if(typeof o.properties!="object")throw new Error(`getSchema: ${r} returned unexpected format: ${JSON.stringify(i)}`);const{properties:a}=o,c=z(a);for(let d in c){let u=c[d];if(u.required=o.required.includes(d),c[d]?.oneOf&&delete c[d]?.oneOf,u.title?.includes("<")&&u.title?.includes(">")){const h=u.title.split("<")[1].slice(0,-1),y=u.title.split("<")[0];u.type=y,h.includes(":")?u.resource=h.split(":")[1]:u.resource=h}else["asset","entry","assets","entries"].includes(u.title)?(u.type=u.title,u.resource=null):u.type=u.title;delete c[d].title}if(s){const d=a._modelTitle.title,u=a._modelTitleField.title;return{properties:c,meta:{modelTitleField:u,modelTitle:d}}}return c}function F(t){return Object.entries(t).map(([e,n])=>typeof n!="object"?{[e]:String(n)}:{...n.sort&&{sort:Array.isArray(n)?n.join(","):n},...n.search&&{[e+"~"]:n.search},...n.notNull&&{[e+"!"]:""},...n.null&&{[e]:""},...n.any&&{[e]:n.any.join(",")},...n.from&&{[e+"From"]:n.from},...n.to&&{[e+"To"]:n.to}}).reduce((e,n)=>({...e,...n}),{})}const fe=F;function v(t){return t._links.collection.href.split("/").slice(-2)[0]}function K(t){const e=t._links.collection.href.split("api/")[0];return Object.keys(k.datamanager).find(s=>k.datamanager[s]===e)}const V=t=>{const e=v(t),n=K(t),s=t._modelTitle,r=t.id;return{dmShortID:e,env:n,model:s,entryID:r}},ge=t=>R(V(t)),he=(t,e)=>C({...V(t),value:e});function pe(t,e){const n=v(e);return e._embedded[`${n}:${e._modelTitle}/${t}/asset`]}async function me({env:t,dmShortID:e,assetGroup:n,assetID:s,token:r}){l({env:t,dmShortID:e,assetGroup:n,assetID:s});const i=m({assetID:s}),o=g(`a/${e}/${n}?${i}`,t),{_embedded:a}=await f(o,{token:r});return a?a["ec:dm-asset"]:void 0}async function ye(t){let{env:e,dmShortID:n,assetGroup:s,token:r,options:i={}}=t;l({env:e,dmShortID:n,assetGroup:s}),i={size:50,page:1,_list:!0,...i};const o=m(i),a=g(`a/${n}/${s}?${o}`,e),{count:c,total:d,_embedded:u}=await f(a,{token:r});let h=u?u["ec:dm-asset"]:[];return h=Array.isArray(h)?h:[h],{count:c,total:d,items:h}}async function we({env:t,dmShortID:e,assetGroup:n,token:s,file:r,name:i,options:o}){l({env:t,dmShortID:e,assetGroup:n,file:r});const a=g(`a/${e}/${n}`,t),c=new FormData;return c.append("file",r,i),o&&Object.keys(o).forEach(u=>{c.append(u,o[u])}),(await f(a,{token:s},{method:"POST",body:c}))._embedded["ec:dm-asset"]}async function be({env:t,dmShortID:e,assetGroup:n,files:s,options:r}){l({env:t,dmShortID:e,assetGroup:n,files:s});const i=g(`a/${e}/${n}`,t),o=new FormData;s.forEach(c=>{o.append("file",c)}),r&&Object.keys(r).forEach(c=>{o.append(c,r[c])});const a=await f(i,{},{method:"POST",body:o});return Array.isArray(a._embedded["ec:dm-asset"])?a._embedded["ec:dm-asset"]:[a._embedded["ec:dm-asset"]]}async function $e({env:t,dmShortID:e,assetGroup:n,assetID:s,token:r}){l({env:t,dmShortID:e,assetGroup:n,assetID:s});const i=g(`a/${e}/${n}/${s}`,t);await f(i,{token:r,rawRes:!0},{method:"DELETE"})}function ke(t,e,n=!1){let s,r;return(n?t?.thumbnails:t?.fileVariants)?.forEach(o=>{const{resolution:{width:a,height:c}}=o,d=Math.abs(Math.max(a,c)-e);(!r||d<r)&&(r=d,s=o)}),s?.url??t?.file?.url??null}function Ee(t="stage",e,n,s,r=!1){const i=Math.max(s.file.resolution.width,s.file.resolution.height),o=n.filter(c=>c<i),a=`https://datamanager${t==="stage"?".cachena":""}.entrecode.de`;return r?o.map(c=>{const d=s.thumbnails.find(y=>c===y.dimension),u=`${a}/t/${e}/${s.assetID}/${c}`,h=d?d.url:u;return{size:c,url:h,generated:d}}):o.map(c=>{const d=s.fileVariants.find(y=>c===Math.max(y.resolution.width,y.resolution.height)),u=`${a}/f/${e}/${s.assetID}/${c}`,h=d?d.url:u;return{size:c,url:h,generated:d}})}async function Te(t){let{env:e,dmID:n,token:s}=t;l({env:e,dmID:n});const r=g(`?dataManagerID=${n}`,e);return f(r,{token:s})}async function Ae(t){let{env:e,options:n={}}=t;l({env:e}),n={size:25,page:1,_list:!0,...n};const s=m(n),r=g(`?${s}`,e),{count:i,total:o,_embedded:a}=await f(r,t);let c=a?a["ec:datamanager"]:[];return c=Array.isArray(c)?c:[c],{count:i,total:o,items:c}}async function _e(t){let{env:e,dmID:n,options:s={}}=t;l({env:e,dmID:n}),s={size:25,dataManagerID:n,page:1,_list:!0,...s};const r=m(s),i=g(`model?${r}`,e),{count:o,total:a,_embedded:c}=await f(i,t);let d=c?c["ec:model"]:[];return d=Array.isArray(d)?d:[d],{count:o,total:a,items:d}}async function Se(t){let{env:e,resource:n,options:s={},subdomain:r="datamanager"}=t;l({env:e,subdomain:r,resource:n}),s={size:25,page:1,_list:!0,...s};const i=m(s),o=g(`${n}?${i}`,e,r),{count:a,total:c,_embedded:d}=await f(o,t);let u=d?d[Object.keys(d)[0]]:[];return u=Array.isArray(u)?u:[u],{count:a,total:c,items:u}}async function ve(t,e={}){let{env:n,route:s,options:r={},subdomain:i="datamanager"}=t;l({env:n,subdomain:i,route:s}),r={...r};const o=m(r),a=g(`${s}?${o}`,n,i);return f(a,t,e)}const Le=Object.freeze(Object.defineProperty({__proto__:null,assetList:ye,createAsset:we,createAssets:be,createEntry:de,deleteAsset:$e,deleteEntry:R,deleteEntryObject:ge,dmList:Ae,editEntry:C,editEntryObject:he,entryList:J,fileVariant:ke,filterOptions:fe,getAsset:me,getDatamanager:Te,getEcAuthKey:re,getEntry:ce,getEntryAsset:pe,getEntryEnv:K,getEntryShortID:v,getFileVariants:Ee,getPublicAuthKey:se,getSchema:le,loginEc:ee,loginPublic:Z,logoutEc:ne,logoutPublic:te,mapEntries:ue,modelList:_e,publicApi:ae,raw:ve,resourceList:Se,sdkOptions:F},Symbol.toStringTag,{value:"Module"})),{entryList:j,mapEntries:je,getEntry:Oe,getAsset:Pe,assetList:O,createAsset:De,createAssets:qe,deleteAsset:Ne,createEntry:xe,editEntry:P,deleteEntry:Be,getSchema:Ie,loginPublic:Me,loginEc:Ue,logoutEc:ze,logoutPublic:Je,getEcAuthKey:b,getPublicAuthKey:$,dmList:Ce,modelList:Re,publicApi:Fe,getDatamanager:Ke,resourceList:Ve,raw:Ge}=Le;function D(t){if(!t||typeof t!="object")return t;const{_links:e,_embedded:n,...s}=t;return s}function He(t){return!t||typeof t!="object"?t:Array.isArray(t.items)?{...t,items:t.items.map(D)}:D(t)}class L{constructor(e={}){if(!e.storageAdapter){let n=new Map;e.storageAdapter={get:s=>n.get(s),set:(s,r)=>n.set(s,r),remove:s=>n.delete(s)}}this.config=e}set(e){return new L({...this.config,...e})}async entries(e={}){const n=await this.getBestToken();return j({...this.config,options:e,token:n})}async entryList(e){const n=await this.getBestToken();return j({...this.config,options:e,token:n}).then(s=>this.maybeClean(s))}async mapEntries(e,n={}){const s=await this.getBestToken();return je({...this.config,options:n,token:s},e)}async getEntry(e){const n=await this.getBestToken();return Oe({...this.config,entryID:e,token:n}).then(s=>this.maybeClean(s))}async editEntrySafe(e,n){const s=await this.getBestToken();return P({...this.config,entryID:e,token:s,value:n,safePut:!0}).then(r=>this.maybeClean(r))}async getSchema(){return Ie(this.config)}async assets(e){const n=await this.getBestToken();return O({...this.config,options:e,token:n})}async assetList(e){const n=await this.getBestToken();return O({...this.config,options:e,token:n})}async createAsset(e){const{file:n,name:s,options:r}=e,i=await this.getBestToken();return De({...this.config,file:n,name:s,options:r,token:i})}async createAssets(e){const{files:n,options:s}=e,r=await this.getBestToken();return qe({...this.config,files:n,options:s,token:r})}async deleteAsset(e){const n=await this.getBestToken();return Ne({...this.config,token:n,assetID:e})}async getAsset(e){const n=await this.getBestToken();return Pe({...this.config,assetID:e,token:n})}async createEntry(e){const n=await this.getBestToken();return xe({...this.config,token:n,value:e}).then(s=>this.maybeClean(s))}async editEntry(e,n){const s=await this.getBestToken();return P({...this.config,entryID:e,token:s,value:n}).then(r=>this.maybeClean(r))}async deleteEntry(e){const n=await this.getBestToken();return Be({...this.config,token:n,entryID:e})}async resourceList(e){const n=await this.getBestToken();return Ve({...this.config,options:e,token:n})}async raw(e,n){const s=await this.getBestToken();return Ge({...this.config,options:e,token:s},n)}storageAdapter(e){return this.set({storageAdapter:e})}removeToken(e){if(!this.config.storageAdapter)throw new Error("cannot removeToken: no storageAdapter defined!");const{remove:n}=this.config.storageAdapter;n(e)}getToken(e){if(!this.config.storageAdapter)throw new Error("cannot getAuth: no storageAdapter defined!");const{get:n}=this.config.storageAdapter;return n(e)}getPublicToken(){return this.config.token||this.getToken($(this.config))}getEcToken(){return this.config.token||this.getToken(b(this.config))}setToken(e,n){if(!this.config.storageAdapter)throw new Error("cannot setEcToken: no storageAdapter defined!");return this.config.storageAdapter.set(e,n)}setEcToken(e){this.setToken(b(this.config),e)}setPublicToken(e){this.setToken($(this.config),e)}loginEc(e){return Ue({...this.config,...e}).then(n=>this.setToken(b(this.config),n.token))}loginPublic(e){return Me({...this.config,...e}).then(n=>this.setToken($(this.config),n.token))}logoutPublic(){const e=this.getPublicToken();return Je({...this.config,token:e}).then(()=>this.removeToken($(this.config)))}logoutEc(){const e=this.getEcToken();return ze({...this.config,token:e}).then(()=>this.removeToken(b(this.config)))}hasPublicToken(){return!!this.getPublicToken()}hasEcToken(){return!!this.getEcToken()}hasAnyToken(){return!!this.getEcToken()||!!this.getPublicToken()}getBestToken(){try{return this.getEcToken()||this.getPublicToken()}catch{return}}clean(e=!0){return this.set({_clean:e})}maybeClean(e){return this.config._clean?He(e):e}model(e){return this.set({model:e})}token(e){return this.set({token:e})}dmShortID(e){return this.set({dmShortID:e})}dm(e){return this.dmShortID(e)}dmID(e){return this.set({dmID:e})}assetGroup(e){return this.set({assetGroup:e})}assetgroup(e){return this.assetGroup(e)}subdomain(e){return this.set({subdomain:e})}resource(e){return this.set({resource:e})}route(e){return this.set({route:e})}publicApi(){return Fe(this.config)}async getDatamanager(e){const n=await this.getBestToken();return Ke({...this.config,dmID:e,token:n})}async dmList(e={}){const n=await this.getBestToken();return Ce({...this.config,options:e,token:n})}async modelList(e={}){const n=await this.getBestToken();return Re({...this.config,options:e,token:n})}}const _=M.join(Y.homedir(),".ec-fdk"),S=M.join(_,"auth.json");function T(){try{return w.existsSync(S)?JSON.parse(w.readFileSync(S,"utf-8")):{}}catch{return{}}}function q(t){w.existsSync(_)||w.mkdirSync(_,{recursive:!0,mode:448}),w.writeFileSync(S,JSON.stringify(t,null,2),{mode:384})}const We={get(t){return T()[t]},set(t,e){const n=T();n[t]=e,q(n)},remove(t){const e=T();delete e[t],q(e)}};function Xe(t){const e=Q.createInterface({input:process.stdin,output:process.stderr});return new Promise(n=>{e.question(t,s=>{e.close(),n(s)})})}function Ye(t){return new Promise(e=>{process.stderr.write(t);const n=process.stdin;n.setRawMode(!0),n.resume(),n.setEncoding("utf-8");let s="";const r=i=>{if(i===""&&(process.stderr.write(`
|
|
5
5
|
`),process.exit(130)),i==="\r"||i===`
|
|
6
|
-
`){
|
|
7
|
-
`),
|
|
6
|
+
`){n.setRawMode(!1),n.pause(),n.removeListener("data",r),process.stderr.write(`
|
|
7
|
+
`),e(s);return}if(i===""||i==="\b"){s.length>0&&(s=s.slice(0,-1),process.stderr.write("\b \b"));return}s+=i,process.stderr.write("*")};n.on("data",r)})}const Qe=X.createRequire(typeof document>"u"?require("url").pathToFileURL(__filename).href:document.currentScript&&document.currentScript.src||new URL("cli.cjs",document.baseURI).href),{version:Ze}=Qe("../package.json"),et=`ec.fdk <command> [options]
|
|
8
8
|
|
|
9
9
|
Commands:
|
|
10
10
|
login Login with ec credentials (interactive prompt)
|
|
11
|
+
dmList List datamanagers
|
|
12
|
+
modelList List models of a datamanager
|
|
13
|
+
getDatamanager Get a single datamanager
|
|
11
14
|
entryList List entries
|
|
12
15
|
getEntry Get a single entry
|
|
13
16
|
createEntry Create an entry
|
|
@@ -19,16 +22,28 @@ Options:
|
|
|
19
22
|
-e, --env <env> Environment: stage|live (default: stage)
|
|
20
23
|
-d, --dm <shortID> DataManager short ID
|
|
21
24
|
-m, --model <name> Model name
|
|
22
|
-
-i, --id <
|
|
25
|
+
-i, --id <id> Entry ID or DataManager UUID (context-dependent)
|
|
23
26
|
--data <json> JSON data (for create/edit, or pipe via stdin)
|
|
24
27
|
-s, --size <n> Page size for list
|
|
25
28
|
-p, --page <n> Page number for list
|
|
26
29
|
--sort <field> Sort field for list
|
|
27
30
|
--raw Include _links and _embedded in output
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
`),process.exit(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
`),
|
|
31
|
+
--md Output entries as readable markdown
|
|
32
|
+
-v, --version Show version
|
|
33
|
+
-h, --help Show help`;function p(t){process.stderr.write(`Error: ${t}
|
|
34
|
+
`),process.exit(2)}function tt(){return new Promise(t=>{let e="";process.stdin.setEncoding("utf-8"),process.stdin.on("data",n=>e+=n),process.stdin.on("end",()=>t(e))})}async function N(t){if(t)try{return JSON.parse(t)}catch{p("--data must be valid JSON")}if(!process.stdin.isTTY){const e=await tt();e.trim()||p("No data provided via stdin");try{return JSON.parse(e)}catch{p("Stdin must be valid JSON")}}p("Provide --data or pipe JSON via stdin")}function x(t){if(!t||typeof t!="object")return t;const{_links:e,_embedded:n,...s}=t;return s}function A(t){return!t||typeof t!="object"?t:Array.isArray(t.items)?{...t,items:t.items.map(x)}:x(t)}const B=40;function I(t){return t.length>B?t.slice(0,B-2)+"..":t}function G(t){return t==null?"":I(typeof t=="object"?JSON.stringify(t):String(t))}function H(t){return Object.keys(t).filter(e=>!e.startsWith("_"))}function E(t,e){return"| "+t.map((n,s)=>n.padEnd(e[s])).join(" | ")+" |"}function nt(t){const e=H(t),n=e.map(d=>G(t[d])),s=Math.max(5,...e.map(d=>d.length)),r=Math.max(5,...n.map(d=>d.length)),i=[s,r],o=E(["Field","Value"],i),a="| "+i.map(d=>"-".repeat(d)).join(" | ")+" |",c=e.map((d,u)=>E([d,n[u]],i));return`${o}
|
|
35
|
+
${a}
|
|
36
|
+
${c.join(`
|
|
37
|
+
`)}`}function st(t){if(!t.items.length)return"No entries found.";const e=H(t.items[0]),n=t.items.map(a=>e.map(c=>G(a[c]))),s=e.map((a,c)=>Math.max(a.length,...n.map(d=>d[c].length))),r=E(e,s),i="| "+s.map(a=>"-".repeat(a)).join(" | ")+" |",o=n.map(a=>E(a,s));return`${r}
|
|
38
|
+
${i}
|
|
39
|
+
${o.join(`
|
|
40
|
+
`)}
|
|
41
|
+
|
|
42
|
+
${t.items.length} of ${t.total} entries`}async function rt(){const{values:t,positionals:e}=W.parseArgs({allowPositionals:!0,options:{env:{type:"string",short:"e",default:"stage"},dm:{type:"string",short:"d"},model:{type:"string",short:"m"},id:{type:"string",short:"i"},data:{type:"string"},size:{type:"string",short:"s"},page:{type:"string",short:"p"},sort:{type:"string"},raw:{type:"boolean",default:!1},md:{type:"boolean",default:!1},version:{type:"boolean",short:"v"},help:{type:"boolean",short:"h"}}});t.version&&(console.log(Ze),process.exit(0)),(t.help||e.length===0)&&(console.log(et),process.exit(0));const n=e[0],s=t.env;s!=="stage"&&s!=="live"&&p('--env must be "stage" or "live"');const r=new L({env:s,storageAdapter:We});if(n==="login"){const i=await Xe("Email: "),o=await Ye("Password: ");try{await r.loginEc({email:i,password:o}),process.stderr.write(`Logged in to ${s} successfully.
|
|
43
|
+
`)}catch(a){process.stderr.write(`Login failed: ${a.message}
|
|
44
|
+
`),process.exit(1)}return}try{let i;switch(n){case"dmList":{const o={};t.size&&(o.size=Number(t.size)),t.page&&(o.page=Number(t.page)),i=await r.dmList(o),t.raw||(i=A(i));break}case"modelList":{t.id||p("--id (datamanager UUID) is required for modelList");const o={};t.size&&(o.size=Number(t.size)),t.page&&(o.page=Number(t.page)),i=await r.dmID(t.id).modelList(o),t.raw||(i=A(i));break}case"getDatamanager":{t.id||p("--id (datamanager UUID) is required for getDatamanager"),i=await r.getDatamanager(t.id),t.raw||(i=A(i));break}case"entryList":case"getEntry":case"createEntry":case"editEntry":case"deleteEntry":case"getSchema":{t.dm||p("--dm is required"),t.model||p("--model is required");const o=r.dm(t.dm).model(t.model).clean(!t.raw);switch(n){case"entryList":{const a={};t.size&&(a.size=Number(t.size)),t.page&&(a.page=Number(t.page)),t.sort&&(a.sort=[t.sort]),i=await o.entryList(a);break}case"getEntry":{t.id||p("--id is required for getEntry"),i=await o.getEntry(t.id);break}case"createEntry":{const a=await N(t.data);i=await o.createEntry(a);break}case"editEntry":{t.id||p("--id is required for editEntry");const a=await N(t.data);i=await o.editEntry(t.id,a);break}case"deleteEntry":{t.id||p("--id is required for deleteEntry"),await o.deleteEntry(t.id),process.stderr.write(`Entry deleted.
|
|
45
|
+
`);return}case"getSchema":{i=await o.getSchema();break}}break}default:p(`Unknown command: ${n}`)}t.md&&i&&typeof i=="object"?Array.isArray(i.items)?process.stdout.write(st(i)+`
|
|
46
|
+
`):process.stdout.write(nt(i)+`
|
|
47
|
+
`):process.stdout.write(JSON.stringify(i,null,2)+`
|
|
48
|
+
`)}catch(i){process.stderr.write(`${i.message}
|
|
49
|
+
`),process.exit(1)}}rt();
|
package/dist/mcp.cjs
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";const K=require("@modelcontextprotocol/sdk/server/mcp.js"),V=require("@modelcontextprotocol/sdk/server/stdio.js"),u=require("zod"),$=require("node:fs"),M=require("node:path"),G=require("node:os");async function h(n,t={},e={}){const{token:s,rawRes:r}=t;s&&(e.headers={...e.headers||{},Authorization:`Bearer ${s}`});const i=await fetch(n,e);if(!i.ok){if(i.headers.get("content-type")?.includes("application/json")){const o=await i.json(),c=`${o.title}
|
|
3
|
+
${o.detail}
|
|
4
|
+
${o.verbose}`;throw new Error(c)}throw new Error(`unexpected fetch error: ${i.statusText}`)}return r?i:await i.json()}const T={datamanager:{live:"https://datamanager.entrecode.de/",stage:"https://datamanager.cachena.entrecode.de/"},accounts:{live:"https://accounts.entrecode.de/",stage:"https://accounts.cachena.entrecode.de/"},appserver:{live:"https://appserver.entrecode.de/",stage:"https://appserver.cachena.entrecode.de/"},"dm-history":{live:"https://dm-history.entrecode.de/",stage:"https://dm-history.cachena.entrecode.de/"}};function m(n,t="stage",e="datamanager"){const s=T[e];if(!s)throw new Error(`subdomain "${e}" not found. Try one of ${Object.keys(T).join(", ")}`);const r=s[t];if(!r)throw new Error(`env "${t}" not found. Try one of ${Object.keys(s[t]).join(", ")}`);return r+n}function b(n,t=!0){return Object.entries(n).sort((e,s)=>e[0].localeCompare(s[0])).map(([e,s])=>`${e}=${s}`).join("&")}function g(n){Object.entries(n).forEach(([t,e])=>{if(e===void 0)throw new Error(`expected ${t} to be set!`)})}const B={stage:"https://accounts.cachena.entrecode.de/",live:"https://accounts.entrecode.de/"};async function H(n){let{env:t,dmShortID:e,email:s,password:r}=n;g({env:t,dmShortID:e,email:s,password:r});const i=m(`api/${e}/_auth/login?clientID=rest`,t);return await h(i,{},{method:"POST",body:JSON.stringify({email:s,password:r}),headers:{"Content-Type":"application/json"}})}async function Q(n){let{env:t,email:e,password:s}=n;g({env:t,email:e,password:s});const r=`${B[t]}auth/login?clientID=rest`;return await h(r,{},{method:"POST",body:JSON.stringify({email:e,password:s}),headers:{"Content-Type":"application/json"}})}async function W(n){let{dmShortID:t,env:e,token:s}=n;g({dmShortID:t,env:e,token:s});const r=m(`api/${t}/_auth/logout?clientID=rest&token=${s}`,e);return await h(r,{rawRes:!0},{method:"POST"})}async function X(n){let{env:t,token:e}=n;g({env:t,token:e});const s=`${B[t]}auth/logout?clientID=rest`;return await h(s,{rawRes:!0,token:e},{method:"POST"})}function Y({dmShortID:n}){return g({dmShortID:n}),n}function Z({env:n}){return g({env:n}),n}let tt=["created","creator","id","modified","private","_created","_creator","_embedded","_entryTitle","_id","_links","_modelTitle","_modelTitleField","_modified"];function N(n){let t={};for(let e in n)tt.includes(e)||(t[e]=n[e]);return t}function et(n){return JSON.parse(JSON.stringify(n))}async function nt(n){let{env:t,dmShortID:e}=n;g({env:t,dmShortID:e});const s=m(`api/${e}`,t);return h(s,n)}async function J(n){let{env:t,dmShortID:e,model:s,options:r={}}=n;g({env:t,dmShortID:e,model:s}),r={size:50,page:1,_list:!0,...r};const i=b(r),o=m(`api/${e}/${s}?${i}`,t),{count:c,total:a,_embedded:l}=await h(o,n);let d=l?l[`${e}:${s}`]:[];return d=Array.isArray(d)?d:[d],{count:c,total:a,items:d}}function st({env:n,dmShortID:t,model:e,entryID:s,token:r}){g({env:n,dmShortID:t,model:e,entryID:s});const i=b({_id:s}),o=m(`api/${t}/${e}?${i}`,n);return h(o,{token:r})}async function rt({env:n,dmShortID:t,model:e,value:s,token:r}){g({env:n,dmShortID:t,model:e,value:s});const i=m(`api/${t}/${e}`,n);return await h(i,{token:r},{method:"POST",body:JSON.stringify(s),headers:{"Content-Type":"application/json"}})}async function q({env:n,dmShortID:t,model:e,entryID:s,value:r,token:i,safePut:o=!1}){g({env:n,dmShortID:t,model:e,entryID:s,value:r});const c={"Content-Type":"application/json"};if(o){if(!("_modified"in r))throw new Error("expected _modified to be set!");c["If-Unmodified-Since"]=new Date(r._modified).toUTCString()}const a=m(`api/${t}/${e}?_id=${s}`,n);return r=et(r),r=N(r),await h(a,{token:i},{method:"PUT",headers:c,body:JSON.stringify(r)})}function C({env:n,dmShortID:t,model:e,entryID:s,token:r}){g({env:n,dmShortID:t,model:e,entryID:s});const i=m(`api/${t}/${e}?_id=${s}`,n);return h(i,{token:r,rawRes:!0},{method:"DELETE",headers:{"Content-Type":"application/json"}})}async function it(n,t){let{env:e,dmShortID:s,model:r,options:i={}}=n;g({env:e,dmShortID:s,model:r}),n.options={size:50,page:1,_list:!0,...i};let o=0,c,a=[];for(;c===void 0||o<c;){const l=await J(n);for(let d of l.items)a.push(await t(d));o+=l.items.length,c=l.total,n.options.page++}return a}async function ot({env:n,dmShortID:t,model:e,withMetadata:s}){g({env:n,dmShortID:t,model:e});const r=m(`api/schema/${t}/${e}`,n),i=await h(r),o=i?.allOf?.[1];if(typeof o.properties!="object")throw new Error(`getSchema: ${r} returned unexpected format: ${JSON.stringify(i)}`);const{properties:c}=o,a=N(c);for(let l in a){let d=a[l];if(d.required=o.required.includes(l),a[l]?.oneOf&&delete a[l]?.oneOf,d.title?.includes("<")&&d.title?.includes(">")){const f=d.title.split("<")[1].slice(0,-1),w=d.title.split("<")[0];d.type=w,f.includes(":")?d.resource=f.split(":")[1]:d.resource=f}else["asset","entry","assets","entries"].includes(d.title)?(d.type=d.title,d.resource=null):d.type=d.title;delete a[l].title}if(s){const l=c._modelTitle.title,d=c._modelTitleField.title;return{properties:a,meta:{modelTitleField:d,modelTitle:l}}}return a}function F(n){return Object.entries(n).map(([t,e])=>typeof e!="object"?{[t]:String(e)}:{...e.sort&&{sort:Array.isArray(e)?e.join(","):e},...e.search&&{[t+"~"]:e.search},...e.notNull&&{[t+"!"]:""},...e.null&&{[t]:""},...e.any&&{[t]:e.any.join(",")},...e.from&&{[t+"From"]:e.from},...e.to&&{[t+"To"]:e.to}}).reduce((t,e)=>({...t,...e}),{})}const at=F;function _(n){return n._links.collection.href.split("/").slice(-2)[0]}function U(n){const t=n._links.collection.href.split("api/")[0];return Object.keys(T.datamanager).find(s=>T.datamanager[s]===t)}const R=n=>{const t=_(n),e=U(n),s=n._modelTitle,r=n.id;return{dmShortID:t,env:e,model:s,entryID:r}},ct=n=>C(R(n)),dt=(n,t)=>q({...R(n),value:t});function lt(n,t){const e=_(t);return t._embedded[`${e}:${t._modelTitle}/${n}/asset`]}async function ut({env:n,dmShortID:t,assetGroup:e,assetID:s,token:r}){g({env:n,dmShortID:t,assetGroup:e,assetID:s});const i=b({assetID:s}),o=m(`a/${t}/${e}?${i}`,n),{_embedded:c}=await h(o,{token:r});return c?c["ec:dm-asset"]:void 0}async function gt(n){let{env:t,dmShortID:e,assetGroup:s,token:r,options:i={}}=n;g({env:t,dmShortID:e,assetGroup:s}),i={size:50,page:1,_list:!0,...i};const o=b(i),c=m(`a/${e}/${s}?${o}`,t),{count:a,total:l,_embedded:d}=await h(c,{token:r});let f=d?d["ec:dm-asset"]:[];return f=Array.isArray(f)?f:[f],{count:a,total:l,items:f}}async function ht({env:n,dmShortID:t,assetGroup:e,token:s,file:r,name:i,options:o}){g({env:n,dmShortID:t,assetGroup:e,file:r});const c=m(`a/${t}/${e}`,n),a=new FormData;return a.append("file",r,i),o&&Object.keys(o).forEach(d=>{a.append(d,o[d])}),(await h(c,{token:s},{method:"POST",body:a}))._embedded["ec:dm-asset"]}async function mt({env:n,dmShortID:t,assetGroup:e,files:s,options:r}){g({env:n,dmShortID:t,assetGroup:e,files:s});const i=m(`a/${t}/${e}`,n),o=new FormData;s.forEach(a=>{o.append("file",a)}),r&&Object.keys(r).forEach(a=>{o.append(a,r[a])});const c=await h(i,{},{method:"POST",body:o});return Array.isArray(c._embedded["ec:dm-asset"])?c._embedded["ec:dm-asset"]:[c._embedded["ec:dm-asset"]]}async function ft({env:n,dmShortID:t,assetGroup:e,assetID:s,token:r}){g({env:n,dmShortID:t,assetGroup:e,assetID:s});const i=m(`a/${t}/${e}/${s}`,n);await h(i,{token:r,rawRes:!0},{method:"DELETE"})}function yt(n,t,e=!1){let s,r;return(e?n?.thumbnails:n?.fileVariants)?.forEach(o=>{const{resolution:{width:c,height:a}}=o,l=Math.abs(Math.max(c,a)-t);(!r||l<r)&&(r=l,s=o)}),s?.url??n?.file?.url??null}function pt(n="stage",t,e,s,r=!1){const i=Math.max(s.file.resolution.width,s.file.resolution.height),o=e.filter(a=>a<i),c=`https://datamanager${n==="stage"?".cachena":""}.entrecode.de`;return r?o.map(a=>{const l=s.thumbnails.find(w=>a===w.dimension),d=`${c}/t/${t}/${s.assetID}/${a}`,f=l?l.url:d;return{size:a,url:f,generated:l}}):o.map(a=>{const l=s.fileVariants.find(w=>a===Math.max(w.resolution.width,w.resolution.height)),d=`${c}/f/${t}/${s.assetID}/${a}`,f=l?l.url:d;return{size:a,url:f,generated:l}})}async function bt(n){let{env:t,dmID:e,token:s}=n;g({env:t,dmID:e});const r=m(`?dataManagerID=${e}`,t);return h(r,{token:s})}async function wt(n){let{env:t,options:e={}}=n;g({env:t}),e={size:25,page:1,_list:!0,...e};const s=b(e),r=m(`?${s}`,t),{count:i,total:o,_embedded:c}=await h(r,n);let a=c?c["ec:datamanager"]:[];return a=Array.isArray(a)?a:[a],{count:i,total:o,items:a}}async function $t(n){let{env:t,dmID:e,options:s={}}=n;g({env:t,dmID:e}),s={size:25,dataManagerID:e,page:1,_list:!0,...s};const r=b(s),i=m(`model?${r}`,t),{count:o,total:c,_embedded:a}=await h(i,n);let l=a?a["ec:model"]:[];return l=Array.isArray(l)?l:[l],{count:o,total:c,items:l}}async function Et(n){let{env:t,resource:e,options:s={},subdomain:r="datamanager"}=n;g({env:t,subdomain:r,resource:e}),s={size:25,page:1,_list:!0,...s};const i=b(s),o=m(`${e}?${i}`,t,r),{count:c,total:a,_embedded:l}=await h(o,n);let d=l?l[Object.keys(l)[0]]:[];return d=Array.isArray(d)?d:[d],{count:c,total:a,items:d}}async function kt(n,t={}){let{env:e,route:s,options:r={},subdomain:i="datamanager"}=n;g({env:e,subdomain:i,route:s}),r={...r};const o=b(r),c=m(`${s}?${o}`,e,i);return h(c,n,t)}const Tt=Object.freeze(Object.defineProperty({__proto__:null,assetList:gt,createAsset:ht,createAssets:mt,createEntry:rt,deleteAsset:ft,deleteEntry:C,deleteEntryObject:ct,dmList:wt,editEntry:q,editEntryObject:dt,entryList:J,fileVariant:yt,filterOptions:at,getAsset:ut,getDatamanager:bt,getEcAuthKey:Z,getEntry:st,getEntryAsset:lt,getEntryEnv:U,getEntryShortID:_,getFileVariants:pt,getPublicAuthKey:Y,getSchema:ot,loginEc:Q,loginPublic:H,logoutEc:X,logoutPublic:W,mapEntries:it,modelList:$t,publicApi:nt,raw:kt,resourceList:Et,sdkOptions:F},Symbol.toStringTag,{value:"Module"})),{entryList:O,mapEntries:At,getEntry:St,getAsset:vt,assetList:j,createAsset:_t,createAssets:zt,deleteAsset:Dt,createEntry:Ot,editEntry:P,deleteEntry:jt,getSchema:Pt,loginPublic:Lt,loginEc:xt,logoutEc:It,logoutPublic:Mt,getEcAuthKey:E,getPublicAuthKey:k,dmList:Bt,modelList:Nt,publicApi:Jt,getDatamanager:qt,resourceList:Ct,raw:Ft}=Tt;function L(n){if(!n||typeof n!="object")return n;const{_links:t,_embedded:e,...s}=n;return s}function Ut(n){return!n||typeof n!="object"?n:Array.isArray(n.items)?{...n,items:n.items.map(L)}:L(n)}class z{constructor(t={}){if(!t.storageAdapter){let e=new Map;t.storageAdapter={get:s=>e.get(s),set:(s,r)=>e.set(s,r),remove:s=>e.delete(s)}}this.config=t}set(t){return new z({...this.config,...t})}async entries(t={}){const e=await this.getBestToken();return O({...this.config,options:t,token:e})}async entryList(t){const e=await this.getBestToken();return O({...this.config,options:t,token:e}).then(s=>this.maybeClean(s))}async mapEntries(t,e={}){const s=await this.getBestToken();return At({...this.config,options:e,token:s},t)}async getEntry(t){const e=await this.getBestToken();return St({...this.config,entryID:t,token:e}).then(s=>this.maybeClean(s))}async editEntrySafe(t,e){const s=await this.getBestToken();return P({...this.config,entryID:t,token:s,value:e,safePut:!0}).then(r=>this.maybeClean(r))}async getSchema(){return Pt(this.config)}async assets(t){const e=await this.getBestToken();return j({...this.config,options:t,token:e})}async assetList(t){const e=await this.getBestToken();return j({...this.config,options:t,token:e})}async createAsset(t){const{file:e,name:s,options:r}=t,i=await this.getBestToken();return _t({...this.config,file:e,name:s,options:r,token:i})}async createAssets(t){const{files:e,options:s}=t,r=await this.getBestToken();return zt({...this.config,files:e,options:s,token:r})}async deleteAsset(t){const e=await this.getBestToken();return Dt({...this.config,token:e,assetID:t})}async getAsset(t){const e=await this.getBestToken();return vt({...this.config,assetID:t,token:e})}async createEntry(t){const e=await this.getBestToken();return Ot({...this.config,token:e,value:t}).then(s=>this.maybeClean(s))}async editEntry(t,e){const s=await this.getBestToken();return P({...this.config,entryID:t,token:s,value:e}).then(r=>this.maybeClean(r))}async deleteEntry(t){const e=await this.getBestToken();return jt({...this.config,token:e,entryID:t})}async resourceList(t){const e=await this.getBestToken();return Ct({...this.config,options:t,token:e})}async raw(t,e){const s=await this.getBestToken();return Ft({...this.config,options:t,token:s},e)}storageAdapter(t){return this.set({storageAdapter:t})}removeToken(t){if(!this.config.storageAdapter)throw new Error("cannot removeToken: no storageAdapter defined!");const{remove:e}=this.config.storageAdapter;e(t)}getToken(t){if(!this.config.storageAdapter)throw new Error("cannot getAuth: no storageAdapter defined!");const{get:e}=this.config.storageAdapter;return e(t)}getPublicToken(){return this.config.token||this.getToken(k(this.config))}getEcToken(){return this.config.token||this.getToken(E(this.config))}setToken(t,e){if(!this.config.storageAdapter)throw new Error("cannot setEcToken: no storageAdapter defined!");return this.config.storageAdapter.set(t,e)}setEcToken(t){this.setToken(E(this.config),t)}setPublicToken(t){this.setToken(k(this.config),t)}loginEc(t){return xt({...this.config,...t}).then(e=>this.setToken(E(this.config),e.token))}loginPublic(t){return Lt({...this.config,...t}).then(e=>this.setToken(k(this.config),e.token))}logoutPublic(){const t=this.getPublicToken();return Mt({...this.config,token:t}).then(()=>this.removeToken(k(this.config)))}logoutEc(){const t=this.getEcToken();return It({...this.config,token:t}).then(()=>this.removeToken(E(this.config)))}hasPublicToken(){return!!this.getPublicToken()}hasEcToken(){return!!this.getEcToken()}hasAnyToken(){return!!this.getEcToken()||!!this.getPublicToken()}getBestToken(){try{return this.getEcToken()||this.getPublicToken()}catch{return}}clean(t=!0){return this.set({_clean:t})}maybeClean(t){return this.config._clean?Ut(t):t}model(t){return this.set({model:t})}token(t){return this.set({token:t})}dmShortID(t){return this.set({dmShortID:t})}dm(t){return this.dmShortID(t)}dmID(t){return this.set({dmID:t})}assetGroup(t){return this.set({assetGroup:t})}assetgroup(t){return this.assetGroup(t)}subdomain(t){return this.set({subdomain:t})}resource(t){return this.set({resource:t})}route(t){return this.set({route:t})}publicApi(){return Jt(this.config)}async getDatamanager(t){const e=await this.getBestToken();return qt({...this.config,dmID:t,token:e})}async dmList(t={}){const e=await this.getBestToken();return Bt({...this.config,options:t,token:e})}async modelList(t={}){const e=await this.getBestToken();return Nt({...this.config,options:t,token:e})}}const S=M.join(G.homedir(),".ec-fdk"),v=M.join(S,"auth.json");function A(){try{return $.existsSync(v)?JSON.parse($.readFileSync(v,"utf-8")):{}}catch{return{}}}function x(n){$.existsSync(S)||$.mkdirSync(S,{recursive:!0,mode:448}),$.writeFileSync(v,JSON.stringify(n,null,2),{mode:384})}const Rt={get(n){return A()[n]},set(n,t){const e=A();e[n]=t,x(e)},remove(n){const t=A();delete t[n],x(t)}},y=new K.McpServer({name:"ec.fdk",version:"0.8.5"});function p(n){return new z({env:n,storageAdapter:Rt}).clean()}function I(n){if(!n||typeof n!="object")return n;const{_links:t,_embedded:e,...s}=n;return s}function D(n){return!n||typeof n!="object"?n:Array.isArray(n.items)?{...n,items:n.items.map(I)}:I(n)}y.tool("entryList","List entries from an entrecode datamanager model",{env:u.z.enum(["stage","live"]).default("stage").describe("Environment"),dm:u.z.string().describe("DataManager short ID"),model:u.z.string().describe("Model name"),size:u.z.number().default(5).describe("Page size"),page:u.z.number().optional().describe("Page number"),sort:u.z.string().optional().describe("Sort field")},async({env:n,dm:t,model:e,size:s,page:r,sort:i})=>{const o={};s&&(o.size=s),r&&(o.page=r),i&&(o.sort=[i]);const c=await p(n).dm(t).model(e).entryList(o);return{content:[{type:"text",text:JSON.stringify(c,null,2)}]}});y.tool("getEntry","Get a single entry by ID",{env:u.z.enum(["stage","live"]).default("stage").describe("Environment"),dm:u.z.string().describe("DataManager short ID"),model:u.z.string().describe("Model name"),id:u.z.string().describe("Entry ID")},async({env:n,dm:t,model:e,id:s})=>{const r=await p(n).dm(t).model(e).getEntry(s);return{content:[{type:"text",text:JSON.stringify(r,null,2)}]}});y.tool("createEntry","Create a new entry",{env:u.z.enum(["stage","live"]).default("stage").describe("Environment"),dm:u.z.string().describe("DataManager short ID"),model:u.z.string().describe("Model name"),data:u.z.object({}).passthrough().describe("Entry data as JSON object")},async({env:n,dm:t,model:e,data:s})=>{const r=await p(n).dm(t).model(e).createEntry(s);return{content:[{type:"text",text:JSON.stringify(r,null,2)}]}});y.tool("editEntry","Edit an existing entry",{env:u.z.enum(["stage","live"]).default("stage").describe("Environment"),dm:u.z.string().describe("DataManager short ID"),model:u.z.string().describe("Model name"),id:u.z.string().describe("Entry ID"),data:u.z.object({}).passthrough().describe("Fields to update as JSON object")},async({env:n,dm:t,model:e,id:s,data:r})=>{const i=await p(n).dm(t).model(e).editEntry(s,r);return{content:[{type:"text",text:JSON.stringify(i,null,2)}]}});y.tool("deleteEntry","Delete an entry",{env:u.z.enum(["stage","live"]).default("stage").describe("Environment"),dm:u.z.string().describe("DataManager short ID"),model:u.z.string().describe("Model name"),id:u.z.string().describe("Entry ID")},async({env:n,dm:t,model:e,id:s})=>(await p(n).dm(t).model(e).deleteEntry(s),{content:[{type:"text",text:"Entry deleted."}]}));y.tool("getSchema","Get the schema of a model (field names, types, requirements)",{env:u.z.enum(["stage","live"]).default("stage").describe("Environment"),dm:u.z.string().describe("DataManager short ID"),model:u.z.string().describe("Model name")},async({env:n,dm:t,model:e})=>{const s=await p(n).dm(t).model(e).getSchema();return{content:[{type:"text",text:JSON.stringify(s,null,2)}]}});y.tool("dmList","List available datamanagers",{env:u.z.enum(["stage","live"]).default("stage").describe("Environment"),size:u.z.number().default(5).describe("Page size"),page:u.z.number().optional().describe("Page number")},async({env:n,size:t,page:e})=>{const s={};t&&(s.size=t),e&&(s.page=e);const r=D(await p(n).dmList(s));return{content:[{type:"text",text:JSON.stringify(r,null,2)}]}});y.tool("modelList","List models of a datamanager",{env:u.z.enum(["stage","live"]).default("stage").describe("Environment"),dmID:u.z.string().describe("DataManager long UUID"),size:u.z.number().default(5).describe("Page size"),page:u.z.number().optional().describe("Page number")},async({env:n,dmID:t,size:e,page:s})=>{const r={};e&&(r.size=e),s&&(r.page=s);const i=D(await p(n).dmID(t).modelList(r));return{content:[{type:"text",text:JSON.stringify(i,null,2)}]}});y.tool("getDatamanager","Get details of a single datamanager",{env:u.z.enum(["stage","live"]).default("stage").describe("Environment"),dmID:u.z.string().describe("DataManager long UUID")},async({env:n,dmID:t})=>{const e=D(await p(n).getDatamanager(t));return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}});async function Kt(){const n=new V.StdioServerTransport;await y.connect(n)}Kt();
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ec.fdk",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.7",
|
|
4
4
|
"description": "ec frontend sdk",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"bin": {
|
|
7
|
-
"ec.fdk": "./dist/cli.cjs"
|
|
7
|
+
"ec.fdk": "./dist/cli.cjs",
|
|
8
|
+
"ec.fdk-mcp": "./dist/mcp.cjs"
|
|
8
9
|
},
|
|
9
10
|
"directories": {
|
|
10
11
|
"lib": "lib"
|
|
@@ -22,19 +23,23 @@
|
|
|
22
23
|
"url": "https://github.com/entrecode/ec.fdk/issues"
|
|
23
24
|
},
|
|
24
25
|
"homepage": "https://github.com/entrecode/ec.fdk#readme",
|
|
25
|
-
"dependencies": {
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
28
|
+
"zod": "^4.3.6"
|
|
29
|
+
},
|
|
26
30
|
"devDependencies": {
|
|
27
|
-
"typedoc": "^0.27.6",
|
|
28
31
|
"jsdoc": "^4.0.2",
|
|
29
32
|
"jsdoc-json": "^2.0.2",
|
|
30
33
|
"jsdoc-to-markdown": "^8.0.0",
|
|
34
|
+
"typedoc": "^0.27.6",
|
|
31
35
|
"typescript": "^5.3.3",
|
|
32
36
|
"vite": "^4.4.9"
|
|
33
37
|
},
|
|
34
38
|
"scripts": {
|
|
35
|
-
"build": "vite build && vite build --config vite.cli.config.js && tsc",
|
|
39
|
+
"build": "vite build && vite build --config vite.cli.config.js && vite build --config vite.mcp.config.js && tsc",
|
|
40
|
+
"build:mcp": "vite build --config vite.mcp.config.js && chmod +x dist/mcp.cjs",
|
|
36
41
|
"build:cli": "vite build --config vite.cli.config.js && chmod +x dist/cli.cjs",
|
|
37
|
-
"postbuild": "chmod +x dist/cli.cjs",
|
|
42
|
+
"postbuild": "chmod +x dist/cli.cjs dist/mcp.cjs",
|
|
38
43
|
"docs": "typedoc --out ../../docs",
|
|
39
44
|
"docs-dec": "typedoc --watch"
|
|
40
45
|
},
|