@ecodrix/erix-api 1.1.5 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +3 -3
- package/dist/index.d.ts +86 -31
- package/dist/ts/browser/index.global.js +7 -7
- package/dist/ts/browser/index.global.js.map +1 -1
- package/dist/ts/cjs/index.cjs +1 -1
- package/dist/ts/cjs/index.cjs.map +1 -1
- package/dist/ts/cjs/index.d.cts +86 -31
- package/dist/ts/esm/index.d.ts +86 -31
- package/dist/ts/esm/index.js +1 -1
- package/dist/ts/esm/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core.ts +17 -12
- package/src/resources/crm/activities.ts +1 -5
- package/src/resources/crm/analytics.ts +49 -14
- package/src/resources/crm/automationDashboard.ts +0 -1
- package/src/resources/crm/automations.ts +2 -10
- package/src/resources/crm/leads.ts +8 -37
- package/src/resources/crm/payments.ts +0 -1
- package/src/resources/crm/scoring.ts +0 -1
- package/src/resources/email.ts +1 -3
- package/src/resources/events.ts +1 -3
- package/src/resources/health.ts +1 -3
- package/src/resources/marketing.ts +1 -4
- package/src/resources/storage.ts +1 -4
- package/src/resources/whatsapp/conversations.ts +9 -22
- package/src/resources/whatsapp/messages.ts +34 -7
- package/src/resources/whatsapp/templates.ts +7 -17
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import ae from"repl";import{Command as ne}from"commander";import re from"dotenv";import o from"picocolors";import te from"axios";import Q from"axios-retry";import{io as se}from"socket.io-client";var V=class extends Error{constructor(e){super(e),this.name="EcodrixError"}},u=class extends V{status;code;constructor(e,t,n){super(e),this.name="APIError",this.status=t,this.code=n}},T=class extends u{constructor(e="Invalid API Key or Client Code"){super(e,401,"AUTH_FAILED"),this.name="AuthenticationError"}};var r=class{constructor(e){this.client=e}async post(e,t,n){try{let s=this.buildConfig(n);return(await this.client.post(e,t,s)).data}catch(s){this.handleError(s)}}async get(e,t){try{let n=this.buildConfig(t);return(await this.client.get(e,n)).data}catch(n){this.handleError(n)}}async patch(e,t,n){try{let s=this.buildConfig(n);return(await this.client.patch(e,t,s)).data}catch(s){this.handleError(s)}}async put(e,t,n){try{let s=this.buildConfig(n);return(await this.client.put(e,t,s)).data}catch(s){this.handleError(s)}}async deleteRequest(e,t){try{let n=this.buildConfig(t);return(await this.client.delete(e,n)).data}catch(n){this.handleError(n)}}buildConfig(e){if(!e)return;let t={...e};return e.idempotencyKey&&(t.headers={...t.headers,"Idempotency-Key":e.idempotencyKey}),t}handleError(e){throw e.response?new u(e.response.data?.message||e.response.data?.error||"API Request Failed",e.response.status,e.response.data?.code):new u(e.message||"Network Error")}};var j=class extends r{async list(e){return this.get(`/api/crm/leads/${e}/notes`)}async create(e,t){return this.post(`/api/crm/leads/${e}/notes`,t)}async update(e,t){return this.patch(`/api/crm/notes/${e}`,{content:t})}async pin(e,t=!0){return this.patch(`/api/crm/notes/${e}/pin`,{isPinned:t})}async delete(e){return this.deleteRequest(`/api/crm/notes/${e}`)}},f=class extends r{notes;constructor(e){super(e),this.notes=new j(e)}async timeline(e,t){return this.get(`/api/crm/leads/${e}/timeline`,{params:t})}async list(e,t){return this.get(`/api/crm/leads/${e}/activities`,{params:{...t}})}async log(e){return this.post(`/api/crm/leads/${e.leadId}/activities`,e)}async logCall(e,t){return this.post(`/api/crm/leads/${e}/calls`,t)}};var b=class extends r{async overview(e){return this.get("/api/crm/analytics/overview",{params:e})}async funnel(e){return this.get("/api/crm/analytics/funnel",{params:{pipelineId:e}})}async forecast(e){return this.get("/api/crm/analytics/forecast",{params:{pipelineId:e}})}async sources(e){return this.get("/api/crm/analytics/sources",{params:e})}async team(e){return this.get("/api/crm/analytics/team",{params:e})}async heatmap(e){return this.get("/api/crm/analytics/heatmap",{params:e})}async scores(){return this.get("/api/crm/analytics/scores")}async stageTime(e){return this.get("/api/crm/analytics/stage-time",{params:{pipelineId:e}})}async tiered(e){return this.get("/api/crm/analytics/tiered",{params:e})}async summary(e){return this.get("/api/crm/analytics/summary",{params:e})}async whatsapp(e){return this.get("/api/crm/analytics/whatsapp",{params:e})}};var x=class extends r{async stats(){return this.get("/api/crm/automation/stats")}async logs(e){return this.get("/api/crm/automation/logs",{params:e})}async retryFailedEvent(e){return this.post(`/api/crm/automation/logs/${e}/retry`,{})}};var v=class extends r{async list(){return this.get("/api/crm/automations")}async create(e){return this.post("/api/crm/automations",e)}async update(e,t){return this.patch(`/api/crm/automations/${e}`,t)}async toggle(e){return this.patch(`/api/crm/automations/${e}/toggle`)}async delete(e){return this.deleteRequest(`/api/crm/automations/${e}`)}async bulkDelete(e){return this.post("/api/crm/automations/bulk-delete",{ids:e})}async test(e,t){return this.post(`/api/crm/automations/${e}/test`,{leadId:t})}async getAvailableEvents(){return this.post("/api/crm/automations/events",{})}async enrollments(e,t){return this.get(`/api/crm/automations/${e}/enrollments`,{params:t})}async getEnrollment(e){return this.get(`/api/crm/automations/enrollments/${e}`)}async pauseEnrollment(e,t){return this.post(`/api/crm/automations/${e}/enrollments/${t}/pause`,{})}async resumeEnrollment(e,t){return this.post(`/api/crm/automations/${e}/enrollments/${t}/resume`,{})}async runs(e){return this.get(`/api/crm/automations/${e}/runs`)}async getRun(e){return this.get(`/api/crm/automations/runs/${e}`)}async resumeRun(e){return this.post(`/api/crm/automations/runs/${e}/resume`,{})}async abortRun(e){return this.post(`/api/crm/automations/runs/${e}/abort`,{})}async webhookEvent(e,t,n){return this.post("/api/crm/webhook-event",{ruleId:e,eventName:t,payload:n})}};var P=class extends r{async create(e){return this.post("/api/crm/leads",e)}async upsert(e){return this.post("/api/crm/leads/upsert",e)}async createMany(e,t=50){let n=[];for(let s=0;s<e.length;s+=t){let l=e.slice(s,s+t).map(g=>this.create(g)),m=await Promise.allSettled(l);for(let g of m)if(g.status==="fulfilled")n.push(g.value);else throw g.reason}return n}async import(e){return this.post("/api/crm/leads/import",{leads:e})}async list(e){let t={...e};return Array.isArray(t.tags)&&(t.tags=t.tags.join(",")),this.get("/api/crm/leads",{params:t})}async*listAutoPaging(e){let t=e?.page||1,n=!0;for(;n;){let s=await this.list({...e,page:t}),i=Array.isArray(s.data)?s.data:s||[];if(i.length===0){n=!1;break}for(let l of i)yield l;s.pagination&&t<s.pagination.pages||!s.pagination&&i.length>0?t++:n=!1}}async retrieve(e){return this.get(`/api/crm/leads/${e}`)}async retrieveByPhone(e){return this.get(`/api/crm/leads/phone/${encodeURIComponent(e)}`)}async retrieveByRef(e,t){return this.get(`/api/crm/leads/ref/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}async update(e,t){return this.patch(`/api/crm/leads/${e}`,t)}async move(e,t){return this.patch(`/api/crm/leads/${e}/move`,{stageId:t})}async convert(e,t,n){return this.post(`/api/crm/leads/${e}/convert`,{outcome:t,reason:n})}async tags(e,t){return this.patch(`/api/crm/leads/${e}/tags`,t)}async recalculateScore(e){return this.post(`/api/crm/leads/${e}/score`,{})}async updateMetadata(e,t){return this.patch(`/api/crm/leads/${e}/metadata`,t)}async fields(){return this.get("/api/crm/leads/fields")}async notes(e){return this.get(`/api/crm/leads/${e}/notes`)}async activities(e,t){return this.get(`/api/crm/leads/${e}/timeline`,{params:t})}async createNote(e,t){return this.post(`/api/crm/leads/${e}/notes`,t)}async updateNote(e,t,n){return this.patch(`/api/crm/notes/${t}`,n)}async deleteNote(e,t){return this.deleteRequest(`/api/crm/notes/${t}`)}async delete(e){return this.deleteRequest(`/api/crm/leads/${e}`)}async bulkDelete(e){return this.deleteRequest("/api/crm/leads",{data:{ids:e}})}};var w=class extends r{async capture(e){return this.post("/api/crm/payments/capture",e)}};var $=class extends r{async list(){return this.get("/api/crm/pipelines")}async create(e){return this.post("/api/crm/pipelines",e)}async retrieve(e){return this.get(`/api/crm/pipelines/${e}`)}async update(e,t){return this.patch(`/api/crm/pipelines/${e}`,t)}async setDefault(e){return this.patch(`/api/crm/pipelines/${e}/default`,{})}async duplicate(e,t){return this.post(`/api/crm/pipelines/${e}/duplicate`,{newName:t})}async archive(e){return this.patch(`/api/crm/pipelines/${e}/archive`,{})}async delete(e){return this.deleteRequest(`/api/crm/pipelines/${e}`)}async board(e){return this.get(`/api/crm/pipelines/${e}/board`)}async forecast(e){return this.get(`/api/crm/pipelines/${e}/forecast`)}async addStage(e,t){return this.post(`/api/crm/pipelines/${e}/stages`,t)}async reorderStages(e,t){return this.patch(`/api/crm/pipelines/${e}/stages/reorder`,{order:t})}async updateStage(e,t){return this.patch(`/api/crm/stages/${e}`,t)}async deleteStage(e,t){return this.deleteRequest(`/api/crm/stages/${e}`,{data:t?{moveLeadsToStageId:t}:void 0})}};var R=class extends r{async getConfig(){return this.get("/api/crm/scoring")}async updateConfig(e){return this.patch("/api/crm/scoring",e)}async recalculate(e){return this.post(`/api/crm/scoring/${e}/recalculate`,{})}};var I=class extends r{async enroll(e){return this.post("/api/crm/sequences/enroll",e)}async unenroll(e){return this.deleteRequest(`/api/crm/sequences/unenroll/${e}`)}async listForLead(e){return this.get(`/api/crm/sequences/lead/${e}`)}};var C=class{leads;pipelines;activities;analytics;automations;sequences;scoring;payments;automationDashboard;constructor(e){this.leads=new P(e),this.pipelines=new $(e),this.activities=new f(e),this.analytics=new b(e),this.automations=new v(e),this.sequences=new I(e),this.scoring=new R(e),this.payments=new w(e),this.automationDashboard=new x(e)}};var A=class extends r{async sendEmailCampaign(e){return this.post("/api/saas/emails/campaign",e)}async sendTestEmail(e){return this.post("/api/saas/emails/test",{to:e})}};var k=class extends r{async list(){return this.get("/api/saas/events")}async assign(e){return this.post("/api/saas/events/assign",e)}async unassign(e){return this.post("/api/saas/events/unassign",{name:e})}async unassignBulk(e){return this.post("/api/saas/events/unassign/bulk",{names:e})}async trigger(e){return this.post("/api/saas/workflows/trigger",e)}async listCustomEvents(){return this.get("/api/saas/crm/custom-events")}async createCustomEvent(e){return this.post("/api/saas/crm/custom-events",e)}async deleteCustomEvent(e){return this.deleteRequest(`/api/saas/crm/custom-events/${e}`)}async emit(e){return this.post("/api/saas/crm/events/emit",e)}};var S=class extends r{async system(){return(await this.get("/api/saas/health",{headers:{accept:"application/json"}})).data}async clientHealth(){return(await this.get("/api/saas/health/client")).data}async jobStatus(e){return(await this.get(`/api/saas/jobs/status/${e}`)).data}};var H=class extends r{async sendCampaign(e){return this.post("/api/saas/marketing/emails/campaign",e)}async sendTest(e){return this.post("/api/saas/marketing/emails/test",{to:e})}},J=class extends r{async list(e){return this.get("/api/saas/marketing/campaigns",{params:e})}async create(e){return this.post("/api/saas/marketing/campaigns",e)}async retrieve(e){return this.get(`/api/saas/marketing/campaigns/${e}`)}async update(e,t){return this.patch(`/api/saas/marketing/campaigns/${e}`,t)}async delete(e){return this.deleteRequest(`/api/saas/marketing/campaigns/${e}`)}async send(e,t){return this.post(`/api/saas/marketing/campaigns/${e}/send`,t||{})}async stats(e){return this.get(`/api/saas/marketing/campaigns/${e}/stats`)}},Y=class extends r{async sendTemplate(e){return this.post("/api/saas/marketing/whatsapp/send-template",e)}},E=class extends r{emails;campaigns;whatsapp;constructor(e){super(e),this.emails=new H(e),this.campaigns=new J(e),this.whatsapp=new Y(e)}};import ee from"axios";var D=class extends r{async getUsage(){return this.get("/api/saas/storage/usage")}async createFolder(e){return this.post("/api/saas/storage/folders",{name:e})}async list(e,t){return this.get(`/api/saas/storage/files/${e}`,{params:t})}async delete(e){return this.deleteRequest("/api/saas/storage/files",{params:{key:e}})}async getDownloadUrl(e){return this.post("/api/saas/storage/download-url",{key:e})}async upload(e,t){let{data:n}=await this.client.post("/api/saas/storage/upload-url",t),{uploadUrl:s,key:i}=n;await ee.put(s,e,{headers:{"Content-Type":t.contentType}});let l=e.size||e.byteLength||0;return this.post("/api/saas/storage/confirm-upload",{key:i,sizeBytes:l})}};var L=class extends r{async create(e){return this.post("/api/saas/meet",e)}async list(e){return this.get("/api/saas/meet",{params:e})}async retrieve(e){return this.get(`/api/saas/meet/${e}`)}async update(e,t){return this.patch(`/api/saas/meet/${e}`,t)}async reschedule(e,t){return this.patch(`/api/saas/meet/${e}`,t)}async delete(e){return this.update(e,{status:"cancelled"})}};var q=class extends r{async listLogs(e){return this.get("/api/saas/events/logs",{params:e})}async retrieveLog(e){return this.get(`/api/saas/events/logs/${e}`)}async getStats(e){return this.get("/api/saas/events/stats",{params:e})}async listCallbacks(e){return this.get("/api/saas/callbacks/logs",{params:e})}async listAlerts(e){return this.get("/api/crm/notifications",{params:e})}async dismissAlert(e){return this.patch(`/api/crm/notifications/${e}/dismiss`)}async clearAllAlerts(){return this.deleteRequest("/api/crm/notifications/clear-all")}async retryAction(e){return this.post(`/api/crm/notifications/${e}/retry`,{})}};var O=class extends r{async listFailed(){return this.get("/api/saas/admin/queue/failed")}async getStats(){return this.get("/api/saas/admin/queue/stats")}async retryJob(e){return this.post(`/api/saas/admin/queue/${e}/retry`,{})}async deleteJob(e){return this.deleteRequest(`/api/saas/admin/queue/${e}`)}};var G=class extends r{async create(e){return this.post("/api/saas/storage/folders",{name:e})}async delete(e){return this.deleteRequest(`/api/saas/storage/folders/${encodeURIComponent(e)}`)}},z=class extends r{async list(e,t){return this.get(`/api/saas/storage/files/${e}`,{params:t})}async getUploadUrl(e){return this.post("/api/saas/storage/upload-url",e)}async confirmUpload(e){return this.post("/api/saas/storage/confirm-upload",e)}async getDownloadUrl(e){return this.post("/api/saas/storage/download-url",{key:e})}async delete(e){return this.deleteRequest("/api/saas/storage/files",{params:{key:e}})}},N=class extends r{folders;files;constructor(e){super(e),this.folders=new G(e),this.files=new z(e)}async usage(){return this.get("/api/saas/storage/usage")}};var h=class extends u{constructor(e){super(e,400,"invalid_signature"),this.name="WebhookSignatureError"}},U=class{async constructEvent(e,t,n){if(!t)throw new h("No webhook signature provided");let s=Array.isArray(t)?t[0]:t;s.startsWith("sha256=")&&(s=s.slice(7));try{let i=await import("crypto"),m=i.createHmac("sha256",n).update(e).digest("hex");if(!i.timingSafeEqual(Buffer.from(m),Buffer.from(s)))throw new h("Invalid webhook signature provided");return JSON.parse(e.toString("utf8"))}catch(i){throw i instanceof h?i:new h(`Webhook payload parsing failed: ${i.message}`)}}};var M=class extends r{async list(e){return this.get("/api/saas/chat/broadcasts",{params:e})}async retrieve(e){return this.get(`/api/saas/chat/broadcasts/${e}`)}async create(e){return this.post("/api/saas/chat/broadcast",e)}async update(e,t){return this.patch(`/api/saas/chat/broadcasts/${e}`,t)}async delete(e){return this.deleteRequest(`/api/saas/chat/broadcasts/${e}`)}};var _=class extends r{async list(e){return this.get("/api/saas/chat/conversations",{params:e})}async create(e){return this.post("/api/saas/chat/conversations",e)}async retrieve(e){return this.get(`/api/saas/chat/conversations/${e}`)}async messages(e,t){return this.get(`/api/saas/chat/conversations/${e}/messages`,{params:t})}async linkLead(e,t,n){return this.post(`/api/saas/chat/conversations/${e}/link-lead`,{leadId:t,leadData:n})}async markRead(e){return this.post(`/api/saas/chat/conversations/${e}/read`,{})}async delete(e){return this.deleteRequest(`/api/saas/chat/conversations/${e}`)}async bulkDelete(e){return this.post("/api/saas/chat/conversations/bulk-delete",{ids:e})}};var F=class extends r{async send(e){return this.post("/api/saas/chat/send",e)}async sendTemplate(e){return this.post("/api/saas/chat/send",{...e,templateLanguage:e.language||e.templateLanguage||"en_US"})}async star(e,t){return this.post(`/api/saas/chat/messages/${e}/star`,{isStarred:t})}async react(e,t){return this.post(`/api/saas/chat/messages/${e}/react`,{reaction:t})}async markRead(e){return this.post(`/api/saas/chat/conversations/${e}/read`)}async upload(e){let t=new FormData;return t.append("file",e),this.post("/api/saas/chat/upload",t,{headers:{"Content-Type":"multipart/form-data"}})}};var K=class extends r{async list(e){return this.get("/api/saas/chat/templates",{params:e})}async sync(){return this.post("/api/saas/chat/templates/sync",{})}async retrieve(e){return this.get(`/api/saas/chat/templates/${encodeURIComponent(e)}`)}async create(e){return this.post("/api/saas/chat/templates",e)}async update(e,t){return this.put(`/api/saas/chat/templates/${e}`,t)}async deleteTemplate(e,t){return this.deleteRequest(`/api/saas/chat/templates/${encodeURIComponent(e)}${t?"?force=true":""}`)}async mappingConfig(){return this.get("/api/saas/chat/templates/mapping/config")}async collections(){return this.get("/api/saas/chat/templates/collections")}async collectionFields(e){return this.get(`/api/saas/chat/templates/collections/${encodeURIComponent(e)}/fields`)}async updateMapping(e,t){return this.put(`/api/saas/chat/templates/${encodeURIComponent(e)}/mapping`,t)}async validate(e){return this.get(`/api/saas/chat/templates/${encodeURIComponent(e)}/validate`)}async preview(e,t){return this.post(`/api/saas/chat/templates/${encodeURIComponent(e)}/preview`,{context:t})}async checkUsage(e){return this.get(`/api/saas/chat/templates/${encodeURIComponent(e)}/usage`)}};var B=class extends r{messages;conversations;broadcasts;templates;constructor(e){super(e),this.messages=new F(e),this.conversations=new _(e),this.broadcasts=new M(e),this.templates=new K(e)}async upload(e,t){let n=new FormData;return n.append("file",e,t),this.post("/api/saas/chat/upload",n,{headers:typeof n.getHeaders=="function"?n.getHeaders():void 0})}async sendTemplate(e){return this.post("/api/saas/marketing/whatsapp/send-template",e)}};var W=class{client;socket;whatsapp;crm;media;meet;notifications;email;events;webhooks;storage;marketing;health;queue;constructor(e){if(!e.apiKey)throw new T("API Key is required");let t=e.baseUrl||"https://api.ecodrix.com",n=e.socketUrl||t,s=typeof window<"u"&&typeof window.document<"u",i=s?"browser":typeof process<"u"?`node ${process.version}`:"unknown",l=s?globalThis.navigator?.userAgent||"browser":typeof process<"u"?process.platform:"unknown";this.client=te.create({baseURL:t,headers:{"x-api-key":e.apiKey,"x-client-code":e.clientCode?.toUpperCase(),"Content-Type":"application/json","x-ecodrix-client-agent":JSON.stringify({sdk_version:"1.0.0",runtime:i,os:l})}}),Q(this.client,{retries:3,retryDelay:Q.exponentialDelay,retryCondition:m=>Q.isNetworkOrIdempotentRequestError(m)||m.response?.status===429}),this.whatsapp=new B(this.client),this.crm=new C(this.client),this.media=new D(this.client),this.meet=new L(this.client),this.notifications=new q(this.client),this.email=new A(this.client),this.events=new k(this.client),this.webhooks=new U,this.storage=new N(this.client),this.marketing=new E(this.client),this.health=new S(this.client),this.queue=new O(this.client),this.socket=se(n,{extraHeaders:{"x-api-key":e.apiKey,"x-client-code":e.clientCode?.toUpperCase()||""}}),this.setupSocket(e.clientCode)}joinRoom(e){this.socket.emit("join-room",e)}leaveRoom(e){this.socket.emit("leave-room",e)}setupSocket(e){this.socket.on("connect",()=>{e&&this.socket.emit("join-room",e.toUpperCase())})}on(e,t){return this.socket.on(e,t),this}disconnect(){this.socket.disconnect()}off(e,t){return this.socket.off(e,t),this}async request(e,t,n,s){try{return(await this.client.request({method:e,url:t,data:n,params:s})).data}catch(i){throw i.response?new u(i.response.data?.message||i.response.data?.error||"Raw Execution Failed",i.response.status,i.response.data?.code):new u(i.message||"Network Error")}}};re.config();var X="1.1.5";var ie="Official Isomorphic SDK for the ECODrIx platform. Native support for WhatsApp, CRM, Storage, and Meetings across TS, JS, Python, and Java.",d=new ne;d.name("erix").description(ie).version(X);function y(a){let e=a.key||process.env.ECOD_API_KEY,t=a.client||process.env.ECOD_CLIENT_CODE;return e||(console.error(o.red("Error: API Key is missing.")),console.log(o.yellow("Set ECOD_API_KEY environment variable or use --key <key>")),process.exit(1)),new W({apiKey:e,clientCode:t,baseUrl:a.baseUrl||process.env.ECOD_BASE_URL})}d.option("-k, --key <key>","ECODrIx API Key").option("-c, --client <code...","Tenant Client Code").option("--base-url <url>","API Base URL override");d.command("whoami").description("Verify current authentication and tenant status").action(async(a,e)=>{let t=e.parent.opts(),n=y(t);console.log(o.cyan("Checking connection to ECODrIx Platform..."));try{let s=await n.request("GET","/api/saas/me/profile");console.log(o.green("\u2714 Authenticated successfully!")),console.log(`${o.bold("User ID:")} ${s.id}`),console.log(`${o.bold("Organisation:")} ${s.organisation?.name||"N/A"}`),t.client&&console.log(`${o.bold("Tenant Code:")} ${o.magenta(t.client)}`)}catch(s){console.error(o.red("\u2716 Authentication failed")),console.error(o.dim(s.message)),process.exit(1)}});var oe=d.command("whatsapp").description("WhatsApp Business API operations");oe.command("send-template").description("Send a WhatsApp template message").argument("<phone>","Recipient phone number").argument("<template>","Template name").option("-v, --vars <json>","Template variables as JSON string","[]").action(async(a,e,t,n)=>{let s=n.parent.parent.opts(),i=y(s);try{let l=JSON.parse(t.vars);console.log(o.cyan(`Sending template '${e}' to ${a}...`));let m=await i.whatsapp.messages.sendTemplate({to:a,templateName:e,language:"en_US",variables:l});console.log(o.green("\u2714 Message sent successfully!")),console.log(o.dim(`ID: ${m?.id||"N/A"}`))}catch(l){console.error(o.red("\u2716 Failed to send message")),console.error(o.dim(l.message))}});var Z=d.command("crm").description("CRM and Lead management");Z.command("leads").description("List recent leads").option("-l, --limit <number>","Number of leads to fetch","10").option("-s, --status <status>","Filter by lead status").option("-p, --pipeline <id>","Filter by pipeline ID").option("-q, --search <query>","Search by name or email").action(async(a,e)=>{let t=e.parent.parent.opts(),n=y(t);try{let s=Number.parseInt(a.limit);console.log(o.cyan(`Fetching last ${s} leads...`));let i={limit:s};a.status&&(i.status=a.status),a.pipeline&&(i.pipelineId=a.pipeline),a.search&&(i.search=a.search);let l=await n.crm.leads.list(i),m=Array.isArray(l.data)?l.data:Array.isArray(l)?l:[];if(m.length===0){console.log(o.yellow("No leads found."));return}console.table(m.map(g=>({ID:g.id||g._id,Name:`${g.firstName} ${g.lastName||""}`.trim(),Phone:g.phone,Status:g.status,Score:g.score||0,Created:new Date(g.createdAt).toLocaleDateString()})))}catch(s){console.error(o.red("\u2716 Failed to fetch leads")),console.error(o.dim(s.message))}});Z.command("pipelines").description("List all CRM pipelines").action(async(a,e)=>{let t=e.parent.parent.opts(),n=y(t);try{console.log(o.cyan("Fetching pipelines..."));let s=await n.crm.pipelines.list(),i=s.data||s||[];if(i.length===0){console.log(o.yellow("No pipelines found."));return}console.table(i.map(l=>({ID:l.id||l._id,Name:l.name,Default:l.isDefault?"Yes":"No",Stages:l.stages?.length||0})))}catch(s){console.error(o.red("\u2716 Failed to fetch pipelines")),console.error(o.dim(s.message))}});var ce=d.command("analytics").description("Business Intelligence Analytics");ce.command("overview").description("Get high-level CRM KPIs").option("-r, --range <range>","Date range (e.g., 24h, 7d, 30d, 365d)","30d").action(async(a,e)=>{let t=e.parent.parent.opts(),n=y(t);try{console.log(o.cyan(`Fetching overview metrics for last ${a.range}...`));let s=await n.crm.analytics.overview({range:a.range}),i=s.data||s;console.log(`
|
|
2
|
+
import ne from"repl";import{Command as re}from"commander";import ie from"dotenv";import o from"picocolors";import te from"axios";import Q from"axios-retry";import{io as se}from"socket.io-client";var V=class extends Error{constructor(e){super(e),this.name="EcodrixError"}},u=class extends V{status;code;constructor(e,t,n){super(e),this.name="APIError",this.status=t,this.code=n}},T=class extends u{constructor(e="Invalid API Key or Client Code"){super(e,401,"AUTH_FAILED"),this.name="AuthenticationError"}};var r=class{constructor(e){this.client=e}async post(e,t,n){try{let s=this.buildConfig(n);return(await this.client.post(e,t,s)).data}catch(s){this.handleError(s)}}async get(e,t){try{let n=this.buildConfig(t);return(await this.client.get(e,n)).data}catch(n){this.handleError(n)}}async patch(e,t,n){try{let s=this.buildConfig(n);return(await this.client.patch(e,t,s)).data}catch(s){this.handleError(s)}}async put(e,t,n){try{let s=this.buildConfig(n);return(await this.client.put(e,t,s)).data}catch(s){this.handleError(s)}}async deleteRequest(e,t){try{let n=this.buildConfig(t);return(await this.client.delete(e,n)).data}catch(n){this.handleError(n)}}buildConfig(e){if(!e)return;let t={...e};return e.idempotencyKey&&(t.headers={...t.headers,"Idempotency-Key":e.idempotencyKey}),t}handleError(e){throw e.response?new u(e.response.data?.message||e.response.data?.error||"API Request Failed",e.response.status,e.response.data?.code):new u(e.message||"Network Error")}};var j=class extends r{async list(e){return this.get(`/api/crm/leads/${e}/notes`)}async create(e,t){return this.post(`/api/crm/leads/${e}/notes`,t)}async update(e,t){return this.patch(`/api/crm/notes/${e}`,{content:t})}async pin(e,t=!0){return this.patch(`/api/crm/notes/${e}/pin`,{isPinned:t})}async delete(e){return this.deleteRequest(`/api/crm/notes/${e}`)}},f=class extends r{notes;constructor(e){super(e),this.notes=new j(e)}async timeline(e,t){return this.get(`/api/crm/leads/${e}/timeline`,{params:t})}async list(e,t){return this.get(`/api/crm/leads/${e}/activities`,{params:{...t}})}async log(e){return this.post(`/api/crm/leads/${e.leadId}/activities`,e)}async logCall(e,t){return this.post(`/api/crm/leads/${e}/calls`,t)}};var b=class extends r{async overview(e){return this.get("/api/crm/analytics/overview",{params:e})}async funnel(e){return this.get("/api/crm/analytics/funnel",{params:{pipelineId:e}})}async forecast(e){return this.get("/api/crm/analytics/forecast",{params:{pipelineId:e}})}async sources(e){return this.get("/api/crm/analytics/sources",{params:e})}async team(e){return this.get("/api/crm/analytics/team",{params:e})}async heatmap(e){return this.get("/api/crm/analytics/heatmap",{params:e})}async scores(){return this.get("/api/crm/analytics/scores")}async stageTime(e){return this.get("/api/crm/analytics/stage-time",{params:{pipelineId:e}})}async tiered(e){return this.get("/api/crm/analytics/tiered",{params:e})}async summary(e){return this.get("/api/crm/analytics/summary",{params:e})}async whatsapp(e){return this.get("/api/crm/analytics/whatsapp",{params:e})}};var x=class extends r{async stats(){return this.get("/api/crm/automation/stats")}async logs(e){return this.get("/api/crm/automation/logs",{params:e})}async retryFailedEvent(e){return this.post(`/api/crm/automation/logs/${e}/retry`,{})}};var v=class extends r{async list(){return this.get("/api/crm/automations")}async create(e){return this.post("/api/crm/automations",e)}async update(e,t){return this.patch(`/api/crm/automations/${e}`,t)}async toggle(e){return this.patch(`/api/crm/automations/${e}/toggle`)}async delete(e){return this.deleteRequest(`/api/crm/automations/${e}`)}async bulkDelete(e){return this.post("/api/crm/automations/bulk-delete",{ids:e})}async test(e,t){return this.post(`/api/crm/automations/${e}/test`,{leadId:t})}async getAvailableEvents(){return this.post("/api/crm/automations/events",{})}async enrollments(e,t){return this.get(`/api/crm/automations/${e}/enrollments`,{params:t})}async getEnrollment(e){return this.get(`/api/crm/automations/enrollments/${e}`)}async pauseEnrollment(e,t){return this.post(`/api/crm/automations/${e}/enrollments/${t}/pause`,{})}async resumeEnrollment(e,t){return this.post(`/api/crm/automations/${e}/enrollments/${t}/resume`,{})}async runs(e){return this.get(`/api/crm/automations/${e}/runs`)}async getRun(e){return this.get(`/api/crm/automations/runs/${e}`)}async resumeRun(e){return this.post(`/api/crm/automations/runs/${e}/resume`,{})}async abortRun(e){return this.post(`/api/crm/automations/runs/${e}/abort`,{})}async webhookEvent(e,t,n){return this.post("/api/crm/webhook-event",{ruleId:e,eventName:t,payload:n})}};var P=class extends r{async create(e){return this.post("/api/crm/leads",e)}async upsert(e){return this.post("/api/crm/leads/upsert",e)}async createMany(e,t=50){let n=[];for(let s=0;s<e.length;s+=t){let l=e.slice(s,s+t).map(g=>this.create(g)),m=await Promise.allSettled(l);for(let g of m)if(g.status==="fulfilled")n.push(g.value);else throw g.reason}return n}async import(e){return this.post("/api/crm/leads/import",{leads:e})}async list(e){let t={...e};return Array.isArray(t.tags)&&(t.tags=t.tags.join(",")),this.get("/api/crm/leads",{params:t})}async*listAutoPaging(e){let t=e?.page||1,n=!0;for(;n;){let s=await this.list({...e,page:t}),i=Array.isArray(s.data)?s.data:s||[];if(i.length===0){n=!1;break}for(let l of i)yield l;s.pagination&&t<s.pagination.pages||!s.pagination&&i.length>0?t++:n=!1}}async retrieve(e){return this.get(`/api/crm/leads/${e}`)}async retrieveByPhone(e){return this.get(`/api/crm/leads/phone/${encodeURIComponent(e)}`)}async retrieveByRef(e,t){return this.get(`/api/crm/leads/ref/${encodeURIComponent(e)}/${encodeURIComponent(t)}`)}async update(e,t){return this.patch(`/api/crm/leads/${e}`,t)}async move(e,t){return this.patch(`/api/crm/leads/${e}/move`,{stageId:t})}async convert(e,t,n){return this.post(`/api/crm/leads/${e}/convert`,{outcome:t,reason:n})}async tags(e,t){return this.patch(`/api/crm/leads/${e}/tags`,t)}async recalculateScore(e){return this.post(`/api/crm/leads/${e}/score`,{})}async updateMetadata(e,t){return this.patch(`/api/crm/leads/${e}/metadata`,t)}async fields(){return this.get("/api/crm/leads/fields")}async notes(e){return this.get(`/api/crm/leads/${e}/notes`)}async activities(e,t){return this.get(`/api/crm/leads/${e}/timeline`,{params:t})}async createNote(e,t){return this.post(`/api/crm/leads/${e}/notes`,t)}async updateNote(e,t,n){return this.patch(`/api/crm/notes/${t}`,n)}async deleteNote(e,t){return this.deleteRequest(`/api/crm/notes/${t}`)}async delete(e){return this.deleteRequest(`/api/crm/leads/${e}`)}async bulkDelete(e){return this.deleteRequest("/api/crm/leads",{data:{ids:e}})}};var w=class extends r{async capture(e){return this.post("/api/crm/payments/capture",e)}};var $=class extends r{async list(){return this.get("/api/crm/pipelines")}async create(e){return this.post("/api/crm/pipelines",e)}async retrieve(e){return this.get(`/api/crm/pipelines/${e}`)}async update(e,t){return this.patch(`/api/crm/pipelines/${e}`,t)}async setDefault(e){return this.patch(`/api/crm/pipelines/${e}/default`,{})}async duplicate(e,t){return this.post(`/api/crm/pipelines/${e}/duplicate`,{newName:t})}async archive(e){return this.patch(`/api/crm/pipelines/${e}/archive`,{})}async delete(e){return this.deleteRequest(`/api/crm/pipelines/${e}`)}async board(e){return this.get(`/api/crm/pipelines/${e}/board`)}async forecast(e){return this.get(`/api/crm/pipelines/${e}/forecast`)}async addStage(e,t){return this.post(`/api/crm/pipelines/${e}/stages`,t)}async reorderStages(e,t){return this.patch(`/api/crm/pipelines/${e}/stages/reorder`,{order:t})}async updateStage(e,t){return this.patch(`/api/crm/stages/${e}`,t)}async deleteStage(e,t){return this.deleteRequest(`/api/crm/stages/${e}`,{data:t?{moveLeadsToStageId:t}:void 0})}};var R=class extends r{async getConfig(){return this.get("/api/crm/scoring")}async updateConfig(e){return this.patch("/api/crm/scoring",e)}async recalculate(e){return this.post(`/api/crm/scoring/${e}/recalculate`,{})}};var I=class extends r{async enroll(e){return this.post("/api/crm/sequences/enroll",e)}async unenroll(e){return this.deleteRequest(`/api/crm/sequences/unenroll/${e}`)}async listForLead(e){return this.get(`/api/crm/sequences/lead/${e}`)}};var C=class{leads;pipelines;activities;analytics;automations;sequences;scoring;payments;automationDashboard;constructor(e){this.leads=new P(e),this.pipelines=new $(e),this.activities=new f(e),this.analytics=new b(e),this.automations=new v(e),this.sequences=new I(e),this.scoring=new R(e),this.payments=new w(e),this.automationDashboard=new x(e)}};var A=class extends r{async sendEmailCampaign(e){return this.post("/api/saas/emails/campaign",e)}async sendTestEmail(e){return this.post("/api/saas/emails/test",{to:e})}};var k=class extends r{async list(){return this.get("/api/saas/events")}async assign(e){return this.post("/api/saas/events/assign",e)}async unassign(e){return this.post("/api/saas/events/unassign",{name:e})}async unassignBulk(e){return this.post("/api/saas/events/unassign/bulk",{names:e})}async trigger(e){return this.post("/api/saas/workflows/trigger",e)}async listCustomEvents(){return this.get("/api/saas/crm/custom-events")}async createCustomEvent(e){return this.post("/api/saas/crm/custom-events",e)}async deleteCustomEvent(e){return this.deleteRequest(`/api/saas/crm/custom-events/${e}`)}async emit(e){return this.post("/api/saas/crm/events/emit",e)}};var S=class extends r{async system(){return(await this.get("/api/saas/health",{headers:{accept:"application/json"}})).data}async clientHealth(){return(await this.get("/api/saas/health/client")).data}async jobStatus(e){return(await this.get(`/api/saas/jobs/status/${e}`)).data}};var H=class extends r{async sendCampaign(e){return this.post("/api/saas/marketing/emails/campaign",e)}async sendTest(e){return this.post("/api/saas/marketing/emails/test",{to:e})}},J=class extends r{async list(e){return this.get("/api/saas/marketing/campaigns",{params:e})}async create(e){return this.post("/api/saas/marketing/campaigns",e)}async retrieve(e){return this.get(`/api/saas/marketing/campaigns/${e}`)}async update(e,t){return this.patch(`/api/saas/marketing/campaigns/${e}`,t)}async delete(e){return this.deleteRequest(`/api/saas/marketing/campaigns/${e}`)}async send(e,t){return this.post(`/api/saas/marketing/campaigns/${e}/send`,t||{})}async stats(e){return this.get(`/api/saas/marketing/campaigns/${e}/stats`)}},Y=class extends r{async sendTemplate(e){return this.post("/api/saas/marketing/whatsapp/send-template",e)}},E=class extends r{emails;campaigns;whatsapp;constructor(e){super(e),this.emails=new H(e),this.campaigns=new J(e),this.whatsapp=new Y(e)}};import ee from"axios";var D=class extends r{async getUsage(){return this.get("/api/saas/storage/usage")}async createFolder(e){return this.post("/api/saas/storage/folders",{name:e})}async list(e,t){return this.get(`/api/saas/storage/files/${e}`,{params:t})}async delete(e){return this.deleteRequest("/api/saas/storage/files",{params:{key:e}})}async getDownloadUrl(e){return this.post("/api/saas/storage/download-url",{key:e})}async upload(e,t){let{data:n}=await this.client.post("/api/saas/storage/upload-url",t),{uploadUrl:s,key:i}=n;await ee.put(s,e,{headers:{"Content-Type":t.contentType}});let l=e.size||e.byteLength||0;return this.post("/api/saas/storage/confirm-upload",{key:i,sizeBytes:l})}};var L=class extends r{async create(e){return this.post("/api/saas/meet",e)}async list(e){return this.get("/api/saas/meet",{params:e})}async retrieve(e){return this.get(`/api/saas/meet/${e}`)}async update(e,t){return this.patch(`/api/saas/meet/${e}`,t)}async reschedule(e,t){return this.patch(`/api/saas/meet/${e}`,t)}async delete(e){return this.update(e,{status:"cancelled"})}};var q=class extends r{async listLogs(e){return this.get("/api/saas/events/logs",{params:e})}async retrieveLog(e){return this.get(`/api/saas/events/logs/${e}`)}async getStats(e){return this.get("/api/saas/events/stats",{params:e})}async listCallbacks(e){return this.get("/api/saas/callbacks/logs",{params:e})}async listAlerts(e){return this.get("/api/crm/notifications",{params:e})}async dismissAlert(e){return this.patch(`/api/crm/notifications/${e}/dismiss`)}async clearAllAlerts(){return this.deleteRequest("/api/crm/notifications/clear-all")}async retryAction(e){return this.post(`/api/crm/notifications/${e}/retry`,{})}};var O=class extends r{async listFailed(){return this.get("/api/saas/admin/queue/failed")}async getStats(){return this.get("/api/saas/admin/queue/stats")}async retryJob(e){return this.post(`/api/saas/admin/queue/${e}/retry`,{})}async deleteJob(e){return this.deleteRequest(`/api/saas/admin/queue/${e}`)}};var G=class extends r{async create(e){return this.post("/api/saas/storage/folders",{name:e})}async delete(e){return this.deleteRequest(`/api/saas/storage/folders/${encodeURIComponent(e)}`)}},z=class extends r{async list(e,t){return this.get(`/api/saas/storage/files/${e}`,{params:t})}async getUploadUrl(e){return this.post("/api/saas/storage/upload-url",e)}async confirmUpload(e){return this.post("/api/saas/storage/confirm-upload",e)}async getDownloadUrl(e){return this.post("/api/saas/storage/download-url",{key:e})}async delete(e){return this.deleteRequest("/api/saas/storage/files",{params:{key:e}})}},M=class extends r{folders;files;constructor(e){super(e),this.folders=new G(e),this.files=new z(e)}async usage(){return this.get("/api/saas/storage/usage")}};var h=class extends u{constructor(e){super(e,400,"invalid_signature"),this.name="WebhookSignatureError"}},N=class{async constructEvent(e,t,n){if(!t)throw new h("No webhook signature provided");let s=Array.isArray(t)?t[0]:t;s.startsWith("sha256=")&&(s=s.slice(7));try{let i=await import("crypto"),m=i.createHmac("sha256",n).update(e).digest("hex");if(!i.timingSafeEqual(Buffer.from(m),Buffer.from(s)))throw new h("Invalid webhook signature provided");return JSON.parse(e.toString("utf8"))}catch(i){throw i instanceof h?i:new h(`Webhook payload parsing failed: ${i.message}`)}}};var U=class extends r{async list(e){return this.get("/api/saas/chat/broadcasts",{params:e})}async retrieve(e){return this.get(`/api/saas/chat/broadcasts/${e}`)}async create(e){return this.post("/api/saas/chat/broadcast",e)}async update(e,t){return this.patch(`/api/saas/chat/broadcasts/${e}`,t)}async delete(e){return this.deleteRequest(`/api/saas/chat/broadcasts/${e}`)}};var _=class extends r{async list(e){return this.get("/api/saas/chat/conversations",{params:e})}async create(e){return this.post("/api/saas/chat/conversations",e)}async retrieve(e){return this.get(`/api/saas/chat/conversations/${e}`)}async messages(e,t){return this.get(`/api/saas/chat/conversations/${e}/messages`,{params:t})}async linkLead(e,t,n){return this.post(`/api/saas/chat/conversations/${e}/link-lead`,{leadId:t,leadData:n})}async markRead(e){return this.post(`/api/saas/chat/conversations/${e}/read`,{})}async delete(e){return this.deleteRequest(`/api/saas/chat/conversations/${e}`)}async bulkDelete(e){return this.post("/api/saas/chat/conversations/bulk-delete",{ids:e})}};var F=class extends r{async send(e){return this.post("/api/saas/chat/send",e)}async sendTemplate(e){return this.post("/api/saas/chat/send",{...e,templateLanguage:e.language||e.templateLanguage||"en_US"})}async star(e,t){return this.post(`/api/saas/chat/messages/${e}/star`,{isStarred:t})}async react(e,t){return this.post(`/api/saas/chat/messages/${e}/react`,{reaction:t})}async markRead(e){return this.post(`/api/saas/chat/conversations/${e}/read`)}async upload(e){let t=new FormData;return t.append("file",e),this.post("/api/saas/chat/upload",t,{headers:{"Content-Type":"multipart/form-data"}})}};var K=class extends r{async list(e){return this.get("/api/saas/chat/templates",{params:e})}async sync(){return this.post("/api/saas/chat/templates/sync",{})}async retrieve(e){return this.get(`/api/saas/chat/templates/${encodeURIComponent(e)}`)}async create(e){return this.post("/api/saas/chat/templates",e)}async update(e,t){return this.put(`/api/saas/chat/templates/${e}`,t)}async deleteTemplate(e,t){return this.deleteRequest(`/api/saas/chat/templates/${encodeURIComponent(e)}${t?"?force=true":""}`)}async mappingConfig(){return this.get("/api/saas/chat/templates/mapping/config")}async collections(){return this.get("/api/saas/chat/templates/collections")}async collectionFields(e){return this.get(`/api/saas/chat/templates/collections/${encodeURIComponent(e)}/fields`)}async updateMapping(e,t){return this.put(`/api/saas/chat/templates/${encodeURIComponent(e)}/mapping`,t)}async validate(e){return this.get(`/api/saas/chat/templates/${encodeURIComponent(e)}/validate`)}async preview(e,t){return this.post(`/api/saas/chat/templates/${encodeURIComponent(e)}/preview`,{context:t})}async checkUsage(e){return this.get(`/api/saas/chat/templates/${encodeURIComponent(e)}/usage`)}};var B=class extends r{messages;conversations;broadcasts;templates;constructor(e){super(e),this.messages=new F(e),this.conversations=new _(e),this.broadcasts=new U(e),this.templates=new K(e)}async upload(e,t){let n=new FormData;return n.append("file",e,t),this.post("/api/saas/chat/upload",n,{headers:typeof n.getHeaders=="function"?n.getHeaders():void 0})}async sendTemplate(e){return this.post("/api/saas/marketing/whatsapp/send-template",e)}};var ae="https://api.ecodrix.com",W=class{client;socket;whatsapp;crm;media;meet;notifications;email;events;webhooks;storage;marketing;health;queue;constructor(e){if(!e.apiKey)throw new T("API Key is required");let t=e.baseUrl??ae,n=e.socketUrl||t,s=typeof window<"u"&&typeof window.document<"u",i=s?"browser":typeof process<"u"?`node ${process.version}`:"unknown",l=s?globalThis.navigator?.userAgent||"browser":typeof process<"u"?process.platform:"unknown";this.client=te.create({baseURL:t,headers:{"x-api-key":e.apiKey,"x-client-code":e.clientCode?.toUpperCase(),"Content-Type":"application/json","x-ecodrix-client-agent":JSON.stringify({sdk_version:"1.0.0",runtime:i,os:l})}}),Q(this.client,{retries:3,retryDelay:Q.exponentialDelay,retryCondition:m=>Q.isNetworkOrIdempotentRequestError(m)||m.response?.status===429}),this.whatsapp=new B(this.client),this.crm=new C(this.client),this.media=new D(this.client),this.meet=new L(this.client),this.notifications=new q(this.client),this.email=new A(this.client),this.events=new k(this.client),this.webhooks=new N,this.storage=new M(this.client),this.marketing=new E(this.client),this.health=new S(this.client),this.queue=new O(this.client),this.socket=se(n,{extraHeaders:{"x-api-key":e.apiKey,"x-client-code":e.clientCode?.toUpperCase()||""}}),this.setupSocket(e.clientCode)}joinRoom(e){this.socket.emit("join-room",e)}leaveRoom(e){this.socket.emit("leave-room",e)}setupSocket(e){this.socket.on("connect",()=>{e&&this.socket.emit("join-room",e.toUpperCase())})}on(e,t){return this.socket.on(e,t),this}disconnect(){this.socket.disconnect()}off(e,t){return this.socket.off(e,t),this}async request(e,t,n,s){try{return(await this.client.request({method:e,url:t,data:n,params:s})).data}catch(i){throw i.response?new u(i.response.data?.message||i.response.data?.error||"Raw Execution Failed",i.response.status,i.response.data?.code):new u(i.message||"Network Error")}}};ie.config();var X="1.1.7";var oe="Official Isomorphic SDK for the ECODrIx platform. Native support for WhatsApp, CRM, Storage, and Meetings across TS, JS, Python, and Java.",d=new re;d.name("erix").description(oe).version(X);function y(a){let e=a.key||process.env.ECOD_API_KEY,t=a.client||process.env.ECOD_CLIENT_CODE;return e||(console.error(o.red("Error: API Key is missing.")),console.log(o.yellow("Set ECOD_API_KEY environment variable or use --key <key>")),process.exit(1)),new W({apiKey:e,clientCode:t,baseUrl:a.baseUrl||process.env.ECOD_BASE_URL})}d.option("-k, --key <key>","ECODrIx API Key").option("-c, --client <code...","Tenant Client Code").option("--base-url <url>","API Base URL override");d.command("whoami").description("Verify current authentication and tenant status").action(async(a,e)=>{let t=e.parent.opts(),n=y(t);console.log(o.cyan("Checking connection to ECODrIx Platform..."));try{let s=await n.request("GET","/api/saas/me/profile");console.log(o.green("\u2714 Authenticated successfully!")),console.log(`${o.bold("User ID:")} ${s.id}`),console.log(`${o.bold("Organisation:")} ${s.organisation?.name||"N/A"}`),t.client&&console.log(`${o.bold("Tenant Code:")} ${o.magenta(t.client)}`)}catch(s){console.error(o.red("\u2716 Authentication failed")),console.error(o.dim(s.message)),process.exit(1)}});var ce=d.command("whatsapp").description("WhatsApp Business API operations");ce.command("send-template").description("Send a WhatsApp template message").argument("<phone>","Recipient phone number").argument("<template>","Template name").option("-v, --vars <json>","Template variables as JSON string","[]").action(async(a,e,t,n)=>{let s=n.parent.parent.opts(),i=y(s);try{let l=JSON.parse(t.vars);console.log(o.cyan(`Sending template '${e}' to ${a}...`));let m=await i.whatsapp.messages.sendTemplate({to:a,templateName:e,language:"en_US",variables:l});console.log(o.green("\u2714 Message sent successfully!")),console.log(o.dim(`ID: ${m?.id||"N/A"}`))}catch(l){console.error(o.red("\u2716 Failed to send message")),console.error(o.dim(l.message))}});var Z=d.command("crm").description("CRM and Lead management");Z.command("leads").description("List recent leads").option("-l, --limit <number>","Number of leads to fetch","10").option("-s, --status <status>","Filter by lead status").option("-p, --pipeline <id>","Filter by pipeline ID").option("-q, --search <query>","Search by name or email").action(async(a,e)=>{let t=e.parent.parent.opts(),n=y(t);try{let s=Number.parseInt(a.limit);console.log(o.cyan(`Fetching last ${s} leads...`));let i={limit:s};a.status&&(i.status=a.status),a.pipeline&&(i.pipelineId=a.pipeline),a.search&&(i.search=a.search);let l=await n.crm.leads.list(i),m=Array.isArray(l.data)?l.data:Array.isArray(l)?l:[];if(m.length===0){console.log(o.yellow("No leads found."));return}console.table(m.map(g=>({ID:g.id||g._id,Name:`${g.firstName} ${g.lastName||""}`.trim(),Phone:g.phone,Status:g.status,Score:g.score||0,Created:new Date(g.createdAt).toLocaleDateString()})))}catch(s){console.error(o.red("\u2716 Failed to fetch leads")),console.error(o.dim(s.message))}});Z.command("pipelines").description("List all CRM pipelines").action(async(a,e)=>{let t=e.parent.parent.opts(),n=y(t);try{console.log(o.cyan("Fetching pipelines..."));let s=await n.crm.pipelines.list(),i=s.data||s||[];if(i.length===0){console.log(o.yellow("No pipelines found."));return}console.table(i.map(l=>({ID:l.id||l._id,Name:l.name,Default:l.isDefault?"Yes":"No",Stages:l.stages?.length||0})))}catch(s){console.error(o.red("\u2716 Failed to fetch pipelines")),console.error(o.dim(s.message))}});var pe=d.command("analytics").description("Business Intelligence Analytics");pe.command("overview").description("Get high-level CRM KPIs").option("-r, --range <range>","Date range (e.g., 24h, 7d, 30d, 365d)","30d").action(async(a,e)=>{let t=e.parent.parent.opts(),n=y(t);try{console.log(o.cyan(`Fetching overview metrics for last ${a.range}...`));let s=await n.crm.analytics.overview({range:a.range}),i=s.data||s;console.log(`
|
|
3
3
|
${o.bold("OVERVIEW KPIs:")}`),console.log(`Total Leads: ${o.green(i.totalLeads||0)}`),console.log(`Open Value: ${o.yellow(`$${(i.openValue||0).toLocaleString()}`)}`),console.log(`Won Revenue: ${o.green(`$${(i.wonRevenue||0).toLocaleString()}`)}`),console.log(`Avg Score: ${o.blue(i.avgScore?.toFixed(1)||0)}`),console.log(`Conversion: ${o.magenta(`${(i.conversionRate||0).toFixed(2)}%`)}
|
|
4
|
-
`)}catch(s){console.error(o.red("\u2716 Failed to fetch analytics overview")),console.error(o.dim(s.message))}});var
|
|
4
|
+
`)}catch(s){console.error(o.red("\u2716 Failed to fetch analytics overview")),console.error(o.dim(s.message))}});var le=d.command("webhooks").description("Webhook utility tools");le.command("verify").description("Verify a cryptographic webhook signature").argument("<payload>","The raw request body string").argument("<signature>","The 'x-ecodrix-signature' header value").argument("<secret>","Your webhook signing secret").action(async(a,e,t,n,s)=>{let i=s.parent.parent.opts(),l=y(i);try{await l.webhooks.constructEvent(a,e,t),console.log(o.green("\u2714 Signature is VALID"))}catch(m){console.error(o.red("\u2716 Error during verification")),console.error(o.dim(m.message))}});d.command("shell").alias("repl").description("Start an interactive SDK shell").action(async(a,e)=>{let t=e.parent.opts(),n=y(t);console.log(o.magenta(o.bold(`
|
|
5
5
|
Welcome to the Erix Interactive Shell`))),console.log(o.dim(`SDK Version: ${X}`)),console.log(o.dim(`The 'ecod' client is pre-initialized and ready.
|
|
6
|
-
`));let s=
|
|
6
|
+
`));let s=ne.start({prompt:o.cyan("erix > "),useColors:!0});s.context.ecod=n,s.context.whatsapp=n.whatsapp,s.context.crm=n.crm,s.context.meet=n.meet,s.context.media=n.media,s.on("exit",()=>{console.log(o.yellow(`
|
|
7
7
|
Goodbye!`)),process.exit(0)})});d.command("completion").description("Generate Bash auto-completion script").action(()=>{console.log(`
|
|
8
8
|
# Erix Bash Completion
|
|
9
9
|
_erix_completions() {
|
package/dist/index.d.ts
CHANGED
|
@@ -132,19 +132,21 @@ declare class Analytics extends APIResource {
|
|
|
132
132
|
* Retrieve high-level CRM performance KPIs.
|
|
133
133
|
* Includes total leads, pipeline value, won revenue, and conversion rates.
|
|
134
134
|
*
|
|
135
|
-
* @param params - Optional filters
|
|
136
|
-
* @returns KPI summary object.
|
|
135
|
+
* @param params - Optional filters including time range (24h, 7d, 30d, etc.) and custom date bounds.
|
|
136
|
+
* @returns {Promise<any>} KPI summary object containing core business metrics.
|
|
137
137
|
* @example
|
|
138
138
|
* ```typescript
|
|
139
139
|
* const stats = await erixClient.crm.analytics.overview({ range: "30d" });
|
|
140
|
+
* console.log(stats.avgScore);
|
|
140
141
|
* ```
|
|
141
142
|
*/
|
|
142
143
|
overview<T = any>(params?: AnalyticsParams): Promise<T>;
|
|
143
144
|
/**
|
|
144
145
|
* Get stage-by-stage lead counts and conversion percentages for a pipeline.
|
|
145
|
-
* Useful for identifying funnel bottlenecks.
|
|
146
|
+
* Useful for identifying funnel bottlenecks and drop-off points.
|
|
146
147
|
*
|
|
147
148
|
* @param pipelineId - The unique ID of the pipeline to analyze.
|
|
149
|
+
* @returns {Promise<any>} Array of funnel stages with count and conversion data.
|
|
148
150
|
* @example
|
|
149
151
|
* ```typescript
|
|
150
152
|
* const funnel = await erixClient.crm.analytics.funnel("pipe_123");
|
|
@@ -152,44 +154,74 @@ declare class Analytics extends APIResource {
|
|
|
152
154
|
*/
|
|
153
155
|
funnel<T = any>(pipelineId: string): Promise<T>;
|
|
154
156
|
/**
|
|
155
|
-
* Revenue forecast: deal value × stage probability.
|
|
157
|
+
* Revenue forecast: Calculates expected revenue based on deal value × stage probability.
|
|
158
|
+
* Helps in sales planning and goal setting.
|
|
159
|
+
*
|
|
160
|
+
* @param pipelineId - Optional pipeline ID to filter the forecast.
|
|
161
|
+
* @returns {Promise<any>} Forecast data including weighted expected revenue.
|
|
162
|
+
* @example
|
|
163
|
+
* ```typescript
|
|
164
|
+
* const prognosis = await erixClient.crm.analytics.forecast("pipe_123");
|
|
165
|
+
* ```
|
|
156
166
|
*/
|
|
157
167
|
forecast<T = any>(pipelineId?: string): Promise<T>;
|
|
158
168
|
/**
|
|
159
|
-
* Lead source breakdown: count, conversion rate, total value per source.
|
|
169
|
+
* Lead source breakdown: count, conversion rate, and total value per source.
|
|
170
|
+
*
|
|
171
|
+
* @param params - Time range filters.
|
|
172
|
+
* @returns {Promise<any>} Breakdown of how different marketing channels are performing.
|
|
160
173
|
*/
|
|
161
174
|
sources<T = any>(params?: AnalyticsParams): Promise<T>;
|
|
162
175
|
/**
|
|
163
|
-
* Team leaderboard: won deals, revenue, activity
|
|
176
|
+
* Team leaderboard: Evaluates agent performance across won deals, revenue, and activity.
|
|
177
|
+
*
|
|
178
|
+
* @param params - Time range filters.
|
|
179
|
+
* @returns {Promise<any>} Ranked list of team members by performance.
|
|
164
180
|
*/
|
|
165
181
|
team<T = any>(params?: AnalyticsParams): Promise<T>;
|
|
166
182
|
/**
|
|
167
|
-
* Daily activity counts by type.
|
|
183
|
+
* Activity heatmap: Daily activity counts by type.
|
|
184
|
+
* Ideal for visualizing engagement patterns on a calendar view.
|
|
185
|
+
*
|
|
186
|
+
* @param params - Time range filters.
|
|
187
|
+
* @returns {Promise<any>} Time-series data of team activities.
|
|
168
188
|
*/
|
|
169
189
|
heatmap<T = any>(params?: AnalyticsParams): Promise<T>;
|
|
170
190
|
/**
|
|
171
|
-
* Score distribution:
|
|
191
|
+
* Score distribution: Groups leads into buckets based on their calculated score (0-100).
|
|
192
|
+
*
|
|
193
|
+
* @returns {Promise<any>} Volume of leads in different readiness tiers.
|
|
172
194
|
*/
|
|
173
195
|
scores<T = any>(): Promise<T>;
|
|
174
196
|
/**
|
|
175
|
-
* Avg time
|
|
197
|
+
* Avg time in stage: Measures the velocity of leads through the sales pipeline.
|
|
198
|
+
*
|
|
199
|
+
* @param pipelineId - Target pipeline ID.
|
|
200
|
+
* @returns {Promise<any>} Velocity metrics per stage.
|
|
176
201
|
*/
|
|
177
202
|
stageTime<T = any>(pipelineId: string): Promise<T>;
|
|
178
203
|
/**
|
|
179
|
-
* Tiered Growth Report matching business sophistication.
|
|
204
|
+
* Tiered Growth Report matching business sophistication (Pulse, Growth, Weapon).
|
|
205
|
+
* Provides deep tactical and strategic insights.
|
|
206
|
+
*
|
|
207
|
+
* @param params - Filtering and range parameters.
|
|
180
208
|
*/
|
|
181
209
|
tiered<T = any>(params?: AnalyticsParams): Promise<T>;
|
|
182
210
|
/**
|
|
183
|
-
* Consolidated analytics including CRM overview and WhatsApp.
|
|
211
|
+
* Consolidated analytics including CRM overview and WhatsApp messaging metrics.
|
|
212
|
+
*
|
|
213
|
+
* @param params - Time range filters.
|
|
184
214
|
*/
|
|
185
215
|
summary<T = any>(params?: AnalyticsParams): Promise<T>;
|
|
186
216
|
/**
|
|
187
217
|
* Retrieve WhatsApp messaging volume and delivery performance analytics.
|
|
218
|
+
* Includes total sent, delivered, read, and daily volume trends.
|
|
188
219
|
*
|
|
189
220
|
* @param params - Optional filters (time range).
|
|
190
221
|
* @example
|
|
191
222
|
* ```typescript
|
|
192
223
|
* const waStats = await erixClient.crm.analytics.whatsapp({ range: "7d" });
|
|
224
|
+
* console.log(waStats.totalSent);
|
|
193
225
|
* ```
|
|
194
226
|
*/
|
|
195
227
|
whatsapp<T = any>(params?: AnalyticsParams): Promise<T>;
|
|
@@ -2213,6 +2245,31 @@ interface SendTemplateParams {
|
|
|
2213
2245
|
* });
|
|
2214
2246
|
* ```
|
|
2215
2247
|
*/
|
|
2248
|
+
/**
|
|
2249
|
+
* Resolved media metadata returned by any upload endpoint.
|
|
2250
|
+
* `variants` is only present for raster images (JPEG, PNG, WebP, AVIF, GIF).
|
|
2251
|
+
*/
|
|
2252
|
+
interface ChatMediaMeta {
|
|
2253
|
+
/** Raw CDN URL — always present, all media types */
|
|
2254
|
+
url: string;
|
|
2255
|
+
/** Categorical type — "image" | "video" | "audio" | "document" */
|
|
2256
|
+
type: "image" | "video" | "audio" | "document";
|
|
2257
|
+
/** Cloudflare-optimised variant URLs. Only present for raster images. */
|
|
2258
|
+
variants?: {
|
|
2259
|
+
/** 150px WebP — use for list thumbnails and chat bubbles */
|
|
2260
|
+
thumb: string;
|
|
2261
|
+
/** 600px WebP — use for modal previews */
|
|
2262
|
+
medium: string;
|
|
2263
|
+
/** 1200px WebP — use for hero or full-screen views */
|
|
2264
|
+
full: string;
|
|
2265
|
+
/** Original CDN URL, no transformation */
|
|
2266
|
+
raw: string;
|
|
2267
|
+
};
|
|
2268
|
+
/** Storage key within the tenant bucket */
|
|
2269
|
+
key?: string;
|
|
2270
|
+
/** Original filename */
|
|
2271
|
+
fileName?: string;
|
|
2272
|
+
}
|
|
2216
2273
|
declare class Messages extends APIResource {
|
|
2217
2274
|
/**
|
|
2218
2275
|
* Send a free-text or media message to a WhatsApp number.
|
|
@@ -2291,26 +2348,24 @@ declare class Messages extends APIResource {
|
|
|
2291
2348
|
/**
|
|
2292
2349
|
* Upload a media file for WhatsApp chat.
|
|
2293
2350
|
*
|
|
2294
|
-
*
|
|
2295
|
-
*
|
|
2296
|
-
*
|
|
2351
|
+
* Works with any file type — image, video, audio, or document.
|
|
2352
|
+
* For raster images the response includes Cloudflare-optimised `variants`
|
|
2353
|
+
* (thumb 150px, medium 600px, full 1200px). Non-image types return only `url`.
|
|
2297
2354
|
*
|
|
2298
2355
|
* @param file - The file to upload (File, Blob, or Buffer).
|
|
2299
|
-
* @returns
|
|
2356
|
+
* @returns Full media metadata `{ url, type, variants?, key, fileName }`.
|
|
2300
2357
|
*
|
|
2301
2358
|
* @example
|
|
2302
2359
|
* ```typescript
|
|
2303
2360
|
* const file = input.files[0];
|
|
2304
2361
|
* const { data } = await ecod.whatsapp.messages.upload(file);
|
|
2305
|
-
*
|
|
2362
|
+
* // For images: data.variants.thumb → 150px WebP from Cloudflare
|
|
2363
|
+
* // For video/audio: use data.url directly in <video> or <audio>
|
|
2306
2364
|
* ```
|
|
2307
2365
|
*/
|
|
2308
|
-
upload
|
|
2309
|
-
url: string;
|
|
2310
|
-
type: string;
|
|
2311
|
-
}>(file: any): Promise<{
|
|
2366
|
+
upload(file: any): Promise<{
|
|
2312
2367
|
success: boolean;
|
|
2313
|
-
data:
|
|
2368
|
+
data: ChatMediaMeta;
|
|
2314
2369
|
}>;
|
|
2315
2370
|
}
|
|
2316
2371
|
|
|
@@ -2480,6 +2535,9 @@ declare class WhatsApp extends APIResource {
|
|
|
2480
2535
|
|
|
2481
2536
|
/**
|
|
2482
2537
|
* Configuration options for the Ecodrix client.
|
|
2538
|
+
*
|
|
2539
|
+
* Minimum required: `apiKey` and `clientCode`.
|
|
2540
|
+
* The backend URL is managed internally and should not need to be changed.
|
|
2483
2541
|
*/
|
|
2484
2542
|
interface EcodrixOptions {
|
|
2485
2543
|
/**
|
|
@@ -2491,22 +2549,19 @@ interface EcodrixOptions {
|
|
|
2491
2549
|
/**
|
|
2492
2550
|
* Your tenant ID (Client Code).
|
|
2493
2551
|
* This scopes all API requests to your specific organisation.
|
|
2494
|
-
* Required for most operations.
|
|
2495
2552
|
* @example "ERIX_CLNT_JHBJHF"
|
|
2496
2553
|
*/
|
|
2497
2554
|
clientCode?: string;
|
|
2498
2555
|
/**
|
|
2499
|
-
* Override
|
|
2500
|
-
*
|
|
2501
|
-
* @default "https://api.ecodrix.com"
|
|
2556
|
+
* @internal Override Socket.io URL for testing/staging.
|
|
2557
|
+
* Not documented — internal use only.
|
|
2502
2558
|
*/
|
|
2503
|
-
|
|
2559
|
+
socketUrl?: string;
|
|
2504
2560
|
/**
|
|
2505
|
-
* Override the
|
|
2506
|
-
*
|
|
2507
|
-
* @default "https://api.ecodrix.com"
|
|
2561
|
+
* @internal Override the backend API URL. Used by the CLI and internal tests only.
|
|
2562
|
+
* Host projects must never set this — the production URL is hardcoded internally.
|
|
2508
2563
|
*/
|
|
2509
|
-
|
|
2564
|
+
baseUrl?: string;
|
|
2510
2565
|
}
|
|
2511
2566
|
/**
|
|
2512
2567
|
* The primary entry point for the ECODrIx SDK.
|
|
@@ -2635,4 +2690,4 @@ declare class Ecodrix {
|
|
|
2635
2690
|
request<T = any>(method: Method, path: string, data?: any, params?: any): Promise<T>;
|
|
2636
2691
|
}
|
|
2637
2692
|
|
|
2638
|
-
export { APIError, Activities, Analytics, type AnalyticsParams, type AnalyticsRange, type AssignEventPayload, AuthenticationError, AutomationDashboard, type AutomationRulePayload, Automations, Broadcasts, CRM, type CampaignResult, Campaigns, type ClientHealth, Conversations, type CreateBroadcastParams, type CreateLeadParams, type CreateMeetingParams, type CreatePipelineParams, Ecodrix, EcodrixError, type EcodrixOptions, EmailResource, Emails, type EventDefinition, EventsResource, Files, Folders, Health, type JobStats, type JobStatus, type LeadSource, type LeadStatus, Leads, type ListLeadsParams, type ListParams, type LogActivityParams, type LogCallParams, type LogFilter, Marketing, MediaResource, Meetings, Messages, Notes, Notifications, Payments, type PipelineStageParams, Pipelines, Queue, RateLimitError, Scoring, type ScoringConfig, type SendCampaignParams, type SendCampaignPayload, type SendMessageParams, type SendTemplateParams, type SendTemplatePayload, Sequences, Storage, type SystemHealth, type TemplateMapping, Templates, type TriggerPayload, type TriggerResponse, type UpdateMeetingParams, type UploadOptions, type UpsertLeadParams, WebhookSignatureError, Webhooks, WhatsApp, WhatsAppMarketing, Ecodrix as default };
|
|
2693
|
+
export { APIError, Activities, Analytics, type AnalyticsParams, type AnalyticsRange, type AssignEventPayload, AuthenticationError, AutomationDashboard, type AutomationRulePayload, Automations, Broadcasts, CRM, type CampaignResult, Campaigns, type ChatMediaMeta, type ClientHealth, Conversations, type CreateBroadcastParams, type CreateLeadParams, type CreateMeetingParams, type CreatePipelineParams, Ecodrix, EcodrixError, type EcodrixOptions, EmailResource, Emails, type EventDefinition, EventsResource, Files, Folders, Health, type JobStats, type JobStatus, type LeadSource, type LeadStatus, Leads, type ListLeadsParams, type ListParams, type LogActivityParams, type LogCallParams, type LogFilter, Marketing, MediaResource, Meetings, Messages, Notes, Notifications, Payments, type PipelineStageParams, Pipelines, Queue, RateLimitError, Scoring, type ScoringConfig, type SendCampaignParams, type SendCampaignPayload, type SendMessageParams, type SendTemplateParams, type SendTemplatePayload, Sequences, Storage, type SystemHealth, type TemplateMapping, Templates, type TriggerPayload, type TriggerResponse, type UpdateMeetingParams, type UploadOptions, type UpsertLeadParams, WebhookSignatureError, Webhooks, WhatsApp, WhatsAppMarketing, Ecodrix as default };
|