migma 1.3.2 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,22 @@
1
1
  'use strict';
2
2
 
3
+ // src/agent-identity.ts
4
+ var AGENT_ID_PATTERN = /^ai:[a-z0-9][a-z0-9._-]{0,62}$/;
5
+ var HOST_AGENT_ENV = [
6
+ { env: "CLAUDECODE", id: "ai:claude-code" },
7
+ { env: "CURSOR_TRACE_ID", id: "ai:cursor" },
8
+ { env: "CODEX_HOME", id: "ai:codex" }
9
+ ];
10
+ function detectAgentId() {
11
+ if (typeof process === "undefined" || !process.env) return null;
12
+ const explicit = (process.env.MIGMA_AGENT_ID || "").trim().toLowerCase();
13
+ if (AGENT_ID_PATTERN.test(explicit)) return explicit;
14
+ for (const { env, id } of HOST_AGENT_ENV) {
15
+ if (process.env[env]) return id;
16
+ }
17
+ return null;
18
+ }
19
+
3
20
  // src/errors.ts
4
21
  var MigmaErrorCode = /* @__PURE__ */ ((MigmaErrorCode2) => {
5
22
  MigmaErrorCode2["VALIDATION_ERROR"] = "validation_error";
@@ -56,9 +73,19 @@ var MigmaError = class _MigmaError extends Error {
56
73
  var MigmaClient = class {
57
74
  apiKey;
58
75
  config;
76
+ headers;
59
77
  constructor(apiKey, config) {
60
78
  this.apiKey = apiKey;
61
79
  this.config = config;
80
+ this.headers = {
81
+ Authorization: `Bearer ${this.apiKey}`,
82
+ "Content-Type": "application/json",
83
+ "User-Agent": "migma-node/1.0.0"
84
+ };
85
+ const agentId = detectAgentId();
86
+ if (agentId) {
87
+ this.headers["X-Agent-Id"] = agentId;
88
+ }
62
89
  }
63
90
  async request(options) {
64
91
  const url = this.buildUrl(options.path, options.query);
@@ -68,11 +95,7 @@ var MigmaClient = class {
68
95
  try {
69
96
  const response = await fetch(url, {
70
97
  method: options.method,
71
- headers: {
72
- Authorization: `Bearer ${this.apiKey}`,
73
- "Content-Type": "application/json",
74
- "User-Agent": "migma-node/1.0.0"
75
- },
98
+ headers: { ...this.headers, ...options.headers },
76
99
  body: options.body ? JSON.stringify(options.body) : void 0
77
100
  });
78
101
  const json = await response.json();
@@ -115,11 +138,7 @@ var MigmaClient = class {
115
138
  try {
116
139
  const response = await fetch(url, {
117
140
  method: options.method,
118
- headers: {
119
- Authorization: `Bearer ${this.apiKey}`,
120
- "Content-Type": "application/json",
121
- "User-Agent": "migma-node/1.0.0"
122
- },
141
+ headers: { ...this.headers, ...options.headers },
123
142
  body: options.body ? JSON.stringify(options.body) : void 0
124
143
  });
125
144
  const json = await response.json();
@@ -153,17 +172,23 @@ var MigmaClient = class {
153
172
  async getWithCount(path, query) {
154
173
  return this.requestWithCount({ method: "GET", path, query });
155
174
  }
156
- async post(path, body) {
157
- return this.request({ method: "POST", path, body });
175
+ async post(path, body, options) {
176
+ return this.request({ method: "POST", path, body, headers: this.callHeaders(options) });
158
177
  }
159
- async patch(path, body) {
160
- return this.request({ method: "PATCH", path, body });
178
+ async patch(path, body, options) {
179
+ return this.request({ method: "PATCH", path, body, headers: this.callHeaders(options) });
161
180
  }
162
181
  async put(path, body) {
163
182
  return this.request({ method: "PUT", path, body });
164
183
  }
165
- async delete(path, query) {
166
- return this.request({ method: "DELETE", path, query });
184
+ async delete(path, query, options) {
185
+ return this.request({ method: "DELETE", path, query, headers: this.callHeaders(options) });
186
+ }
187
+ callHeaders(options) {
188
+ if (options?.idempotencyKey) {
189
+ return { "Idempotency-Key": options.idempotencyKey };
190
+ }
191
+ return void 0;
167
192
  }
168
193
  buildUrl(path, query) {
169
194
  const url = new URL(`${this.config.baseUrl}${path}`);
@@ -194,8 +219,8 @@ var Contacts = class {
194
219
  constructor(client) {
195
220
  this.client = client;
196
221
  }
197
- async create(params) {
198
- return this.client.post("/contacts", params);
222
+ async create(params, options) {
223
+ return this.client.post("/contacts", params, options);
199
224
  }
200
225
  async list(params) {
201
226
  const { projectId, page, limit, tags, status, search } = params;
@@ -211,20 +236,24 @@ var Contacts = class {
211
236
  async get(id, projectId) {
212
237
  return this.client.get(`/contacts/${id}`, { projectId });
213
238
  }
214
- async update(id, params) {
215
- return this.client.patch(`/contacts/${id}`, params);
239
+ async update(id, params, options) {
240
+ return this.client.patch(`/contacts/${id}`, params, options);
216
241
  }
217
- async remove(id, projectId) {
218
- return this.client.delete(`/contacts/${id}`, { projectId });
242
+ async remove(id, projectId, options) {
243
+ return this.client.delete(`/contacts/${id}`, { projectId }, options);
219
244
  }
220
- async bulkImport(params) {
221
- return this.client.post("/contacts/bulk", params);
245
+ async bulkImport(params, options) {
246
+ return this.client.post("/contacts/bulk", params, options);
222
247
  }
223
248
  async getBulkImportStatus(jobId) {
224
249
  return this.client.get(`/contacts/bulk/${jobId}`);
225
250
  }
226
- async changeStatus(params) {
227
- return this.client.post("/contacts/status", params);
251
+ /** Batch delete contacts by email (up to 1000). Emails with no match come back in `notFound`. */
252
+ async bulkDeleteByEmail(params, options) {
253
+ return this.client.post("/contacts/bulk-delete", params, options);
254
+ }
255
+ async changeStatus(params, options) {
256
+ return this.client.post("/contacts/status", params, options);
228
257
  }
229
258
  };
230
259
 
@@ -325,8 +354,8 @@ var Sending = class {
325
354
  constructor(client) {
326
355
  this.client = client;
327
356
  }
328
- async send(params) {
329
- return this.client.post("/sending", params);
357
+ async send(params, options) {
358
+ return this.client.post("/sending", params, options);
330
359
  }
331
360
  async getBatchStatus(batchId) {
332
361
  return this.client.get(`/sending/batches/${batchId}`);
@@ -404,6 +433,15 @@ var Projects = class {
404
433
  `/projects/import/${projectId}/retry`
405
434
  );
406
435
  }
436
+ async fieldCatalog(projectId, params) {
437
+ return this.client.get(
438
+ `/projects/${projectId}/field-catalog`,
439
+ {
440
+ segmentId: params?.segmentId,
441
+ tag: params?.tag
442
+ }
443
+ );
444
+ }
407
445
  /**
408
446
  * Import a project and wait for completion.
409
447
  * Polls getImportStatus until status is 'active' or 'error'.
@@ -439,10 +477,11 @@ var Emails = class {
439
477
  });
440
478
  }
441
479
  /** Start async email generation */
442
- async generate(params) {
480
+ async generate(params, options) {
443
481
  return this.client.post(
444
482
  "/projects/emails/generate",
445
- params
483
+ params,
484
+ options
446
485
  );
447
486
  }
448
487
  /** Check email generation status */
@@ -451,30 +490,23 @@ var Emails = class {
451
490
  `/projects/emails/${conversationId}/status`
452
491
  );
453
492
  }
454
- /** Fetch one generated email by artifact id */
455
- async get(artifactId) {
456
- return this.client.get(`/emails/${artifactId}`);
457
- }
458
- /** Replace one generated email's Migma Email source and persist compiled HTML */
459
- async update(artifactId, params) {
460
- return this.client.patch(
461
- `/emails/${artifactId}`,
462
- params
463
- );
493
+ /** Fetch one generated email by email id */
494
+ async get(emailId) {
495
+ return this.client.get(`/emails/${emailId}`);
464
496
  }
465
- /** Compile an email artifact's source without persisting */
466
- async compile(artifactId, params) {
497
+ /** Prompt Migma to edit one generated email */
498
+ async edit(emailId, params) {
467
499
  return this.client.post(
468
- `/emails/${artifactId}/compile`,
469
- params || {}
500
+ `/emails/${emailId}/edit`,
501
+ params
470
502
  );
471
503
  }
472
504
  /**
473
505
  * Generate an email and wait for completion.
474
506
  * Polls getGenerationStatus until status is 'completed' or 'failed'.
475
507
  */
476
- async generateAndWait(params, options) {
477
- const startResult = await this.generate(params);
508
+ async generateAndWait(params, options, callOptions) {
509
+ const startResult = await this.generate(params, callOptions);
478
510
  if (startResult.error) {
479
511
  return { data: null, error: startResult.error };
480
512
  }
@@ -652,6 +684,22 @@ var Domains = class {
652
684
  async removeManaged(domain) {
653
685
  return this.client.delete(`/domains/managed/${domain}`);
654
686
  }
687
+ /**
688
+ * Provision a transactional or marketing stream identity on a domain you own.
689
+ * Creates notify.<rootDomain> (transactional) or send.<rootDomain> (marketing)
690
+ * to isolate transactional reputation from marketing. Returns DNS records to publish.
691
+ */
692
+ async provisionStream(params) {
693
+ return this.client.post("/domains/streams", params);
694
+ }
695
+ /**
696
+ * Provision BOTH stream identities for a domain you own in one call:
697
+ * send.<rootDomain> (marketing) and notify.<rootDomain> (transactional).
698
+ * Idempotent. Returns both domains with DNS records to publish.
699
+ */
700
+ async setup(params) {
701
+ return this.client.post("/domains/setup", params);
702
+ }
655
703
  };
656
704
 
657
705
  // src/resources/webhooks.ts
@@ -760,28 +808,47 @@ var Campaigns = class {
760
808
  this.client = client;
761
809
  }
762
810
  async list(params) {
763
- const { projectId, status, page, limit } = params;
811
+ const { projectId, status, page, limit, archived } = params;
764
812
  return this.client.get("/campaigns", {
765
813
  projectId,
766
814
  status,
767
815
  page,
768
- limit
816
+ limit,
817
+ archived
769
818
  });
770
819
  }
771
- async create(params) {
772
- return this.client.post("/campaigns", params);
820
+ async create(params, options) {
821
+ return this.client.post("/campaigns", params, options);
773
822
  }
774
823
  async get(id) {
775
824
  return this.client.get(`/campaigns/${id}`);
776
825
  }
777
- async send(id) {
778
- return this.client.post(`/campaigns/${id}/send`);
826
+ async send(id, options) {
827
+ return this.client.post(`/campaigns/${id}/send`, void 0, options);
828
+ }
829
+ async schedule(id, params, options) {
830
+ return this.client.post(`/campaigns/${id}/schedule`, params, options);
831
+ }
832
+ async cancel(id, options) {
833
+ return this.client.post(`/campaigns/${id}/cancel`, void 0, options);
834
+ }
835
+ /** Aggregated engagement metrics for a campaign (cached, may be slightly stale). */
836
+ async stats(id) {
837
+ return this.client.get(`/campaigns/${id}/stats`);
838
+ }
839
+ /** Per-recipient email logs for a campaign (cursor-paginated). */
840
+ async logs(id, params) {
841
+ return this.client.get(`/campaigns/${id}/logs`, {
842
+ limit: params?.limit,
843
+ cursor: params?.cursor,
844
+ status: params?.status
845
+ });
779
846
  }
780
- async schedule(id, params) {
781
- return this.client.post(`/campaigns/${id}/schedule`, params);
847
+ async archive(id) {
848
+ return this.client.post(`/campaigns/${id}/archive`);
782
849
  }
783
- async cancel(id) {
784
- return this.client.post(`/campaigns/${id}/cancel`);
850
+ async unarchive(id) {
851
+ return this.client.post(`/campaigns/${id}/unarchive`);
785
852
  }
786
853
  };
787
854