@mirad-work/sms-core
Version:
A framework-agnostic TypeScript SMS service core with provider abstraction for Iranian SMS providers
121 lines • 3.75 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpClient = void 0;
const node_fetch_1 = __importDefault(require("node-fetch"));
/**
* Framework-agnostic HTTP client implementation using node-fetch
* This can be easily replaced with any other HTTP library
*/
class HttpClient {
constructor(timeout = 10000) {
if (timeout <= 0) {
throw new Error("Timeout must be a positive number");
}
this.defaultTimeout = timeout;
}
async request(config) {
const { method, url, headers = {}, data, timeout = this.defaultTimeout, } = config;
this.validateRequestConfig(config);
const requestOptions = {
method,
headers: {
"Content-Type": "application/json",
Accept: "application/json",
...headers,
},
body: data ? JSON.stringify(data) : undefined,
};
// Create AbortController for timeout
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
requestOptions.signal = controller.signal;
try {
const response = await (0, node_fetch_1.default)(url, requestOptions);
clearTimeout(timeoutId);
const responseData = await this.parseResponse(response);
// Convert node-fetch headers to plain object
const responseHeaders = {};
response.headers.forEach((value, key) => {
responseHeaders[key] = value;
});
return {
data: responseData,
status: response.status,
statusText: response.statusText,
headers: responseHeaders,
};
}
catch (error) {
clearTimeout(timeoutId);
const err = error;
if (err.name === "AbortError") {
throw new Error(`Request timeout after ${timeout}ms`);
}
throw new Error(`HTTP request failed: ${err.message}`);
}
}
async get(url, config = {}) {
return this.request({
method: "GET",
url,
...config,
});
}
async post(url, data, config = {}) {
return this.request({
method: "POST",
url,
data,
...config,
});
}
async put(url, data, config = {}) {
return this.request({
method: "PUT",
url,
data,
...config,
});
}
async delete(url, config = {}) {
return this.request({
method: "DELETE",
url,
...config,
});
}
/**
* Validate request configuration
*/
validateRequestConfig(config) {
if (!config.url) {
throw new Error("URL is required");
}
if (!config.method) {
throw new Error("HTTP method is required");
}
try {
new URL(config.url);
}
catch {
throw new Error("Invalid URL format");
}
}
/**
* Parse response data based on content type
*/
async parseResponse(response) {
const contentType = response.headers.get("content-type");
if (contentType && contentType.includes("application/json")) {
return (await response.json());
}
else {
return (await response.text());
}
}
}
exports.HttpClient = HttpClient;
//# sourceMappingURL=http-client.js.map