@emuanalytics/flow-cli 2.2.4 → 2.2.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/dist/index.mjs +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -24,4 +24,4 @@ ${Gs(e)}
|
|
|
24
24
|
`)}function Gs(e){const t=e.docs;return t?`
|
|
25
25
|
${w.dim("Further reading:")}
|
|
26
26
|
|
|
27
|
-
${w.dim("-")} ${w.cyan(t)}`:""}function Zs(e){let t=me.get(e);return t||(t=Fs(e),t.catch(a=>{l(a)}),me.set(e,t)),t}async function Fs(e){const t=process.cwd(),a=P(t,".tmp-flow-starter"),i=await Ts(e);return le(a),await Ps(i,a),await qs("install",a),async n=>{const s=P(t,n);await Js(a,s),await Ue({files:[P(s,"*"),P(s,"config/**"),P(s,"src/**")],from:/flow-starter-project-name/g,to:n,allowEmptyPaths:!0}),le(null)}}function Ks(e){return!/[^a-zA-Z0-9-]/.test(e)}function zs(e,t){if(e.includes("/"))return{name:e,repo:e};const a=t.find(i=>i.name===e);if(!a)throw new Error(`Starter "${e}" does not exist.`);return a}const Vs=["new [name]"],Ws="Create a new Flo.w app",Bs=e=>e.option("s",{alias:"starter",describe:"Starter template",type:"string"}).positional("name",{describe:"Project name",type:"string"});async function Hs(e){try{const t=await fetch(`${re}/index.json`).then(i=>i.json());if(!e.starter){const i=await b.prompt([{type:"select",name:"starter",message:"Starter template",choices:t.map(n=>n.name),default:t[0].name}]);e.starter=i.starter}const a=zs(e.starter,t);await Rs(a,e.name,!1)}catch(t){l(t.message)}}const Qs={__proto__:null,builder:Bs,command:Vs,desc:Ws,handler:Hs},Xs=["cache [id]"],Ys="Show pipeline cache",eo=e=>e.positional("id",{describe:"Pipeline id (or unique prefix)",type:"string"});async function to({client:e,id:t,format:a}){try{const i=await p(t,e.pipelines,"id",["components"],["id","components.index"]);if(!i){d({message:`Pipeline not found: ${t}`},a??"json");return}const n=(i.components??[]).filter(o=>o.class==="cache").sort((o,r)=>o.index-r.index),s=n.map(o=>({id:o.id,type:o.type,description:o.description,related_components:o.metadata.components.join()}));if(a==="json"){d({id:i.id,environment:i.environment,caches:n},"json");return}s.length?d(s,"table",null,{noWrap:!0}):v("No Caches Found")}catch(i){l(i)}}const io={__proto__:null,builder:eo,command:Xs,desc:Ys,handler:to},ao=["components <id>","comps <id>"],no="Show pipeline components",so=e=>e.positional("id",{describe:"Pipeline id (or unique prefix)",type:"string"});async function oo({client:e,id:t,format:a}){try{const i=await p(t,e.pipelines,"id",["components"],["id","components.index"]);if(!i){d({message:`Pipeline not found: ${t}`},a??"json");return}const n=i.components??[];if(a==="json"){d(n,"json");return}const s=ro(n);if(!s.length){v("No Components Found");return}d(s,"table",["id","class","type","description","note"])}catch(i){l(i)}}function ro(e){if(!e.length)return[];const t={};e.forEach(o=>t[o.id]={...o,next:[],previous:[],indent:0}),Object.values(t).forEach(o=>{const r=o.metadata||{},c=r.previousComponents??[],m=r.nextComponents??[];o.previous=c.map(y=>t[y]),o.next=m.map(y=>t[y])});const a={};Object.values(t).forEach(o=>{const r=(o.metadata||{}).parentComponent;r&&(a[r]||(a[r]=[]),a[r].push(o))}),Object.values(a).forEach(o=>{o.sort((r,c)=>r.index-c.index)});const i=Object.values(t).filter(o=>o.class!=="cache"&&(o.previous??[]).length===0),n=new Set;function s(o,r){if(!o||n.has(o.id))return;n.add(o.id),o.indent=r,o.class==="pipeline"&&(a[o.id]??[]).forEach(y=>s(y,r+1));const c=(o.next??[]).filter(y=>y.class!=="cache"),m=o.type==="fp:fork"||c.length>1;c.forEach(y=>s(y,m?r+1:r))}return i.forEach(o=>s(o,0)),Object.values(t).filter(o=>o.class!=="cache").sort((o,r)=>o.index-r.index).map(o=>{const r=[],c=(o.metadata||{}).caches??[];c.length>0&&r.push(`uses cache: ${c.join(", ")}`);const m=o.indent>0?" ".repeat(o.indent)+"> ":"";function y(f){return f.class==="pipeline"?`(${f.id})`:f.type==="fp:fork"?`[${f.id}]`:f.id}return{id:m+y(o),class:o.class,type:o.type,description:o.description,note:r.join()}})}const co={__proto__:null,builder:so,command:ao,desc:no,handler:oo},lo=["config [id]"],po="Show pipeline config",mo=e=>e.positional("id",{describe:"Pipeline id (or unique prefix)",type:"string"});async function uo({client:e,id:t,format:a}){try{const i=(await p(t,e.pipelines,"id"))?.config;if(!i||Object.keys(i).length===0){d({message:`No configuration found for pipeline ${t}`},a??"json");return}const n=X(i);if(a==="json"){d(i,"json");return}const s=Object.entries(n).map(([o,r])=>({key:o,value:r}));d(s,"table",["key","value"],{noWrap:!0})}catch(i){l(i)}}function ue(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function X(e,t="",a={}){for(const[i,n]of Object.entries(e)){const s=t?`${t}.${i}`:i;Array.isArray(n)?n.forEach((o,r)=>{const c=`${s}[${r}]`;ue(o)?X(o,c,a):a[c]=o}):ue(n)?X(n,s,a):a[s]=n}return a}const yo={__proto__:null,builder:mo,command:lo,desc:po,handler:uo},fo=["list [id]","ls","$0"],bo="List pipelines",go=e=>e.option("limit",{alias:"n",type:"number",describe:"Limit to n results"}).option("sort",{alias:["s"],type:"string",describe:"Sort by attribute"}).option("filter-cache",{type:"string",describe:"Filter pipelines using a specific cache ID (partial match)"}).option("filter-dataset",{type:"string",describe:"Filter pipelines using a specific dataset ID (partial match)"}).option("components",{type:"boolean",describe:"Include pipeline components in the JSON output"}).positional("id",{describe:"Pipeline id (or unique prefix)",type:"string"}).conflicts("id",["limit","sort","filter-cache","filter-dataset"]);async function ho({client:e,id:t,format:a,limit:i,sort:n,filterCache:s,filterDataset:o,components:r}){try{if(n??="id",t){const f=await p(t,e.pipelines,"id",void 0,n),g=fe(f);a==="table"?d(ye(g),"table",null,{noWrap:!0}):d(g,a);return}const c=!!s||!!o,m=r||c,y=(await e.pipelines.list({sort:n,limit:c?void 0:i,join:m?"components":void 0})).filter(f=>$o(f,s)).filter(f=>wo(f,o)).slice(0,c?i:void 0).map(f=>r?f:_o(f));xo(y,a)}catch(c){l(c)}}function wo(e,t){return!t||ie(e.components).some(a=>a.class==="sink"&&a.type==="fp:flow-ingest-stream"&&a.config?.datasetId?.includes(t))}function $o(e,t){return!t||ie(e.components).some(a=>a.class==="cache"&&a.config?.id?.includes(t))}function _o({components:e,...t}){return t}function xo(e,t){const a=e.map(fe);t==="table"?d(a.map(ye),"table",["id","environment","version","description","startedAt","heartbeatAt"]):d(a,t??"json")}function ye(e){const t=e.heartbeatAt&&(Date.now()-new Date(e.heartbeatAt).getTime())/1e3<30;return{...e,heartbeatAt:{color:t?"06a453":"e11529",value:e.heartbeatAt}}}function fe(e){const t=e.metadata.version?.tag;return{...e,version:t&&t.replace(/^release-/,"")}}const vo={__proto__:null,builder:go,command:fo,desc:bo,handler:ho},So=["sink [id]"],Ao="Show pipeline sink",Do=e=>e.positional("id",{describe:"Pipeline id (or unique prefix)",type:"string"});async function No({client:e,id:t,format:a}){try{const i=await p(t,e.pipelines,"id",["components"],["id","components.index"]);if(!i){d({message:`Pipeline not found: ${t}`},a??"json");return}const n=(i.components??[]).filter(o=>o.class==="sink").sort((o,r)=>o.index-r.index),s=n.reduce((o,r)=>(o[r.type]??=[],o[r.type].push(r),o),{});if(a==="json"){d({id:i.id,environment:i.environment,sinks:n},"json");return}if(Object.keys(s).length)for(const[,o]of Object.entries(s)){const r=o.map(c=>({id:c.id,description:c.description,...jo(c)}));d(r,"table")}else v("No Sinks Found")}catch(i){l(i)}}function jo(e){const t=e.config||{};switch(e.type){case"fp:amqp-writable-stream":return{vhost:t.vhost??"N/A",exchange:typeof t.exchange=="string"?t.exchange:t.exchange?.name??"N/A",enable:t.enable};case"fp:flow-ingest-stream":return{datasetId:t.datasetId??"N/A",enable:t.enable};case"fp:sqs-writable-stream":return{queueUrl:t.queueUrl??"N/A",region:t.region??"N/A",enable:t.enable};case"fp:sns-writable-stream":return{topicArn:t.topicArn??"N/A",region:t.region??"N/A",enable:t.enable};case"fp:null-sink":return{logging:t.logging};default:return{}}}const ko={__proto__:null,builder:Do,command:So,desc:Ao,handler:No},Io=["source [id]"],Oo="Show pipeline source",To=e=>e.positional("id",{describe:"Pipeline id (or unique prefix)",type:"string"});async function Po({client:e,id:t,format:a}){try{const i=await p(t,e.pipelines,"id",["components"],["id","components.index"]);if(!i){d({message:`Pipeline not found: ${t}`},a??"json");return}const n=(i.components??[]).filter(o=>o.class==="source").sort((o,r)=>o.index-r.index),s=n.map(o=>({id:o.id,type:o.type,description:o.description,...Mo(o)}));if(a==="json"){d({id:i.id,environment:i.environment,sources:n},"json");return}s.length?d(s,"table"):v("No Sources Found")}catch(i){l(i)}}function Mo(e){const t=e.config||{};switch(e.type){case"fp:amqp-readable-stream":return{vhost:t.vhost??"N/A",exchange:t.queue?.bindTo?.exchange??t.exchange??"N/A",queue:typeof t.queue=="string"?t.queue:t.queue?.name??"N/A"};case"fp:mqtt-subscriber-stream":return{serverUrl:t.serverUrl??"N/A",topic:t.topic??"N/A"};case"fp:flow-dataset-stream":return{datasetId:t.datasetId??"N/A"};case"fp:db-timeseries-stream":return{database:t.database??"N/A",table:t.table??"N/A"};case"fp:sqs-readable-stream":return{queueUrl:t.queueUrl??"N/A",region:t.region??"N/A"};case"fp:s3-file-list-stream":return{bucket:t.bucket??"N/A"};case"fp:s3-file-loader-stream":return{bucket:t.bucket??"N/A"};case"fp:planefinder-firehose-stream":return{host:t.host??"N/A"};case"fp:tcp-tls-readable-stream":return{hostname:t.hostname??"N/A"};case"fp:timer-stream":return{interval:t.interval??"N/A"};default:return{}}}const Eo={__proto__:null,builder:To,command:Io,desc:Oo,handler:Po},Lo=["pipelines <command>","pipes"],qo="Pipeline commands",Co=e=>e.command(vo).command(yo).command(co).command(Eo).command(ko).command(io).demandCommand(1),Uo={__proto__:null,builder:Co,command:Lo,desc:qo},Jo="create <id>",Ro="Create a new map style",Go=e=>e.positional("id",{describe:"Map style id",type:"string"}).option("name",{alias:"n",describe:"Name for new style",type:"string"}).option("description",{alias:"d",describe:"Description for new style",type:"string"}).option("interactive",{alias:"i",describe:"Show interactive prompts",type:"boolean",default:"true"}).option("sourceId",{alias:"sid",describe:"ID of source style",type:"string",default:"darkmatter"}).option("sourceKey",{alias:"skey",describe:"API key to access source style",type:"string",default:"6f19c5c7-1a9b-425b-84ab-09ba56e905b2"}),Zo=async e=>{try{const t=[].concat(await be(e.host,e.apiKey),await be(e.host,e.sourceKey)),a=t.map(s=>({name:s.name,value:s,short:s.name}));let i=t.find(s=>s.id===e.sourceId);if(e.interactive){const s=await b.prompt([{type:"input",name:"name",message:"Name for new style",default:e.name},{type:"input",name:"description",message:"Description for new style",default:e.description},{type:"select",name:"sourceStyle",message:"Select the source style to copy",choices:a,default:i}]);e.name=s.name,e.description=s.description,e.sourceId=s.sourceStyle.id,i=t.find(o=>o.id===e.sourceId)}i.style.id=e.id,i.style.name=e.name,i.style.metadata.description=e.description;let n={id:e.id,name:e.name,description:e.description,type:"plain",style:i.style};n=await e.client.styles.create(n),e.format==="table"?d(n,"table",["id","name","description","type"]):d(n,e.format??"json")}catch(t){l(t)}};async function be(e,t){return new K(e,t).styles.list()}const Fo={__proto__:null,builder:Go,command:Jo,desc:Ro,handler:Zo},Ko=["delete <id>","rm","del"],zo="Delete a map style",Vo=e=>e.option("yes",{alias:"y",description:"Answer 'yes' to confirmation messages",default:!1}).positional("id",{describe:"Map style id (or unique prefix)",type:"string"});async function Wo({client:e,id:t,yes:a}){try{const i=await p(t,e.styles);let n=a;n||(n=(await b.prompt({name:"confirmed",type:"confirm",message:`Are you sure you want to delete '${i.id}'`,default:!1})).confirmed),n&&(await e.styles.delete(i.id),_("Deleted"))}catch(i){l(i)}}const Bo={__proto__:null,builder:Vo,command:Ko,desc:zo,handler:Wo},Ho=j.dirname(Ee(import.meta.url)),x=z();x.use(z.json({limit:"1mb"})),x.use(z.static(j.join(Ho,"../maputnik"))),x.get("/styles",(e,t)=>{v(":thumbsup: Maputnik connected");const a=x.get("style");t.json([a.id])}),x.get("/styles/:id",async(e,t)=>{try{const a=x.get("style");v(`Loading style '${a.id}'`),t.json(a)}catch(a){l(a.message)}}),x.put("/styles/:id",async(e,t)=>{try{const a=x.get("client");if(x.set("style",e.body),!x.get("writeable"))return t.status(204).send();const i={...e.body};i.sources=Qo(i.sources,`${a.baseUrl}`),i.glyphs=q(i.glyphs,a.baseUrl),i.sprite=q(i.sprite,a.baseUrl),await Yo(a,i.id,i),t.status(204).send()}catch(a){l(a.message)}});function Qo(e,t){return Object.keys(e).reduce((a,i)=>{let n=e[i];return Object.prototype.hasOwnProperty.call(n,"url")&&(n={...n,url:q(n.url,t)}),Object.prototype.hasOwnProperty.call(n,"data")&&(n={...n,data:q(n.data,t)}),Object.prototype.hasOwnProperty.call(n,"tiles")&&(n={...n,tiles:n.tiles.map(s=>q(s,t))}),a[i]=n,a},{})}function q(e,t){const a=new URL(e,t);return a.searchParams.delete("apikey"),a.toString().replace(t,"").replace(/%7B/g,"{").replace(/%7D/g,"}")}function Xo(e,t,a){return e.styles.update(t,{style:a})}const Yo=Re(Xo,2e3,{leading:!0});class Y{server;port;constructor(t,a,i){this.port=this.normalizePort(process.env.PORT||"8000"),x.set("port",this.port),x.set("style",a),x.set("writeable",i),x.set("client",t),this.server=Je.createServer(x),this.server.listen(this.port),this.server.on("error",this.onError.bind(this)),this.server.on("listening",this.onListening.bind(this))}normalizePort(t){const a=parseInt(t,10);return isNaN(a)?t:a>=0?a:!1}onError(t){if(t.syscall!=="listen")throw t;const a=typeof this.port=="string"?`Pipe ${this.port}`:`Port ${this.port}`;switch(t.code){case"EACCES":l(`${a} requires elevated privileges`),process.exit(1);break;case"EADDRINUSE":l(`${a} is already in use`),process.exit(1);break;default:throw t}}onListening(){_(`Style server listening on port ${this.port}`),v(`:rocket: Point your browser at http://localhost:${this.port}`),this.postListen()}postListen(){return Promise.resolve(null)}}const er="edit <id>",tr="Edit a map style in maputnik",ir=e=>e.positional("id",{describe:"Map style id (or unique prefix)",type:"string"}),ar=async({client:e,id:t})=>{try{const a=await p(t,e.styles),i=await e.maps.get(a.id,{apikey:e.apiKey});new Y(e,i,!0),V("http://localhost:8000")}catch(a){l(a)}},nr={__proto__:null,builder:ir,command:er,desc:tr,handler:ar},sr=["list [id]","ls","$0"],or="List map styles",rr=e=>e.option("limit",{alias:"n",type:"number",describe:"Limit to n results"}).option("sort",{alias:["s"],type:"string",describe:"Sort by attribute"}).conflicts("id",["limit","sort"]).positional("id",{describe:"Map style id (or unique prefix)",type:"string"});async function dr({client:e,id:t,format:a,limit:i,sort:n}){try{if(t){const s=await p(t,e.styles);d(s,a)}else{const s=await e.styles.list({limit:i,sort:n});a==="table"?d(s,"table",["id","name","description","type"]):d(s,a??"json")}}catch(s){l(s)}}const cr={__proto__:null,builder:rr,command:sr,desc:or,handler:dr},lr=["metadata <id>","meta"],pr="Get/set resource metadata",mr=e=>e.positional("id",{describe:"Map style id (or unique prefix)",type:"string"}).option("set",{type:"array",describe:"One or more key/values to set in form <key>=<value>. Use <key>= to delete a key."});async function ur({client:e,id:t,set:a}){try{if(a){let i=await p(t,e.styles);const n=k(a);for(const s of Object.keys(n)){const o=n[s];o===""?await e.styles.deleteMetadata(i.id,s):await e.styles.setMetadata(i.id,s,o)}i=await p(t,e.styles),d(i.metadata,"json")}else{const i=await p(t,e.styles);d(i.metadata,"json")}}catch(i){l(i)}}const yr={__proto__:null,builder:mr,command:lr,desc:pr,handler:ur},fr="view <id>",br="View a map style in maputnik",gr=e=>e.positional("id",{describe:"Map style id (or unique prefix)",type:"string"}),hr=async({client:e,id:t})=>{try{const a=await p(t,e.styles),i=await e.maps.get(a.id,{apikey:e.apiKey});new Y(e,i,!1),V("http://localhost:8000")}catch(a){l(a)}},wr={__proto__:null,builder:gr,command:fr,desc:br,handler:hr},$r="styles <command>",_r="Style commands",xr=e=>e.command(cr).command(Fo).command(Bo).command(nr).command(wr).command(yr).demandCommand(1),vr={__proto__:null,builder:xr,command:$r,desc:_r},Sr=["create <id>"],Ar="Create a new tile source",Dr=e=>e.option("type",{alias:"t",description:"Tilesource type",type:"string",choices:["tilelive","dataset"]}).option("source",{alias:"s",description:"Tilesource source (tilelive URL or dataset ID)",type:"string"}).option("attribution",{alias:"a",description:"Tilesource attribution",type:"string"}).option("minZoom",{alias:"m",description:"Minimum zoom",type:"number"}).option("maxZoom",{alias:"M",description:"Maximum zoom",type:"number"}).option("extent",{alias:"e",description:"Extent x1,y1,x2,y2 (lng/lat)",type:"array"}).option("headers",{alias:"H",description:"Tile HTTP headers (space-separated <name>=<value> pairs)",type:"array"}).option("interactive",{alias:"i",describe:"Show interactive prompts",type:"boolean",default:"true"}).positional("id",{describe:"Tilesource id",type:"string"});async function Nr(e){const t=e.client,a=await t.tileSources.drivers();try{if(e.interactive){const s=await b.prompt([{type:"select",name:"type",message:"Data source",choices:a,default:e.type||"dataset"},{type:"input",name:"source",message:"TileLive URL",default:e.source,when:({type:o})=>o==="tilelive"},{type:"select",name:"source",message:"Dataset",choices:kr.bind(null,e.client),default:e.source,when:({type:o})=>o==="dataset"},{type:"input",name:"attribution",message:"Attribution",default:e.attribution},{type:"input",name:"minZoom",message:"Minimum zoom",default:e.minZoom||0,validate:o=>ee(o)||"Enter a number"},{type:"input",name:"maxZoom",message:"Maximum zoom",default:e.maxZoom||18,validate:o=>ee(o)||"Enter a number"},{type:"confirm",name:"overrideExtent",message:"Override auto-calculated map extent",default:e.extent?!!e.extent.length:!1},{type:"input",name:"extent",message:"Map extent (x1 y1 x2 y2) (blank for auto-detect)",validate:o=>ge(o)||"Enter lng/lat bounding box as x1 y1 x2 y2",when:({overrideExtent:o})=>o}]);e.type=s.type,e.source=s.source,e.attribution=s.attribution,e.minZoom=s.minZoom,e.maxZoom=s.maxZoom,e.extent=s.overrideExtent?s.extent.split(" "):[]}let i;if(e.extent&&e.extent.length===0)i=null;else if(e.extent){if(!ge(e.extent))throw new Error("Bad format for extent: specify 'x1 y1 x2 y2' (lng/lat)");i=jr(e.extent)}let n={id:e.id,type:e.type,source:e.source,attribution:e.attribution,minZoom:e.minZoom,maxZoom:e.maxZoom,extentLngLat:i};n=await t.tileSources.create(n),e.format==="table"?d(n,"table",["id","type","source","minZoom","maxZoom"]):d(n,e.format??"json")}catch(i){l(i)}}function ee(e){return!isNaN(parseFloat(e))&&isFinite(e)}function ge(e){return!e||e.length===0||(typeof e=="string"&&(e=e.split(" ")),e.length!==4)?!1:!e.find(t=>!ee(t))}function jr(e){return e==null?null:(typeof e=="string"&&(e=e.split(" ")),e.map(t=>parseFloat(t)))}async function kr(e){return(await e.datasets.list({sort:"id"})).map(t=>t.id)}const Ir={__proto__:null,builder:Dr,command:Sr,desc:Ar,handler:Nr},Or=["delete <id>","rm","del"],Tr="Delete a tile source",Pr=e=>e.option("yes",{alias:"y",description:"Answer 'yes' to confirmation messages",default:!1}).positional("id",{describe:"Tile source id (or unique prefix)",type:"string"});async function Mr({client:e,id:t,yes:a}){try{const i=await p(t,e.tileSources);let n=a;n||(n=(await b.prompt({name:"confirmed",type:"confirm",message:`Are you sure you want to delete '${i.id}'`,default:!1})).confirmed),n&&(await e.tileSources.delete(i.id),_("Deleted"))}catch(i){l(i)}}const Er={__proto__:null,builder:Pr,command:Or,desc:Tr,handler:Mr},Lr=["list [id]","ls","$0"],qr="List tile sources",Cr=e=>e.option("limit",{alias:"n",type:"number",describe:"Limit to n results"}).option("sort",{alias:["s"],type:"string",describe:"Sort by attribute"}).conflicts("id",["limit","sort"]).positional("id",{describe:"Tile source id",type:"string"});async function Ur({client:e,id:t,format:a,limit:i,sort:n}){try{if(t){const s=await p(t,e.tileSources);d(s,a)}else{const s=await e.tileSources.list({limit:i,sort:n});a==="table"?d(s,"table",["id","type","source","minZoom","maxZoom"]):d(s,a??"json")}}catch(s){l(s)}}const Jr={__proto__:null,builder:Cr,command:Lr,desc:qr,handler:Ur},Rr=["metadata <id>","meta"],Gr="Get/set resource metadata",Zr=e=>e.positional("id",{describe:"Tile Source id (or unique prefix)",type:"string"}).option("set",{type:"array",describe:"One or more key/values to set in form <key>=<value>. Use <key>= to delete a key."});async function Fr({client:e,id:t,set:a}){try{if(a){let i=await p(t,e.tileSources);const n=k(a);for(const s of Object.keys(n)){const o=n[s];o===""?await e.tileSources.deleteMetadata(i.id,s):await e.tileSources.setMetadata(i.id,s,o)}i=await p(t,e.tileSources),d(i.metadata,"json")}else{const i=await p(t,e.tileSources);d(i.metadata,"json")}}catch(i){l(i)}}const Kr={__proto__:null,builder:Zr,command:Rr,desc:Gr,handler:Fr},zr="preview <tilesourceId>",Vr="Preview a tile source in maputnik",Wr=async({client:e,tilesourceId:t})=>{try{const a=await p(t,e.tileSources),i=await e.tiles.getPreviewStyle(a.id,{apikey:e.apiKey});new Y(e,i,!1),V("http://localhost:8000")}catch(a){l(a)}},Br={__proto__:null,command:zr,desc:Vr,handler:Wr},Hr=["tilespec <tilesourceId>"],Qr="Get tileJson for tile source",Xr=e=>e.positional("tilesourceId",{describe:"Tile source id",type:"string"}),Yr=async({client:e,format:t,tilesourceId:a})=>{try{const i=await p(a,e.tileSources),n=await e.tiles.getTileSpec(i.id);t==="table"&&(delete n.vector_layers,delete n.attribution,delete n.tiles,n.center=JSON.stringify(n.center),n.bounds=JSON.stringify(n.bounds)),d(n,t)}catch(i){l(i)}},ed={__proto__:null,builder:Xr,command:Hr,desc:Qr,handler:Yr},td=["update <id>"],id="Update a tile source",ad=e=>e.option("type",{alias:"t",description:"Tilesource type",type:"string"}).option("source",{alias:"s",description:"Tilesource source (tilelive URL or dataset ID)",type:"string"}).option("attribution",{alias:"a",description:"Tilesource attribution",type:"string"}).option("minZoom",{alias:"m",description:"Minimum zoom",type:"number"}).option("maxZoom",{alias:"M",description:"Maximum zoom",type:"number"}).option("extent",{alias:"e",description:"Extent x1,y1,x2,y2 (lng/lat)",type:"array"}).option("headers",{alias:"H",description:"Tile HTTP headers (space-separated <name>=<value> pairs)",type:"array"}).option("interactive",{alias:"i",describe:"Show interactive prompts",type:"boolean",default:"true"}).positional("id",{describe:"Tilesource id (or unique prefix)",type:"string"});async function nd(e){const t=e.client,a=e.id,i=await t.tileSources.drivers();try{let n=await p(a,t.tileSources);if(e.interactive){const r=await b.prompt([{type:"select",name:"type",message:"Tilesource Type",choices:i,default:e.type||n.type},{type:"input",name:"source",message:"TileLive URL",default:e.source||n.source,when:({type:c})=>c==="tilelive"},{type:"select",name:"source",message:"Dataset",choices:sd.bind(null,e.client),default:e.source||n.source,when:({type:c})=>c!=="tilelive"},{type:"input",name:"attribution",message:"Attribution",default:e.attribution||n.attribution},{type:"input",name:"minZoom",message:"Minimum zoom",default:e.minZoom||n.minZoom,validate:c=>M(c)||"Enter a number"},{type:"input",name:"maxZoom",message:"Maximum zoom",default:e.maxZoom||n.maxZoom,validate:c=>M(c)||"Enter a number"},{type:"confirm",name:"overrideExtent",message:"Override map extent specfied by dataset",default:e.extent?!!e.extent.length:!!n.extentLngLat},{type:"input",name:"extent",message:"Map extent (x1 y1 x2 y2) (blank to use extent specified by dataset)",default:R(e.extent||n.extentLngLat),validate:c=>J(c)||"Enter lng/lat bounding box as x1 y1 x2 y2",when:({overrideExtent:c})=>c}]);e.type=r.type,e.source=r.source,e.attribution=r.attribution,e.minZoom=r.minZoom,e.maxZoom=r.maxZoom,e.extent=r.overrideExtent?r.extent.split(" "):[]}let s;e.headers&&(s=e.headers.reduce((r,c)=>{const[m,y]=c.split("=");if(!m||!y)throw new Error("Bad format for headers: specify key/value pairs as <header>=<value>");return r[m]=y,r},{}));let o;if(e.extent&&e.extent.length===0)o=null;else if(e.extent){if(!J(e.extent))throw new Error("Bad format for extent: specify 'x1 y1 x2 y2' (lng/lat)");o=W(e.extent)}n=await t.tileSources.update(n.id,{id:e.id,type:e.type,source:e.source,attribution:e.attribution,headers:s,minZoom:e.minZoom,maxZoom:e.maxZoom,extentLngLat:o}),d(n,"table")}catch(n){l(n)}}async function sd(e){return(await e.datasets.list({sort:"id"})).map(t=>t.id)}const od={__proto__:null,builder:ad,command:td,desc:id,handler:nd},rd="tiles <command>",dd="Tile commands",cd=e=>e.command(Jr).command(Ir).command(Er).command(od).command(Kr).command(Br).command(ed).demandCommand(1),ld={__proto__:null,builder:cd,command:rd,desc:dd},pd=["list [id]","ls"],md="List uploads",ud=e=>e.option("limit",{alias:"n",type:"number",describe:"Limit to n results"}).option("sort",{alias:["s"],type:"string",describe:"Sort by attribute"}).positional("id",{describe:"Upload id",type:"string"}).conflicts("id",["limit","sort"]);async function yd({client:e,id:t,format:a,limit:i,sort:n}){try{if(t){const s=await p(t,e.uploads);d(s,a)}else{const s=await e.uploads.list({limit:i,sort:n});a==="table"?d(s,"table",["id","fileName","status"]):d(s,a??"json")}}catch(s){l(s)}}const fd={__proto__:null,builder:ud,command:pd,desc:md,handler:yd},{fileSize:bd}=Ge,gd=1e3,hd=["upload <filePath>","$0"],wd="Upload a geospatial data file",$d=e=>e.option("i",{alias:"id",describe:"Dataset id",type:"string"}).option("n",{alias:"name",describe:"Dataset name",type:"string"}).option("d",{alias:"description",describe:"Dataset description",type:"string"}).option("a",{alias:"attribution",describe:"Tiles source attribution",type:"string"}).option("source-srid",{describe:"Source SRID (default auto-detected from source)",type:"number"}).option("target-srid",{describe:"Target SRID (default auto-detected from source)",number:!0,type:"number"}).option("schema",{describe:"Database schema (defaults to 'public' if not specified)",type:"string"}).positional("filePath",{describe:"Path to file to upload",type:"string"}),_d=async e=>{Object.prototype.hasOwnProperty.call(e,"source-srid")&&isNaN(e["source-srid"])&&(l("--source-srid must be a number"),process.exit(1)),Object.prototype.hasOwnProperty.call(e,"target-srid")&&isNaN(e["target-srid"])&&(l("--target-srid must be a number"),process.exit(1));const t=j.basename(e.filePath);v(`Uploading file ${t} ...`);const a=T("Uploading").start(),i=T("Ingesting"),n=T("Processing");try{const s=$.createReadStream(e.filePath),o=await e.client.uploads.upload({data:s,filename:t,datasetId:e.id,datasetName:e.name,datasetDescription:e.description,attribution:e.attribution,sourceSrid:e["source-srid"],targetSrid:e["target-srid"],schema:e.schema}),r=o.id,c=g=>new Promise(S=>{setTimeout(S,g)});let m,y=o.status,f=a;for(;;)if(await c(gd),m=await e.client.uploads.get(r),m.status!==y)if(y=m.status,y==="ingesting")a.succeed(),f=i,f.start();else if(y==="processing")a.succeed(),i.start(),i.succeed(),f=n,f.start();else if(y==="done"){a.succeed(),i.succeed(),n.succeed(),v(`Dataset uploaded with id '${m.options.datasetId}' (${bd(m.size)})`);break}else{f.fail(),l(m.error.message),_(m.error.stderr||m.error.stdout);break}}catch(s){a.stop(),i.stop(),n.stop(),l(s)}},xd={__proto__:null,builder:$d,command:hd,desc:wd,handler:_d},vd="upload <command>",Sd="Upload commands",Ad=e=>e.command(fd).command(xd).demandCommand(1),Dd={__proto__:null,builder:Ad,command:vd,desc:Sd},Nd=["create <email>"],jd="Create a user",kd=e=>e.option("firstName",{description:"First name",type:"string"}).option("lastName",{description:"Last name",type:"string"}).option("roles",{alias:"r",description:"Roles (comma-separated)",type:"array"}).option("emailVerified",{description:"Email verified",type:"boolean"}).option("enabled",{alias:"e",description:"Login enabled",type:"boolean"}).option("interactive",{alias:"i",describe:"Show interactive prompts",type:"boolean",default:"true"}).positional("email",{describe:"Email (or unique prefix)",type:"string"});async function Id(e){const t=e.client;try{if(e.interactive){const n=await b.prompt([{type:"input",name:"firstName",message:"First name",default:e.firstName},{type:"input",name:"lastName",message:"Last name",default:e.lastName},{type:"input",name:"roles",message:"Roles (comma separated)",default:(e.roles??[]).join(", ")},{type:"confirm",name:"emailVerified",message:"Verified?",default:Object.prototype.hasOwnProperty.call(e,"emailVerified")?e.emailVerified:!0},{type:"confirm",name:"enabled",message:"Enabled?",default:Object.prototype.hasOwnProperty.call(e,"enabled")?e.enabled:!0},{type:"password",name:"password",message:"Password"},{type:"password",name:"confirmPassword",message:"Confirm password"}]);if(n.password!==n.confirmPassword)throw new Error("Passwords do not match");e.firstName=n.firstName,e.lastName=n.lastName,e.roles=n.roles.split(",").map(s=>s.trim()),e.emailVerified=n.emailVerified,e.enabled=n.enabled,e.password=n.password}const a=await t.auth.users.create({email:e.email,firstName:e.firstName,lastName:e.lastName,roles:e.roles,emailVerified:e.emailVerified,enabled:e.enabled,password:e.password}),i=te();await t.auth.users.update(a.id,{passwordResetToken:i}),await t.auth.resetPassword(a.email,e.password,a.applicationId,i),e.format==="table"?d(a,"table"):d(a,"json")}catch(a){l(a)}}const Od={__proto__:null,builder:kd,command:Nd,desc:jd,handler:Id},Td=["delete <email>","rm","del"],Pd="Delete a user",Md=e=>e.option("yes",{alias:"y",description:"Answer 'yes' to confirmation messages",default:!1}).positional("email",{describe:"Email (or unique prefix)",type:"string"});async function Ed({client:e,email:t,yes:a}){try{const i=await p(t,e.auth.users,"email");let n=a;n||(n=(await b.prompt({name:"confirmed",type:"confirm",message:`Are you sure you want to delete '${i.email}'`,default:!1})).confirmed),n&&(await e.auth.users.delete(i.id),_("Deleted"))}catch(i){l(i)}}const Ld={__proto__:null,builder:Md,command:Td,desc:Pd,handler:Ed},qd=["list [email]","ls","$0"],Cd="List users",Ud=e=>e.option("limit",{alias:"n",type:"number",describe:"Limit to n results"}).option("sort",{alias:["s"],type:"string",describe:"Sort by attribute"}).conflicts("email",["limit","sort"]).positional("email",{describe:"User email (or unique prefix)",type:"string"});async function Jd({client:e,email:t,format:a,limit:i,sort:n}){try{if(t){const s=await p(t,e.auth.users,"email");d(s,a)}else{let s=await e.auth.users.list({limit:i,sort:n});a==="table"?(s=s.map(o=>({...o,name:`${o.firstName} ${o.lastName}`})),d(s,"table",["id","email","name","emailVerified","enabled"])):d(s,a??"json")}}catch(s){l(s)}}const Rd={__proto__:null,builder:Ud,command:qd,desc:Cd,handler:Jd},Gd=["metadata <email>","meta"],Zd="Get/set resource metadata",Fd=e=>e.positional("email",{describe:"User email (or unique prefix)",type:"string"}).option("set",{type:"array",describe:"One or more key/values to set in form <key>=<value>. Use <key>= to delete a key."});async function Kd({client:e,email:t,set:a}){try{if(a){let i=await p(t,e.auth.users,"email");const n=k(a);for(const s of Object.keys(n)){const o=n[s];o===""?await e.auth.users.deleteMetadata(i.id,s):await e.auth.users.setMetadata(i.id,s,o)}i=await p(t,e.auth.users,"email"),d(i.metadata,"json")}else{const i=await p(t,e.auth.users,"email");d(i.metadata,"json")}}catch(i){l(i)}}const zd={__proto__:null,builder:Fd,command:Gd,desc:Zd,handler:Kd},Vd=["update <email>"],Wd="Update a user",Bd=e=>e.option("firstName",{description:"First name",type:"string"}).option("lastName",{description:"Last name",type:"string"}).option("roles",{alias:"r",description:"Roles (comma-separated)",type:"array"}).option("emailVerified",{description:"Email verified",type:"boolean"}).option("enabled",{alias:"e",description:"Login enabled",type:"boolean"}).option("interactive",{alias:"i",describe:"Show interactive prompts",type:"boolean",default:"true"}).positional("email",{describe:"Email (or unique prefix)",type:"string"});async function Hd(e){const t=e.client,a=e.email;try{const i=await p(a,t.auth.users,"email");if(e.interactive){const s=await b.prompt([{type:"input",name:"firstName",message:"First name",default:e.firstName||i.firstName},{type:"input",name:"lastName",message:"Last name",default:e.lastName||i.lastName},{type:"input",name:"roles",message:"Roles (comma separated)",default:(e.roles||i.roles).join(", ")},{type:"confirm",name:"emailVerified",message:"Verified?",default:Object.prototype.hasOwnProperty.call(e,"emailVerified")?e.emailVerified:i.emailVerified},{type:"confirm",name:"enabled",message:"Enabled?",default:Object.prototype.hasOwnProperty.call(e,"enabled")?e.enabled:i.enabled},{type:"confirm",name:"changePassword",message:"Change password?",default:!1},{type:"password",name:"password",message:"New password",when:({changePassword:o})=>o},{type:"password",name:"confirmPassword",message:"Confirm password",when:({changePassword:o})=>o}]);if(s.changePassword){if(s.password!==s.confirmPassword)throw new Error("Passwords do not match");e.password=s.password}e.firstName=s.firstName,e.lastName=s.lastName,e.roles=s.roles.split(",").map(o=>o.trim()),e.emailVerified=s.emailVerified,e.enabled=s.enabled}if(e.password){const s=te();await t.auth.users.update(i.id,{passwordResetToken:s}),await t.auth.resetPassword(i.email,e.password,i.applicationId,s)}const n=await t.auth.users.update(i.id,{firstName:e.firstName,lastName:e.lastName,roles:e.roles,emailVerified:e.emailVerified,enabled:e.enabled});e.format==="table"?d(n,"table"):d(n,"json")}catch(i){l(i)}}const Qd={__proto__:null,builder:Bd,command:Vd,desc:Wd,handler:Hd},Xd="users <command>",Yd="User commands",ec=e=>e.command(Rd).command(Od).command(Ld).command(zd).command(Qd).demandCommand(1),tc={__proto__:null,builder:ec,command:Xd,desc:Yd},ic="@emuanalytics/flow-cli",ac="2.2.4",nc="module",sc="dist/index.mjs",oc="Robin Summerhill <robin.summerhill@emu-analytics.com>",rc="Copyright 2018 Emu Analytics Limited",dc={flow:"dist/index.mjs"},cc=["dist","maputnik"],lc={start:"node dist/index.mjs",typecheck:"tsc --noEmit",build:"unbuild",clean:"rimraf dist",lint:"eslint src",format:'prettier "src/**/*.ts" --write',prepublishOnly:"npm run build",prebuild:"npm run clean",precommit:"lint-staged"},pc={"@eslint/js":"^10.0.1","@types/cli-spinner":"^0.2.0","@types/express":"^4.17.25","@types/humanize-plus":"^1.8.0","@types/node":"^20.0.0","@types/table":"^4.0.5","@types/uuid":"^8.3.4","@types/yauzl":"^2.9.1",eslint:"^10.3.0","lint-staged":"^16.4.0",prettier:"^3.0.0",typescript:"^5.9.2","typescript-eslint":"^8.59.2",unbuild:"^3.6.1"},mc={"@emuanalytics/flow-engine-client":"^2.2.3","@modelcontextprotocol/sdk":"^1.12.0","@types/yargs":"^17.0.35",JSONStream:"^1.3.5",chalk:"^5.6.2","cli-spinner":"^0.2.10",colorette:"^2.0.19","csv-stringify":"^5.3.3","debounce-promise":"^3.1.0",execa:"^5.1.1",express:"^4.16.3","find-up":"^8.0.0","humanize-plus":"^1.8.2",inquirer:"^13.4.3","loose-json":"^1.1.2","node-emoji":"^2.2.0",open:"^11.0.0",ora:"^9.4.0","replace-in-file":"^5.0.2","string-width":"^8.2.1",table:"^6.9.0",tslib:"^2.8.1",uuid:"^8.3.2",yargs:"^18.0.0",yauzl:"^2.10.0",zod:"^3.23.0"},uc={"@types/serve-static":"^1.15.0"},yc="0eec8b4cf9a947d3c45347bbd85a863d4d850c52",fc={name:ic,version:ac,type:nc,main:sc,author:oc,license:rc,bin:dc,files:cc,scripts:lc,devDependencies:pc,dependencies:mc,overrides:uc,"lint-staged":{"./src/**/*.ts":["eslint"]},gitHead:yc},bc="version",gc="Display Flo.w Engine version information",hc=async({host:e,apiKey:t,client:a,format:i})=>{try{const n=await a.config(),s={"CLI version":fc.version,"Flo.w version":n.version.tag,"Flo.w host":e,"API key":t};d(s,i)}catch(n){l(n.message)}},wc={__proto__:null,command:bc,desc:gc,handler:hc},he=$e([".flowrc",".flowrc.json"]),$c=he?JSON.parse($.readFileSync(he).toString("utf8")):{},_c=e=>{e.client=new K(e.host,e.apiKey)},we=_e(xe(process.argv));we.config($c).env("FLOW").option("k",{alias:"apiKey",demandOption:!0,describe:"Flo.w Engine API key",type:"string",global:!0}).option("h",{alias:"host",default:"https://flow.emu-analytics.net",describe:"Flo.w Engine host URL",type:"string"}).option("f",{alias:"format",default:"table",describe:"Output format",type:"string",choices:["table","csv","json","geojson"]}).command(ft).command($t).command(oi).command(Ji).command(sa).command(an).command(xn).command(Qn).command(Os).command(Qs).command(Uo).command(vr).command(ld).command(Dd).command(tc).command(wc).command(is).demandCommand(1).wrap(Math.min(100,we.terminalWidth())).help().version().middleware([_c]).parse();
|
|
27
|
+
${w.dim("-")} ${w.cyan(t)}`:""}function Zs(e){let t=me.get(e);return t||(t=Fs(e),t.catch(a=>{l(a)}),me.set(e,t)),t}async function Fs(e){const t=process.cwd(),a=P(t,".tmp-flow-starter"),i=await Ts(e);return le(a),await Ps(i,a),await qs("install",a),async n=>{const s=P(t,n);await Js(a,s),await Ue({files:[P(s,"*"),P(s,"config/**"),P(s,"src/**")],from:/flow-starter-project-name/g,to:n,allowEmptyPaths:!0}),le(null)}}function Ks(e){return!/[^a-zA-Z0-9-]/.test(e)}function zs(e,t){if(e.includes("/"))return{name:e,repo:e};const a=t.find(i=>i.name===e);if(!a)throw new Error(`Starter "${e}" does not exist.`);return a}const Vs=["new [name]"],Ws="Create a new Flo.w app",Bs=e=>e.option("s",{alias:"starter",describe:"Starter template",type:"string"}).positional("name",{describe:"Project name",type:"string"});async function Hs(e){try{const t=await fetch(`${re}/index.json`).then(i=>i.json());if(!e.starter){const i=await b.prompt([{type:"select",name:"starter",message:"Starter template",choices:t.map(n=>n.name),default:t[0].name}]);e.starter=i.starter}const a=zs(e.starter,t);await Rs(a,e.name,!1)}catch(t){l(t.message)}}const Qs={__proto__:null,builder:Bs,command:Vs,desc:Ws,handler:Hs},Xs=["cache [id]"],Ys="Show pipeline cache",eo=e=>e.positional("id",{describe:"Pipeline id (or unique prefix)",type:"string"});async function to({client:e,id:t,format:a}){try{const i=await p(t,e.pipelines,"id",["components"],["id","components.index"]);if(!i){d({message:`Pipeline not found: ${t}`},a??"json");return}const n=(i.components??[]).filter(o=>o.class==="cache").sort((o,r)=>o.index-r.index),s=n.map(o=>({id:o.id,type:o.type,description:o.description,related_components:o.metadata.components.join()}));if(a==="json"){d({id:i.id,environment:i.environment,caches:n},"json");return}s.length?d(s,"table",null,{noWrap:!0}):v("No Caches Found")}catch(i){l(i)}}const io={__proto__:null,builder:eo,command:Xs,desc:Ys,handler:to},ao=["components <id>","comps <id>"],no="Show pipeline components",so=e=>e.positional("id",{describe:"Pipeline id (or unique prefix)",type:"string"});async function oo({client:e,id:t,format:a}){try{const i=await p(t,e.pipelines,"id",["components"],["id","components.index"]);if(!i){d({message:`Pipeline not found: ${t}`},a??"json");return}const n=i.components??[];if(a==="json"){d(n,"json");return}const s=ro(n);if(!s.length){v("No Components Found");return}d(s,"table",["id","class","type","description","note"])}catch(i){l(i)}}function ro(e){if(!e.length)return[];const t={};e.forEach(o=>t[o.id]={...o,next:[],previous:[],indent:0}),Object.values(t).forEach(o=>{const r=o.metadata||{},c=r.previousComponents??[],m=r.nextComponents??[];o.previous=c.map(y=>t[y]),o.next=m.map(y=>t[y])});const a={};Object.values(t).forEach(o=>{const r=(o.metadata||{}).parentComponent;r&&(a[r]||(a[r]=[]),a[r].push(o))}),Object.values(a).forEach(o=>{o.sort((r,c)=>r.index-c.index)});const i=Object.values(t).filter(o=>o.class!=="cache"&&(o.previous??[]).length===0),n=new Set;function s(o,r){if(!o||n.has(o.id))return;n.add(o.id),o.indent=r,o.class==="pipeline"&&(a[o.id]??[]).forEach(y=>s(y,r+1));const c=(o.next??[]).filter(y=>y.class!=="cache"),m=o.type==="fp:fork"||c.length>1;c.forEach(y=>s(y,m?r+1:r))}return i.forEach(o=>s(o,0)),Object.values(t).filter(o=>o.class!=="cache").sort((o,r)=>o.index-r.index).map(o=>{const r=[],c=(o.metadata||{}).caches??[];c.length>0&&r.push(`uses cache: ${c.join(", ")}`);const m=o.indent>0?" ".repeat(o.indent)+"> ":"";function y(f){return f.class==="pipeline"?`(${f.id})`:f.type==="fp:fork"?`[${f.id}]`:f.id}return{id:m+y(o),class:o.class,type:o.type,description:o.description,note:r.join()}})}const co={__proto__:null,builder:so,command:ao,desc:no,handler:oo},lo=["config [id]"],po="Show pipeline config",mo=e=>e.positional("id",{describe:"Pipeline id (or unique prefix)",type:"string"});async function uo({client:e,id:t,format:a}){try{const i=(await p(t,e.pipelines,"id"))?.config;if(!i||Object.keys(i).length===0){d({message:`No configuration found for pipeline ${t}`},a??"json");return}const n=X(i);if(a==="json"){d(i,"json");return}const s=Object.entries(n).map(([o,r])=>({key:o,value:r}));d(s,"table",["key","value"],{noWrap:!0})}catch(i){l(i)}}function ue(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function X(e,t="",a={}){for(const[i,n]of Object.entries(e)){const s=t?`${t}.${i}`:i;Array.isArray(n)?n.forEach((o,r)=>{const c=`${s}[${r}]`;ue(o)?X(o,c,a):a[c]=o}):ue(n)?X(n,s,a):a[s]=n}return a}const yo={__proto__:null,builder:mo,command:lo,desc:po,handler:uo},fo=["list [id]","ls","$0"],bo="List pipelines",go=e=>e.option("limit",{alias:"n",type:"number",describe:"Limit to n results"}).option("sort",{alias:["s"],type:"string",describe:"Sort by attribute"}).option("filter-cache",{type:"string",describe:"Filter pipelines using a specific cache ID (partial match)"}).option("filter-dataset",{type:"string",describe:"Filter pipelines using a specific dataset ID (partial match)"}).option("components",{type:"boolean",describe:"Include pipeline components in the JSON output"}).positional("id",{describe:"Pipeline id (or unique prefix)",type:"string"}).conflicts("id",["limit","sort","filter-cache","filter-dataset"]);async function ho({client:e,id:t,format:a,limit:i,sort:n,filterCache:s,filterDataset:o,components:r}){try{if(n??="id",t){const f=await p(t,e.pipelines,"id",void 0,n),g=fe(f);a==="table"?d(ye(g),"table",null,{noWrap:!0}):d(g,a);return}const c=!!s||!!o,m=r||c,y=(await e.pipelines.list({sort:n,limit:c?void 0:i,join:m?"components":void 0})).filter(f=>$o(f,s)).filter(f=>wo(f,o)).slice(0,c?i:void 0).map(f=>r?f:_o(f));xo(y,a)}catch(c){l(c)}}function wo(e,t){return!t||ie(e.components).some(a=>a.class==="sink"&&a.type==="fp:flow-ingest-stream"&&a.config?.datasetId?.includes(t))}function $o(e,t){return!t||ie(e.components).some(a=>a.class==="cache"&&a.config?.id?.includes(t))}function _o({components:e,...t}){return t}function xo(e,t){const a=e.map(fe);t==="table"?d(a.map(ye),"table",["id","environment","version","description","startedAt","heartbeatAt"]):d(a,t??"json")}function ye(e){const t=e.heartbeatAt&&(Date.now()-new Date(e.heartbeatAt).getTime())/1e3<30;return{...e,heartbeatAt:{color:t?"06a453":"e11529",value:e.heartbeatAt}}}function fe(e){const t=e.metadata.version?.tag;return{...e,version:t&&t.replace(/^release-/,"")}}const vo={__proto__:null,builder:go,command:fo,desc:bo,handler:ho},So=["sink [id]"],Ao="Show pipeline sink",Do=e=>e.positional("id",{describe:"Pipeline id (or unique prefix)",type:"string"});async function No({client:e,id:t,format:a}){try{const i=await p(t,e.pipelines,"id",["components"],["id","components.index"]);if(!i){d({message:`Pipeline not found: ${t}`},a??"json");return}const n=(i.components??[]).filter(o=>o.class==="sink").sort((o,r)=>o.index-r.index),s=n.reduce((o,r)=>(o[r.type]??=[],o[r.type].push(r),o),{});if(a==="json"){d({id:i.id,environment:i.environment,sinks:n},"json");return}if(Object.keys(s).length)for(const[,o]of Object.entries(s)){const r=o.map(c=>({id:c.id,description:c.description,...jo(c)}));d(r,"table")}else v("No Sinks Found")}catch(i){l(i)}}function jo(e){const t=e.config||{};switch(e.type){case"fp:amqp-writable-stream":return{vhost:t.vhost??"N/A",exchange:typeof t.exchange=="string"?t.exchange:t.exchange?.name??"N/A",enable:t.enable};case"fp:flow-ingest-stream":return{datasetId:t.datasetId??"N/A",enable:t.enable};case"fp:sqs-writable-stream":return{queueUrl:t.queueUrl??"N/A",region:t.region??"N/A",enable:t.enable};case"fp:sns-writable-stream":return{topicArn:t.topicArn??"N/A",region:t.region??"N/A",enable:t.enable};case"fp:null-sink":return{logging:t.logging};default:return{}}}const ko={__proto__:null,builder:Do,command:So,desc:Ao,handler:No},Io=["source [id]"],Oo="Show pipeline source",To=e=>e.positional("id",{describe:"Pipeline id (or unique prefix)",type:"string"});async function Po({client:e,id:t,format:a}){try{const i=await p(t,e.pipelines,"id",["components"],["id","components.index"]);if(!i){d({message:`Pipeline not found: ${t}`},a??"json");return}const n=(i.components??[]).filter(o=>o.class==="source").sort((o,r)=>o.index-r.index),s=n.map(o=>({id:o.id,type:o.type,description:o.description,...Mo(o)}));if(a==="json"){d({id:i.id,environment:i.environment,sources:n},"json");return}s.length?d(s,"table"):v("No Sources Found")}catch(i){l(i)}}function Mo(e){const t=e.config||{};switch(e.type){case"fp:amqp-readable-stream":return{vhost:t.vhost??"N/A",exchange:t.queue?.bindTo?.exchange??t.exchange??"N/A",queue:typeof t.queue=="string"?t.queue:t.queue?.name??"N/A"};case"fp:mqtt-subscriber-stream":return{serverUrl:t.serverUrl??"N/A",topic:t.topic??"N/A"};case"fp:flow-dataset-stream":return{datasetId:t.datasetId??"N/A"};case"fp:db-timeseries-stream":return{database:t.database??"N/A",table:t.table??"N/A"};case"fp:sqs-readable-stream":return{queueUrl:t.queueUrl??"N/A",region:t.region??"N/A"};case"fp:s3-file-list-stream":return{bucket:t.bucket??"N/A"};case"fp:s3-file-loader-stream":return{bucket:t.bucket??"N/A"};case"fp:planefinder-firehose-stream":return{host:t.host??"N/A"};case"fp:tcp-tls-readable-stream":return{hostname:t.hostname??"N/A"};case"fp:timer-stream":return{interval:t.interval??"N/A"};default:return{}}}const Eo={__proto__:null,builder:To,command:Io,desc:Oo,handler:Po},Lo=["pipelines <command>","pipes"],qo="Pipeline commands",Co=e=>e.command(vo).command(yo).command(co).command(Eo).command(ko).command(io).demandCommand(1),Uo={__proto__:null,builder:Co,command:Lo,desc:qo},Jo="create <id>",Ro="Create a new map style",Go=e=>e.positional("id",{describe:"Map style id",type:"string"}).option("name",{alias:"n",describe:"Name for new style",type:"string"}).option("description",{alias:"d",describe:"Description for new style",type:"string"}).option("interactive",{alias:"i",describe:"Show interactive prompts",type:"boolean",default:"true"}).option("sourceId",{alias:"sid",describe:"ID of source style",type:"string",default:"darkmatter"}).option("sourceKey",{alias:"skey",describe:"API key to access source style",type:"string",default:"6f19c5c7-1a9b-425b-84ab-09ba56e905b2"}),Zo=async e=>{try{const t=[].concat(await be(e.host,e.apiKey),await be(e.host,e.sourceKey)),a=t.map(s=>({name:s.name,value:s,short:s.name}));let i=t.find(s=>s.id===e.sourceId);if(e.interactive){const s=await b.prompt([{type:"input",name:"name",message:"Name for new style",default:e.name},{type:"input",name:"description",message:"Description for new style",default:e.description},{type:"select",name:"sourceStyle",message:"Select the source style to copy",choices:a,default:i}]);e.name=s.name,e.description=s.description,e.sourceId=s.sourceStyle.id,i=t.find(o=>o.id===e.sourceId)}i.style.id=e.id,i.style.name=e.name,i.style.metadata.description=e.description;let n={id:e.id,name:e.name,description:e.description,type:"plain",style:i.style};n=await e.client.styles.create(n),e.format==="table"?d(n,"table",["id","name","description","type"]):d(n,e.format??"json")}catch(t){l(t)}};async function be(e,t){return new K(e,t).styles.list()}const Fo={__proto__:null,builder:Go,command:Jo,desc:Ro,handler:Zo},Ko=["delete <id>","rm","del"],zo="Delete a map style",Vo=e=>e.option("yes",{alias:"y",description:"Answer 'yes' to confirmation messages",default:!1}).positional("id",{describe:"Map style id (or unique prefix)",type:"string"});async function Wo({client:e,id:t,yes:a}){try{const i=await p(t,e.styles);let n=a;n||(n=(await b.prompt({name:"confirmed",type:"confirm",message:`Are you sure you want to delete '${i.id}'`,default:!1})).confirmed),n&&(await e.styles.delete(i.id),_("Deleted"))}catch(i){l(i)}}const Bo={__proto__:null,builder:Vo,command:Ko,desc:zo,handler:Wo},Ho=j.dirname(Ee(import.meta.url)),x=z();x.use(z.json({limit:"1mb"})),x.use(z.static(j.join(Ho,"../maputnik"))),x.get("/styles",(e,t)=>{v(":thumbsup: Maputnik connected");const a=x.get("style");t.json([a.id])}),x.get("/styles/:id",async(e,t)=>{try{const a=x.get("style");v(`Loading style '${a.id}'`),t.json(a)}catch(a){l(a.message)}}),x.put("/styles/:id",async(e,t)=>{try{const a=x.get("client");if(x.set("style",e.body),!x.get("writeable"))return t.status(204).send();const i={...e.body};i.sources=Qo(i.sources,`${a.baseUrl}`),i.glyphs=q(i.glyphs,a.baseUrl),i.sprite=q(i.sprite,a.baseUrl),await Yo(a,i.id,i),t.status(204).send()}catch(a){l(a.message)}});function Qo(e,t){return Object.keys(e).reduce((a,i)=>{let n=e[i];return Object.prototype.hasOwnProperty.call(n,"url")&&(n={...n,url:q(n.url,t)}),Object.prototype.hasOwnProperty.call(n,"data")&&(n={...n,data:q(n.data,t)}),Object.prototype.hasOwnProperty.call(n,"tiles")&&(n={...n,tiles:n.tiles.map(s=>q(s,t))}),a[i]=n,a},{})}function q(e,t){const a=new URL(e,t);return a.searchParams.delete("apikey"),a.toString().replace(t,"").replace(/%7B/g,"{").replace(/%7D/g,"}")}function Xo(e,t,a){return e.styles.update(t,{style:a})}const Yo=Re(Xo,2e3,{leading:!0});class Y{server;port;constructor(t,a,i){this.port=this.normalizePort(process.env.PORT||"8000"),x.set("port",this.port),x.set("style",a),x.set("writeable",i),x.set("client",t),this.server=Je.createServer(x),this.server.listen(this.port),this.server.on("error",this.onError.bind(this)),this.server.on("listening",this.onListening.bind(this))}normalizePort(t){const a=parseInt(t,10);return isNaN(a)?t:a>=0?a:!1}onError(t){if(t.syscall!=="listen")throw t;const a=typeof this.port=="string"?`Pipe ${this.port}`:`Port ${this.port}`;switch(t.code){case"EACCES":l(`${a} requires elevated privileges`),process.exit(1);break;case"EADDRINUSE":l(`${a} is already in use`),process.exit(1);break;default:throw t}}onListening(){_(`Style server listening on port ${this.port}`),v(`:rocket: Point your browser at http://localhost:${this.port}`),this.postListen()}postListen(){return Promise.resolve(null)}}const er="edit <id>",tr="Edit a map style in maputnik",ir=e=>e.positional("id",{describe:"Map style id (or unique prefix)",type:"string"}),ar=async({client:e,id:t})=>{try{const a=await p(t,e.styles),i=await e.maps.get(a.id,{apikey:e.apiKey});new Y(e,i,!0),V("http://localhost:8000")}catch(a){l(a)}},nr={__proto__:null,builder:ir,command:er,desc:tr,handler:ar},sr=["list [id]","ls","$0"],or="List map styles",rr=e=>e.option("limit",{alias:"n",type:"number",describe:"Limit to n results"}).option("sort",{alias:["s"],type:"string",describe:"Sort by attribute"}).conflicts("id",["limit","sort"]).positional("id",{describe:"Map style id (or unique prefix)",type:"string"});async function dr({client:e,id:t,format:a,limit:i,sort:n}){try{if(t){const s=await p(t,e.styles);d(s,a)}else{const s=await e.styles.list({limit:i,sort:n});a==="table"?d(s,"table",["id","name","description","type"]):d(s,a??"json")}}catch(s){l(s)}}const cr={__proto__:null,builder:rr,command:sr,desc:or,handler:dr},lr=["metadata <id>","meta"],pr="Get/set resource metadata",mr=e=>e.positional("id",{describe:"Map style id (or unique prefix)",type:"string"}).option("set",{type:"array",describe:"One or more key/values to set in form <key>=<value>. Use <key>= to delete a key."});async function ur({client:e,id:t,set:a}){try{if(a){let i=await p(t,e.styles);const n=k(a);for(const s of Object.keys(n)){const o=n[s];o===""?await e.styles.deleteMetadata(i.id,s):await e.styles.setMetadata(i.id,s,o)}i=await p(t,e.styles),d(i.metadata,"json")}else{const i=await p(t,e.styles);d(i.metadata,"json")}}catch(i){l(i)}}const yr={__proto__:null,builder:mr,command:lr,desc:pr,handler:ur},fr="view <id>",br="View a map style in maputnik",gr=e=>e.positional("id",{describe:"Map style id (or unique prefix)",type:"string"}),hr=async({client:e,id:t})=>{try{const a=await p(t,e.styles),i=await e.maps.get(a.id,{apikey:e.apiKey});new Y(e,i,!1),V("http://localhost:8000")}catch(a){l(a)}},wr={__proto__:null,builder:gr,command:fr,desc:br,handler:hr},$r="styles <command>",_r="Style commands",xr=e=>e.command(cr).command(Fo).command(Bo).command(nr).command(wr).command(yr).demandCommand(1),vr={__proto__:null,builder:xr,command:$r,desc:_r},Sr=["create <id>"],Ar="Create a new tile source",Dr=e=>e.option("type",{alias:"t",description:"Tilesource type",type:"string",choices:["tilelive","dataset"]}).option("source",{alias:"s",description:"Tilesource source (tilelive URL or dataset ID)",type:"string"}).option("attribution",{alias:"a",description:"Tilesource attribution",type:"string"}).option("minZoom",{alias:"m",description:"Minimum zoom",type:"number"}).option("maxZoom",{alias:"M",description:"Maximum zoom",type:"number"}).option("extent",{alias:"e",description:"Extent x1,y1,x2,y2 (lng/lat)",type:"array"}).option("headers",{alias:"H",description:"Tile HTTP headers (space-separated <name>=<value> pairs)",type:"array"}).option("interactive",{alias:"i",describe:"Show interactive prompts",type:"boolean",default:"true"}).positional("id",{describe:"Tilesource id",type:"string"});async function Nr(e){const t=e.client,a=await t.tileSources.drivers();try{if(e.interactive){const s=await b.prompt([{type:"select",name:"type",message:"Data source",choices:a,default:e.type||"dataset"},{type:"input",name:"source",message:"TileLive URL",default:e.source,when:({type:o})=>o==="tilelive"},{type:"select",name:"source",message:"Dataset",choices:kr.bind(null,e.client),default:e.source,when:({type:o})=>o==="dataset"},{type:"input",name:"attribution",message:"Attribution",default:e.attribution},{type:"input",name:"minZoom",message:"Minimum zoom",default:e.minZoom||0,validate:o=>ee(o)||"Enter a number"},{type:"input",name:"maxZoom",message:"Maximum zoom",default:e.maxZoom||18,validate:o=>ee(o)||"Enter a number"},{type:"confirm",name:"overrideExtent",message:"Override auto-calculated map extent",default:e.extent?!!e.extent.length:!1},{type:"input",name:"extent",message:"Map extent (x1 y1 x2 y2) (blank for auto-detect)",validate:o=>ge(o)||"Enter lng/lat bounding box as x1 y1 x2 y2",when:({overrideExtent:o})=>o}]);e.type=s.type,e.source=s.source,e.attribution=s.attribution,e.minZoom=s.minZoom,e.maxZoom=s.maxZoom,e.extent=s.overrideExtent?s.extent.split(" "):[]}let i;if(e.extent&&e.extent.length===0)i=null;else if(e.extent){if(!ge(e.extent))throw new Error("Bad format for extent: specify 'x1 y1 x2 y2' (lng/lat)");i=jr(e.extent)}let n={id:e.id,type:e.type,source:e.source,attribution:e.attribution,minZoom:e.minZoom,maxZoom:e.maxZoom,extentLngLat:i};n=await t.tileSources.create(n),e.format==="table"?d(n,"table",["id","type","source","minZoom","maxZoom"]):d(n,e.format??"json")}catch(i){l(i)}}function ee(e){return!isNaN(parseFloat(e))&&isFinite(e)}function ge(e){return!e||e.length===0||(typeof e=="string"&&(e=e.split(" ")),e.length!==4)?!1:!e.find(t=>!ee(t))}function jr(e){return e==null?null:(typeof e=="string"&&(e=e.split(" ")),e.map(t=>parseFloat(t)))}async function kr(e){return(await e.datasets.list({sort:"id"})).map(t=>t.id)}const Ir={__proto__:null,builder:Dr,command:Sr,desc:Ar,handler:Nr},Or=["delete <id>","rm","del"],Tr="Delete a tile source",Pr=e=>e.option("yes",{alias:"y",description:"Answer 'yes' to confirmation messages",default:!1}).positional("id",{describe:"Tile source id (or unique prefix)",type:"string"});async function Mr({client:e,id:t,yes:a}){try{const i=await p(t,e.tileSources);let n=a;n||(n=(await b.prompt({name:"confirmed",type:"confirm",message:`Are you sure you want to delete '${i.id}'`,default:!1})).confirmed),n&&(await e.tileSources.delete(i.id),_("Deleted"))}catch(i){l(i)}}const Er={__proto__:null,builder:Pr,command:Or,desc:Tr,handler:Mr},Lr=["list [id]","ls","$0"],qr="List tile sources",Cr=e=>e.option("limit",{alias:"n",type:"number",describe:"Limit to n results"}).option("sort",{alias:["s"],type:"string",describe:"Sort by attribute"}).conflicts("id",["limit","sort"]).positional("id",{describe:"Tile source id",type:"string"});async function Ur({client:e,id:t,format:a,limit:i,sort:n}){try{if(t){const s=await p(t,e.tileSources);d(s,a)}else{const s=await e.tileSources.list({limit:i,sort:n});a==="table"?d(s,"table",["id","type","source","minZoom","maxZoom"]):d(s,a??"json")}}catch(s){l(s)}}const Jr={__proto__:null,builder:Cr,command:Lr,desc:qr,handler:Ur},Rr=["metadata <id>","meta"],Gr="Get/set resource metadata",Zr=e=>e.positional("id",{describe:"Tile Source id (or unique prefix)",type:"string"}).option("set",{type:"array",describe:"One or more key/values to set in form <key>=<value>. Use <key>= to delete a key."});async function Fr({client:e,id:t,set:a}){try{if(a){let i=await p(t,e.tileSources);const n=k(a);for(const s of Object.keys(n)){const o=n[s];o===""?await e.tileSources.deleteMetadata(i.id,s):await e.tileSources.setMetadata(i.id,s,o)}i=await p(t,e.tileSources),d(i.metadata,"json")}else{const i=await p(t,e.tileSources);d(i.metadata,"json")}}catch(i){l(i)}}const Kr={__proto__:null,builder:Zr,command:Rr,desc:Gr,handler:Fr},zr="preview <tilesourceId>",Vr="Preview a tile source in maputnik",Wr=async({client:e,tilesourceId:t})=>{try{const a=await p(t,e.tileSources),i=await e.tiles.getPreviewStyle(a.id,{apikey:e.apiKey});new Y(e,i,!1),V("http://localhost:8000")}catch(a){l(a)}},Br={__proto__:null,command:zr,desc:Vr,handler:Wr},Hr=["tilespec <tilesourceId>"],Qr="Get tileJson for tile source",Xr=e=>e.positional("tilesourceId",{describe:"Tile source id",type:"string"}),Yr=async({client:e,format:t,tilesourceId:a})=>{try{const i=await p(a,e.tileSources),n=await e.tiles.getTileSpec(i.id);t==="table"&&(delete n.vector_layers,delete n.attribution,delete n.tiles,n.center=JSON.stringify(n.center),n.bounds=JSON.stringify(n.bounds)),d(n,t)}catch(i){l(i)}},ed={__proto__:null,builder:Xr,command:Hr,desc:Qr,handler:Yr},td=["update <id>"],id="Update a tile source",ad=e=>e.option("type",{alias:"t",description:"Tilesource type",type:"string"}).option("source",{alias:"s",description:"Tilesource source (tilelive URL or dataset ID)",type:"string"}).option("attribution",{alias:"a",description:"Tilesource attribution",type:"string"}).option("minZoom",{alias:"m",description:"Minimum zoom",type:"number"}).option("maxZoom",{alias:"M",description:"Maximum zoom",type:"number"}).option("extent",{alias:"e",description:"Extent x1,y1,x2,y2 (lng/lat)",type:"array"}).option("headers",{alias:"H",description:"Tile HTTP headers (space-separated <name>=<value> pairs)",type:"array"}).option("interactive",{alias:"i",describe:"Show interactive prompts",type:"boolean",default:"true"}).positional("id",{describe:"Tilesource id (or unique prefix)",type:"string"});async function nd(e){const t=e.client,a=e.id,i=await t.tileSources.drivers();try{let n=await p(a,t.tileSources);if(e.interactive){const r=await b.prompt([{type:"select",name:"type",message:"Tilesource Type",choices:i,default:e.type||n.type},{type:"input",name:"source",message:"TileLive URL",default:e.source||n.source,when:({type:c})=>c==="tilelive"},{type:"select",name:"source",message:"Dataset",choices:sd.bind(null,e.client),default:e.source||n.source,when:({type:c})=>c!=="tilelive"},{type:"input",name:"attribution",message:"Attribution",default:e.attribution||n.attribution},{type:"input",name:"minZoom",message:"Minimum zoom",default:e.minZoom||n.minZoom,validate:c=>M(c)||"Enter a number"},{type:"input",name:"maxZoom",message:"Maximum zoom",default:e.maxZoom||n.maxZoom,validate:c=>M(c)||"Enter a number"},{type:"confirm",name:"overrideExtent",message:"Override map extent specfied by dataset",default:e.extent?!!e.extent.length:!!n.extentLngLat},{type:"input",name:"extent",message:"Map extent (x1 y1 x2 y2) (blank to use extent specified by dataset)",default:R(e.extent||n.extentLngLat),validate:c=>J(c)||"Enter lng/lat bounding box as x1 y1 x2 y2",when:({overrideExtent:c})=>c}]);e.type=r.type,e.source=r.source,e.attribution=r.attribution,e.minZoom=r.minZoom,e.maxZoom=r.maxZoom,e.extent=r.overrideExtent?r.extent.split(" "):[]}let s;e.headers&&(s=e.headers.reduce((r,c)=>{const[m,y]=c.split("=");if(!m||!y)throw new Error("Bad format for headers: specify key/value pairs as <header>=<value>");return r[m]=y,r},{}));let o;if(e.extent&&e.extent.length===0)o=null;else if(e.extent){if(!J(e.extent))throw new Error("Bad format for extent: specify 'x1 y1 x2 y2' (lng/lat)");o=W(e.extent)}n=await t.tileSources.update(n.id,{id:e.id,type:e.type,source:e.source,attribution:e.attribution,headers:s,minZoom:e.minZoom,maxZoom:e.maxZoom,extentLngLat:o}),d(n,"table")}catch(n){l(n)}}async function sd(e){return(await e.datasets.list({sort:"id"})).map(t=>t.id)}const od={__proto__:null,builder:ad,command:td,desc:id,handler:nd},rd="tiles <command>",dd="Tile commands",cd=e=>e.command(Jr).command(Ir).command(Er).command(od).command(Kr).command(Br).command(ed).demandCommand(1),ld={__proto__:null,builder:cd,command:rd,desc:dd},pd=["list [id]","ls"],md="List uploads",ud=e=>e.option("limit",{alias:"n",type:"number",describe:"Limit to n results"}).option("sort",{alias:["s"],type:"string",describe:"Sort by attribute"}).positional("id",{describe:"Upload id",type:"string"}).conflicts("id",["limit","sort"]);async function yd({client:e,id:t,format:a,limit:i,sort:n}){try{if(t){const s=await p(t,e.uploads);d(s,a)}else{const s=await e.uploads.list({limit:i,sort:n});a==="table"?d(s,"table",["id","fileName","status"]):d(s,a??"json")}}catch(s){l(s)}}const fd={__proto__:null,builder:ud,command:pd,desc:md,handler:yd},{fileSize:bd}=Ge,gd=1e3,hd=["upload <filePath>","$0"],wd="Upload a geospatial data file",$d=e=>e.option("i",{alias:"id",describe:"Dataset id",type:"string"}).option("n",{alias:"name",describe:"Dataset name",type:"string"}).option("d",{alias:"description",describe:"Dataset description",type:"string"}).option("a",{alias:"attribution",describe:"Tiles source attribution",type:"string"}).option("source-srid",{describe:"Source SRID (default auto-detected from source)",type:"number"}).option("target-srid",{describe:"Target SRID (default auto-detected from source)",number:!0,type:"number"}).option("schema",{describe:"Database schema (defaults to 'public' if not specified)",type:"string"}).positional("filePath",{describe:"Path to file to upload",type:"string"}),_d=async e=>{Object.prototype.hasOwnProperty.call(e,"source-srid")&&isNaN(e["source-srid"])&&(l("--source-srid must be a number"),process.exit(1)),Object.prototype.hasOwnProperty.call(e,"target-srid")&&isNaN(e["target-srid"])&&(l("--target-srid must be a number"),process.exit(1));const t=j.basename(e.filePath);v(`Uploading file ${t} ...`);const a=T("Uploading").start(),i=T("Ingesting"),n=T("Processing");try{const s=$.createReadStream(e.filePath),o=await e.client.uploads.upload({data:s,filename:t,datasetId:e.id,datasetName:e.name,datasetDescription:e.description,attribution:e.attribution,sourceSrid:e["source-srid"],targetSrid:e["target-srid"],schema:e.schema}),r=o.id,c=g=>new Promise(S=>{setTimeout(S,g)});let m,y=o.status,f=a;for(;;)if(await c(gd),m=await e.client.uploads.get(r),m.status!==y)if(y=m.status,y==="ingesting")a.succeed(),f=i,f.start();else if(y==="processing")a.succeed(),i.start(),i.succeed(),f=n,f.start();else if(y==="done"){a.succeed(),i.succeed(),n.succeed(),v(`Dataset uploaded with id '${m.options.datasetId}' (${bd(m.size)})`);break}else{f.fail(),l(m.error.message),_(m.error.stderr||m.error.stdout);break}}catch(s){a.stop(),i.stop(),n.stop(),l(s)}},xd={__proto__:null,builder:$d,command:hd,desc:wd,handler:_d},vd="upload <command>",Sd="Upload commands",Ad=e=>e.command(fd).command(xd).demandCommand(1),Dd={__proto__:null,builder:Ad,command:vd,desc:Sd},Nd=["create <email>"],jd="Create a user",kd=e=>e.option("firstName",{description:"First name",type:"string"}).option("lastName",{description:"Last name",type:"string"}).option("roles",{alias:"r",description:"Roles (comma-separated)",type:"array"}).option("emailVerified",{description:"Email verified",type:"boolean"}).option("enabled",{alias:"e",description:"Login enabled",type:"boolean"}).option("interactive",{alias:"i",describe:"Show interactive prompts",type:"boolean",default:"true"}).positional("email",{describe:"Email (or unique prefix)",type:"string"});async function Id(e){const t=e.client;try{if(e.interactive){const n=await b.prompt([{type:"input",name:"firstName",message:"First name",default:e.firstName},{type:"input",name:"lastName",message:"Last name",default:e.lastName},{type:"input",name:"roles",message:"Roles (comma separated)",default:(e.roles??[]).join(", ")},{type:"confirm",name:"emailVerified",message:"Verified?",default:Object.prototype.hasOwnProperty.call(e,"emailVerified")?e.emailVerified:!0},{type:"confirm",name:"enabled",message:"Enabled?",default:Object.prototype.hasOwnProperty.call(e,"enabled")?e.enabled:!0},{type:"password",name:"password",message:"Password"},{type:"password",name:"confirmPassword",message:"Confirm password"}]);if(n.password!==n.confirmPassword)throw new Error("Passwords do not match");e.firstName=n.firstName,e.lastName=n.lastName,e.roles=n.roles.split(",").map(s=>s.trim()),e.emailVerified=n.emailVerified,e.enabled=n.enabled,e.password=n.password}const a=await t.auth.users.create({email:e.email,firstName:e.firstName,lastName:e.lastName,roles:e.roles,emailVerified:e.emailVerified,enabled:e.enabled,password:e.password}),i=te();await t.auth.users.update(a.id,{passwordResetToken:i}),await t.auth.resetPassword(a.email,e.password,a.applicationId,i),e.format==="table"?d(a,"table"):d(a,"json")}catch(a){l(a)}}const Od={__proto__:null,builder:kd,command:Nd,desc:jd,handler:Id},Td=["delete <email>","rm","del"],Pd="Delete a user",Md=e=>e.option("yes",{alias:"y",description:"Answer 'yes' to confirmation messages",default:!1}).positional("email",{describe:"Email (or unique prefix)",type:"string"});async function Ed({client:e,email:t,yes:a}){try{const i=await p(t,e.auth.users,"email");let n=a;n||(n=(await b.prompt({name:"confirmed",type:"confirm",message:`Are you sure you want to delete '${i.email}'`,default:!1})).confirmed),n&&(await e.auth.users.delete(i.id),_("Deleted"))}catch(i){l(i)}}const Ld={__proto__:null,builder:Md,command:Td,desc:Pd,handler:Ed},qd=["list [email]","ls","$0"],Cd="List users",Ud=e=>e.option("limit",{alias:"n",type:"number",describe:"Limit to n results"}).option("sort",{alias:["s"],type:"string",describe:"Sort by attribute"}).conflicts("email",["limit","sort"]).positional("email",{describe:"User email (or unique prefix)",type:"string"});async function Jd({client:e,email:t,format:a,limit:i,sort:n}){try{if(t){const s=await p(t,e.auth.users,"email");d(s,a)}else{let s=await e.auth.users.list({limit:i,sort:n});a==="table"?(s=s.map(o=>({...o,name:`${o.firstName} ${o.lastName}`})),d(s,"table",["id","email","name","emailVerified","enabled"])):d(s,a??"json")}}catch(s){l(s)}}const Rd={__proto__:null,builder:Ud,command:qd,desc:Cd,handler:Jd},Gd=["metadata <email>","meta"],Zd="Get/set resource metadata",Fd=e=>e.positional("email",{describe:"User email (or unique prefix)",type:"string"}).option("set",{type:"array",describe:"One or more key/values to set in form <key>=<value>. Use <key>= to delete a key."});async function Kd({client:e,email:t,set:a}){try{if(a){let i=await p(t,e.auth.users,"email");const n=k(a);for(const s of Object.keys(n)){const o=n[s];o===""?await e.auth.users.deleteMetadata(i.id,s):await e.auth.users.setMetadata(i.id,s,o)}i=await p(t,e.auth.users,"email"),d(i.metadata,"json")}else{const i=await p(t,e.auth.users,"email");d(i.metadata,"json")}}catch(i){l(i)}}const zd={__proto__:null,builder:Fd,command:Gd,desc:Zd,handler:Kd},Vd=["update <email>"],Wd="Update a user",Bd=e=>e.option("firstName",{description:"First name",type:"string"}).option("lastName",{description:"Last name",type:"string"}).option("roles",{alias:"r",description:"Roles (comma-separated)",type:"array"}).option("emailVerified",{description:"Email verified",type:"boolean"}).option("enabled",{alias:"e",description:"Login enabled",type:"boolean"}).option("interactive",{alias:"i",describe:"Show interactive prompts",type:"boolean",default:"true"}).positional("email",{describe:"Email (or unique prefix)",type:"string"});async function Hd(e){const t=e.client,a=e.email;try{const i=await p(a,t.auth.users,"email");if(e.interactive){const s=await b.prompt([{type:"input",name:"firstName",message:"First name",default:e.firstName||i.firstName},{type:"input",name:"lastName",message:"Last name",default:e.lastName||i.lastName},{type:"input",name:"roles",message:"Roles (comma separated)",default:(e.roles||i.roles).join(", ")},{type:"confirm",name:"emailVerified",message:"Verified?",default:Object.prototype.hasOwnProperty.call(e,"emailVerified")?e.emailVerified:i.emailVerified},{type:"confirm",name:"enabled",message:"Enabled?",default:Object.prototype.hasOwnProperty.call(e,"enabled")?e.enabled:i.enabled},{type:"confirm",name:"changePassword",message:"Change password?",default:!1},{type:"password",name:"password",message:"New password",when:({changePassword:o})=>o},{type:"password",name:"confirmPassword",message:"Confirm password",when:({changePassword:o})=>o}]);if(s.changePassword){if(s.password!==s.confirmPassword)throw new Error("Passwords do not match");e.password=s.password}e.firstName=s.firstName,e.lastName=s.lastName,e.roles=s.roles.split(",").map(o=>o.trim()),e.emailVerified=s.emailVerified,e.enabled=s.enabled}if(e.password){const s=te();await t.auth.users.update(i.id,{passwordResetToken:s}),await t.auth.resetPassword(i.email,e.password,i.applicationId,s)}const n=await t.auth.users.update(i.id,{firstName:e.firstName,lastName:e.lastName,roles:e.roles,emailVerified:e.emailVerified,enabled:e.enabled});e.format==="table"?d(n,"table"):d(n,"json")}catch(i){l(i)}}const Qd={__proto__:null,builder:Bd,command:Vd,desc:Wd,handler:Hd},Xd="users <command>",Yd="User commands",ec=e=>e.command(Rd).command(Od).command(Ld).command(zd).command(Qd).demandCommand(1),tc={__proto__:null,builder:ec,command:Xd,desc:Yd},ic="@emuanalytics/flow-cli",ac="2.2.5",nc="module",sc="dist/index.mjs",oc="Robin Summerhill <robin.summerhill@emu-analytics.com>",rc="Copyright 2018 Emu Analytics Limited",dc={flow:"dist/index.mjs"},cc=["dist","maputnik"],lc={start:"node dist/index.mjs",typecheck:"tsc --noEmit",build:"unbuild",clean:"rimraf dist",lint:"eslint src",format:'prettier "src/**/*.ts" --write',prepublishOnly:"npm run build",prebuild:"npm run clean",precommit:"lint-staged"},pc={"@eslint/js":"^10.0.1","@types/cli-spinner":"^0.2.0","@types/express":"^4.17.25","@types/humanize-plus":"^1.8.0","@types/node":"^20.0.0","@types/table":"^4.0.5","@types/uuid":"^8.3.4","@types/yauzl":"^2.9.1",eslint:"^10.3.0","lint-staged":"^16.4.0",prettier:"^3.0.0",typescript:"^5.9.2","typescript-eslint":"^8.59.2",unbuild:"^3.6.1"},mc={"@emuanalytics/flow-engine-client":"^2.2.5","@modelcontextprotocol/sdk":"^1.12.0","@types/yargs":"^17.0.35",JSONStream:"^1.3.5",chalk:"^5.6.2","cli-spinner":"^0.2.10",colorette:"^2.0.19","csv-stringify":"^5.3.3","debounce-promise":"^3.1.0",execa:"^5.1.1",express:"^4.16.3","find-up":"^8.0.0","humanize-plus":"^1.8.2",inquirer:"^13.4.3","loose-json":"^1.1.2","node-emoji":"^2.2.0",open:"^11.0.0",ora:"^9.4.0","replace-in-file":"^5.0.2","string-width":"^8.2.1",table:"^6.9.0",tslib:"^2.8.1",uuid:"^8.3.2",yargs:"^18.0.0",yauzl:"^2.10.0",zod:"^3.23.0"},uc={"@types/serve-static":"^1.15.0"},yc="ebec740a96cc0c8d2feea4c6d01e48e8a20fe83c",fc={name:ic,version:ac,type:nc,main:sc,author:oc,license:rc,bin:dc,files:cc,scripts:lc,devDependencies:pc,dependencies:mc,overrides:uc,"lint-staged":{"./src/**/*.ts":["eslint"]},gitHead:yc},bc="version",gc="Display Flo.w Engine version information",hc=async({host:e,apiKey:t,client:a,format:i})=>{try{const n=await a.config(),s={"CLI version":fc.version,"Flo.w version":n.version.tag,"Flo.w host":e,"API key":t};d(s,i)}catch(n){l(n.message)}},wc={__proto__:null,command:bc,desc:gc,handler:hc},he=$e([".flowrc",".flowrc.json"]),$c=he?JSON.parse($.readFileSync(he).toString("utf8")):{},_c=e=>{e.client=new K(e.host,e.apiKey)},we=_e(xe(process.argv));we.config($c).env("FLOW").option("k",{alias:"apiKey",demandOption:!0,describe:"Flo.w Engine API key",type:"string",global:!0}).option("h",{alias:"host",default:"https://flow.emu-analytics.net",describe:"Flo.w Engine host URL",type:"string"}).option("f",{alias:"format",default:"table",describe:"Output format",type:"string",choices:["table","csv","json","geojson"]}).command(ft).command($t).command(oi).command(Ji).command(sa).command(an).command(xn).command(Qn).command(Os).command(Qs).command(Uo).command(vr).command(ld).command(Dd).command(tc).command(wc).command(is).demandCommand(1).wrap(Math.min(100,we.terminalWidth())).help().version().middleware([_c]).parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@emuanalytics/flow-cli",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.mjs",
|
|
6
6
|
"author": "Robin Summerhill <robin.summerhill@emu-analytics.com>",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"unbuild": "^3.6.1"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@emuanalytics/flow-engine-client": "^2.2.
|
|
43
|
+
"@emuanalytics/flow-engine-client": "^2.2.5",
|
|
44
44
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
45
45
|
"@types/yargs": "^17.0.35",
|
|
46
46
|
"JSONStream": "^1.3.5",
|
|
@@ -75,5 +75,5 @@
|
|
|
75
75
|
"eslint"
|
|
76
76
|
]
|
|
77
77
|
},
|
|
78
|
-
"gitHead": "
|
|
78
|
+
"gitHead": "ebec740a96cc0c8d2feea4c6d01e48e8a20fe83c"
|
|
79
79
|
}
|