ec.fdk 0.9.4 → 0.9.5
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 +8 -0
- package/dist/cli.cjs +28 -26
- package/package.json +1 -1
- package/skill/SKILL.md +290 -0
package/README.md
CHANGED
|
@@ -221,6 +221,7 @@ ec.fdk <command> [options]
|
|
|
221
221
|
| `login` | Login via browser (OIDC). Use `--password` for email/password prompt. | — |
|
|
222
222
|
| `logout` | Logout and remove stored token | — |
|
|
223
223
|
| `whoami` | Show current logged-in user | — |
|
|
224
|
+
| `install-skill` | Install Claude Code skill | — (optional `--dir <path>`) |
|
|
224
225
|
| `resourceList` | List any resource type | `--resource`, `-f` for query params |
|
|
225
226
|
| `resourceGet` | Get a single resource | `--resource`, `-f` for identifying params |
|
|
226
227
|
| `resourceEdit` | Edit a single resource | `--resource`, `-f` for identifying params, `--data` |
|
|
@@ -263,6 +264,7 @@ ec.fdk <command> [options]
|
|
|
263
264
|
| `--sort <field>` | Sort field for list |
|
|
264
265
|
| `-f, --filter <k=v>` | Filter for list (repeatable) |
|
|
265
266
|
| `--password` | Use email/password login instead of browser OIDC |
|
|
267
|
+
| `--dir <path>` | Target directory for `install-skill` (default: `~/.claude`) |
|
|
266
268
|
| `--raw` | Include `_links` and `_embedded` in output |
|
|
267
269
|
| `--md` | Output entries as readable markdown table |
|
|
268
270
|
| `-v, --version` | Show version |
|
|
@@ -303,6 +305,12 @@ ec.fdk logout -e stage
|
|
|
303
305
|
# Show current user
|
|
304
306
|
ec.fdk whoami -e stage
|
|
305
307
|
|
|
308
|
+
# Install Claude Code skill (to ~/.claude/skills/ec-fdk/)
|
|
309
|
+
ec.fdk install-skill
|
|
310
|
+
|
|
311
|
+
# Install to custom directory
|
|
312
|
+
ec.fdk install-skill --dir ~/entrecode/.claude
|
|
313
|
+
|
|
306
314
|
# List datamanagers
|
|
307
315
|
ec.fdk dmList -e stage
|
|
308
316
|
|
package/dist/cli.cjs
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";const
|
|
2
|
+
"use strict";var he=Object.create;var H=Object.defineProperty;var pe=Object.getOwnPropertyDescriptor;var ye=Object.getOwnPropertyNames;var ke=Object.getPrototypeOf,we=Object.prototype.hasOwnProperty;var De=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ye(t))!we.call(e,o)&&o!==n&&H(e,o,{get:()=>t[o],enumerable:!(r=pe(t,o))||r.enumerable});return e};var U=(e,t,n)=>(n=e!=null?he(ke(e)):{},De(t||!e||!e.__esModule?H(n,"default",{value:e,enumerable:!0}):n,e));const Te=require("node:util"),be=require("node:module"),E=require("node:fs"),ee=require("node:path"),$e=require("node:os"),Ee=require("node:readline"),B=require("node:crypto"),ve=require("node:http"),Ie=require("node:child_process");async function l(e,t={},n={}){const{token:r,rawRes:o}=t;r&&(n.headers={...n.headers||{},Authorization:`Bearer ${r}`});const a=await fetch(e,n);if(!a.ok){if(a.headers.get("content-type")?.includes("application/json")){const s=await a.json(),c=`${s.title}
|
|
3
3
|
${s.detail}
|
|
4
|
-
${s.verbose}`;throw new Error(c)}throw new Error(`unexpected fetch error: ${a.statusText}`)}if(o)return a;if(a.status===204)return;const i=await a.text();return i?JSON.parse(i):void 0}const q={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 r=q[n];if(!r)throw new Error(`subdomain "${n}" not found. Try one of ${Object.keys(q).join(", ")}`);const o=r[e];if(!o)throw new Error(`env "${e}" not found. Try one of ${Object.keys(r[e]).join(", ")}`);return o+t}function h(t,e=!0){return Object.entries(t).sort((n,r)=>n[0].localeCompare(r[0])).map(([n,r])=>`${n}=${r}`).join("&")}function d(t){Object.entries(t).forEach(([e,n])=>{if(n===void 0)throw new Error(`expected ${e} to be set!`)})}const Z={stage:"https://accounts.cachena.entrecode.de/",live:"https://accounts.entrecode.de/"};async function ke(t){let{env:e,dmShortID:n,email:r,password:o}=t;d({env:e,dmShortID:n,email:r,password:o});const a=g(`api/${n}/_auth/login?clientID=rest`,e);return await u(a,{},{method:"POST",body:JSON.stringify({email:r,password:o}),headers:{"Content-Type":"application/json"}})}async function we(t){let{env:e,email:n,password:r}=t;d({env:e,email:n,password:r});const o=`${Z[e]}auth/login?clientID=rest`;return await u(o,{},{method:"POST",body:JSON.stringify({email:n,password:r}),headers:{"Content-Type":"application/json"}})}async function De(t){let{dmShortID:e,env:n,token:r}=t;d({dmShortID:e,env:n,token:r});const o=g(`api/${e}/_auth/logout?clientID=rest&token=${r}`,n);return await u(o,{rawRes:!0},{method:"POST"})}async function Te(t){let{env:e,token:n}=t;d({env:e,token:n});const r=`${Z[e]}auth/logout?clientID=rest`;return await u(r,{rawRes:!0,token:n},{method:"POST"})}function be({dmShortID:t}){return d({dmShortID:t}),t}function $e({env:t}){return d({env:t}),t}let Ee=["created","creator","id","modified","private","_created","_creator","_embedded","_entryTitle","_id","_links","_modelTitle","_modelTitleField","_modified"];function ee(t){let e={};for(let n in t)Ee.includes(n)||(e[n]=t[n]);return e}function ve(t){return JSON.parse(JSON.stringify(t))}async function Ae(t){let{env:e,dmShortID:n}=t;d({env:e,dmShortID:n});const r=g(`api/${n}`,e);return u(r,t)}async function te(t){let{env:e,dmShortID:n,model:r,options:o={}}=t;d({env:e,dmShortID:n,model:r}),o={size:50,page:1,_list:!0,...o};const a=h(o),i=g(`api/${n}/${r}?${a}`,e),{count:s,total:c,_embedded:f}=await u(i,t);let m=f?f[`${n}:${r}`]:[];return m=Array.isArray(m)?m:[m],{count:s,total:c,items:m}}function Ie({env:t,dmShortID:e,model:n,entryID:r,token:o}){d({env:t,dmShortID:e,model:n,entryID:r});const a=h({_id:r}),i=g(`api/${e}/${n}?${a}`,t);return u(i,{token:o})}async function Se({env:t,dmShortID:e,model:n,value:r,token:o}){d({env:t,dmShortID:e,model:n,value:r});const a=g(`api/${e}/${n}`,t);return await u(a,{token:o},{method:"POST",body:JSON.stringify(r),headers:{"Content-Type":"application/json"}})}async function ne({env:t,dmShortID:e,model:n,entryID:r,value:o,token:a,safePut:i=!1}){d({env:t,dmShortID:e,model:n,entryID:r,value:o});const s={"Content-Type":"application/json"};if(i){if(!("_modified"in o))throw new Error("expected _modified to be set!");s["If-Unmodified-Since"]=new Date(o._modified).toUTCString()}const c=g(`api/${e}/${n}?_id=${r}`,t);return o=ve(o),o=ee(o),await u(c,{token:a},{method:"PUT",headers:s,body:JSON.stringify(o)})}function re({env:t,dmShortID:e,model:n,entryID:r,token:o}){d({env:t,dmShortID:e,model:n,entryID:r});const a=g(`api/${e}/${n}?_id=${r}`,t);return u(a,{token:o,rawRes:!0},{method:"DELETE",headers:{"Content-Type":"application/json"}})}async function _e(t,e){let{env:n,dmShortID:r,model:o,options:a={}}=t;d({env:n,dmShortID:r,model:o}),t.options={size:50,page:1,_list:!0,...a};let i=0,s,c=[];for(;s===void 0||i<s;){const f=await te(t);for(let m of f.items)c.push(await e(m));i+=f.items.length,s=f.total,t.options.page++}return c}async function qe({env:t,dmShortID:e,model:n,withMetadata:r}){d({env:t,dmShortID:e,model:n});const o=g(`api/schema/${e}/${n}`,t),a=await u(o),i=a?.allOf?.[1];if(typeof i.properties!="object")throw new Error(`getSchema: ${o} returned unexpected format: ${JSON.stringify(a)}`);const{properties:s}=i,c=ee(s);for(let f in c){let m=c[f];if(m.required=i.required.includes(f),c[f]?.oneOf&&delete c[f]?.oneOf,m.title?.includes("<")&&m.title?.includes(">")){const k=m.title.split("<")[1].slice(0,-1),w=m.title.split("<")[0];m.type=w,k.includes(":")?m.resource=k.split(":")[1]:m.resource=k}else["asset","entry","assets","entries"].includes(m.title)?(m.type=m.title,m.resource=null):m.type=m.title;delete c[f].title}if(r){const f=s._modelTitle.title,m=s._modelTitleField.title;return{properties:c,meta:{modelTitleField:m,modelTitle:f}}}return c}function oe(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 Oe=oe;function B(t){return t._links.collection.href.split("/").slice(-2)[0]}function ae(t){const e=t._links.collection.href.split("api/")[0];return Object.keys(q.datamanager).find(r=>q.datamanager[r]===e)}const se=t=>{const e=B(t),n=ae(t),r=t._modelTitle,o=t.id;return{dmShortID:e,env:n,model:r,entryID:o}},Ce=t=>re(se(t)),Ue=(t,e)=>ne({...se(t),value:e});function Me(t,e){const n=B(e);return e._embedded[`${n}:${e._modelTitle}/${t}/asset`]}async function Le({env:t,dmShortID:e,assetGroup:n,assetID:r,token:o}){d({env:t,dmShortID:e,assetGroup:n,assetID:r});const a=h({assetID:r}),i=g(`a/${e}/${n}?${a}`,t),{_embedded:s}=await u(i,{token:o});return s?s["ec:dm-asset"]:void 0}async function Re(t){let{env:e,dmShortID:n,assetGroup:r,token:o,options:a={}}=t;d({env:e,dmShortID:n,assetGroup:r}),a={size:50,page:1,_list:!0,...a};const i=h(a),s=g(`a/${n}/${r}?${i}`,e),{count:c,total:f,_embedded:m}=await u(s,{token:o});let k=m?m["ec:dm-asset"]:[];return k=Array.isArray(k)?k:[k],{count:c,total:f,items:k}}async function Pe({env:t,dmShortID:e,assetGroup:n,token:r,file:o,name:a,options:i}){d({env:t,dmShortID:e,assetGroup:n,file:o});const s=g(`a/${e}/${n}`,t),c=new FormData;return c.append("file",o,a),i&&Object.keys(i).forEach(m=>{c.append(m,i[m])}),(await u(s,{token:r},{method:"POST",body:c}))._embedded["ec:dm-asset"]}async function Be({env:t,dmShortID:e,assetGroup:n,files:r,options:o}){d({env:t,dmShortID:e,assetGroup:n,files:r});const a=g(`a/${e}/${n}`,t),i=new FormData;r.forEach(c=>{i.append("file",c)}),o&&Object.keys(o).forEach(c=>{i.append(c,o[c])});const s=await u(a,{},{method:"POST",body:i});return Array.isArray(s._embedded["ec:dm-asset"])?s._embedded["ec:dm-asset"]:[s._embedded["ec:dm-asset"]]}async function Ge({env:t,dmShortID:e,assetGroup:n,assetID:r,token:o}){d({env:t,dmShortID:e,assetGroup:n,assetID:r});const a=g(`a/${e}/${n}/${r}`,t);await u(a,{token:o,rawRes:!0},{method:"DELETE"})}function Ne(t,e,n=!1){let r,o;return(n?t?.thumbnails:t?.fileVariants)?.forEach(i=>{const{resolution:{width:s,height:c}}=i,f=Math.abs(Math.max(s,c)-e);(!o||f<o)&&(o=f,r=i)}),r?.url??t?.file?.url??null}function xe(t="stage",e,n,r,o=!1){const a=Math.max(r.file.resolution.width,r.file.resolution.height),i=n.filter(c=>c<a),s=`https://datamanager${t==="stage"?".cachena":""}.entrecode.de`;return o?i.map(c=>{const f=r.thumbnails.find(w=>c===w.dimension),m=`${s}/t/${e}/${r.assetID}/${c}`,k=f?f.url:m;return{size:c,url:k,generated:f}}):i.map(c=>{const f=r.fileVariants.find(w=>c===Math.max(w.resolution.width,w.resolution.height)),m=`${s}/f/${e}/${r.assetID}/${c}`,k=f?f.url:m;return{size:c,url:k,generated:f}})}const p={"Content-Type":"application/json"};async function je(t){let{env:e,dmID:n,token:r}=t;d({env:e,dmID:n});const o=g(`?dataManagerID=${n}`,e);return u(o,{token:r})}async function Je(t){let{env:e,options:n={}}=t;d({env:e}),n={size:25,page:1,_list:!0,...n};const r=h(n),o=g(`?${r}`,e),{count:a,total:i,_embedded:s}=await u(o,t);let c=s?s["ec:datamanager"]:[];return c=Array.isArray(c)?c:[c],{count:a,total:i,items:c}}async function Fe(t){let{env:e,dmID:n,options:r={}}=t;d({env:e,dmID:n}),r={size:25,dataManagerID:n,page:1,_list:!0,...r};const o=h(r),a=g(`model?${o}`,e),{count:i,total:s,_embedded:c}=await u(a,t);let f=c?c["ec:model"]:[];return f=Array.isArray(f)?f:[f],{count:i,total:s,items:f}}async function He(t){let{env:e,resource:n,options:r={},subdomain:o="datamanager"}=t;d({env:e,subdomain:o,resource:n}),r={size:25,page:1,_list:!0,...r};const a=h(r),i=g(`${n}?${a}`,e,o),{count:s,total:c,_embedded:f}=await u(i,t);let m=f?f[Object.keys(f)[0]]:[];return m=Array.isArray(m)?m:[m],{count:s,total:c,items:m}}async function ze(t){let{env:e,resource:n,options:r={},subdomain:o="datamanager"}=t;d({env:e,subdomain:o,resource:n});const a=h(r),i=g(`${n}?${a}`,e,o);return u(i,t)}async function Ke(t){let{env:e,resource:n,options:r={},subdomain:o="datamanager",value:a}=t;d({env:e,subdomain:o,resource:n,value:a});const i=h(r),s=g(`${n}?${i}`,e,o);return u(s,t,{method:"PUT",body:JSON.stringify(a),headers:p})}async function Ve(t){let{env:e,resource:n,options:r={},subdomain:o="datamanager"}=t;d({env:e,subdomain:o,resource:n});const a=h(r),i=g(`${n}?${a}`,e,o);return u(i,{...t,rawRes:!0},{method:"DELETE",headers:p})}async function Ye(t,e={}){let{env:n,route:r,options:o={},subdomain:a="datamanager"}=t;d({env:n,subdomain:a,route:r}),o={...o};const i=h(o),s=g(`${r}?${i}`,n,a);return u(s,t,e)}async function We(t){let{env:e,token:n,value:r}=t;d({env:e,value:r});const o=g("",e);return u(o,{token:n},{method:"POST",body:JSON.stringify(r),headers:p})}async function Xe(t){let{env:e,token:n,dmID:r,value:o}=t;d({env:e,dmID:r,value:o});const a=h({dataManagerID:r}),i=g(`?${a}`,e);return u(i,{token:n},{method:"PUT",body:JSON.stringify(o),headers:p})}async function Qe(t){let{env:e,token:n,dmID:r}=t;d({env:e,dmID:r});const o=h({dataManagerID:r}),a=g(`?${o}`,e);return u(a,{token:n,rawRes:!0},{method:"DELETE",headers:p})}async function Ze(t){let{env:e,token:n,dmID:r,value:o}=t;d({env:e,dmID:r,value:o});const a=h({dataManagerID:r}),i=g(`model?${a}`,e);return u(i,{token:n},{method:"POST",body:JSON.stringify(o),headers:p})}async function et(t){let{env:e,token:n,dmID:r,modelID:o,value:a}=t;d({env:e,dmID:r,modelID:o,value:a});const i=h({dataManagerID:r,modelID:o}),s=g(`model?${i}`,e);return u(s,{token:n},{method:"PUT",body:JSON.stringify(a),headers:p})}async function tt(t){let{env:e,token:n,dmID:r,modelID:o}=t;d({env:e,dmID:r,modelID:o});const a=h({dataManagerID:r,modelID:o}),i=g(`model?${a}`,e);return u(i,{token:n,rawRes:!0},{method:"DELETE",headers:p})}async function nt(t){let{env:e,token:n,value:r}=t;d({env:e,value:r});const o=g("template",e);return u(o,{token:n},{method:"POST",body:JSON.stringify(r),headers:p})}async function rt(t){let{env:e,token:n,dmID:r,value:o}=t;d({env:e,dmID:r,value:o});const a=h({dataManagerID:r}),i=g(`assetgroup?${a}`,e);return u(i,{token:n},{method:"POST",body:JSON.stringify(o),headers:p})}async function ot(t){let{env:e,token:n,dmID:r,assetGroupID:o,value:a}=t;d({env:e,dmID:r,assetGroupID:o,value:a});const i=h({dataManagerID:r,assetGroupID:o}),s=g(`assetgroup?${i}`,e);return u(s,{token:n},{method:"PUT",body:JSON.stringify(a),headers:p})}async function at(t){let{env:e,token:n,dmShortID:r,assetGroup:o,assetID:a,value:i}=t;d({env:e,dmShortID:r,assetGroup:o,assetID:a,value:i});const s=g(`a/${r}/${o}/${a}`,e);return u(s,{token:n},{method:"PUT",body:JSON.stringify(i),headers:p})}async function st(t){let{env:e,token:n,dmID:r,clientID:o,value:a}=t;d({env:e,dmID:r,clientID:o,value:a});const i=h({dataManagerID:r,clientID:o}),s=g(`client?${i}`,e);return u(s,{token:n},{method:"PUT",body:JSON.stringify(a),headers:p})}async function it(t){let{env:e,token:n,dmID:r,value:o}=t;d({env:e,dmID:r,value:o});const a=h({dataManagerID:r}),i=g(`role?${a}`,e);return u(i,{token:n},{method:"POST",body:JSON.stringify(o),headers:p})}async function ct(t){let{env:e,token:n,dmID:r,roleID:o,value:a}=t;d({env:e,dmID:r,roleID:o,value:a});const i=h({dataManagerID:r,roleID:o}),s=g(`role?${i}`,e);return u(s,{token:n},{method:"PUT",body:JSON.stringify(a),headers:p})}async function dt(t){let{env:e,token:n,dmID:r,roleID:o}=t;d({env:e,dmID:r,roleID:o});const a=h({dataManagerID:r,roleID:o}),i=g(`role?${a}`,e);return u(i,{token:n,rawRes:!0},{method:"DELETE",headers:p})}async function ut(t){let{env:e,token:n,dmID:r,accountID:o,value:a}=t;d({env:e,dmID:r,accountID:o,value:a});const i=h({dataManagerID:r,accountID:o}),s=g(`account?${i}`,e);return u(s,{token:n},{method:"PUT",body:JSON.stringify(a),headers:p})}async function lt(t){let{env:e,token:n,dmID:r,accountID:o}=t;d({env:e,dmID:r,accountID:o});const a=h({dataManagerID:r,accountID:o}),i=g(`account?${a}`,e);return u(i,{token:n,rawRes:!0},{method:"DELETE",headers:p})}async function ft(t){let{env:e,token:n,options:r={}}=t;d({env:e});const o=h(r),a=g(`stats?${o}`,e);return u(a,{token:n})}async function gt(t){let{env:e,token:n,options:r={}}=t;d({env:e});const o=h(r),a=g(`entries?${o}`,e,"dm-history");return u(a,{token:n})}async function mt(t){let{env:e,token:n,value:r}=t;d({env:e,value:r});const o=g("client",e,"accounts");return u(o,{token:n},{method:"POST",body:JSON.stringify(r),headers:p})}async function ht(t){let{env:e,token:n,clientID:r,value:o}=t;d({env:e,clientID:r,value:o});const a=h({clientID:r}),i=g(`client?${a}`,e,"accounts");return u(i,{token:n},{method:"PUT",body:JSON.stringify(o),headers:p})}async function pt(t){let{env:e,token:n,clientID:r}=t;d({env:e,clientID:r});const o=h({clientID:r}),a=g(`client?${o}`,e,"accounts");return u(a,{token:n,rawRes:!0},{method:"DELETE",headers:p})}async function yt(t){let{env:e,token:n,value:r}=t;d({env:e,value:r});const o=g("group",e,"accounts");return u(o,{token:n},{method:"POST",body:JSON.stringify(r),headers:p})}async function kt(t){let{env:e,token:n,groupID:r,value:o}=t;d({env:e,groupID:r,value:o});const a=h({groupID:r}),i=g(`group?${a}`,e,"accounts");return u(i,{token:n},{method:"PUT",body:JSON.stringify(o),headers:p})}async function wt(t){let{env:e,token:n,groupID:r}=t;d({env:e,groupID:r});const o=h({groupID:r}),a=g(`group?${o}`,e,"accounts");return u(a,{token:n,rawRes:!0},{method:"DELETE",headers:p})}async function Dt(t){let{env:e,token:n,value:r}=t;d({env:e,value:r});const o=g("invite",e,"accounts"),a=await u(o,{token:n},{method:"POST",body:JSON.stringify(r),headers:p});return a?._embedded?.["ec:invite"]??a}async function Tt(t){let{env:e,token:n,inviteID:r,value:o}=t;d({env:e,inviteID:r,value:o});const a=h({invite:r}),i=g(`invite?${a}`,e,"accounts");return u(i,{token:n},{method:"PUT",body:JSON.stringify(o),headers:p})}async function bt(t){let{env:e,token:n,inviteID:r}=t;d({env:e,inviteID:r});const o=h({invite:r}),a=g(`invite?${o}`,e,"accounts");return u(a,{token:n,rawRes:!0},{method:"DELETE",headers:p})}async function $t(t){let{env:e,token:n,accountID:r,value:o}=t;d({env:e,accountID:r,value:o});const a=h({accountID:r}),i=g(`account?${a}`,e,"accounts");return u(i,{token:n},{method:"PUT",body:JSON.stringify(o),headers:p})}async function Et(t){let{env:e,token:n,accountID:r}=t;d({env:e,accountID:r});const o=h({accountID:r}),a=g(`account/tokens?${o}`,e,"accounts");let s=(await u(a,{token:n}))?._embedded?.["ec:account/token"]??[];return Array.isArray(s)?s:[s]}async function vt(t){let{env:e,token:n,accountID:r}=t;d({env:e,accountID:r});const o=h({accountID:r}),a=g(`account/tokens?${o}`,e,"accounts");return u(a,{token:n},{method:"POST",headers:p})}async function At(t){let{env:e,token:n,accountID:r,accessTokenID:o}=t;d({env:e,accountID:r,accessTokenID:o});const a=h({accessTokenID:o,accountID:r}),i=g(`account/tokens?${a}`,e,"accounts");return u(i,{token:n,rawRes:!0},{method:"DELETE",headers:p})}const It=Object.freeze(Object.defineProperty({__proto__:null,assetList:Re,createAccountClient:mt,createAsset:Pe,createAssetGroup:rt,createAssets:Be,createDatamanager:We,createEntry:Se,createGroup:yt,createInvite:Dt,createModel:Ze,createRole:it,createTemplate:nt,createToken:vt,deleteAccountClient:pt,deleteAsset:Ge,deleteDatamanager:Qe,deleteDmAccount:lt,deleteEntry:re,deleteEntryObject:Ce,deleteGroup:wt,deleteInvite:bt,deleteModel:tt,deleteRole:dt,deleteToken:At,dmList:Je,editAccount:$t,editAccountClient:ht,editAsset:at,editAssetGroup:ot,editDatamanager:Xe,editDmAccount:ut,editDmClient:st,editEntry:ne,editEntryObject:Ue,editGroup:kt,editInvite:Tt,editModel:et,editRole:ct,entryList:te,fileVariant:Ne,filterOptions:Oe,getAsset:Le,getDatamanager:je,getEcAuthKey:$e,getEntry:Ie,getEntryAsset:Me,getEntryEnv:ae,getEntryShortID:B,getFileVariants:xe,getHistory:gt,getPublicAuthKey:be,getSchema:qe,getStats:ft,listTokens:Et,loginEc:we,loginPublic:ke,logoutEc:Te,logoutPublic:De,mapEntries:_e,modelList:Fe,publicApi:Ae,raw:Ye,resourceDelete:Ve,resourceEdit:Ke,resourceGet:ze,resourceList:He,sdkOptions:oe},Symbol.toStringTag,{value:"Module"})),{entryList:F,mapEntries:St,getEntry:_t,getAsset:qt,assetList:H,createAsset:Ot,createAssets:Ct,deleteAsset:Ut,createEntry:Mt,editEntry:z,deleteEntry:Lt,getSchema:Rt,loginPublic:Pt,loginEc:Bt,logoutEc:Gt,logoutPublic:Nt,getEcAuthKey:b,getPublicAuthKey:A,dmList:xt,modelList:jt,publicApi:Jt,getDatamanager:Ft,resourceList:Ht,resourceGet:zt,resourceEdit:Kt,resourceDelete:Vt,raw:Yt,createDatamanager:Wt,editDatamanager:Xt,deleteDatamanager:Qt,createModel:Zt,editModel:en,deleteModel:tn,createTemplate:nn,createAssetGroup:rn,editAssetGroup:on,editAsset:an,editDmClient:sn,createRole:cn,editRole:dn,deleteRole:un,editDmAccount:ln,deleteDmAccount:fn,getStats:gn,getHistory:mn,createAccountClient:hn,editAccountClient:pn,deleteAccountClient:yn,createGroup:kn,editGroup:wn,deleteGroup:Dn,createInvite:Tn,editInvite:bn,deleteInvite:$n,editAccount:En,listTokens:vn,createToken:An,deleteToken:In}=It;function K(t){if(!t||typeof t!="object")return t;const{_links:e,_embedded:n,...r}=t;return r}function Sn(t){return!t||typeof t!="object"?t:Array.isArray(t.items)?{...t,items:t.items.map(K)}:K(t)}class G{constructor(e={}){if(!e.storageAdapter){let n=new Map;e.storageAdapter={get:r=>n.get(r),set:(r,o)=>n.set(r,o),remove:r=>n.delete(r)}}this.config=e}set(e){return new G({...this.config,...e})}async entries(e={}){const n=await this.getBestToken();return F({...this.config,options:e,token:n})}async entryList(e){const n=await this.getBestToken();return F({...this.config,options:e,token:n}).then(r=>this.maybeClean(r))}async mapEntries(e,n={}){const r=await this.getBestToken();return St({...this.config,options:n,token:r},e)}async getEntry(e){const n=await this.getBestToken();return _t({...this.config,entryID:e,token:n}).then(r=>this.maybeClean(r))}async editEntrySafe(e,n){const r=await this.getBestToken();return z({...this.config,entryID:e,token:r,value:n,safePut:!0}).then(o=>this.maybeClean(o))}async getSchema(){return Rt(this.config)}async assets(e){const n=await this.getBestToken();return H({...this.config,options:e,token:n})}async assetList(e){const n=await this.getBestToken();return H({...this.config,options:e,token:n})}async createAsset(e){const{file:n,name:r,options:o}=e,a=await this.getBestToken();return Ot({...this.config,file:n,name:r,options:o,token:a})}async createAssets(e){const{files:n,options:r}=e,o=await this.getBestToken();return Ct({...this.config,files:n,options:r,token:o})}async deleteAsset(e){const n=await this.getBestToken();return Ut({...this.config,token:n,assetID:e})}async getAsset(e){const n=await this.getBestToken();return qt({...this.config,assetID:e,token:n})}async createEntry(e){const n=await this.getBestToken();return Mt({...this.config,token:n,value:e}).then(r=>this.maybeClean(r))}async editEntry(e,n){const r=await this.getBestToken();return z({...this.config,entryID:e,token:r,value:n}).then(o=>this.maybeClean(o))}async deleteEntry(e){const n=await this.getBestToken();return Lt({...this.config,token:n,entryID:e})}async resourceList(e){const n=await this.getBestToken();return Ht({...this.config,options:e,token:n})}async resourceGet(e){const n=await this.getBestToken();return zt({...this.config,options:e,token:n})}async resourceEdit(e,n){const r=await this.getBestToken();return Kt({...this.config,options:e,token:r,value:n})}async resourceDelete(e){const n=await this.getBestToken();return Vt({...this.config,options:e,token:n})}async raw(e,n){const r=await this.getBestToken();return Yt({...this.config,options:e,token:r},n)}async createDatamanager(e){const n=await this.getBestToken();return Wt({...this.config,token:n,value:e})}async editDatamanager(e,n){const r=await this.getBestToken();return Xt({...this.config,token:r,dmID:e,value:n})}async deleteDatamanager(e){const n=await this.getBestToken();return Qt({...this.config,token:n,dmID:e})}async createModel(e){const n=await this.getBestToken();return Zt({...this.config,token:n,value:e})}async editModel(e,n){const r=await this.getBestToken();return en({...this.config,token:r,modelID:e,value:n})}async deleteModel(e){const n=await this.getBestToken();return tn({...this.config,token:n,modelID:e})}async createTemplate(e){const n=await this.getBestToken();return nn({...this.config,token:n,value:e})}async createAssetGroup(e){const n=await this.getBestToken();return rn({...this.config,token:n,value:e})}async editAssetGroup(e,n){const r=await this.getBestToken();return on({...this.config,token:r,assetGroupID:e,value:n})}async editAsset(e,n){const r=await this.getBestToken();return an({...this.config,token:r,assetID:e,value:n})}async editDmClient(e,n){const r=await this.getBestToken();return sn({...this.config,token:r,clientID:e,value:n})}async createRole(e){const n=await this.getBestToken();return cn({...this.config,token:n,value:e})}async editRole(e,n){const r=await this.getBestToken();return dn({...this.config,token:r,roleID:e,value:n})}async deleteRole(e){const n=await this.getBestToken();return un({...this.config,token:n,roleID:e})}async editDmAccount(e,n){const r=await this.getBestToken();return ln({...this.config,token:r,accountID:e,value:n})}async deleteDmAccount(e){const n=await this.getBestToken();return fn({...this.config,token:n,accountID:e})}async getStats(e={}){const n=await this.getBestToken();return gn({...this.config,token:n,options:e})}async getHistory(e={}){const n=await this.getBestToken();return mn({...this.config,token:n,options:e})}async createAccountClient(e){const n=await this.getBestToken();return hn({...this.config,token:n,value:e})}async editAccountClient(e,n){const r=await this.getBestToken();return pn({...this.config,token:r,clientID:e,value:n})}async deleteAccountClient(e){const n=await this.getBestToken();return yn({...this.config,token:n,clientID:e})}async createGroup(e){const n=await this.getBestToken();return kn({...this.config,token:n,value:e})}async editGroup(e,n){const r=await this.getBestToken();return wn({...this.config,token:r,groupID:e,value:n})}async deleteGroup(e){const n=await this.getBestToken();return Dn({...this.config,token:n,groupID:e})}async createInvite(e){const n=await this.getBestToken();return Tn({...this.config,token:n,value:e})}async editInvite(e,n){const r=await this.getBestToken();return bn({...this.config,token:r,inviteID:e,value:n})}async deleteInvite(e){const n=await this.getBestToken();return $n({...this.config,token:n,inviteID:e})}async editAccount(e,n){const r=await this.getBestToken();return En({...this.config,token:r,accountID:e,value:n})}async listTokens(e){const n=await this.getBestToken();return vn({...this.config,token:n,accountID:e})}async createToken(e){const n=await this.getBestToken();return An({...this.config,token:n,accountID:e})}async deleteToken(e,n){const r=await this.getBestToken();return In({...this.config,token:r,accountID:e,accessTokenID: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(A(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)}removeEcToken(){this.removeToken(b(this.config))}setPublicToken(e){this.setToken(A(this.config),e)}loginEc(e){return Bt({...this.config,...e}).then(n=>this.setToken(b(this.config),n.token))}loginPublic(e){return Pt({...this.config,...e}).then(n=>this.setToken(A(this.config),n.token))}logoutPublic(){const e=this.getPublicToken();return Nt({...this.config,token:e}).then(()=>this.removeToken(A(this.config)))}logoutEc(){const e=this.getEcToken();return Gt({...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?Sn(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 Jt(this.config)}async getDatamanager(e){const n=await this.getBestToken();return Ft({...this.config,dmID:e,token:n})}async dmList(e={}){const n=await this.getBestToken();return xt({...this.config,options:e,token:n})}async modelList(e={}){const n=await this.getBestToken();return jt({...this.config,options:e,token:n})}}const M=Q.join(me.homedir(),".ec-fdk"),L=Q.join(M,"auth.json");function U(){try{return E.existsSync(L)?JSON.parse(E.readFileSync(L,"utf-8")):{}}catch{return{}}}function V(t){E.existsSync(M)||E.mkdirSync(M,{recursive:!0,mode:448}),E.writeFileSync(L,JSON.stringify(t,null,2),{mode:384})}const $={get(t){return U()[t]},set(t,e){const n=U();n[t]=e,V(n)},remove(t){const e=U();delete e[t],V(e)}};function _n(t){const e=he.createInterface({input:process.stdin,output:process.stderr});return new Promise(n=>{e.question(t,r=>{e.close(),n(r)})})}function qn(t){return new Promise(e=>{process.stderr.write(t);const n=process.stdin;n.setRawMode(!0),n.resume(),n.setEncoding("utf-8");let r="";const o=a=>{for(const i of a){if(i===""&&(process.stderr.write(`
|
|
4
|
+
${s.verbose}`;throw new Error(c)}throw new Error(`unexpected fetch error: ${a.statusText}`)}if(o)return a;if(a.status===204)return;const i=await a.text();return i?JSON.parse(i):void 0}const q={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(e,t="stage",n="datamanager"){const r=q[n];if(!r)throw new Error(`subdomain "${n}" not found. Try one of ${Object.keys(q).join(", ")}`);const o=r[t];if(!o)throw new Error(`env "${t}" not found. Try one of ${Object.keys(r[t]).join(", ")}`);return o+e}function h(e,t=!0){return Object.entries(e).sort((n,r)=>n[0].localeCompare(r[0])).map(([n,r])=>`${n}=${r}`).join("&")}function d(e){Object.entries(e).forEach(([t,n])=>{if(n===void 0)throw new Error(`expected ${t} to be set!`)})}const te={stage:"https://accounts.cachena.entrecode.de/",live:"https://accounts.entrecode.de/"};async function Ae(e){let{env:t,dmShortID:n,email:r,password:o}=e;d({env:t,dmShortID:n,email:r,password:o});const a=g(`api/${n}/_auth/login?clientID=rest`,t);return await l(a,{},{method:"POST",body:JSON.stringify({email:r,password:o}),headers:{"Content-Type":"application/json"}})}async function Se(e){let{env:t,email:n,password:r}=e;d({env:t,email:n,password:r});const o=`${te[t]}auth/login?clientID=rest`;return await l(o,{},{method:"POST",body:JSON.stringify({email:n,password:r}),headers:{"Content-Type":"application/json"}})}async function _e(e){let{dmShortID:t,env:n,token:r}=e;d({dmShortID:t,env:n,token:r});const o=g(`api/${t}/_auth/logout?clientID=rest&token=${r}`,n);return await l(o,{rawRes:!0},{method:"POST"})}async function qe(e){let{env:t,token:n}=e;d({env:t,token:n});const r=`${te[t]}auth/logout?clientID=rest`;return await l(r,{rawRes:!0,token:n},{method:"POST"})}function Oe({dmShortID:e}){return d({dmShortID:e}),e}function Ce({env:e}){return d({env:e}),e}let Ue=["created","creator","id","modified","private","_created","_creator","_embedded","_entryTitle","_id","_links","_modelTitle","_modelTitleField","_modified"];function ne(e){let t={};for(let n in e)Ue.includes(n)||(t[n]=e[n]);return t}function Le(e){return JSON.parse(JSON.stringify(e))}async function Me(e){let{env:t,dmShortID:n}=e;d({env:t,dmShortID:n});const r=g(`api/${n}`,t);return l(r,e)}async function re(e){let{env:t,dmShortID:n,model:r,options:o={}}=e;d({env:t,dmShortID:n,model:r}),o={size:50,page:1,_list:!0,...o};const a=h(o),i=g(`api/${n}/${r}?${a}`,t),{count:s,total:c,_embedded:u}=await l(i,e);let m=u?u[`${n}:${r}`]:[];return m=Array.isArray(m)?m:[m],{count:s,total:c,items:m}}function Re({env:e,dmShortID:t,model:n,entryID:r,token:o}){d({env:e,dmShortID:t,model:n,entryID:r});const a=h({_id:r}),i=g(`api/${t}/${n}?${a}`,e);return l(i,{token:o})}async function Pe({env:e,dmShortID:t,model:n,value:r,token:o}){d({env:e,dmShortID:t,model:n,value:r});const a=g(`api/${t}/${n}`,e);return await l(a,{token:o},{method:"POST",body:JSON.stringify(r),headers:{"Content-Type":"application/json"}})}async function oe({env:e,dmShortID:t,model:n,entryID:r,value:o,token:a,safePut:i=!1}){d({env:e,dmShortID:t,model:n,entryID:r,value:o});const s={"Content-Type":"application/json"};if(i){if(!("_modified"in o))throw new Error("expected _modified to be set!");s["If-Unmodified-Since"]=new Date(o._modified).toUTCString()}const c=g(`api/${t}/${n}?_id=${r}`,e);return o=Le(o),o=ne(o),await l(c,{token:a},{method:"PUT",headers:s,body:JSON.stringify(o)})}function ae({env:e,dmShortID:t,model:n,entryID:r,token:o}){d({env:e,dmShortID:t,model:n,entryID:r});const a=g(`api/${t}/${n}?_id=${r}`,e);return l(a,{token:o,rawRes:!0},{method:"DELETE",headers:{"Content-Type":"application/json"}})}async function Be(e,t){let{env:n,dmShortID:r,model:o,options:a={}}=e;d({env:n,dmShortID:r,model:o}),e.options={size:50,page:1,_list:!0,...a};let i=0,s,c=[];for(;s===void 0||i<s;){const u=await re(e);for(let m of u.items)c.push(await t(m));i+=u.items.length,s=u.total,e.options.page++}return c}async function Ge({env:e,dmShortID:t,model:n,withMetadata:r}){d({env:e,dmShortID:t,model:n});const o=g(`api/schema/${t}/${n}`,e),a=await l(o),i=a?.allOf?.[1];if(typeof i.properties!="object")throw new Error(`getSchema: ${o} returned unexpected format: ${JSON.stringify(a)}`);const{properties:s}=i,c=ne(s);for(let u in c){let m=c[u];if(m.required=i.required.includes(u),c[u]?.oneOf&&delete c[u]?.oneOf,m.title?.includes("<")&&m.title?.includes(">")){const y=m.title.split("<")[1].slice(0,-1),w=m.title.split("<")[0];m.type=w,y.includes(":")?m.resource=y.split(":")[1]:m.resource=y}else["asset","entry","assets","entries"].includes(m.title)?(m.type=m.title,m.resource=null):m.type=m.title;delete c[u].title}if(r){const u=s._modelTitle.title,m=s._modelTitleField.title;return{properties:c,meta:{modelTitleField:m,modelTitle:u}}}return c}function se(e){return Object.entries(e).map(([t,n])=>typeof n!="object"?{[t]:String(n)}:{...n.sort&&{sort:Array.isArray(n)?n.join(","):n},...n.search&&{[t+"~"]:n.search},...n.notNull&&{[t+"!"]:""},...n.null&&{[t]:""},...n.any&&{[t]:n.any.join(",")},...n.from&&{[t+"From"]:n.from},...n.to&&{[t+"To"]:n.to}}).reduce((t,n)=>({...t,...n}),{})}const Ne=se;function G(e){return e._links.collection.href.split("/").slice(-2)[0]}function ie(e){const t=e._links.collection.href.split("api/")[0];return Object.keys(q.datamanager).find(r=>q.datamanager[r]===t)}const ce=e=>{const t=G(e),n=ie(e),r=e._modelTitle,o=e.id;return{dmShortID:t,env:n,model:r,entryID:o}},xe=e=>ae(ce(e)),je=(e,t)=>oe({...ce(e),value:t});function Je(e,t){const n=G(t);return t._embedded[`${n}:${t._modelTitle}/${e}/asset`]}async function Fe({env:e,dmShortID:t,assetGroup:n,assetID:r,token:o}){d({env:e,dmShortID:t,assetGroup:n,assetID:r});const a=h({assetID:r}),i=g(`a/${t}/${n}?${a}`,e),{_embedded:s}=await l(i,{token:o});return s?s["ec:dm-asset"]:void 0}async function He(e){let{env:t,dmShortID:n,assetGroup:r,token:o,options:a={}}=e;d({env:t,dmShortID:n,assetGroup:r}),a={size:50,page:1,_list:!0,...a};const i=h(a),s=g(`a/${n}/${r}?${i}`,t),{count:c,total:u,_embedded:m}=await l(s,{token:o});let y=m?m["ec:dm-asset"]:[];return y=Array.isArray(y)?y:[y],{count:c,total:u,items:y}}async function ze({env:e,dmShortID:t,assetGroup:n,token:r,file:o,name:a,options:i}){d({env:e,dmShortID:t,assetGroup:n,file:o});const s=g(`a/${t}/${n}`,e),c=new FormData;return c.append("file",o,a),i&&Object.keys(i).forEach(m=>{c.append(m,i[m])}),(await l(s,{token:r},{method:"POST",body:c}))._embedded["ec:dm-asset"]}async function Ke({env:e,dmShortID:t,assetGroup:n,files:r,options:o}){d({env:e,dmShortID:t,assetGroup:n,files:r});const a=g(`a/${t}/${n}`,e),i=new FormData;r.forEach(c=>{i.append("file",c)}),o&&Object.keys(o).forEach(c=>{i.append(c,o[c])});const s=await l(a,{},{method:"POST",body:i});return Array.isArray(s._embedded["ec:dm-asset"])?s._embedded["ec:dm-asset"]:[s._embedded["ec:dm-asset"]]}async function Ve({env:e,dmShortID:t,assetGroup:n,assetID:r,token:o}){d({env:e,dmShortID:t,assetGroup:n,assetID:r});const a=g(`a/${t}/${n}/${r}`,e);await l(a,{token:o,rawRes:!0},{method:"DELETE"})}function Ye(e,t,n=!1){let r,o;return(n?e?.thumbnails:e?.fileVariants)?.forEach(i=>{const{resolution:{width:s,height:c}}=i,u=Math.abs(Math.max(s,c)-t);(!o||u<o)&&(o=u,r=i)}),r?.url??e?.file?.url??null}function We(e="stage",t,n,r,o=!1){const a=Math.max(r.file.resolution.width,r.file.resolution.height),i=n.filter(c=>c<a),s=`https://datamanager${e==="stage"?".cachena":""}.entrecode.de`;return o?i.map(c=>{const u=r.thumbnails.find(w=>c===w.dimension),m=`${s}/t/${t}/${r.assetID}/${c}`,y=u?u.url:m;return{size:c,url:y,generated:u}}):i.map(c=>{const u=r.fileVariants.find(w=>c===Math.max(w.resolution.width,w.resolution.height)),m=`${s}/f/${t}/${r.assetID}/${c}`,y=u?u.url:m;return{size:c,url:y,generated:u}})}const p={"Content-Type":"application/json"};async function Xe(e){let{env:t,dmID:n,token:r}=e;d({env:t,dmID:n});const o=g(`?dataManagerID=${n}`,t);return l(o,{token:r})}async function Qe(e){let{env:t,options:n={}}=e;d({env:t}),n={size:25,page:1,_list:!0,...n};const r=h(n),o=g(`?${r}`,t),{count:a,total:i,_embedded:s}=await l(o,e);let c=s?s["ec:datamanager"]:[];return c=Array.isArray(c)?c:[c],{count:a,total:i,items:c}}async function Ze(e){let{env:t,dmID:n,options:r={}}=e;d({env:t,dmID:n}),r={size:25,dataManagerID:n,page:1,_list:!0,...r};const o=h(r),a=g(`model?${o}`,t),{count:i,total:s,_embedded:c}=await l(a,e);let u=c?c["ec:model"]:[];return u=Array.isArray(u)?u:[u],{count:i,total:s,items:u}}async function et(e){let{env:t,resource:n,options:r={},subdomain:o="datamanager"}=e;d({env:t,subdomain:o,resource:n}),r={size:25,page:1,_list:!0,...r};const a=h(r),i=g(`${n}?${a}`,t,o),{count:s,total:c,_embedded:u}=await l(i,e);let m=u?u[Object.keys(u)[0]]:[];return m=Array.isArray(m)?m:[m],{count:s,total:c,items:m}}async function tt(e){let{env:t,resource:n,options:r={},subdomain:o="datamanager"}=e;d({env:t,subdomain:o,resource:n});const a=h(r),i=g(`${n}?${a}`,t,o);return l(i,e)}async function nt(e){let{env:t,resource:n,options:r={},subdomain:o="datamanager",value:a}=e;d({env:t,subdomain:o,resource:n,value:a});const i=h(r),s=g(`${n}?${i}`,t,o);return l(s,e,{method:"PUT",body:JSON.stringify(a),headers:p})}async function rt(e){let{env:t,resource:n,options:r={},subdomain:o="datamanager"}=e;d({env:t,subdomain:o,resource:n});const a=h(r),i=g(`${n}?${a}`,t,o);return l(i,{...e,rawRes:!0},{method:"DELETE",headers:p})}async function ot(e,t={}){let{env:n,route:r,options:o={},subdomain:a="datamanager"}=e;d({env:n,subdomain:a,route:r}),o={...o};const i=h(o),s=g(`${r}?${i}`,n,a);return l(s,e,t)}async function at(e){let{env:t,token:n,value:r}=e;d({env:t,value:r});const o=g("",t);return l(o,{token:n},{method:"POST",body:JSON.stringify(r),headers:p})}async function st(e){let{env:t,token:n,dmID:r,value:o}=e;d({env:t,dmID:r,value:o});const a=h({dataManagerID:r}),i=g(`?${a}`,t);return l(i,{token:n},{method:"PUT",body:JSON.stringify(o),headers:p})}async function it(e){let{env:t,token:n,dmID:r}=e;d({env:t,dmID:r});const o=h({dataManagerID:r}),a=g(`?${o}`,t);return l(a,{token:n,rawRes:!0},{method:"DELETE",headers:p})}async function ct(e){let{env:t,token:n,dmID:r,value:o}=e;d({env:t,dmID:r,value:o});const a=h({dataManagerID:r}),i=g(`model?${a}`,t);return l(i,{token:n},{method:"POST",body:JSON.stringify(o),headers:p})}async function dt(e){let{env:t,token:n,dmID:r,modelID:o,value:a}=e;d({env:t,dmID:r,modelID:o,value:a});const i=h({dataManagerID:r,modelID:o}),s=g(`model?${i}`,t);return l(s,{token:n},{method:"PUT",body:JSON.stringify(a),headers:p})}async function ut(e){let{env:t,token:n,dmID:r,modelID:o}=e;d({env:t,dmID:r,modelID:o});const a=h({dataManagerID:r,modelID:o}),i=g(`model?${a}`,t);return l(i,{token:n,rawRes:!0},{method:"DELETE",headers:p})}async function lt(e){let{env:t,token:n,value:r}=e;d({env:t,value:r});const o=g("template",t);return l(o,{token:n},{method:"POST",body:JSON.stringify(r),headers:p})}async function ft(e){let{env:t,token:n,dmID:r,value:o}=e;d({env:t,dmID:r,value:o});const a=h({dataManagerID:r}),i=g(`assetgroup?${a}`,t);return l(i,{token:n},{method:"POST",body:JSON.stringify(o),headers:p})}async function gt(e){let{env:t,token:n,dmID:r,assetGroupID:o,value:a}=e;d({env:t,dmID:r,assetGroupID:o,value:a});const i=h({dataManagerID:r,assetGroupID:o}),s=g(`assetgroup?${i}`,t);return l(s,{token:n},{method:"PUT",body:JSON.stringify(a),headers:p})}async function mt(e){let{env:t,token:n,dmShortID:r,assetGroup:o,assetID:a,value:i}=e;d({env:t,dmShortID:r,assetGroup:o,assetID:a,value:i});const s=g(`a/${r}/${o}/${a}`,t);return l(s,{token:n},{method:"PUT",body:JSON.stringify(i),headers:p})}async function ht(e){let{env:t,token:n,dmID:r,clientID:o,value:a}=e;d({env:t,dmID:r,clientID:o,value:a});const i=h({dataManagerID:r,clientID:o}),s=g(`client?${i}`,t);return l(s,{token:n},{method:"PUT",body:JSON.stringify(a),headers:p})}async function pt(e){let{env:t,token:n,dmID:r,value:o}=e;d({env:t,dmID:r,value:o});const a=h({dataManagerID:r}),i=g(`role?${a}`,t);return l(i,{token:n},{method:"POST",body:JSON.stringify(o),headers:p})}async function yt(e){let{env:t,token:n,dmID:r,roleID:o,value:a}=e;d({env:t,dmID:r,roleID:o,value:a});const i=h({dataManagerID:r,roleID:o}),s=g(`role?${i}`,t);return l(s,{token:n},{method:"PUT",body:JSON.stringify(a),headers:p})}async function kt(e){let{env:t,token:n,dmID:r,roleID:o}=e;d({env:t,dmID:r,roleID:o});const a=h({dataManagerID:r,roleID:o}),i=g(`role?${a}`,t);return l(i,{token:n,rawRes:!0},{method:"DELETE",headers:p})}async function wt(e){let{env:t,token:n,dmID:r,accountID:o,value:a}=e;d({env:t,dmID:r,accountID:o,value:a});const i=h({dataManagerID:r,accountID:o}),s=g(`account?${i}`,t);return l(s,{token:n},{method:"PUT",body:JSON.stringify(a),headers:p})}async function Dt(e){let{env:t,token:n,dmID:r,accountID:o}=e;d({env:t,dmID:r,accountID:o});const a=h({dataManagerID:r,accountID:o}),i=g(`account?${a}`,t);return l(i,{token:n,rawRes:!0},{method:"DELETE",headers:p})}async function Tt(e){let{env:t,token:n,options:r={}}=e;d({env:t});const o=h(r),a=g(`stats?${o}`,t);return l(a,{token:n})}async function bt(e){let{env:t,token:n,options:r={}}=e;d({env:t});const o=h(r),a=g(`entries?${o}`,t,"dm-history");return l(a,{token:n})}async function $t(e){let{env:t,token:n,value:r}=e;d({env:t,value:r});const o=g("client",t,"accounts");return l(o,{token:n},{method:"POST",body:JSON.stringify(r),headers:p})}async function Et(e){let{env:t,token:n,clientID:r,value:o}=e;d({env:t,clientID:r,value:o});const a=h({clientID:r}),i=g(`client?${a}`,t,"accounts");return l(i,{token:n},{method:"PUT",body:JSON.stringify(o),headers:p})}async function vt(e){let{env:t,token:n,clientID:r}=e;d({env:t,clientID:r});const o=h({clientID:r}),a=g(`client?${o}`,t,"accounts");return l(a,{token:n,rawRes:!0},{method:"DELETE",headers:p})}async function It(e){let{env:t,token:n,value:r}=e;d({env:t,value:r});const o=g("group",t,"accounts");return l(o,{token:n},{method:"POST",body:JSON.stringify(r),headers:p})}async function At(e){let{env:t,token:n,groupID:r,value:o}=e;d({env:t,groupID:r,value:o});const a=h({groupID:r}),i=g(`group?${a}`,t,"accounts");return l(i,{token:n},{method:"PUT",body:JSON.stringify(o),headers:p})}async function St(e){let{env:t,token:n,groupID:r}=e;d({env:t,groupID:r});const o=h({groupID:r}),a=g(`group?${o}`,t,"accounts");return l(a,{token:n,rawRes:!0},{method:"DELETE",headers:p})}async function _t(e){let{env:t,token:n,value:r}=e;d({env:t,value:r});const o=g("invite",t,"accounts"),a=await l(o,{token:n},{method:"POST",body:JSON.stringify(r),headers:p});return a?._embedded?.["ec:invite"]??a}async function qt(e){let{env:t,token:n,inviteID:r,value:o}=e;d({env:t,inviteID:r,value:o});const a=h({invite:r}),i=g(`invite?${a}`,t,"accounts");return l(i,{token:n},{method:"PUT",body:JSON.stringify(o),headers:p})}async function Ot(e){let{env:t,token:n,inviteID:r}=e;d({env:t,inviteID:r});const o=h({invite:r}),a=g(`invite?${o}`,t,"accounts");return l(a,{token:n,rawRes:!0},{method:"DELETE",headers:p})}async function Ct(e){let{env:t,token:n,accountID:r,value:o}=e;d({env:t,accountID:r,value:o});const a=h({accountID:r}),i=g(`account?${a}`,t,"accounts");return l(i,{token:n},{method:"PUT",body:JSON.stringify(o),headers:p})}async function Ut(e){let{env:t,token:n,accountID:r}=e;d({env:t,accountID:r});const o=h({accountID:r}),a=g(`account/tokens?${o}`,t,"accounts");let s=(await l(a,{token:n}))?._embedded?.["ec:account/token"]??[];return Array.isArray(s)?s:[s]}async function Lt(e){let{env:t,token:n,accountID:r}=e;d({env:t,accountID:r});const o=h({accountID:r}),a=g(`account/tokens?${o}`,t,"accounts");return l(a,{token:n},{method:"POST",headers:p})}async function Mt(e){let{env:t,token:n,accountID:r,accessTokenID:o}=e;d({env:t,accountID:r,accessTokenID:o});const a=h({accessTokenID:o,accountID:r}),i=g(`account/tokens?${a}`,t,"accounts");return l(i,{token:n,rawRes:!0},{method:"DELETE",headers:p})}const Rt=Object.freeze(Object.defineProperty({__proto__:null,assetList:He,createAccountClient:$t,createAsset:ze,createAssetGroup:ft,createAssets:Ke,createDatamanager:at,createEntry:Pe,createGroup:It,createInvite:_t,createModel:ct,createRole:pt,createTemplate:lt,createToken:Lt,deleteAccountClient:vt,deleteAsset:Ve,deleteDatamanager:it,deleteDmAccount:Dt,deleteEntry:ae,deleteEntryObject:xe,deleteGroup:St,deleteInvite:Ot,deleteModel:ut,deleteRole:kt,deleteToken:Mt,dmList:Qe,editAccount:Ct,editAccountClient:Et,editAsset:mt,editAssetGroup:gt,editDatamanager:st,editDmAccount:wt,editDmClient:ht,editEntry:oe,editEntryObject:je,editGroup:At,editInvite:qt,editModel:dt,editRole:yt,entryList:re,fileVariant:Ye,filterOptions:Ne,getAsset:Fe,getDatamanager:Xe,getEcAuthKey:Ce,getEntry:Re,getEntryAsset:Je,getEntryEnv:ie,getEntryShortID:G,getFileVariants:We,getHistory:bt,getPublicAuthKey:Oe,getSchema:Ge,getStats:Tt,listTokens:Ut,loginEc:Se,loginPublic:Ae,logoutEc:qe,logoutPublic:_e,mapEntries:Be,modelList:Ze,publicApi:Me,raw:ot,resourceDelete:rt,resourceEdit:nt,resourceGet:tt,resourceList:et,sdkOptions:se},Symbol.toStringTag,{value:"Module"})),{entryList:z,mapEntries:Pt,getEntry:Bt,getAsset:Gt,assetList:K,createAsset:Nt,createAssets:xt,deleteAsset:jt,createEntry:Jt,editEntry:V,deleteEntry:Ft,getSchema:Ht,loginPublic:zt,loginEc:Kt,logoutEc:Vt,logoutPublic:Yt,getEcAuthKey:b,getPublicAuthKey:I,dmList:Wt,modelList:Xt,publicApi:Qt,getDatamanager:Zt,resourceList:en,resourceGet:tn,resourceEdit:nn,resourceDelete:rn,raw:on,createDatamanager:an,editDatamanager:sn,deleteDatamanager:cn,createModel:dn,editModel:un,deleteModel:ln,createTemplate:fn,createAssetGroup:gn,editAssetGroup:mn,editAsset:hn,editDmClient:pn,createRole:yn,editRole:kn,deleteRole:wn,editDmAccount:Dn,deleteDmAccount:Tn,getStats:bn,getHistory:$n,createAccountClient:En,editAccountClient:vn,deleteAccountClient:In,createGroup:An,editGroup:Sn,deleteGroup:_n,createInvite:qn,editInvite:On,deleteInvite:Cn,editAccount:Un,listTokens:Ln,createToken:Mn,deleteToken:Rn}=Rt;function Y(e){if(!e||typeof e!="object")return e;const{_links:t,_embedded:n,...r}=e;return r}function Pn(e){return!e||typeof e!="object"?e:Array.isArray(e.items)?{...e,items:e.items.map(Y)}:Y(e)}class N{constructor(t={}){if(!t.storageAdapter){let n=new Map;t.storageAdapter={get:r=>n.get(r),set:(r,o)=>n.set(r,o),remove:r=>n.delete(r)}}this.config=t}set(t){return new N({...this.config,...t})}async entries(t={}){const n=await this.getBestToken();return z({...this.config,options:t,token:n})}async entryList(t){const n=await this.getBestToken();return z({...this.config,options:t,token:n}).then(r=>this.maybeClean(r))}async mapEntries(t,n={}){const r=await this.getBestToken();return Pt({...this.config,options:n,token:r},t)}async getEntry(t){const n=await this.getBestToken();return Bt({...this.config,entryID:t,token:n}).then(r=>this.maybeClean(r))}async editEntrySafe(t,n){const r=await this.getBestToken();return V({...this.config,entryID:t,token:r,value:n,safePut:!0}).then(o=>this.maybeClean(o))}async getSchema(){return Ht(this.config)}async assets(t){const n=await this.getBestToken();return K({...this.config,options:t,token:n})}async assetList(t){const n=await this.getBestToken();return K({...this.config,options:t,token:n})}async createAsset(t){const{file:n,name:r,options:o}=t,a=await this.getBestToken();return Nt({...this.config,file:n,name:r,options:o,token:a})}async createAssets(t){const{files:n,options:r}=t,o=await this.getBestToken();return xt({...this.config,files:n,options:r,token:o})}async deleteAsset(t){const n=await this.getBestToken();return jt({...this.config,token:n,assetID:t})}async getAsset(t){const n=await this.getBestToken();return Gt({...this.config,assetID:t,token:n})}async createEntry(t){const n=await this.getBestToken();return Jt({...this.config,token:n,value:t}).then(r=>this.maybeClean(r))}async editEntry(t,n){const r=await this.getBestToken();return V({...this.config,entryID:t,token:r,value:n}).then(o=>this.maybeClean(o))}async deleteEntry(t){const n=await this.getBestToken();return Ft({...this.config,token:n,entryID:t})}async resourceList(t){const n=await this.getBestToken();return en({...this.config,options:t,token:n})}async resourceGet(t){const n=await this.getBestToken();return tn({...this.config,options:t,token:n})}async resourceEdit(t,n){const r=await this.getBestToken();return nn({...this.config,options:t,token:r,value:n})}async resourceDelete(t){const n=await this.getBestToken();return rn({...this.config,options:t,token:n})}async raw(t,n){const r=await this.getBestToken();return on({...this.config,options:t,token:r},n)}async createDatamanager(t){const n=await this.getBestToken();return an({...this.config,token:n,value:t})}async editDatamanager(t,n){const r=await this.getBestToken();return sn({...this.config,token:r,dmID:t,value:n})}async deleteDatamanager(t){const n=await this.getBestToken();return cn({...this.config,token:n,dmID:t})}async createModel(t){const n=await this.getBestToken();return dn({...this.config,token:n,value:t})}async editModel(t,n){const r=await this.getBestToken();return un({...this.config,token:r,modelID:t,value:n})}async deleteModel(t){const n=await this.getBestToken();return ln({...this.config,token:n,modelID:t})}async createTemplate(t){const n=await this.getBestToken();return fn({...this.config,token:n,value:t})}async createAssetGroup(t){const n=await this.getBestToken();return gn({...this.config,token:n,value:t})}async editAssetGroup(t,n){const r=await this.getBestToken();return mn({...this.config,token:r,assetGroupID:t,value:n})}async editAsset(t,n){const r=await this.getBestToken();return hn({...this.config,token:r,assetID:t,value:n})}async editDmClient(t,n){const r=await this.getBestToken();return pn({...this.config,token:r,clientID:t,value:n})}async createRole(t){const n=await this.getBestToken();return yn({...this.config,token:n,value:t})}async editRole(t,n){const r=await this.getBestToken();return kn({...this.config,token:r,roleID:t,value:n})}async deleteRole(t){const n=await this.getBestToken();return wn({...this.config,token:n,roleID:t})}async editDmAccount(t,n){const r=await this.getBestToken();return Dn({...this.config,token:r,accountID:t,value:n})}async deleteDmAccount(t){const n=await this.getBestToken();return Tn({...this.config,token:n,accountID:t})}async getStats(t={}){const n=await this.getBestToken();return bn({...this.config,token:n,options:t})}async getHistory(t={}){const n=await this.getBestToken();return $n({...this.config,token:n,options:t})}async createAccountClient(t){const n=await this.getBestToken();return En({...this.config,token:n,value:t})}async editAccountClient(t,n){const r=await this.getBestToken();return vn({...this.config,token:r,clientID:t,value:n})}async deleteAccountClient(t){const n=await this.getBestToken();return In({...this.config,token:n,clientID:t})}async createGroup(t){const n=await this.getBestToken();return An({...this.config,token:n,value:t})}async editGroup(t,n){const r=await this.getBestToken();return Sn({...this.config,token:r,groupID:t,value:n})}async deleteGroup(t){const n=await this.getBestToken();return _n({...this.config,token:n,groupID:t})}async createInvite(t){const n=await this.getBestToken();return qn({...this.config,token:n,value:t})}async editInvite(t,n){const r=await this.getBestToken();return On({...this.config,token:r,inviteID:t,value:n})}async deleteInvite(t){const n=await this.getBestToken();return Cn({...this.config,token:n,inviteID:t})}async editAccount(t,n){const r=await this.getBestToken();return Un({...this.config,token:r,accountID:t,value:n})}async listTokens(t){const n=await this.getBestToken();return Ln({...this.config,token:n,accountID:t})}async createToken(t){const n=await this.getBestToken();return Mn({...this.config,token:n,accountID:t})}async deleteToken(t,n){const r=await this.getBestToken();return Rn({...this.config,token:r,accountID:t,accessTokenID:n})}storageAdapter(t){return this.set({storageAdapter:t})}removeToken(t){if(!this.config.storageAdapter)throw new Error("cannot removeToken: no storageAdapter defined!");const{remove:n}=this.config.storageAdapter;n(t)}getToken(t){if(!this.config.storageAdapter)throw new Error("cannot getAuth: no storageAdapter defined!");const{get:n}=this.config.storageAdapter;return n(t)}getPublicToken(){return this.config.token||this.getToken(I(this.config))}getEcToken(){return this.config.token||this.getToken(b(this.config))}setToken(t,n){if(!this.config.storageAdapter)throw new Error("cannot setEcToken: no storageAdapter defined!");return this.config.storageAdapter.set(t,n)}setEcToken(t){this.setToken(b(this.config),t)}removeEcToken(){this.removeToken(b(this.config))}setPublicToken(t){this.setToken(I(this.config),t)}loginEc(t){return Kt({...this.config,...t}).then(n=>this.setToken(b(this.config),n.token))}loginPublic(t){return zt({...this.config,...t}).then(n=>this.setToken(I(this.config),n.token))}logoutPublic(){const t=this.getPublicToken();return Yt({...this.config,token:t}).then(()=>this.removeToken(I(this.config)))}logoutEc(){const t=this.getEcToken();return Vt({...this.config,token:t}).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(t=!0){return this.set({_clean:t})}maybeClean(t){return this.config._clean?Pn(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 Qt(this.config)}async getDatamanager(t){const n=await this.getBestToken();return Zt({...this.config,dmID:t,token:n})}async dmList(t={}){const n=await this.getBestToken();return Wt({...this.config,options:t,token:n})}async modelList(t={}){const n=await this.getBestToken();return Xt({...this.config,options:t,token:n})}}const M=ee.join($e.homedir(),".ec-fdk"),R=ee.join(M,"auth.json");function L(){try{return E.existsSync(R)?JSON.parse(E.readFileSync(R,"utf-8")):{}}catch{return{}}}function W(e){E.existsSync(M)||E.mkdirSync(M,{recursive:!0,mode:448}),E.writeFileSync(R,JSON.stringify(e,null,2),{mode:384})}const $={get(e){return L()[e]},set(e,t){const n=L();n[e]=t,W(n)},remove(e){const t=L();delete t[e],W(t)}};function Bn(e){const t=Ee.createInterface({input:process.stdin,output:process.stderr});return new Promise(n=>{t.question(e,r=>{t.close(),n(r)})})}function Gn(e){return new Promise(t=>{process.stderr.write(e);const n=process.stdin;n.setRawMode(!0),n.resume(),n.setEncoding("utf-8");let r="";const o=a=>{for(const i of a){if(i===""&&(process.stderr.write(`
|
|
5
5
|
`),process.exit(130)),i==="\r"||i===`
|
|
6
6
|
`){n.setRawMode(!1),n.pause(),n.removeListener("data",o),process.stderr.write(`
|
|
7
|
-
`),
|
|
8
|
-
<div style="text-align:center"><h1>Login successful</h1><p>You can close this tab.</p></div></body></html>`,
|
|
9
|
-
<div style="text-align:center"><h1>Login failed</h1><p>${
|
|
10
|
-
`),
|
|
7
|
+
`),t(r);return}if(i===""||i==="\b"){r.length>0&&(r=r.slice(0,-1),process.stderr.write("\b \b"));continue}r+=i,process.stderr.write("*")}};n.on("data",o)})}const de={stage:{authEndpoint:"https://login.cachena.entrecode.de/oidc/auth",tokenEndpoint:"https://login.cachena.entrecode.de/oidc/token"},live:{authEndpoint:"https://login.entrecode.de/oidc/auth",tokenEndpoint:"https://login.entrecode.de/oidc/token"}},P="ec-fdk-cli",X="http://localhost:19836/callback",Nn=12e4;function x(e){return e.toString("base64url")}function xn(){return x(B.randomBytes(32))}function jn(e){return x(B.createHash("sha256").update(e).digest())}function Jn(e){const t=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";Ie.exec(`${t} ${JSON.stringify(e)}`)}const Fn=`<!DOCTYPE html><html><body style="font-family:system-ui;display:flex;justify-content:center;align-items:center;height:100vh;margin:0">
|
|
8
|
+
<div style="text-align:center"><h1>Login successful</h1><p>You can close this tab.</p></div></body></html>`,A=e=>`<!DOCTYPE html><html><body style="font-family:system-ui;display:flex;justify-content:center;align-items:center;height:100vh;margin:0">
|
|
9
|
+
<div style="text-align:center"><h1>Login failed</h1><p>${e}</p></div></body></html>`;async function Hn(e,t){const{tokenEndpoint:n}=de[e],r=await fetch(n,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"refresh_token",client_id:P,refresh_token:t})});if(!r.ok){const a=await r.text();throw new Error(`Token refresh failed: ${r.status} ${a}`)}const o=await r.json();if(!o.access_token)throw new Error("No access_token in refresh response");return{access_token:o.access_token,refresh_token:o.refresh_token}}function zn(e){const{authEndpoint:t,tokenEndpoint:n}=de[e],r=xn(),o=jn(r),a=x(B.randomBytes(16));return new Promise((i,s)=>{const c=ve.createServer(async(y,w)=>{if(!y.url?.startsWith("/callback")){w.writeHead(404),w.end();return}const T=new URL(y.url,"http://localhost").searchParams,j=T.get("code"),ge=T.get("state"),C=T.get("error");if(C){w.writeHead(200,{"Content-Type":"text/html"}),w.end(A(T.get("error_description")||C)),m(),s(new Error(T.get("error_description")||C));return}if(ge!==a){w.writeHead(200,{"Content-Type":"text/html"}),w.end(A("State mismatch")),m(),s(new Error("State mismatch — possible CSRF attack"));return}if(!j){w.writeHead(200,{"Content-Type":"text/html"}),w.end(A("No authorization code received")),m(),s(new Error("No authorization code received"));return}try{const D=await fetch(n,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"authorization_code",client_id:P,redirect_uri:X,code:j,code_verifier:r})});if(!D.ok){const me=await D.text();throw new Error(`Token exchange failed: ${D.status} ${me}`)}const J=await D.json(),F=J.access_token;if(!F)throw new Error("No access_token in token response");w.writeHead(200,{"Content-Type":"text/html"}),w.end(Fn),m(),i({access_token:F,refresh_token:J.refresh_token})}catch(D){w.writeHead(200,{"Content-Type":"text/html"}),w.end(A(D.message)),m(),s(D)}}),u=setTimeout(()=>{m(),s(new Error("Login timed out after 2 minutes"))},Nn);function m(){clearTimeout(u),c.close()}c.listen(19836,()=>{const y=`${t}?`+new URLSearchParams({client_id:P,redirect_uri:X,response_type:"code",scope:"openid offline_access",state:a,code_challenge:o,code_challenge_method:"S256"}).toString();process.stderr.write(`Opening browser for login...
|
|
10
|
+
`),Jn(y)}),c.on("error",y=>{m(),s(new Error(`Could not start local server: ${y.message}`))})})}const ue=be.createRequire(typeof document>"u"?require("url").pathToFileURL(__filename).href:document.currentScript&&document.currentScript.src||new URL("cli.cjs",document.baseURI).href),{version:Kn}=ue("../package.json"),Vn=`ec.fdk <command> [options]
|
|
11
11
|
|
|
12
12
|
Commands:
|
|
13
13
|
login Login via browser (OIDC). Use --password for email/password prompt.
|
|
14
14
|
logout Logout and remove stored token
|
|
15
15
|
whoami Show current logged-in user
|
|
16
|
+
install-skill Install Claude Code skill (default: ~/.claude/skills, or --dir <path>)
|
|
16
17
|
|
|
17
18
|
Entry commands (require --dm, --model):
|
|
18
19
|
entryList List entries
|
|
@@ -107,34 +108,35 @@ Options:
|
|
|
107
108
|
--md Output entries as readable markdown
|
|
108
109
|
-v, --version Show version
|
|
109
110
|
--password Use email/password login instead of browser
|
|
110
|
-
-h, --help Show help`;function S(
|
|
111
|
-
`),process.exit(2)}function
|
|
111
|
+
-h, --help Show help`;function S(e){return Object.fromEntries(e.map(t=>{const n=t.indexOf("=");return n===-1&&f(`Invalid filter: "${t}" (expected key=value)`),[t.slice(0,n),t.slice(n+1)]}))}function f(e){process.stderr.write(`Error: ${e}
|
|
112
|
+
`),process.exit(2)}function Yn(){return new Promise(e=>{let t="";process.stdin.setEncoding("utf-8"),process.stdin.on("data",n=>t+=n),process.stdin.on("end",()=>e(t))})}async function k(e){if(e)try{return JSON.parse(e)}catch{f("--data must be valid JSON")}if(!process.stdin.isTTY){const t=await Yn();t.trim()||f("No data provided via stdin");try{return JSON.parse(t)}catch{f("Stdin must be valid JSON")}}f("Provide --data or pipe JSON via stdin")}function v(e){if(!e||typeof e!="object")return e;const{_links:t,_embedded:n,...r}=e;return r}function _(e){return!e||typeof e!="object"?e:Array.isArray(e.items)?{...e,items:e.items.map(v)}:v(e)}const Q=40;function Z(e){return e.length>Q?e.slice(0,Q-2)+"..":e}function le(e){return e==null?"":Z(typeof e=="object"?JSON.stringify(e):String(e))}function fe(e){return Object.keys(e).filter(t=>!t.startsWith("_"))}function O(e,t){return"| "+e.map((n,r)=>n.padEnd(t[r])).join(" | ")+" |"}function Wn(e){const t=fe(e),n=t.map(u=>le(e[u])),r=Math.max(5,...t.map(u=>u.length)),o=Math.max(5,...n.map(u=>u.length)),a=[r,o],i=O(["Field","Value"],a),s="| "+a.map(u=>"-".repeat(u)).join(" | ")+" |",c=t.map((u,m)=>O([u,n[m]],a));return`${i}
|
|
112
113
|
${s}
|
|
113
114
|
${c.join(`
|
|
114
|
-
`)}`}function
|
|
115
|
+
`)}`}function Xn(e){if(!e.items.length)return"No entries found.";const t=fe(e.items[0]),n=e.items.map(s=>t.map(c=>le(s[c]))),r=t.map((s,c)=>Math.max(s.length,...n.map(u=>u[c].length))),o=O(t,r),a="| "+r.map(s=>"-".repeat(s)).join(" | ")+" |",i=n.map(s=>O(s,r));return`${o}
|
|
115
116
|
${a}
|
|
116
117
|
${i.join(`
|
|
117
118
|
`)}
|
|
118
119
|
|
|
119
|
-
${
|
|
120
|
+
${e.items.length} of ${e.total} entries`}async function Qn(){const{values:e,positionals:t}=Te.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"},filter:{type:"string",short:"f",multiple:!0,default:[]},rid:{type:"string"},"account-id":{type:"string"},assetgroup:{type:"string"},resource:{type:"string"},subdomain:{type:"string"},raw:{type:"boolean",default:!1},md:{type:"boolean",default:!1},password:{type:"boolean",default:!1},dir:{type:"string"},version:{type:"boolean",short:"v"},help:{type:"boolean",short:"h"}}});e.version&&(console.log(Kn),process.exit(0)),(e.help||t.length===0)&&(console.log(Vn),process.exit(0));const n=t[0],r=e.env;r!=="stage"&&r!=="live"&&f('--env must be "stage" or "live"');const o=new N({env:r,storageAdapter:$});if(n!=="login"&&n!=="logout"){const a=o.getEcToken(),i=$.get(`${r}_refresh`);if(a&&i)try{const s=JSON.parse(Buffer.from(a.split(".")[1],"base64url").toString());if(s.exp&&s.exp*1e3<Date.now()){const c=await Hn(r,i);o.setEcToken(c.access_token),c.refresh_token&&$.set(`${r}_refresh`,c.refresh_token)}}catch{}}if(n==="login"){try{if(e.password){const a=await Bn("Email: "),i=await Gn("Password: ");await o.loginEc({email:a,password:i})}else{const a=await zn(r);o.setEcToken(a.access_token),a.refresh_token&&$.set(`${r}_refresh`,a.refresh_token)}process.stderr.write(`Logged in to ${r} successfully.
|
|
120
121
|
`)}catch(a){process.stderr.write(`Login failed: ${a.message}
|
|
121
122
|
`),process.exit(1)}return}if(n==="whoami"){const a=o.getEcToken();a||(process.stderr.write(`Not logged in to ${r}.
|
|
122
123
|
`),process.exit(1));try{const i=JSON.parse(Buffer.from(a.split(".")[1],"base64url").toString()),s={env:r};i.email&&(s.email=i.email),i.sub&&(s.accountID=i.sub),i.iss&&(s.issuer=i.iss),i.exp&&(s.expires=new Date(i.exp*1e3).toISOString()),process.stdout.write(JSON.stringify(s,null,2)+`
|
|
123
|
-
`)}catch{
|
|
124
|
-
`);return}
|
|
125
|
-
`);return}
|
|
126
|
-
`);return}
|
|
127
|
-
`);return}case"getSchema":{a=await s.
|
|
128
|
-
`);return}case"
|
|
129
|
-
`);return}case"
|
|
130
|
-
`);return}case"
|
|
131
|
-
`);return}case"
|
|
132
|
-
`);return}case"
|
|
133
|
-
`);return}case"
|
|
134
|
-
`);return}case"
|
|
135
|
-
`);return}
|
|
136
|
-
`);return}
|
|
137
|
-
`):process.stdout.write(
|
|
124
|
+
`)}catch{f("Could not decode token")}return}if(n==="install-skill"){const{mkdirSync:a,copyFileSync:i}=await import("node:fs"),{join:s,resolve:c}=await import("node:path"),{homedir:u}=await import("node:os"),m=e.dir?c(e.dir):s(u(),".claude"),y=s(m,"skills","ec-fdk"),w=ue.resolve("../skill/SKILL.md");a(y,{recursive:!0}),i(w,s(y,"SKILL.md")),process.stderr.write(`Installed skill to ${y}/SKILL.md
|
|
125
|
+
`);return}if(n==="logout"){try{o.hasEcToken()&&await o.logoutEc()}catch{}o.removeEcToken(),$.remove(`${r}_refresh`),process.stderr.write(`Logged out of ${r}.
|
|
126
|
+
`);return}try{let a;const i=()=>{const s={...S(e.filter)};return e.size&&(s.size=Number(e.size)),e.page&&(s.page=Number(e.page)),e.sort&&(s.sort=[e.sort]),s};switch(n){case"dmList":{a=await o.dmList(i()),e.raw||(a=_(a));break}case"modelList":{e.id||f("--id (datamanager UUID) is required for modelList"),a=await o.dmID(e.id).modelList(i()),e.raw||(a=_(a));break}case"getDatamanager":{e.id||f("--id (datamanager UUID) is required for getDatamanager"),a=await o.getDatamanager(e.id),e.raw||(a=_(a));break}case"resourceList":{e.resource||f("--resource is required for resourceList");let s=o.resource(e.resource);e.subdomain&&(s=s.subdomain(e.subdomain)),a=await s.resourceList(i()),e.raw||(a=_(a));break}case"resourceGet":{e.resource||f("--resource is required for resourceGet");let s=o.resource(e.resource);e.subdomain&&(s=s.subdomain(e.subdomain)),a=await s.resourceGet(S(e.filter)),e.raw||(a=v(a));break}case"resourceEdit":{e.resource||f("--resource is required for resourceEdit");let s=o.resource(e.resource);e.subdomain&&(s=s.subdomain(e.subdomain));const c=await k(e.data);if(a=await s.resourceEdit(S(e.filter),c),!a){process.stderr.write(`Resource updated.
|
|
127
|
+
`);return}e.raw||(a=v(a));break}case"resourceDelete":{e.resource||f("--resource is required for resourceDelete");let s=o.resource(e.resource);e.subdomain&&(s=s.subdomain(e.subdomain)),await s.resourceDelete(S(e.filter)),process.stderr.write(`Resource deleted.
|
|
128
|
+
`);return}case"getStats":{a=await o.getStats(i());break}case"getHistory":{a=await o.getHistory(i());break}case"entryList":case"getEntry":case"createEntry":case"editEntry":case"deleteEntry":case"getSchema":{e.dm||f("--dm is required"),e.model||f("--model is required");const s=o.dm(e.dm).model(e.model).clean(!e.raw);switch(n){case"entryList":{a=await s.entryList(i());break}case"getEntry":{e.id||f("--id is required for getEntry"),a=await s.getEntry(e.id);break}case"createEntry":{const c=await k(e.data);a=await s.createEntry(c);break}case"editEntry":{e.id||f("--id is required for editEntry");const c=await k(e.data);a=await s.editEntry(e.id,c);break}case"deleteEntry":{e.id||f("--id is required for deleteEntry"),await s.deleteEntry(e.id),process.stderr.write(`Entry deleted.
|
|
129
|
+
`);return}case"getSchema":{a=await s.getSchema();break}}break}case"createDatamanager":{const s=await k(e.data);a=await o.createDatamanager(s);break}case"editDatamanager":{e.id||f("--id (datamanager UUID) is required for editDatamanager");const s=await k(e.data);a=await o.editDatamanager(e.id,s);break}case"deleteDatamanager":{e.id||f("--id (datamanager UUID) is required for deleteDatamanager"),await o.deleteDatamanager(e.id),process.stderr.write(`Datamanager deleted.
|
|
130
|
+
`);return}case"createModel":{e.id||f("--id (datamanager UUID) is required for createModel");const s=await k(e.data);a=await o.dmID(e.id).createModel(s);break}case"editModel":{e.id||f("--id (datamanager UUID) is required for editModel"),e.rid||f("--rid (model ID) is required for editModel");const s=await k(e.data);a=await o.dmID(e.id).editModel(e.rid,s);break}case"deleteModel":{e.id||f("--id (datamanager UUID) is required for deleteModel"),e.rid||f("--rid (model ID) is required for deleteModel"),await o.dmID(e.id).deleteModel(e.rid),process.stderr.write(`Model deleted.
|
|
131
|
+
`);return}case"createTemplate":{const s=await k(e.data);a=await o.createTemplate(s);break}case"createAssetGroup":{e.id||f("--id (datamanager UUID) is required for createAssetGroup");const s=await k(e.data);a=await o.dmID(e.id).createAssetGroup(s);break}case"editAssetGroup":{e.id||f("--id (datamanager UUID) is required for editAssetGroup"),e.rid||f("--rid (asset group ID) is required for editAssetGroup");const s=await k(e.data);a=await o.dmID(e.id).editAssetGroup(e.rid,s);break}case"editAsset":{e.dm||f("--dm (short ID) is required for editAsset"),e.assetgroup||f("--assetgroup is required for editAsset"),e.rid||f("--rid (asset ID) is required for editAsset");const s=await k(e.data);a=await o.dm(e.dm).assetGroup(e.assetgroup).editAsset(e.rid,s);break}case"editDmClient":{e.id||f("--id (datamanager UUID) is required for editDmClient"),e.rid||f("--rid (client ID) is required for editDmClient");const s=await k(e.data);a=await o.dmID(e.id).editDmClient(e.rid,s);break}case"createRole":{e.id||f("--id (datamanager UUID) is required for createRole");const s=await k(e.data);a=await o.dmID(e.id).createRole(s);break}case"editRole":{e.id||f("--id (datamanager UUID) is required for editRole"),e.rid||f("--rid (role ID) is required for editRole");const s=await k(e.data);a=await o.dmID(e.id).editRole(e.rid,s);break}case"deleteRole":{e.id||f("--id (datamanager UUID) is required for deleteRole"),e.rid||f("--rid (role ID) is required for deleteRole"),await o.dmID(e.id).deleteRole(e.rid),process.stderr.write(`Role deleted.
|
|
132
|
+
`);return}case"editDmAccount":{e.id||f("--id (datamanager UUID) is required for editDmAccount"),e["account-id"]||f("--account-id is required for editDmAccount");const s=await k(e.data);a=await o.dmID(e.id).editDmAccount(e["account-id"],s);break}case"deleteDmAccount":{e.id||f("--id (datamanager UUID) is required for deleteDmAccount"),e["account-id"]||f("--account-id is required for deleteDmAccount"),await o.dmID(e.id).deleteDmAccount(e["account-id"]),process.stderr.write(`DM account deleted.
|
|
133
|
+
`);return}case"createAccountClient":{const s=await k(e.data);a=await o.createAccountClient(s);break}case"editAccountClient":{e.rid||f("--rid (client ID) is required for editAccountClient");const s=await k(e.data);a=await o.editAccountClient(e.rid,s);break}case"deleteAccountClient":{e.rid||f("--rid (client ID) is required for deleteAccountClient"),await o.deleteAccountClient(e.rid),process.stderr.write(`Account client deleted.
|
|
134
|
+
`);return}case"createGroup":{const s=await k(e.data);a=await o.createGroup(s);break}case"editGroup":{e.rid||f("--rid (group ID) is required for editGroup");const s=await k(e.data);a=await o.editGroup(e.rid,s);break}case"deleteGroup":{e.rid||f("--rid (group ID) is required for deleteGroup"),await o.deleteGroup(e.rid),process.stderr.write(`Group deleted.
|
|
135
|
+
`);return}case"createInvite":{const s=await k(e.data);a=await o.createInvite(s);break}case"editInvite":{e.rid||f("--rid (invite ID) is required for editInvite");const s=await k(e.data);a=await o.editInvite(e.rid,s);break}case"deleteInvite":{e.rid||f("--rid (invite ID) is required for deleteInvite"),await o.deleteInvite(e.rid),process.stderr.write(`Invite deleted.
|
|
136
|
+
`);return}case"editAccount":{e["account-id"]||f("--account-id is required for editAccount");const s=await k(e.data);if(a=await o.editAccount(e["account-id"],s),!a){process.stderr.write(`Account updated.
|
|
137
|
+
`);return}break}case"listTokens":{e["account-id"]||f("--account-id is required for listTokens");const s=await o.listTokens(e["account-id"]);a=e.raw?s:s.map(v);break}case"createToken":{e["account-id"]||f("--account-id is required for createToken"),a=await o.createToken(e["account-id"]);break}case"deleteToken":{e["account-id"]||f("--account-id is required for deleteToken"),e.rid||f("--rid (access token ID) is required for deleteToken"),await o.deleteToken(e["account-id"],e.rid),process.stderr.write(`Token deleted.
|
|
138
|
+
`);return}default:f(`Unknown command: ${n}`)}e.md&&a&&typeof a=="object"?Array.isArray(a.items)?process.stdout.write(Xn(a)+`
|
|
139
|
+
`):process.stdout.write(Wn(a)+`
|
|
138
140
|
`):process.stdout.write(JSON.stringify(a,null,2)+`
|
|
139
141
|
`)}catch(a){process.stderr.write(`${a.message}
|
|
140
|
-
`),process.exit(1)}}
|
|
142
|
+
`),process.exit(1)}}Qn();
|
package/package.json
CHANGED
package/skill/SKILL.md
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ec-fdk
|
|
3
|
+
description: Use when interacting with entrecode APIs, managing datamanagers, models, entries, assets, roles, accounts, or any ec.fdk CLI operations. Use when user mentions ec.fdk, entrecode, datamanager, shortID, or wants to open ec.editor4 URLs.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ec.fdk CLI
|
|
7
|
+
|
|
8
|
+
Use the `ec.fdk` CLI + `jq` for all entrecode API interactions. Always pipe output through `jq` to minimize tokens in context.
|
|
9
|
+
|
|
10
|
+
## Entry Commands (require `--dm`, `--model`)
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
# List entries
|
|
14
|
+
ec.fdk entryList -d <shortID> -m <model> | jq '.items'
|
|
15
|
+
|
|
16
|
+
# List entries sorted by newest first
|
|
17
|
+
ec.fdk entryList -d <shortID> -m <model> --sort=-_created -s 1
|
|
18
|
+
|
|
19
|
+
# List entries with filters
|
|
20
|
+
ec.fdk entryList -d <shortID> -m <model> -f name~=chocolate -f createdFrom=2024-01-01
|
|
21
|
+
|
|
22
|
+
# Get a single entry
|
|
23
|
+
ec.fdk getEntry -d <shortID> -m <model> -i <entryID>
|
|
24
|
+
|
|
25
|
+
# Get model schema (returns field names as top-level keys)
|
|
26
|
+
ec.fdk getSchema -d <shortID> -m <model> | jq 'keys'
|
|
27
|
+
|
|
28
|
+
# Create an entry
|
|
29
|
+
ec.fdk createEntry -d <shortID> -m <model> --data '{"name":"new","value":10}'
|
|
30
|
+
|
|
31
|
+
# Create via stdin pipe
|
|
32
|
+
echo '{"name":"piped"}' | ec.fdk createEntry -d <shortID> -m <model>
|
|
33
|
+
|
|
34
|
+
# Edit an entry
|
|
35
|
+
ec.fdk editEntry -d <shortID> -m <model> -i <entryID> --data '{"name":"updated"}'
|
|
36
|
+
|
|
37
|
+
# Delete an entry
|
|
38
|
+
ec.fdk deleteEntry -d <shortID> -m <model> -i <entryID>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Datamanager Commands
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
# Find a datamanager's shortID
|
|
45
|
+
ec.fdk dmList -f title=HO | jq '.items[0].shortID'
|
|
46
|
+
|
|
47
|
+
# Find a datamanager's UUID
|
|
48
|
+
ec.fdk dmList -f title=HO | jq '.items[0].dataManagerID'
|
|
49
|
+
|
|
50
|
+
# Get a single datamanager
|
|
51
|
+
ec.fdk getDatamanager --id <dataManagerID>
|
|
52
|
+
|
|
53
|
+
# Create a datamanager
|
|
54
|
+
ec.fdk createDatamanager --data '{"title":"My DM","config":{}}'
|
|
55
|
+
|
|
56
|
+
# editDatamanager is a full PUT — pass the complete resource, not just changed fields.
|
|
57
|
+
ec.fdk getDatamanager --id <dataManagerID> \
|
|
58
|
+
| jq '.title = "New Title"' \
|
|
59
|
+
| ec.fdk editDatamanager --id <dataManagerID>
|
|
60
|
+
|
|
61
|
+
# Delete a datamanager
|
|
62
|
+
ec.fdk deleteDatamanager --id <dataManagerID>
|
|
63
|
+
|
|
64
|
+
# Datamanager stats
|
|
65
|
+
ec.fdk getStats
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Model Commands (`--id` = DM UUID)
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
# List models of a datamanager
|
|
72
|
+
ec.fdk modelList --id <dataManagerID> | jq '[.items[].title]'
|
|
73
|
+
|
|
74
|
+
# Search models by name
|
|
75
|
+
ec.fdk modelList --id <dataManagerID> -f title~=muffin | jq '[.items[].title]'
|
|
76
|
+
|
|
77
|
+
# Create a model
|
|
78
|
+
ec.fdk createModel --id <dataManagerID> --data '{"title":"article","locales":[],"fields":[]}'
|
|
79
|
+
|
|
80
|
+
# Edit a model
|
|
81
|
+
ec.fdk editModel --id <dataManagerID> --rid <modelID> --data '{"title":"renamed","locales":[],"fields":[]}'
|
|
82
|
+
|
|
83
|
+
# Delete a model
|
|
84
|
+
ec.fdk deleteModel --id <dataManagerID> --rid <modelID>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Generic Resource Commands
|
|
88
|
+
|
|
89
|
+
For any resource type not covered by specific commands, use `resource*`:
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
# List any resource type
|
|
93
|
+
ec.fdk resourceList --resource template -s 5
|
|
94
|
+
ec.fdk resourceList --resource client --subdomain accounts
|
|
95
|
+
|
|
96
|
+
# Get / edit / delete (use -f to identify the resource)
|
|
97
|
+
ec.fdk resourceGet --resource model -f dataManagerID=<dataManagerID> -f modelID=<modelID>
|
|
98
|
+
ec.fdk resourceGet --resource group --subdomain accounts -f groupID=<groupID>
|
|
99
|
+
ec.fdk resourceEdit --resource invite --subdomain accounts -f invite=<inviteID> --data '{"email":"user@example.com","permissions":["dm-read"],"groups":[]}'
|
|
100
|
+
ec.fdk resourceDelete --resource role -f dataManagerID=<dataManagerID> -f roleID=<roleID>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### `resourceList` Resource Types
|
|
104
|
+
|
|
105
|
+
| `--resource` | `--subdomain` | Typical filters |
|
|
106
|
+
| --- | --- | --- |
|
|
107
|
+
| `model` | — | `-f dataManagerID=<dataManagerID>` |
|
|
108
|
+
| `assetgroup` | — | `-f dataManagerID=<dataManagerID>` |
|
|
109
|
+
| `client` | — | `-f dataManagerID=<dataManagerID>` |
|
|
110
|
+
| `role` | — | `-f dataManagerID=<dataManagerID>` |
|
|
111
|
+
| `account` | — | `-f dataManagerID=<dataManagerID>` |
|
|
112
|
+
| `template` | — | — |
|
|
113
|
+
| `tag` | — | `-f dataManagerID=<dataManagerID>` |
|
|
114
|
+
| `account` | `accounts` | — |
|
|
115
|
+
| `client` | `accounts` | — |
|
|
116
|
+
| `group` | `accounts` | — |
|
|
117
|
+
| `invite` | `accounts` | — |
|
|
118
|
+
| `account/tokens` | `accounts` | `-f accountID=<accountID>` |
|
|
119
|
+
|
|
120
|
+
## Other Admin Commands
|
|
121
|
+
|
|
122
|
+
```sh
|
|
123
|
+
# Login via browser OIDC (stores token in ~/.ec-fdk/auth.json)
|
|
124
|
+
ec.fdk login -e stage
|
|
125
|
+
|
|
126
|
+
# Login via email/password prompt
|
|
127
|
+
ec.fdk login -e stage --password
|
|
128
|
+
|
|
129
|
+
# Logout (removes stored token)
|
|
130
|
+
ec.fdk logout -e stage
|
|
131
|
+
|
|
132
|
+
# Show current user
|
|
133
|
+
ec.fdk whoami -e stage
|
|
134
|
+
|
|
135
|
+
# dm-history (requires shortID filter)
|
|
136
|
+
ec.fdk getHistory -f shortID=<shortID> -s 10
|
|
137
|
+
|
|
138
|
+
# Template
|
|
139
|
+
ec.fdk createTemplate --data '{"name":"My Template","collection":{"id":"<collectionID>","name":"my-collection","order":[],"requests":[]}}'
|
|
140
|
+
|
|
141
|
+
# Asset group
|
|
142
|
+
ec.fdk createAssetGroup --id <dataManagerID> --data '{"assetGroupID":"photos"}'
|
|
143
|
+
ec.fdk editAssetGroup --id <dataManagerID> --rid <assetGroup> --data '{"public":true}'
|
|
144
|
+
|
|
145
|
+
# Asset metadata
|
|
146
|
+
ec.fdk editAsset --dm <shortID> --assetgroup <assetGroup> --rid <assetID> --data '{"title":"sunset"}'
|
|
147
|
+
|
|
148
|
+
# DM client
|
|
149
|
+
ec.fdk editDmClient --id <dataManagerID> --rid <clientID> --data '{"callbackURL":"https://example.com/cb"}'
|
|
150
|
+
|
|
151
|
+
# Role
|
|
152
|
+
ec.fdk createRole --id <dataManagerID> --data '{"name":"editor"}'
|
|
153
|
+
ec.fdk editRole --id <dataManagerID> --rid <roleID> --data '{"name":"admin"}'
|
|
154
|
+
ec.fdk deleteRole --id <dataManagerID> --rid <roleID>
|
|
155
|
+
|
|
156
|
+
# DM account
|
|
157
|
+
ec.fdk editDmAccount --id <dataManagerID> --account-id <accountID> --data '{"email":"user@example.com"}'
|
|
158
|
+
ec.fdk deleteDmAccount --id <dataManagerID> --account-id <accountID>
|
|
159
|
+
|
|
160
|
+
# Account client (editAccountClient is a full PUT — clientID is required in the body)
|
|
161
|
+
ec.fdk createAccountClient --data '{"clientID":"my-client","callbackURL":"https://example.com/cb"}'
|
|
162
|
+
ec.fdk deleteAccountClient --rid <clientID>
|
|
163
|
+
|
|
164
|
+
# Group
|
|
165
|
+
ec.fdk createGroup --data '{"name":"devs"}'
|
|
166
|
+
ec.fdk editGroup --rid <groupID> --data '{"name":"developers"}'
|
|
167
|
+
ec.fdk deleteGroup --rid <groupID>
|
|
168
|
+
|
|
169
|
+
# Invite (editInvite is a full PUT — pass the complete resource)
|
|
170
|
+
ec.fdk createInvite --data '{"email":"user@example.com"}'
|
|
171
|
+
ec.fdk editInvite --rid <inviteID> --data '{"email":"user@example.com","permissions":["dm-read"],"groups":[]}'
|
|
172
|
+
ec.fdk deleteInvite --rid <inviteID>
|
|
173
|
+
|
|
174
|
+
# Account
|
|
175
|
+
ec.fdk editAccount --account-id <accountID> --data '{"email":"user@example.com"}'
|
|
176
|
+
|
|
177
|
+
# Tokens
|
|
178
|
+
ec.fdk listTokens --account-id <accountID>
|
|
179
|
+
ec.fdk createToken --account-id <accountID>
|
|
180
|
+
ec.fdk deleteToken --account-id <accountID> --rid <tokenID>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Quick Reference
|
|
184
|
+
|
|
185
|
+
| Command | Required flags |
|
|
186
|
+
| --- | --- |
|
|
187
|
+
| **Entry** (require `--dm`, `--model`) | |
|
|
188
|
+
| `entryList` | `--dm`, `--model` |
|
|
189
|
+
| `getEntry` | `--dm`, `--model`, `--id` |
|
|
190
|
+
| `createEntry` | `--dm`, `--model`, `--data` |
|
|
191
|
+
| `editEntry` | `--dm`, `--model`, `--id`, `--data` |
|
|
192
|
+
| `deleteEntry` | `--dm`, `--model`, `--id` |
|
|
193
|
+
| `getSchema` | `--dm`, `--model` |
|
|
194
|
+
| **Datamanager** (`--id` = DM UUID) | |
|
|
195
|
+
| `dmList` | — |
|
|
196
|
+
| `getDatamanager` | `--id` |
|
|
197
|
+
| `createDatamanager` | `--data` |
|
|
198
|
+
| `editDatamanager` | `--id`, `--data` (full PUT) |
|
|
199
|
+
| `deleteDatamanager` | `--id` |
|
|
200
|
+
| `getStats` | — |
|
|
201
|
+
| **Model** (`--id` = DM UUID) | |
|
|
202
|
+
| `modelList` | `--id` |
|
|
203
|
+
| `createModel` | `--id`, `--data` |
|
|
204
|
+
| `editModel` | `--id`, `--rid`, `--data` |
|
|
205
|
+
| `deleteModel` | `--id`, `--rid` |
|
|
206
|
+
| **Generic resource** | |
|
|
207
|
+
| `resourceList` | `--resource` |
|
|
208
|
+
| `resourceGet` | `--resource`, `-f` filters |
|
|
209
|
+
| `resourceEdit` | `--resource`, `-f` filters, `--data` |
|
|
210
|
+
| `resourceDelete` | `--resource`, `-f` filters |
|
|
211
|
+
| **Auth** | |
|
|
212
|
+
| `login` | — (add `--password` for email/password prompt) |
|
|
213
|
+
| `logout` | — |
|
|
214
|
+
| `whoami` | — |
|
|
215
|
+
| `install-skill` | — (optional `--dir <path>`) |
|
|
216
|
+
|
|
217
|
+
## Options
|
|
218
|
+
|
|
219
|
+
| Option | Description |
|
|
220
|
+
| --- | --- |
|
|
221
|
+
| `-e, --env` | `stage` (default) or `live` |
|
|
222
|
+
| `-d, --dm` | DataManager short ID |
|
|
223
|
+
| `-m, --model` | Model name |
|
|
224
|
+
| `-i, --id` | Entry ID or DataManager UUID (context-dependent) |
|
|
225
|
+
| `--rid` | Resource ID (model, role, client, asset group, invite, token, etc.) |
|
|
226
|
+
| `--account-id` | Account ID |
|
|
227
|
+
| `--assetgroup` | Asset group name (for `editAsset`) |
|
|
228
|
+
| `--resource` | Resource name (for `resource*` commands) |
|
|
229
|
+
| `--subdomain` | Subdomain override (for `resource*` commands, default: `datamanager`) |
|
|
230
|
+
| `--data` | JSON data (via flag or stdin pipe) |
|
|
231
|
+
| `-s, --size` | Page size |
|
|
232
|
+
| `-p, --page` | Page number |
|
|
233
|
+
| `--sort` | Sort field (system fields: `_created`, `_modified`) |
|
|
234
|
+
| `-f, --filter` | Repeatable filter (`key=value`) |
|
|
235
|
+
| `--password` | Use email/password login instead of browser OIDC |
|
|
236
|
+
| `--dir` | Target directory for `install-skill` (default: `~/.claude`) |
|
|
237
|
+
| `--raw` | Include `_links` and `_embedded` |
|
|
238
|
+
| `--md` | Output as markdown table |
|
|
239
|
+
|
|
240
|
+
## Filter Suffixes
|
|
241
|
+
|
|
242
|
+
Filters map to entrecode filter query params:
|
|
243
|
+
|
|
244
|
+
- `~` — search (contains): `-f name~=chocolate`
|
|
245
|
+
- `From` — greater than / after: `-f createdFrom=2024-01-01`
|
|
246
|
+
- `To` — less than / before: `-f createdTo=2025-01-01`
|
|
247
|
+
- (none) — exact match: `-f title=HO`
|
|
248
|
+
|
|
249
|
+
## Common Mistakes
|
|
250
|
+
|
|
251
|
+
- **Using `--id` for entry commands** — entry commands need `--dm` (shortID) + `--model`, not `--id` for the DM
|
|
252
|
+
- **Partial PUT on editDatamanager/editAccountClient/editInvite** — these are full PUT operations, pass the complete resource
|
|
253
|
+
- **Forgetting `jq`** — always pipe through `jq` to keep output concise
|
|
254
|
+
- **Wrong ID type** — `--dm` takes shortID, `--id` takes UUID for datamanager commands
|
|
255
|
+
|
|
256
|
+
## ec.editor4 URLs
|
|
257
|
+
|
|
258
|
+
Base URLs:
|
|
259
|
+
- Stage: `https://e4.cachena.entrecode.de`
|
|
260
|
+
- Live: `https://e4.entrecode.de`
|
|
261
|
+
|
|
262
|
+
When the user asks to "open" a resource, output the full editor URL. Use `open <url>` via Bash to open it in the browser. Default to stage unless the user specifies live.
|
|
263
|
+
|
|
264
|
+
| Resource | URL pattern |
|
|
265
|
+
|---|---|
|
|
266
|
+
| Datamanager | `/d/{shortID}` |
|
|
267
|
+
| Model list | `/d/{shortID}/model` |
|
|
268
|
+
| Model entries | `/d/{shortID}/model/{model}/entry` |
|
|
269
|
+
| Model settings | `/d/{shortID}/model/{model}/settings` |
|
|
270
|
+
| Create entry | `/d/{shortID}/model/{model}/entry/create` |
|
|
271
|
+
| Entry | `/d/{shortID}/model/{model}/entry/{entryID}` |
|
|
272
|
+
| Entry history | `/d/{shortID}/model/{model}/entry/{entryID}/history` |
|
|
273
|
+
| Asset groups | `/d/{shortID}/assetgroup` |
|
|
274
|
+
| Asset group | `/d/{shortID}/assetgroup/{assetgroup}` |
|
|
275
|
+
| Asset | `/d/{shortID}/assetgroup/{assetgroup}/asset/{assetID}` |
|
|
276
|
+
| Roles | `/d/{shortID}/roles` |
|
|
277
|
+
| Role | `/d/{shortID}/roles/{roleID}` |
|
|
278
|
+
| Clients | `/d/{shortID}/clients` |
|
|
279
|
+
| DM Accounts | `/d/{shortID}/accounts` |
|
|
280
|
+
| DM Graph | `/d/{shortID}/graph` |
|
|
281
|
+
| DM Settings | `/d/{shortID}/settings` |
|
|
282
|
+
| Accounts | `/accounts` |
|
|
283
|
+
| Account | `/accounts/{accountID}` |
|
|
284
|
+
| Apps | `/apps` |
|
|
285
|
+
|
|
286
|
+
## Notes
|
|
287
|
+
|
|
288
|
+
- Status/error messages go to stderr, data goes to stdout — piping always works cleanly
|
|
289
|
+
- `editDatamanager`, `editAccountClient`, and `editInvite` are full PUT operations — pass the complete resource
|
|
290
|
+
- `--data` accepts JSON via flag or stdin pipe (e.g. `echo '{}' | ec.fdk createEntry ...`)
|