channel3-sdk
Version:
The official TypeScript/JavaScript SDK for Channel3 AI Shopping API
128 lines • 5.76 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AsyncChannel3Client = exports.Channel3Client = void 0;
const cross_fetch_1 = __importDefault(require("cross-fetch"));
const exceptions_1 = require("./exceptions");
const generated_1 = require("./generated");
class Channel3Client {
constructor(config) {
var _a;
this.timeoutMs = 30000;
if (!config.apiKey) {
const envApiKey = typeof process !== 'undefined' ? (_a = process.env) === null || _a === void 0 ? void 0 : _a.CHANNEL3_API_KEY : undefined;
if (!envApiKey) {
throw new Error('No API key provided. Set CHANNEL3_API_KEY environment variable or pass apiKey in config.');
}
this.apiKey = envApiKey;
}
else {
this.apiKey = config.apiKey;
}
const configuration = new generated_1.Configuration({
basePath: (typeof process !== 'undefined' && process.env && process.env.CHANNEL3_BASE_PATH) ||
'https://api.trychannel3.com',
apiKey: async () => this.apiKey,
fetchApi: cross_fetch_1.default,
});
this.api = new generated_1.Channel3ApiApi(configuration);
}
createTimeoutOverride() {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
const initOverride = async ({ init }) => ({
...init,
signal: controller.signal,
});
const clear = () => clearTimeout(timeoutId);
return { initOverride, clear };
}
async handleGeneratedCall(fn) {
const { initOverride, clear } = this.createTimeoutOverride();
try {
const result = await fn(initOverride);
clear();
return result;
}
catch (error) {
clear();
await this.rethrowAsChannel3Error(error);
throw error;
}
}
async rethrowAsChannel3Error(error) {
if (error && typeof error === 'object' && 'name' in error) {
const err = error;
if (err.name === 'ResponseError' && err.response) {
const status = err.response.status;
let responseData = null;
try {
responseData = await err.response.clone().json();
}
catch (_a) {
try {
const text = await err.response.clone().text();
responseData = { detail: text };
}
catch (_b) {
responseData = null;
}
}
const url = err.response.url;
const errorMessage = (responseData === null || responseData === void 0 ? void 0 : responseData.detail) || `Request failed with status ${status}`;
switch (status) {
case 401:
throw new exceptions_1.Channel3AuthenticationError('Invalid or missing API key', status, responseData);
case 404:
throw new exceptions_1.Channel3NotFoundError(errorMessage, status, responseData);
case 422:
throw new exceptions_1.Channel3ValidationError(`Validation error: ${errorMessage}`, status, responseData);
case 500:
throw new exceptions_1.Channel3ServerError('Internal server error', status, responseData);
default:
throw new exceptions_1.Channel3Error(`Request to ${url} failed: ${errorMessage}`, status, responseData);
}
}
if (err.name === 'FetchError') {
throw new exceptions_1.Channel3ConnectionError(`Request failed: ${err.message}`);
}
if (err.name === 'AbortError') {
throw new exceptions_1.Channel3ConnectionError('Request timed out');
}
}
if (error instanceof exceptions_1.Channel3Error) {
throw error;
}
if (error instanceof Error) {
throw new exceptions_1.Channel3ConnectionError(`Request failed: ${error.message}`);
}
throw new exceptions_1.Channel3Error(`Unexpected error: ${String(error)}`);
}
async search(options = {}) {
const products = await this.handleGeneratedCall((initOverride) => this.api.searchV0SearchPost({ searchRequest: options }, initOverride));
return products;
}
async getProduct(productId) {
if (!productId || !productId.trim()) {
throw new Error('productId cannot be empty');
}
const product = await this.handleGeneratedCall((initOverride) => this.api.getProductDetailV0ProductsProductIdGet({ productId }, initOverride));
return product;
}
async getBrands(options = {}) {
const result = await this.handleGeneratedCall((initOverride) => this.api.getBrandsV0BrandsGet({ query: options.query, page: options.page, size: options.size }, initOverride));
return result;
}
async getBrand(brandId) {
if (!brandId || !brandId.trim()) {
throw new Error('brandId cannot be empty');
}
const brand = await this.handleGeneratedCall((initOverride) => this.api.getBrandDetailV0BrandsBrandIdGet({ brandId }, initOverride));
return brand;
}
}
exports.Channel3Client = Channel3Client;
exports.AsyncChannel3Client = Channel3Client;
//# sourceMappingURL=client.js.map