ec.fdk 0.8.5 → 0.8.6

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 CHANGED
@@ -128,6 +128,7 @@ ec.fdk <command> [options]
128
128
  | `-p, --page <n>` | Page number for list |
129
129
  | `--sort <field>` | Sort field for list |
130
130
  | `--raw` | Include `_links` and `_embedded` in output |
131
+ | `--md` | Output entries as readable markdown table |
131
132
  | `-h, --help` | Show help |
132
133
 
133
134
  ### Examples
package/dist/cli.cjs CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- "use strict";const M=require("node:util"),w=require("node:fs"),q=require("node:path"),R=require("node:os"),U=require("node:readline");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(),a=`${o.title}
2
+ "use strict";const G=require("node:util"),w=require("node:fs"),x=require("node:path"),H=require("node:os"),W=require("node:readline");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(),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 f(n,t="stage",e="datamanager"){const s=k[e];if(!s)throw new Error(`subdomain "${e}" not found. Try one of ${Object.keys(k).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 J={stage:"https://accounts.cachena.entrecode.de/",live:"https://accounts.entrecode.de/"};async function X(n){let{env:t,dmShortID:e,email:s,password:r}=n;l({env:t,dmShortID:e,email:s,password:r});const i=f(`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 Y(n){let{env:t,email:e,password:s}=n;l({env:t,email:e,password:s});const r=`${J[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 Q(n){let{dmShortID:t,env:e,token:s}=n;l({dmShortID:t,env:e,token:s});const r=f(`api/${t}/_auth/logout?clientID=rest&token=${s}`,e);return await h(r,{rawRes:!0},{method:"POST"})}async function Z(n){let{env:t,token:e}=n;l({env:t,token:e});const s=`${J[t]}auth/logout?clientID=rest`;return await h(s,{rawRes:!0,token:e},{method:"POST"})}function tt({dmShortID:n}){return l({dmShortID:n}),n}function et({env:n}){return l({env:n}),n}let nt=["created","creator","id","modified","private","_created","_creator","_embedded","_entryTitle","_id","_links","_modelTitle","_modelTitleField","_modified"];function M(n){let t={};for(let e in n)nt.includes(e)||(t[e]=n[e]);return t}function st(n){return JSON.parse(JSON.stringify(n))}async function rt(n){let{env:t,dmShortID:e}=n;l({env:t,dmShortID:e});const s=f(`api/${e}`,t);return h(s,n)}async function C(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=f(`api/${e}/${s}?${i}`,t),{count:a,total:c,_embedded:d}=await h(o,n);let u=d?d[`${e}:${s}`]:[];return u=Array.isArray(u)?u:[u],{count:a,total:c,items:u}}function it({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=f(`api/${t}/${e}?${i}`,n);return h(o,{token:r})}async function ot({env:n,dmShortID:t,model:e,value:s,token:r}){l({env:n,dmShortID:t,model:e,value:s});const i=f(`api/${t}/${e}`,n);return await h(i,{token:r},{method:"POST",body:JSON.stringify(s),headers:{"Content-Type":"application/json"}})}async function I({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=f(`api/${t}/${e}?_id=${s}`,n);return r=st(r),r=M(r),await h(c,{token:i},{method:"PUT",headers:a,body:JSON.stringify(r)})}function F({env:n,dmShortID:t,model:e,entryID:s,token:r}){l({env:n,dmShortID:t,model:e,entryID:s});const i=f(`api/${t}/${e}?_id=${s}`,n);return h(i,{token:r,rawRes:!0},{method:"DELETE",headers:{"Content-Type":"application/json"}})}async function at(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 d=await C(n);for(let u of d.items)c.push(await t(u));o+=d.items.length,a=d.total,n.options.page++}return c}async function ct({env:n,dmShortID:t,model:e,withMetadata:s}){l({env:n,dmShortID:t,model:e});const r=f(`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=M(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 g=u.title.split("<")[1].slice(0,-1),y=u.title.split("<")[0];u.type=y,g.includes(":")?u.resource=g.split(":")[1]:u.resource=g}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 z(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 dt=z;function _(n){return n._links.collection.href.split("/").slice(-2)[0]}function R(n){const t=n._links.collection.href.split("api/")[0];return Object.keys(k.datamanager).find(s=>k.datamanager[s]===t)}const U=n=>{const t=_(n),e=R(n),s=n._modelTitle,r=n.id;return{dmShortID:t,env:e,model:s,entryID:r}},ut=n=>F(U(n)),lt=(n,t)=>I({...U(n),value:t});function ht(n,t){const e=_(t);return t._embedded[`${e}:${t._modelTitle}/${n}/asset`]}async function ft({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=f(`a/${t}/${e}?${i}`,n),{_embedded:a}=await h(o,{token:r});return a?a["ec:dm-asset"]:void 0}async function gt(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=f(`a/${e}/${s}?${o}`,t),{count:c,total:d,_embedded:u}=await h(a,{token:r});let g=u?u["ec:dm-asset"]:[];return g=Array.isArray(g)?g:[g],{count:c,total:d,items:g}}async function pt({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=f(`a/${t}/${e}`,n),c=new FormData;return c.append("file",r,i),o&&Object.keys(o).forEach(u=>{c.append(u,o[u])}),(await h(a,{token:s},{method:"POST",body:c}))._embedded["ec:dm-asset"]}async function mt({env:n,dmShortID:t,assetGroup:e,files:s,options:r}){l({env:n,dmShortID:t,assetGroup:e,files:s});const i=f(`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 yt({env:n,dmShortID:t,assetGroup:e,assetID:s,token:r}){l({env:n,dmShortID:t,assetGroup:e,assetID:s});const i=f(`a/${t}/${e}/${s}`,n);await h(i,{token:r,rawRes:!0},{method:"DELETE"})}function wt(n,t,e=!1){let s,r;return(e?n?.thumbnails:n?.fileVariants)?.forEach(o=>{const{resolution:{width:a,height:c}}=o,d=Math.abs(Math.max(a,c)-t);(!r||d<r)&&(r=d,s=o)}),s?.url??n?.file?.url??null}function $t(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 d=s.thumbnails.find(y=>c===y.dimension),u=`${a}/t/${t}/${s.assetID}/${c}`,g=d?d.url:u;return{size:c,url:g,generated:d}}):o.map(c=>{const d=s.fileVariants.find(y=>c===Math.max(y.resolution.width,y.resolution.height)),u=`${a}/f/${t}/${s.assetID}/${c}`,g=d?d.url:u;return{size:c,url:g,generated:d}})}async function bt(n){let{env:t,dmID:e,token:s}=n;l({env:t,dmID:e});const r=f(`?dataManagerID=${e}`,t);return h(r,{token:s})}async function kt(n){let{env:t,options:e={}}=n;l({env:t}),e={size:25,page:1,_list:!0,...e};const s=m(e),r=f(`?${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 Et(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=f(`model?${r}`,t),{count:o,total:a,_embedded:c}=await h(i,n);let d=c?c["ec:model"]:[];return d=Array.isArray(d)?d:[d],{count:o,total:a,items:d}}async function Tt(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=f(`${e}?${i}`,t,r),{count:a,total:c,_embedded:d}=await h(o,n);let u=d?d[Object.keys(d)[0]]:[];return u=Array.isArray(u)?u:[u],{count:a,total:c,items:u}}async function At(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=f(`${s}?${o}`,e,i);return h(a,n,t)}const St=Object.freeze(Object.defineProperty({__proto__:null,assetList:gt,createAsset:pt,createAssets:mt,createEntry:ot,deleteAsset:yt,deleteEntry:F,deleteEntryObject:ut,dmList:kt,editEntry:I,editEntryObject:lt,entryList:C,fileVariant:wt,filterOptions:dt,getAsset:ft,getDatamanager:bt,getEcAuthKey:et,getEntry:it,getEntryAsset:ht,getEntryEnv:R,getEntryShortID:_,getFileVariants:$t,getPublicAuthKey:tt,getSchema:ct,loginEc:Y,loginPublic:X,logoutEc:Z,logoutPublic:Q,mapEntries:at,modelList:Et,publicApi:rt,raw:At,resourceList:Tt,sdkOptions:z},Symbol.toStringTag,{value:"Module"})),{entryList:j,mapEntries:_t,getEntry:Ot,getAsset:jt,assetList:v,createAsset:vt,createAssets:Pt,deleteAsset:Lt,createEntry:Dt,editEntry:P,deleteEntry:qt,getSchema:Nt,loginPublic:Bt,loginEc:xt,logoutEc:Jt,logoutPublic:Mt,getEcAuthKey:$,getPublicAuthKey:b,dmList:Ct,modelList:It,publicApi:Ft,getDatamanager:zt,resourceList:Rt,raw:Ut}=St;function L(n){if(!n||typeof n!="object")return n;const{_links:t,_embedded:e,...s}=n;return s}function Kt(n){return!n||typeof n!="object"?n:Array.isArray(n.items)?{...n,items:n.items.map(L)}:L(n)}class O{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 O({...this.config,...t})}async entries(t={}){const e=await this.getBestToken();return j({...this.config,options:t,token:e})}async entryList(t){const e=await this.getBestToken();return j({...this.config,options:t,token:e}).then(s=>this.maybeClean(s))}async mapEntries(t,e={}){const s=await this.getBestToken();return _t({...this.config,options:e,token:s},t)}async getEntry(t){const e=await this.getBestToken();return Ot({...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 Nt(this.config)}async assets(t){const e=await this.getBestToken();return v({...this.config,options:t,token:e})}async assetList(t){const e=await this.getBestToken();return v({...this.config,options:t,token:e})}async createAsset(t){const{file:e,name:s,options:r}=t,i=await this.getBestToken();return vt({...this.config,file:e,name:s,options:r,token:i})}async createAssets(t){const{files:e,options:s}=t,r=await this.getBestToken();return Pt({...this.config,files:e,options:s,token:r})}async deleteAsset(t){const e=await this.getBestToken();return Lt({...this.config,token:e,assetID:t})}async getAsset(t){const e=await this.getBestToken();return jt({...this.config,assetID:t,token:e})}async createEntry(t){const e=await this.getBestToken();return Dt({...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 qt({...this.config,token:e,entryID:t})}async resourceList(t){const e=await this.getBestToken();return Rt({...this.config,options:t,token:e})}async raw(t,e){const s=await this.getBestToken();return Ut({...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 xt({...this.config,...t}).then(e=>this.setToken($(this.config),e.token))}loginPublic(t){return Bt({...this.config,...t}).then(e=>this.setToken(b(this.config),e.token))}logoutPublic(){const t=this.getPublicToken();return Mt({...this.config,token:t}).then(()=>this.removeToken(b(this.config)))}logoutEc(){const t=this.getEcToken();return Jt({...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?Kt(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 Ft(this.config)}async getDatamanager(t){const e=await this.getBestToken();return zt({...this.config,dmID:t,token:e})}async dmList(t={}){const e=await this.getBestToken();return Ct({...this.config,options:t,token:e})}async modelList(t={}){const e=await this.getBestToken();return It({...this.config,options:t,token:e})}}const A=x.join(H.homedir(),".ec-fdk"),S=x.join(A,"auth.json");function T(){try{return w.existsSync(S)?JSON.parse(w.readFileSync(S,"utf-8")):{}}catch{return{}}}function D(n){w.existsSync(A)||w.mkdirSync(A,{recursive:!0,mode:448}),w.writeFileSync(S,JSON.stringify(n,null,2),{mode:384})}const Vt={get(n){return T()[n]},set(n,t){const e=T();e[n]=t,D(e)},remove(n){const t=T();delete t[n],D(t)}};function Gt(n){const t=W.createInterface({input:process.stdin,output:process.stderr});return new Promise(e=>{t.question(n,s=>{t.close(),e(s)})})}function Ht(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(`
5
5
  `),process.exit(130)),i==="\r"||i===`
6
6
  `){e.setRawMode(!1),e.pause(),e.removeListener("data",r),process.stderr.write(`
7
- `),t(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("*")};e.on("data",r)})}const Ut=`ec.fdk <command> [options]
7
+ `),t(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("*")};e.on("data",r)})}const Wt=`ec.fdk <command> [options]
8
8
 
9
9
  Commands:
10
10
  login Login with ec credentials (interactive prompt)
@@ -25,10 +25,21 @@ Options:
25
25
  -p, --page <n> Page number for list
26
26
  --sort <field> Sort field for list
27
27
  --raw Include _links and _embedded in output
28
+ --md Output entries as readable markdown
28
29
  -h, --help Show help`;function p(n){process.stderr.write(`Error: ${n}
29
- `),process.exit(2)}function Kt(){return new Promise(n=>{let t="";process.stdin.setEncoding("utf-8"),process.stdin.on("data",e=>t+=e),process.stdin.on("end",()=>n(t))})}async function D(n){if(n)try{return JSON.parse(n)}catch{p("--data must be valid JSON")}if(!process.stdin.isTTY){const t=await Kt();t.trim()||p("No data provided via stdin");try{return JSON.parse(t)}catch{p("Stdin must be valid JSON")}}p("Provide --data or pipe JSON via stdin")}async function Vt(){const{values:n,positionals:t}=M.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},help:{type:"boolean",short:"h"}}});(n.help||t.length===0)&&(console.log(Ut),process.exit(0));const e=t[0],s=n.env;s!=="stage"&&s!=="live"&&p('--env must be "stage" or "live"');const r=new _({env:s,storageAdapter:Ft});if(e==="login"){const o=await Mt("Email: "),a=await Rt("Password: ");try{await r.loginEc({email:o,password:a}),process.stderr.write(`Logged in to ${s} successfully.
30
+ `),process.exit(2)}function Xt(){return new Promise(n=>{let t="";process.stdin.setEncoding("utf-8"),process.stdin.on("data",e=>t+=e),process.stdin.on("end",()=>n(t))})}async function q(n){if(n)try{return JSON.parse(n)}catch{p("--data must be valid JSON")}if(!process.stdin.isTTY){const t=await Xt();t.trim()||p("No data provided via stdin");try{return JSON.parse(t)}catch{p("Stdin must be valid JSON")}}p("Provide --data or pipe JSON via stdin")}const N=40;function B(n){return n.length>N?n.slice(0,N-2)+"..":n}function K(n){return n==null?"":B(typeof n=="object"?JSON.stringify(n):String(n))}function V(n){return Object.keys(n).filter(t=>!t.startsWith("_"))}function E(n,t){return"| "+n.map((e,s)=>e.padEnd(t[s])).join(" | ")+" |"}function Yt(n){const t=V(n),e=t.map(d=>K(n[d])),s=Math.max(5,...t.map(d=>d.length)),r=Math.max(5,...e.map(d=>d.length)),i=[s,r],o=E(["Field","Value"],i),a="| "+i.map(d=>"-".repeat(d)).join(" | ")+" |",c=t.map((d,u)=>E([d,e[u]],i));return`${o}
31
+ ${a}
32
+ ${c.join(`
33
+ `)}`}function Qt(n){if(!n.items.length)return"No entries found.";const t=V(n.items[0]),e=n.items.map(a=>t.map(c=>K(a[c]))),s=t.map((a,c)=>Math.max(a.length,...e.map(d=>d[c].length))),r=E(t,s),i="| "+s.map(a=>"-".repeat(a)).join(" | ")+" |",o=e.map(a=>E(a,s));return`${r}
34
+ ${i}
35
+ ${o.join(`
36
+ `)}
37
+
38
+ ${n.items.length} of ${n.total} entries`}async function Zt(){const{values:n,positionals:t}=G.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},help:{type:"boolean",short:"h"}}});(n.help||t.length===0)&&(console.log(Wt),process.exit(0));const e=t[0],s=n.env;s!=="stage"&&s!=="live"&&p('--env must be "stage" or "live"');const r=new O({env:s,storageAdapter:Vt});if(e==="login"){const o=await Gt("Email: "),a=await Ht("Password: ");try{await r.loginEc({email:o,password:a}),process.stderr.write(`Logged in to ${s} successfully.
30
39
  `)}catch(c){process.stderr.write(`Login failed: ${c.message}
31
- `),process.exit(1)}return}n.dm||p("--dm is required"),n.model,n.model||p("--model is required");const i=r.dm(n.dm).model(n.model).clean(!n.raw);try{let o;switch(e){case"entryList":{const a={};n.size&&(a.size=Number(n.size)),n.page&&(a.page=Number(n.page)),n.sort&&(a.sort=[n.sort]),o=await i.entryList(a);break}case"getEntry":{n.id||p("--id is required for getEntry"),o=await i.getEntry(n.id);break}case"createEntry":{const a=await D(n.data);o=await i.createEntry(a);break}case"editEntry":{n.id||p("--id is required for editEntry");const a=await D(n.data);o=await i.editEntry(n.id,a);break}case"deleteEntry":{n.id||p("--id is required for deleteEntry"),await i.deleteEntry(n.id),process.stderr.write(`Entry deleted.
32
- `);return}case"getSchema":{o=await i.getSchema();break}default:p(`Unknown command: ${e}`)}process.stdout.write(JSON.stringify(o,null,2)+`
40
+ `),process.exit(1)}return}n.dm||p("--dm is required"),n.model,n.model||p("--model is required");const i=r.dm(n.dm).model(n.model).clean(!n.raw);try{let o;switch(e){case"entryList":{const a={};n.size&&(a.size=Number(n.size)),n.page&&(a.page=Number(n.page)),n.sort&&(a.sort=[n.sort]),o=await i.entryList(a);break}case"getEntry":{n.id||p("--id is required for getEntry"),o=await i.getEntry(n.id);break}case"createEntry":{const a=await q(n.data);o=await i.createEntry(a);break}case"editEntry":{n.id||p("--id is required for editEntry");const a=await q(n.data);o=await i.editEntry(n.id,a);break}case"deleteEntry":{n.id||p("--id is required for deleteEntry"),await i.deleteEntry(n.id),process.stderr.write(`Entry deleted.
41
+ `);return}case"getSchema":{o=await i.getSchema();break}default:p(`Unknown command: ${e}`)}n.md&&o&&typeof o=="object"?Array.isArray(o.items)?process.stdout.write(Qt(o)+`
42
+ `):process.stdout.write(Yt(o)+`
43
+ `):process.stdout.write(JSON.stringify(o,null,2)+`
33
44
  `)}catch(o){process.stderr.write(`${o.message}
34
- `),process.exit(1)}}Vt();
45
+ `),process.exit(1)}}Zt();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ec.fdk",
3
- "version": "0.8.5",
3
+ "version": "0.8.6",
4
4
  "description": "ec frontend sdk",
5
5
  "main": "dist/index.cjs",
6
6
  "bin": {