evolution-api-sdk
Version:
Unofficial SDK for the Evolution Whatsapp API v2
245 lines (242 loc) • 8.08 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
// src/api/service.ts
var service_exports = {};
__export(service_exports, {
ApiService: () => ApiService
});
module.exports = __toCommonJS(service_exports);
// src/api/errors.ts
var EvolutionApiError = class _EvolutionApiError extends Error {
constructor(message, cause, statusCode) {
const extractedMessage = extractErrorMessage(cause);
const finalMessage = extractedMessage || message || "Unknown error occurred";
super(finalMessage);
__publicField(this, "statusCode");
__publicField(this, "details");
this.name = _EvolutionApiError.name;
this.message = finalMessage;
this.statusCode = statusCode;
this.details = cause;
if (Error.captureStackTrace) {
Error.captureStackTrace(this, _EvolutionApiError);
}
}
/**
* Returns a user-friendly string representation of the error
*/
toString() {
let result = `${this.name}: ${this.message}`;
if (this.statusCode) {
result += ` (${this.statusCode})`;
}
if (this.details && typeof this.details === "object") {
const details = this.details;
const relevantDetails = [];
if (details.url) {
relevantDetails.push(`URL: ${details.url}`);
}
if (details.method) {
relevantDetails.push(`Method: ${details.method}`);
}
if (details.response && typeof details.response === "object") {
const response = details.response;
if (response.error && response.error !== this.message) {
relevantDetails.push(`Server Error: ${response.error}`);
}
if (response.message && response.message !== this.message) {
relevantDetails.push(`Server Message: ${response.message}`);
}
}
if (relevantDetails.length > 0) {
result += `
${relevantDetails.join("\n ")}`;
}
}
return result;
}
/**
* Returns a JSON representation suitable for logging
*/
toJSON() {
return {
name: this.name,
message: this.message,
statusCode: this.statusCode,
details: this.details,
stack: this.stack
};
}
};
function extractErrorMessage(response) {
if (!response) {
return null;
}
if (typeof response === "string") {
return response;
}
if (typeof response === "object" && response !== null) {
const errorObj = response;
const messagePaths = [
// Evolution API specific nested structure (most common)
errorObj.response?.response?.message?.[0],
errorObj.response?.response?.error,
errorObj.response?.response?.description,
// Evolution API first level nested
Array.isArray(errorObj.response?.message) ? errorObj.response.message[0] : null,
errorObj.response?.error,
errorObj.response?.description,
// Direct error message
Array.isArray(errorObj.message) ? errorObj.message[0] : errorObj.message,
errorObj.error,
errorObj.description,
errorObj.detail,
// Other nested error messages
errorObj.data?.error,
errorObj.data?.message,
// Array format messages (fallback)
Array.isArray(errorObj.error) ? errorObj.error[0] : null,
Array.isArray(errorObj.errors) ? errorObj.errors[0] : null
];
for (const path of messagePaths) {
if (typeof path === "string" && path.trim()) {
return path.trim();
}
if (typeof path === "object" && path !== null) {
const nestedMessage = extractErrorMessage(path);
if (nestedMessage) {
return nestedMessage;
}
}
}
if (errorObj.validation && Array.isArray(errorObj.validation)) {
const validationErrors = errorObj.validation.map((v) => v.message || v.error || String(v)).filter(Boolean).join(", ");
if (validationErrors) {
return `Validation error: ${validationErrors}`;
}
}
if (errorObj.statusCode && errorObj.statusText) {
return `${errorObj.statusCode}: ${errorObj.statusText}`;
}
if (Object.keys(errorObj).length > 0) {
try {
return JSON.stringify(errorObj);
} catch {
return "[Complex error object]";
}
}
}
return null;
}
// src/api/service.ts
var ApiService = class {
constructor(options) {
this.options = options;
}
setInstance(instance) {
this.options.instance = instance;
}
async request(path, options = {}) {
const { isInstanceUrl = true } = options;
let instance = this.options.instance;
if (options.instance) {
instance = options.instance;
delete options.instance;
}
if (isInstanceUrl && !instance) {
throw new EvolutionApiError("Instance not set", {
message: "Please set the instance before making a request or pass instance in the method options."
});
}
const { init, params } = this.makeInit(options);
const urlPath = isInstanceUrl ? `/${path}/${instance}/` : `/${path}/`;
const url = new URL(urlPath, this.options.serverUrl);
if (params.toString()) {
url.search = params.toString();
}
let response;
let data;
try {
response = await fetch(url, init);
data = await response.json();
} catch (error) {
throw new EvolutionApiError("Network or parsing error", error);
}
if (!response.ok) {
const errorMessage = extractErrorMessage(data) || `Request failed with status ${response.status}: ${response.statusText}`;
throw new EvolutionApiError(
errorMessage,
{
message: errorMessage,
response: JSON.stringify(data),
url: url.toString(),
params: params.toString(),
body: JSON.stringify(options.body)
},
response.status
);
}
return data;
}
makeInit(options) {
const init = {
method: options.method || "GET",
headers: {
"Content-Type": "application/json",
apikey: this.options.token,
// Evolution API uses apikey header
...this.options.headers,
...options.headers
}
};
if (options.body) {
init.body = JSON.stringify(options.body);
}
const params = new URLSearchParams();
if (options.params) {
Object.entries(options.params).forEach(([key, value]) => {
if (value !== void 0 && value !== null) {
params.append(key, String(value));
}
});
}
return { init, params };
}
async get(path, options = {}) {
return this.request(path, { ...options, method: "GET" });
}
async post(path, options = {}) {
return this.request(path, { ...options, method: "POST" });
}
async put(path, options = {}) {
return this.request(path, { ...options, method: "PUT" });
}
async patch(path, options = {}) {
return this.request(path, { ...options, method: "PATCH" });
}
async delete(path, options = {}) {
return this.request(path, { ...options, method: "DELETE" });
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ApiService
});
//# sourceMappingURL=service.js.map