@open-apime/sdk 0.2.2 → 0.3.1

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.cjs CHANGED
@@ -176,6 +176,18 @@ function errorFromResponse(status, body, headers) {
176
176
  }
177
177
  }
178
178
 
179
+ // src/http/dispatcher.ts
180
+ var import_node_dns = require("dns");
181
+ var applied;
182
+ function preferIpFamily(family) {
183
+ if (applied !== void 0) return;
184
+ try {
185
+ (0, import_node_dns.setDefaultResultOrder)(family === 4 ? "ipv4first" : "ipv6first");
186
+ applied = family;
187
+ } catch {
188
+ }
189
+ }
190
+
179
191
  // src/http/url.ts
180
192
  var BLOCKED_HOSTS = /* @__PURE__ */ new Set(["169.254.169.254", "metadata.google.internal"]);
181
193
  function assertUsableBaseUrl(raw) {
@@ -237,6 +249,7 @@ var HttpClient = class {
237
249
  this.auth = options.auth;
238
250
  this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
239
251
  this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;
252
+ if (options.ipFamily) preferIpFamily(options.ipFamily);
240
253
  this.fetchImpl = options.fetch ?? globalThis.fetch;
241
254
  this.userAgent = options.appName ? `open-apime-sdk (${options.appName})` : "open-apime-sdk";
242
255
  this.observer = options.observer;
@@ -481,7 +494,7 @@ var MessagesResource = class {
481
494
  return this.http.request({ method: "POST", path: `${this.base}/audio`, body: form, ...options ? { options } : {} });
482
495
  }
483
496
  sendDocument(input, options) {
484
- const form = toForm(input, ["file"]);
497
+ const form = toForm(input, ["file", "filename"]);
485
498
  form.set("file", input.file, input.filename ?? fileName(input.file, "document"));
486
499
  return this.http.request({ method: "POST", path: `${this.base}/document`, body: form, ...options ? { options } : {} });
487
500
  }
@@ -503,7 +516,13 @@ function toForm(input, skip) {
503
516
  const form = new FormData();
504
517
  for (const [key, value] of Object.entries(input)) {
505
518
  if (skip.includes(key) || value === void 0 || value === null) continue;
506
- form.set(key, typeof value === "string" ? value : String(value));
519
+ if (typeof value === "string") {
520
+ form.set(key, value);
521
+ } else if (Array.isArray(value) || typeof value === "object" && !(value instanceof Blob)) {
522
+ form.set(key, JSON.stringify(value));
523
+ } else {
524
+ form.set(key, String(value));
525
+ }
507
526
  }
508
527
  return form;
509
528
  }
@@ -745,6 +764,7 @@ function toHttpOptions(auth, options) {
745
764
  ...options.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : {},
746
765
  ...options.maxRetries !== void 0 ? { maxRetries: options.maxRetries } : {},
747
766
  ...options.fetch !== void 0 ? { fetch: options.fetch } : {},
767
+ ...options.ipFamily !== void 0 ? { ipFamily: options.ipFamily } : {},
748
768
  ...options.appName !== void 0 ? { appName: options.appName } : {},
749
769
  ...options.observer !== void 0 ? { observer: options.observer } : {},
750
770
  ...options.autoReport !== void 0 ? { autoReport: options.autoReport } : {}
package/dist/index.d.cts CHANGED
@@ -79,6 +79,8 @@ interface Observer {
79
79
  /** True when the app has an initialized Sentry. Absent means every report is a no-op. */
80
80
  declare function hasSentry(): boolean;
81
81
 
82
+ type IpFamily = 4 | 6;
83
+
82
84
  interface RequestOptions {
83
85
  timeoutMs?: number;
84
86
  maxRetries?: number;
@@ -97,6 +99,12 @@ interface HttpClientOptions {
97
99
  timeoutMs?: number;
98
100
  maxRetries?: number;
99
101
  fetch?: typeof globalThis.fetch;
102
+ /**
103
+ * Tries this IP family first when resolving the host. Use 4 when the apime
104
+ * answers AAAA but the network has no IPv6 route, so failed v6 attempts stop
105
+ * polluting the errors. Process-wide: Node offers no per-request knob.
106
+ */
107
+ ipFamily?: IpFamily;
100
108
  /** Appended to the User-Agent, to identify the calling app in the apime logs. */
101
109
  appName?: string;
102
110
  /** Where the app plugs its logger or error tracker. See Observer. */
@@ -461,6 +469,12 @@ interface ClientOptions {
461
469
  timeoutMs?: number;
462
470
  maxRetries?: number;
463
471
  fetch?: typeof globalThis.fetch;
472
+ /**
473
+ * Tries this IP family first when resolving the host. Use 4 when the apime
474
+ * answers AAAA but the network has no IPv6 route, so failed v6 attempts stop
475
+ * polluting the errors. Process-wide: Node offers no per-request knob.
476
+ */
477
+ ipFamily?: IpFamily;
464
478
  appName?: string;
465
479
  /**
466
480
  * Reports every request, failure and retry to the app's own logger or error
@@ -468,8 +482,8 @@ interface ClientOptions {
468
482
  */
469
483
  observer?: Observer;
470
484
  /**
471
- * Sem `observer`, a falha definitiva ainda vai para o Sentry que o app
472
- * roda, achado pelo cliente global. Sem Sentry, não faz nada. `false` cala.
485
+ * With no `observer`, definitive failures still reach the Sentry the app
486
+ * already runs, found through its global client. No Sentry means no-op.
473
487
  */
474
488
  autoReport?: boolean;
475
489
  }
@@ -509,4 +523,4 @@ declare const Apime: {
509
523
  }, options: ClientOptions): ApimeInstanceClient;
510
524
  };
511
525
 
512
- export { type ApiToken, type ApiTokenAuth, Apime, ApimeError, ApimeInstanceClient, ApimeUserClient, type Auth, type AuthKind, type CheckNumberResult, type ClientOptions, type ContactEntry, type CreateInstanceInput, EventLogEntry, type FailureInfo, type GroupInfo, type GroupParticipant, Instance, InstanceInfo, type InstanceTokenAuth, type JoinRequestAction, type MarkReadInput, type Observer, type ParticipantAction, type PresenceState, Profile, QrCode, type QuoteInput, type RequestInfo, type RequestOptions, type SendAudioInput, type SendContactInput, type SendDocumentInput, type SendLocationInput, type SendMediaInput, type SendTextInput, SentMessage, type SuccessInfo, type UpdateInstanceInput, type User, type UserAuth, type UserJwtAuth, hasSentry };
526
+ export { type ApiToken, type ApiTokenAuth, Apime, ApimeError, ApimeInstanceClient, ApimeUserClient, type Auth, type AuthKind, type CheckNumberResult, type ClientOptions, type ContactEntry, type CreateInstanceInput, EventLogEntry, type FailureInfo, type GroupInfo, type GroupParticipant, Instance, InstanceInfo, type InstanceTokenAuth, type IpFamily, type JoinRequestAction, type MarkReadInput, type Observer, type ParticipantAction, type PresenceState, Profile, QrCode, type QuoteInput, type RequestInfo, type RequestOptions, type SendAudioInput, type SendContactInput, type SendDocumentInput, type SendLocationInput, type SendMediaInput, type SendTextInput, SentMessage, type SuccessInfo, type UpdateInstanceInput, type User, type UserAuth, type UserJwtAuth, hasSentry };
package/dist/index.d.ts CHANGED
@@ -79,6 +79,8 @@ interface Observer {
79
79
  /** True when the app has an initialized Sentry. Absent means every report is a no-op. */
80
80
  declare function hasSentry(): boolean;
81
81
 
82
+ type IpFamily = 4 | 6;
83
+
82
84
  interface RequestOptions {
83
85
  timeoutMs?: number;
84
86
  maxRetries?: number;
@@ -97,6 +99,12 @@ interface HttpClientOptions {
97
99
  timeoutMs?: number;
98
100
  maxRetries?: number;
99
101
  fetch?: typeof globalThis.fetch;
102
+ /**
103
+ * Tries this IP family first when resolving the host. Use 4 when the apime
104
+ * answers AAAA but the network has no IPv6 route, so failed v6 attempts stop
105
+ * polluting the errors. Process-wide: Node offers no per-request knob.
106
+ */
107
+ ipFamily?: IpFamily;
100
108
  /** Appended to the User-Agent, to identify the calling app in the apime logs. */
101
109
  appName?: string;
102
110
  /** Where the app plugs its logger or error tracker. See Observer. */
@@ -461,6 +469,12 @@ interface ClientOptions {
461
469
  timeoutMs?: number;
462
470
  maxRetries?: number;
463
471
  fetch?: typeof globalThis.fetch;
472
+ /**
473
+ * Tries this IP family first when resolving the host. Use 4 when the apime
474
+ * answers AAAA but the network has no IPv6 route, so failed v6 attempts stop
475
+ * polluting the errors. Process-wide: Node offers no per-request knob.
476
+ */
477
+ ipFamily?: IpFamily;
464
478
  appName?: string;
465
479
  /**
466
480
  * Reports every request, failure and retry to the app's own logger or error
@@ -468,8 +482,8 @@ interface ClientOptions {
468
482
  */
469
483
  observer?: Observer;
470
484
  /**
471
- * Sem `observer`, a falha definitiva ainda vai para o Sentry que o app
472
- * roda, achado pelo cliente global. Sem Sentry, não faz nada. `false` cala.
485
+ * With no `observer`, definitive failures still reach the Sentry the app
486
+ * already runs, found through its global client. No Sentry means no-op.
473
487
  */
474
488
  autoReport?: boolean;
475
489
  }
@@ -509,4 +523,4 @@ declare const Apime: {
509
523
  }, options: ClientOptions): ApimeInstanceClient;
510
524
  };
511
525
 
512
- export { type ApiToken, type ApiTokenAuth, Apime, ApimeError, ApimeInstanceClient, ApimeUserClient, type Auth, type AuthKind, type CheckNumberResult, type ClientOptions, type ContactEntry, type CreateInstanceInput, EventLogEntry, type FailureInfo, type GroupInfo, type GroupParticipant, Instance, InstanceInfo, type InstanceTokenAuth, type JoinRequestAction, type MarkReadInput, type Observer, type ParticipantAction, type PresenceState, Profile, QrCode, type QuoteInput, type RequestInfo, type RequestOptions, type SendAudioInput, type SendContactInput, type SendDocumentInput, type SendLocationInput, type SendMediaInput, type SendTextInput, SentMessage, type SuccessInfo, type UpdateInstanceInput, type User, type UserAuth, type UserJwtAuth, hasSentry };
526
+ export { type ApiToken, type ApiTokenAuth, Apime, ApimeError, ApimeInstanceClient, ApimeUserClient, type Auth, type AuthKind, type CheckNumberResult, type ClientOptions, type ContactEntry, type CreateInstanceInput, EventLogEntry, type FailureInfo, type GroupInfo, type GroupParticipant, Instance, InstanceInfo, type InstanceTokenAuth, type IpFamily, type JoinRequestAction, type MarkReadInput, type Observer, type ParticipantAction, type PresenceState, Profile, QrCode, type QuoteInput, type RequestInfo, type RequestOptions, type SendAudioInput, type SendContactInput, type SendDocumentInput, type SendLocationInput, type SendMediaInput, type SendTextInput, SentMessage, type SuccessInfo, type UpdateInstanceInput, type User, type UserAuth, type UserJwtAuth, hasSentry };
package/dist/index.js CHANGED
@@ -107,6 +107,18 @@ function errorFromResponse(status, body, headers) {
107
107
  }
108
108
  }
109
109
 
110
+ // src/http/dispatcher.ts
111
+ import { setDefaultResultOrder } from "dns";
112
+ var applied;
113
+ function preferIpFamily(family) {
114
+ if (applied !== void 0) return;
115
+ try {
116
+ setDefaultResultOrder(family === 4 ? "ipv4first" : "ipv6first");
117
+ applied = family;
118
+ } catch {
119
+ }
120
+ }
121
+
110
122
  // src/http/url.ts
111
123
  var BLOCKED_HOSTS = /* @__PURE__ */ new Set(["169.254.169.254", "metadata.google.internal"]);
112
124
  function assertUsableBaseUrl(raw) {
@@ -168,6 +180,7 @@ var HttpClient = class {
168
180
  this.auth = options.auth;
169
181
  this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
170
182
  this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;
183
+ if (options.ipFamily) preferIpFamily(options.ipFamily);
171
184
  this.fetchImpl = options.fetch ?? globalThis.fetch;
172
185
  this.userAgent = options.appName ? `open-apime-sdk (${options.appName})` : "open-apime-sdk";
173
186
  this.observer = options.observer;
@@ -412,7 +425,7 @@ var MessagesResource = class {
412
425
  return this.http.request({ method: "POST", path: `${this.base}/audio`, body: form, ...options ? { options } : {} });
413
426
  }
414
427
  sendDocument(input, options) {
415
- const form = toForm(input, ["file"]);
428
+ const form = toForm(input, ["file", "filename"]);
416
429
  form.set("file", input.file, input.filename ?? fileName(input.file, "document"));
417
430
  return this.http.request({ method: "POST", path: `${this.base}/document`, body: form, ...options ? { options } : {} });
418
431
  }
@@ -434,7 +447,13 @@ function toForm(input, skip) {
434
447
  const form = new FormData();
435
448
  for (const [key, value] of Object.entries(input)) {
436
449
  if (skip.includes(key) || value === void 0 || value === null) continue;
437
- form.set(key, typeof value === "string" ? value : String(value));
450
+ if (typeof value === "string") {
451
+ form.set(key, value);
452
+ } else if (Array.isArray(value) || typeof value === "object" && !(value instanceof Blob)) {
453
+ form.set(key, JSON.stringify(value));
454
+ } else {
455
+ form.set(key, String(value));
456
+ }
438
457
  }
439
458
  return form;
440
459
  }
@@ -676,6 +695,7 @@ function toHttpOptions(auth, options) {
676
695
  ...options.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : {},
677
696
  ...options.maxRetries !== void 0 ? { maxRetries: options.maxRetries } : {},
678
697
  ...options.fetch !== void 0 ? { fetch: options.fetch } : {},
698
+ ...options.ipFamily !== void 0 ? { ipFamily: options.ipFamily } : {},
679
699
  ...options.appName !== void 0 ? { appName: options.appName } : {},
680
700
  ...options.observer !== void 0 ? { observer: options.observer } : {},
681
701
  ...options.autoReport !== void 0 ? { autoReport: options.autoReport } : {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-apime/sdk",
3
- "version": "0.2.2",
3
+ "version": "0.3.1",
4
4
  "description": "Cliente TypeScript da API do apime: WhatsApp, instâncias e webhooks",
5
5
  "license": "MIT",
6
6
  "repository": {