@ecodrix/erix-api 1.0.0 → 1.0.3

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.
Files changed (39) hide show
  1. package/README.md +32 -25
  2. package/dist/cli.js +38 -0
  3. package/dist/index.d.cts +1871 -0
  4. package/dist/index.d.ts +902 -42
  5. package/dist/ts/browser/index.global.js +14 -14
  6. package/dist/ts/browser/index.global.js.map +1 -1
  7. package/dist/ts/cjs/index.cjs +1 -1
  8. package/dist/ts/cjs/index.cjs.map +1 -1
  9. package/dist/ts/cjs/index.d.cts +902 -42
  10. package/dist/ts/esm/index.d.ts +902 -42
  11. package/dist/ts/esm/index.js +1 -1
  12. package/dist/ts/esm/index.js.map +1 -1
  13. package/package.json +7 -2
  14. package/src/cli.ts +318 -0
  15. package/src/core.ts +20 -0
  16. package/src/index.ts +17 -1
  17. package/src/resource.ts +44 -5
  18. package/src/resources/crm/activities.ts +89 -0
  19. package/src/resources/crm/analytics.ts +89 -0
  20. package/src/resources/crm/automationDashboard.ts +24 -0
  21. package/src/resources/crm/automations.ts +145 -0
  22. package/src/resources/crm/index.ts +24 -0
  23. package/src/resources/crm/leads.ts +170 -42
  24. package/src/resources/crm/payments.ts +10 -0
  25. package/src/resources/crm/pipelines.ts +117 -0
  26. package/src/resources/crm/scoring.ts +33 -0
  27. package/src/resources/crm/sequences.ts +24 -0
  28. package/src/resources/events.ts +41 -0
  29. package/src/resources/health.ts +61 -0
  30. package/src/resources/marketing.ts +104 -0
  31. package/src/resources/meet.ts +9 -2
  32. package/src/resources/notifications.ts +30 -0
  33. package/src/resources/queue.ts +39 -0
  34. package/src/resources/storage.ts +72 -0
  35. package/src/resources/whatsapp/broadcasts.ts +31 -0
  36. package/src/resources/whatsapp/conversations.ts +34 -9
  37. package/src/resources/whatsapp/index.ts +20 -0
  38. package/src/resources/whatsapp/messages.ts +24 -0
  39. package/src/resources/whatsapp/templates.ts +99 -0
package/README.md CHANGED
@@ -165,10 +165,10 @@ Use this specifically to dispatch high-priority utility templates containing dyn
165
165
  const { messageId } = await ecod.whatsapp.sendTemplate({
166
166
  phone: "+919876543210",
167
167
  templateName: "payment_confirmation",
168
- variables: {
169
- name: "Dhanesh",
170
- amount: "₹1,500"
171
- }
168
+ variables: {
169
+ name: "Dhanesh",
170
+ amount: "₹1,500",
171
+ },
172
172
  });
173
173
  ```
174
174
 
@@ -223,7 +223,7 @@ const { data: leads } = await ecod.crm.leads.list({
223
223
  });
224
224
  ```
225
225
 
226
- *(See [Enterprise Capabilities](#enterprise-capabilities) for efficient auto-pagination or bulk-creation tricks like `listAutoPaging` and `createMany`).*
226
+ _(See [Enterprise Capabilities](#enterprise-capabilities) for efficient auto-pagination or bulk-creation tricks like `listAutoPaging` and `createMany`)._
227
227
 
228
228
  **Retrieve a Lead by ID**
229
229
 
@@ -331,7 +331,7 @@ const { data } = await ecod.storage.upload(file, {
331
331
  contentType: "image/png"
332
332
  });
333
333
 
334
- console.log(data.url);
334
+ console.log(data.url);
335
335
  // -> https://cdn.ecodrix.com/avatars/dhanesh.png
336
336
  ```
337
337
 
@@ -396,7 +396,7 @@ Register a new entry point that you want to show up in the CRM Automation Builde
396
396
  await ecod.events.assign({
397
397
  name: "cart_abandoned",
398
398
  displayName: "Shopping Cart Abandoned",
399
- pipelineId: "pipeline_123", /* Auto map leads to this pipeline */
399
+ pipelineId: "pipeline_123" /* Auto map leads to this pipeline */,
400
400
  });
401
401
  ```
402
402
 
@@ -461,6 +461,7 @@ const { data: callbacks } = await ecod.notifications.listCallbacks({
461
461
  The SDK is equipped with state-of-the-art native patterns for robust execution, zero-downtime performance, and unparalleled developer experience. All network requests automatically utilize an exponential-backoff retry engine to gracefully handle temporary network errors.
462
462
 
463
463
  ### Auto-Paginating Iterators
464
+
464
465
  To rapidly ingest records without manually iterating pages, use standard Node.js `for await` loops. The SDK controls memory buffers and page fetching dynamically.
465
466
 
466
467
  ```typescript
@@ -471,6 +472,7 @@ for await (const lead of ecod.crm.leads.listAutoPaging({ status: "won" })) {
471
472
  ```
472
473
 
473
474
  ### Bulk Data Chunking
475
+
474
476
  Need to insert 5,000 leads at once but worried about network congestion or rate limits? `createMany` automatically chunks arrays into concurrent streams.
475
477
 
476
478
  ```typescript
@@ -480,43 +482,48 @@ console.log(`Successfully ingested ${results.length} leads.`);
480
482
  ```
481
483
 
482
484
  ### Idempotency Keys
485
+
483
486
  Because the SDK provides an automatic network retry engine (`axios-retry`), temporary blips could duplicate events. Passing an `idempotencyKey` strictly tells the backend: "Only execute this once, even if I accidentally retry the same payload."
484
487
 
485
488
  ```typescript
486
489
  await ecod.email.sendEmailCampaign(
487
490
  { subject: "Promo", recipients: ["user@example.com"] },
488
- { idempotencyKey: "promo_campaign_uuid_123_abc" }
491
+ { idempotencyKey: "promo_campaign_uuid_123_abc" },
489
492
  );
490
493
  ```
491
494
 
492
495
  ### Webhook Signature Verification
496
+
493
497
  Verify cryptographic webhook payloads issued by the ECODrIx platform reliably in Node environments, mitigating spoofing attacks seamlessly.
494
498
 
495
499
  ```typescript
496
- app.post("/api/webhooks", express.raw({ type: "application/json" }), async (req, res) => {
497
- try {
498
- const event = await ecod.webhooks.constructEvent(
499
- req.body.toString(),
500
- req.headers['x-ecodrix-signature'],
501
- "whsec_your_secret_key"
502
- );
503
- console.log("Verified event received:", event);
504
- } catch (err) {
505
- return res.status(400).send(`Invalid signature: ${err.message}`);
506
- }
507
- });
500
+ app.post(
501
+ "/api/webhooks",
502
+ express.raw({ type: "application/json" }),
503
+ async (req, res) => {
504
+ try {
505
+ const event = await ecod.webhooks.constructEvent(
506
+ req.body.toString(),
507
+ req.headers["x-ecodrix-signature"],
508
+ "whsec_your_secret_key",
509
+ );
510
+ console.log("Verified event received:", event);
511
+ } catch (err) {
512
+ return res.status(400).send(`Invalid signature: ${err.message}`);
513
+ }
514
+ },
515
+ );
508
516
  ```
509
517
 
510
518
  ### Raw Execution Engine
519
+
511
520
  Need to execute an experimental, undocumented, or beta endpoint but still want full authentication mapping, global headers, and intelligent retries?
512
521
 
513
522
  ```typescript
514
523
  // Bypass strictly typed resources with full network resiliency
515
- const customData = await ecod.request(
516
- "POST",
517
- "/api/saas/beta-feature-route",
518
- { experimentalFlag: true }
519
- );
524
+ const customData = await ecod.request("POST", "/api/saas/beta-feature-route", {
525
+ experimentalFlag: true,
526
+ });
520
527
  ```
521
528
 
522
529
  ---
package/dist/cli.js ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ import{Command as ae}from"commander";import ne from"dotenv";import o from"picocolors";import re from"repl";import se from"axios";import Q from"axios-retry";var V=class extends Error{constructor(e){super(e),this.name="EcodrixError"}},u=class extends V{status;code;constructor(e,s,n){super(e),this.name="APIError",this.status=s,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,s,n){try{let t=this.buildConfig(n);return(await this.client.post(e,s,t)).data}catch(t){this.handleError(t)}}async get(e,s){try{let n=this.buildConfig(s);return(await this.client.get(e,n)).data}catch(n){this.handleError(n)}}async patch(e,s,n){try{let t=this.buildConfig(n);return(await this.client.patch(e,s,t)).data}catch(t){this.handleError(t)}}async put(e,s,n){try{let t=this.buildConfig(n);return(await this.client.put(e,s,t)).data}catch(t){this.handleError(t)}}async deleteRequest(e,s){try{let n=this.buildConfig(s);return(await this.client.delete(e,n)).data}catch(n){this.handleError(n)}}buildConfig(e){if(!e)return;let s={...e};return e.idempotencyKey&&(s.headers={...s.headers,"Idempotency-Key":e.idempotencyKey}),s}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 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||"en_US"})}async star(e,s){return this.post(`/api/saas/chat/messages/${e}/star`,{isStarred:s})}async react(e,s){return this.post(`/api/saas/chat/messages/${e}/react`,{reaction:s})}async markRead(e){return this.post(`/api/saas/chat/conversations/${e}/read`)}};var b=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,s){return this.get(`/api/saas/chat/conversations/${e}/messages`,{params:s})}async linkLead(e,s,n){return this.post(`/api/saas/chat/conversations/${e}/link-lead`,{leadId:s,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 x=class extends r{async list(e){return this.get("/api/saas/chat/broadcasts",{params:e})}async create(e){return this.post("/api/saas/chat/broadcast",e)}};var v=class extends r{async list(e){return this.get("/api/saas/whatsapp/templates",{params:e})}async sync(){return this.post("/api/saas/whatsapp/templates/sync",{})}async retrieve(e){return this.get(`/api/saas/whatsapp/templates/${encodeURIComponent(e)}`)}async create(e){return this.post("/api/saas/whatsapp/templates",e)}async update(e,s){return this.put(`/api/saas/whatsapp/templates/${e}`,s)}async deleteTemplate(e,s){return this.deleteRequest(`/api/saas/whatsapp/templates/${encodeURIComponent(e)}${s?"?force=true":""}`)}async mappingConfig(){return this.get("/api/saas/whatsapp/templates/mapping/config")}async collections(){return this.get("/api/saas/whatsapp/templates/collections")}async collectionFields(e){return this.get(`/api/saas/whatsapp/templates/collections/${encodeURIComponent(e)}/fields`)}async updateMapping(e,s){return this.put(`/api/saas/whatsapp/templates/${encodeURIComponent(e)}/mapping`,s)}async validate(e){return this.get(`/api/saas/whatsapp/templates/${encodeURIComponent(e)}/validate`)}async preview(e,s){return this.post(`/api/saas/whatsapp/templates/${encodeURIComponent(e)}/preview`,{context:s})}async checkUsage(e){return this.get(`/api/saas/whatsapp/templates/${encodeURIComponent(e)}/usage`)}};var w=class extends r{messages;conversations;broadcasts;templates;constructor(e){super(e),this.messages=new f(e),this.conversations=new b(e),this.broadcasts=new x(e),this.templates=new v(e)}async upload(e,s){let n=new FormData;return n.append("file",e,s),this.post("/api/saas/whatsapp/upload",n,{headers:typeof n.getHeaders=="function"?n.getHeaders():void 0})}async sendTemplate(e){return this.post("/api/saas/whatsapp/send-template",e)}};var P=class extends r{async create(e){return this.post("/api/services/leads",e)}async upsert(e){return this.post("/api/services/leads/upsert",e)}async createMany(e,s=50){let n=[];for(let t=0;t<e.length;t+=s){let l=e.slice(t,t+s).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/services/leads/import",{leads:e})}async list(e){let s={...e};return Array.isArray(s.tags)&&(s.tags=s.tags.join(",")),this.get("/api/services/leads",{params:s})}async*listAutoPaging(e){let s=e?.page||1,n=!0;for(;n;){let t=await this.list({...e,page:s}),i=Array.isArray(t.data)?t.data:t||[];if(i.length===0){n=!1;break}for(let l of i)yield l;t.pagination&&s<t.pagination.pages||!t.pagination&&i.length>0?s++:n=!1}}async retrieve(e){return this.get(`/api/services/leads/${e}`)}async retrieveByPhone(e){return this.get(`/api/services/leads/phone/${encodeURIComponent(e)}`)}async retrieveByRef(e,s){return this.get(`/api/services/leads/ref/${encodeURIComponent(e)}/${encodeURIComponent(s)}`)}async update(e,s){return this.post(`/api/services/leads/${e}`,s)}async move(e,s){return this.patch(`/api/services/leads/${e}/move`,{stageId:s})}async convert(e,s,n){return this.post(`/api/services/leads/${e}/convert`,{outcome:s,reason:n})}async tags(e,s){return this.patch(`/api/services/leads/${e}/tags`,s)}async recalculateScore(e){return this.post(`/api/services/leads/${e}/score`,{})}async updateMetadata(e,s){return this.patch(`/api/services/leads/${e}/metadata`,s)}async fields(){return this.get("/api/services/leads/fields")}async delete(e){return this.deleteRequest(`/api/services/leads/${e}`)}async bulkDelete(e){return this.deleteRequest("/api/services/leads",{data:{ids:e}})}};var R=class extends r{async list(e){return this.get("/api/saas/crm/pipelines",{params:e})}async create(e){return this.post("/api/saas/crm/pipelines",e)}async retrieve(e){return this.get(`/api/saas/crm/pipelines/${e}`)}async update(e,s){return this.patch(`/api/saas/crm/pipelines/${e}`,s)}async setDefault(e){return this.post(`/api/saas/crm/pipelines/${e}/default`,{})}async duplicate(e,s){return this.post(`/api/saas/crm/pipelines/${e}/duplicate`,{newName:s})}async archive(e){return this.post(`/api/saas/crm/pipelines/${e}/archive`,{})}async delete(e){return this.deleteRequest(`/api/saas/crm/pipelines/${e}`)}async board(e){return this.get(`/api/saas/crm/pipelines/${e}/board`)}async forecast(e){return this.get(`/api/saas/crm/pipelines/${e}/forecast`)}async addStage(e,s){return this.post(`/api/saas/crm/pipelines/${e}/stages`,s)}async reorderStages(e,s){return this.put(`/api/saas/crm/pipelines/${e}/stages/reorder`,{order:s})}async updateStage(e,s){return this.patch(`/api/saas/crm/stages/${e}`,s)}async deleteStage(e,s){return this.deleteRequest(`/api/saas/crm/stages/${e}`,{data:s?{moveLeadsToStageId:s}:void 0})}};var H=class extends r{async list(e){return this.get(`/api/saas/crm/leads/${e}/notes`)}async create(e,s){return this.post(`/api/saas/crm/leads/${e}/notes`,s)}async update(e,s){return this.patch(`/api/saas/crm/notes/${e}`,{content:s})}async pin(e,s=!0){return this.patch(`/api/saas/crm/notes/${e}/pin`,{isPinned:s})}async delete(e){return this.deleteRequest(`/api/saas/crm/notes/${e}`)}},$=class extends r{notes;constructor(e){super(e),this.notes=new H(e)}async timeline(e,s){return this.get(`/api/saas/crm/leads/${e}/timeline`,{params:s})}async list(e,s){return this.get("/api/saas/crm/activities",{params:{leadId:e,...s}})}async log(e){return this.post("/api/saas/crm/activities",e)}async logCall(e,s){return this.post(`/api/saas/crm/leads/${e}/calls`,s)}};var I=class extends r{async overview(e){return this.get("/api/saas/crm/analytics/overview",{params:e})}async funnel(e){return this.get("/api/saas/crm/analytics/funnel",{params:{pipelineId:e}})}async forecast(e){return this.get("/api/saas/crm/analytics/forecast",{params:{pipelineId:e}})}async sources(e){return this.get("/api/saas/crm/analytics/sources",{params:e})}async team(e){return this.get("/api/saas/crm/analytics/team",{params:e})}async heatmap(e){return this.get("/api/saas/crm/analytics/heatmap",{params:e})}async scores(){return this.get("/api/saas/crm/analytics/scores")}async stageTime(e){return this.get("/api/saas/crm/analytics/stage-time",{params:{pipelineId:e}})}async tiered(e){return this.get("/api/saas/crm/analytics/tiered",{params:e})}async summary(e){return this.get("/api/saas/crm/analytics/summary",{params:e})}async whatsapp(e){return this.get("/api/saas/crm/analytics/whatsapp",{params:e})}};var C=class extends r{async list(){return this.get("/api/saas/crm/automations")}async create(e){return this.post("/api/saas/crm/automations",e)}async update(e,s){return this.patch(`/api/saas/crm/automations/${e}`,s)}async toggle(e){return this.patch(`/api/saas/crm/automations/${e}/toggle`)}async deleteRule(e){return this.deleteRequest(`/api/saas/crm/automations/${e}`)}async bulkDelete(e){return this.post("/api/saas/crm/automations/bulk-delete",{ids:e})}async test(e,s){return this.post(`/api/saas/crm/automations/${e}/test`,{leadId:s})}async getAvailableEvents(){return this.post("/api/saas/crm/automations/events",{})}async enrollments(e,s){return this.get(`/api/saas/crm/automations/${e}/enrollments`,{params:s})}async getEnrollment(e){return this.get(`/api/saas/crm/automations/enrollments/${e}`)}async pauseEnrollment(e,s){return this.post(`/api/saas/crm/automations/${e}/enrollments/${s}/pause`,{})}async resumeEnrollment(e,s){return this.post(`/api/saas/crm/automations/${e}/enrollments/${s}/resume`,{})}async runs(e){return this.get(`/api/saas/crm/automations/${e}/runs`)}async getRun(e){return this.get(`/api/saas/crm/automations/runs/${e}`)}async resumeRun(e){return this.post(`/api/saas/crm/automations/runs/${e}/resume`,{})}async abortRun(e){return this.post(`/api/saas/crm/automations/runs/${e}/abort`,{})}async webhookEvent(e,s,n){return this.post("/api/saas/crm/webhook-event",{ruleId:e,eventName:s,payload:n})}};var A=class extends r{async enroll(e){return this.post("/api/saas/crm/sequences/enroll",e)}async unenroll(e){return this.deleteRequest(`/api/saas/crm/sequences/unenroll/${e}`)}async listForLead(e){return this.get(`/api/saas/crm/sequences/lead/${e}`)}};var S=class extends r{async getConfig(){return this.get("/api/saas/crm/scoring")}async updateConfig(e){return this.patch("/api/saas/crm/scoring",e)}async recalculate(e){return this.post(`/api/saas/crm/scoring/${e}/recalculate`,{})}};var k=class extends r{async capture(e){return this.post("/api/saas/crm/payments/capture",e)}};var E=class extends r{async stats(){return this.get("/api/saas/crm/automation/stats")}async logs(e){return this.get("/api/saas/crm/automation/logs",{params:e})}async retryFailedEvent(e){return this.post(`/api/saas/crm/automation/logs/${e}/retry`,{})}};var D=class{leads;pipelines;activities;analytics;automations;sequences;scoring;payments;automationDashboard;constructor(e){this.leads=new P(e),this.pipelines=new R(e),this.activities=new $(e),this.analytics=new I(e),this.automations=new C(e),this.sequences=new A(e),this.scoring=new S(e),this.payments=new k(e),this.automationDashboard=new E(e)}};import ee from"axios";var L=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,s){return this.get(`/api/saas/storage/files/${e}`,{params:s})}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,s){let{data:n}=await this.client.post("/api/saas/storage/upload-url",s),{uploadUrl:t,key:i}=n;await ee.put(t,e,{headers:{"Content-Type":s.contentType}});let l=e.size||e.byteLength||0;return this.post("/api/saas/storage/confirm-upload",{key:i,sizeBytes:l})}};var q=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,s){return this.patch(`/api/saas/meet/${e}`,s)}async reschedule(e,s){return this.patch(`/api/saas/meet/${e}`,s)}async delete(e){return this.update(e,{status:"cancelled"})}};var O=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/saas/crm/notifications",{params:e})}async dismissAlert(e){return this.patch(`/api/saas/crm/notifications/${e}/dismiss`)}async clearAllAlerts(){return this.deleteRequest("/api/saas/crm/notifications/clear-all")}async retryAction(e){return this.post(`/api/saas/crm/notifications/${e}/retry`,{})}};var U=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 M=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 h=class extends u{constructor(e){super(e,400,"invalid_signature"),this.name="WebhookSignatureError"}},N=class{async constructEvent(e,s,n){if(!s)throw new h("No webhook signature provided");let t=Array.isArray(s)?s[0]:s;t.startsWith("sha256=")&&(t=t.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(t)))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 j=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)}`)}},J=class extends r{async list(e,s){return this.get(`/api/saas/storage/files/${e}`,{params:s})}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}})}},_=class extends r{folders;files;constructor(e){super(e),this.folders=new j(e),this.files=new J(e)}async usage(){return this.get("/api/saas/storage/usage")}};var Y=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})}},G=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,s){return this.patch(`/api/saas/marketing/campaigns/${e}`,s)}async delete(e){return this.deleteRequest(`/api/saas/marketing/campaigns/${e}`)}async send(e,s){return this.post(`/api/saas/marketing/campaigns/${e}/send`,s||{})}async stats(e){return this.get(`/api/saas/marketing/campaigns/${e}/stats`)}},z=class extends r{async sendTemplate(e){return this.post("/api/saas/marketing/whatsapp/send-template",e)}},F=class extends r{emails;campaigns;whatsapp;constructor(e){super(e),this.emails=new Y(e),this.campaigns=new G(e),this.whatsapp=new z(e)}};var K=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 B=class extends r{async listFailed(){return this.get("/api/saas/queue/failed")}async getStats(){return this.get("/api/saas/queue/stats")}async retryJob(e){return this.post(`/api/saas/queue/${e}/retry`,{})}async deleteJob(e){return this.deleteRequest(`/api/saas/queue/${e}`)}};import{io as te}from"socket.io-client";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 s=e.baseUrl||"https://api.ecodrix.com",n=e.socketUrl||s,t=typeof window<"u"&&typeof window.document<"u",i=t?"browser":typeof process<"u"?`node ${process.version}`:"unknown",l=t?globalThis.navigator?.userAgent||"browser":typeof process<"u"?process.platform:"unknown";this.client=se.create({baseURL:s,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 w(this.client),this.crm=new D(this.client),this.media=new L(this.client),this.meet=new q(this.client),this.notifications=new O(this.client),this.email=new U(this.client),this.events=new M(this.client),this.webhooks=new N,this.storage=new _(this.client),this.marketing=new F(this.client),this.health=new K(this.client),this.queue=new B(this.client),this.socket=te(n,{extraHeaders:{"x-api-key":e.apiKey,"x-client-code":e.clientCode?.toUpperCase()||""}}),this.setupSocket(e.clientCode)}setupSocket(e){this.socket.on("connect",()=>{e&&this.socket.emit("join-room",e.toUpperCase())})}on(e,s){return this.socket.on(e,s),this}disconnect(){this.socket.disconnect()}async request(e,s,n,t){try{return(await this.client.request({method:e,url:s,data:n,params:t})).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")}}};ne.config();var X="1.0.3";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 ae;d.name("erix").description(ie).version(X);function y(a){let e=a.key||process.env.ECOD_API_KEY,s=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:s,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 s=e.parent.opts(),n=y(s);console.log(o.cyan("Checking connection to ECODrIx Platform..."));try{let t=await n.request("GET","/api/saas/me/profile");console.log(o.green("\u2714 Authenticated successfully!")),console.log(`${o.bold("User ID:")} ${t.id}`),console.log(`${o.bold("Organisation:")} ${t.organisation?.name||"N/A"}`),s.client&&console.log(`${o.bold("Tenant Code:")} ${o.magenta(s.client)}`)}catch(t){console.error(o.red("\u2716 Authentication failed")),console.error(o.dim(t.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,s,n)=>{let t=n.parent.parent.opts(),i=y(t);try{let l=JSON.parse(s.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 s=e.parent.parent.opts(),n=y(s);try{let t=parseInt(a.limit);console.log(o.cyan(`Fetching last ${t} leads...`));let i={limit:t};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(t){console.error(o.red("\u2716 Failed to fetch leads")),console.error(o.dim(t.message))}});Z.command("pipelines").description("List all CRM pipelines").action(async(a,e)=>{let s=e.parent.parent.opts(),n=y(s);try{console.log(o.cyan("Fetching pipelines..."));let t=await n.crm.pipelines.list(),i=t.data||t||[];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(t){console.error(o.red("\u2716 Failed to fetch pipelines")),console.error(o.dim(t.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 s=e.parent.parent.opts(),n=y(s);try{console.log(o.cyan(`Fetching overview metrics for last ${a.range}...`));let t=await n.crm.analytics.overview({range:a.range}),i=t.data||t;console.log(`
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(t){console.error(o.red("\u2716 Failed to fetch analytics overview")),console.error(o.dim(t.message))}});var pe=d.command("webhooks").description("Webhook utility tools");pe.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,s,n,t)=>{let i=t.parent.parent.opts(),l=y(i);try{await l.webhooks.constructEvent(a,e,s),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 s=e.parent.opts(),n=y(s);console.log(o.magenta(o.bold(`
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 t=re.start({prompt:o.cyan("erix > "),useColors:!0});t.context.ecod=n,t.context.whatsapp=n.whatsapp,t.context.crm=n.crm,t.context.meet=n.meet,t.context.media=n.media,t.on("exit",()=>{console.log(o.yellow(`
7
+ Goodbye!`)),process.exit(0)})});d.command("completion").description("Generate Bash auto-completion script").action(()=>{console.log(`
8
+ # Erix Bash Completion
9
+ _erix_completions() {
10
+ local cur opts
11
+ COMPREPLY=()
12
+ cur="\${COMP_WORDS[COMP_CWORD]}"
13
+ opts="whoami whatsapp crm analytics webhooks shell completion"
14
+
15
+ if [[ \${COMP_CWORD} -eq 1 ]] ; then
16
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
17
+ return 0
18
+ fi
19
+
20
+ # Simple sub-command completion
21
+ case "\${COMP_WORDS[1]}" in
22
+ whatsapp)
23
+ COMPREPLY=( $(compgen -W "send-template" -- \${cur}) )
24
+ ;;
25
+ crm)
26
+ COMPREPLY=( $(compgen -W "leads pipelines" -- \${cur}) )
27
+ ;;
28
+ analytics)
29
+ COMPREPLY=( $(compgen -W "overview" -- \${cur}) )
30
+ ;;
31
+ webhooks)
32
+ COMPREPLY=( $(compgen -W "verify" -- \${cur}) )
33
+ ;;
34
+ esac
35
+ }
36
+ complete -F _erix_completions erix
37
+ `.trim()),console.error(o.yellow(`
38
+ # To enable, run: eval "$(erix completion)"`)),console.error(o.dim("# Or add it to your ~/.bashrc: erix completion >> ~/.bashrc"))});d.parse();