wulf-pulse/lib/services/salesbldr-client.ts

209 lines
6 KiB
TypeScript
Raw Normal View History

interface SalesBldrConfig {
apiUrl: string;
apiKey: string;
}
interface QuoteItem {
id: string;
category?: object;
cost?: number;
mpn?: string;
markup?: number;
deliveryDate?: string;
discount?: number;
unit?: string;
term?: string;
name: string;
price?: number;
quantity: number;
shortDescription?: string;
}
interface Quote {
id: string;
title: string;
number: string;
status: string;
createdAt: string;
sentAt?: string;
expiresAt?: string;
approvedAt?: string;
company?: {
id: string;
name: string;
externalIdentifier?: string;
};
contact?: object;
owner?: object;
items?: QuoteItem[];
opportunity?: {
id: string;
name: string;
description?: string;
};
}
interface QuoteSearchResponse {
results: Quote[];
total: number;
filters?: any[];
sortOptions?: any[];
}
export class SalesBldrClient {
private config: SalesBldrConfig;
constructor(config?: SalesBldrConfig) {
this.config = config || {
apiUrl: process.env.SALESBLDR_API_URL || '',
apiKey: process.env.SALESBLDR_API_KEY || ''
};
}
private ensureConfig() {
if (!this.config.apiUrl || !this.config.apiKey) {
throw new Error('SalesBldr API URL and API Key are required');
}
}
private async request<T>(
endpoint: string,
options: RequestInit = {}
): Promise<T> {
this.ensureConfig();
const url = `${this.config.apiUrl}${endpoint}`;
const headers: HeadersInit = {
'api-key': this.config.apiKey,
'Content-Type': 'application/json',
...options.headers,
};
const response = await fetch(url, {
...options,
headers,
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(
`SalesBldr API error: ${response.status} ${response.statusText} - ${errorText}`
);
}
return response.json();
}
async getQuotes(params?: {
sort?: string;
filters?: string;
query?: string;
size?: number;
from?: number;
}): Promise<QuoteSearchResponse> {
const queryParams = new URLSearchParams();
if (params?.sort) queryParams.append('sort', params.sort);
if (params?.filters) queryParams.append('filters', params.filters);
if (params?.query) queryParams.append('query', params.query);
if (params?.size !== undefined) queryParams.append('size', params.size.toString());
if (params?.from !== undefined) queryParams.append('from', params.from.toString());
const endpoint = `/public-api/quote${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
return this.request<QuoteSearchResponse>(endpoint);
}
async getOpenQuotes(size: number = 10): Promise<QuoteSearchResponse> {
return this.getQuotes({
filters: 'status:sent|draft',
sort: '-createdAt',
size
});
}
async getApprovedQuotes(size: number = 10): Promise<Quote[]> {
const endpoint = `/public-api/quote/approved`;
return this.request<Quote[]>(endpoint);
}
async getOpportunities(params?: {
sort?: string;
filters?: string;
query?: string;
size?: number;
from?: number;
}): Promise<any> {
const queryParams = new URLSearchParams();
if (params?.sort) queryParams.append('sort', params.sort);
if (params?.filters) queryParams.append('filters', params.filters);
if (params?.query) queryParams.append('query', params.query);
if (params?.size !== undefined) queryParams.append('size', params.size.toString());
if (params?.from !== undefined) queryParams.append('from', params.from.toString());
const endpoint = `/public-api/opportunity${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
return this.request(endpoint);
}
async getProducts(params?: {
includeBundles?: boolean;
sort?: string;
filters?: string;
query?: string;
size?: number;
from?: number;
}): Promise<any> {
const queryParams = new URLSearchParams();
if (params?.includeBundles !== undefined) queryParams.append('includeBundles', params.includeBundles.toString());
if (params?.sort) queryParams.append('sort', params.sort);
if (params?.filters) queryParams.append('filters', params.filters);
if (params?.query) queryParams.append('query', params.query);
if (params?.size !== undefined) queryParams.append('size', params.size.toString());
if (params?.from !== undefined) queryParams.append('from', params.from.toString());
const endpoint = `/public-api/product${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
return this.request(endpoint);
}
async getCompanies(params?: {
sort?: string;
filters?: string;
query?: string;
size?: number;
from?: number;
}): Promise<any> {
const queryParams = new URLSearchParams();
if (params?.sort) queryParams.append('sort', params.sort);
if (params?.filters) queryParams.append('filters', params.filters);
if (params?.query) queryParams.append('query', params.query);
if (params?.size !== undefined) queryParams.append('size', params.size.toString());
if (params?.from !== undefined) queryParams.append('from', params.from.toString());
const endpoint = `/public-api/company${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
return this.request(endpoint);
}
async getContacts(params?: {
sort?: string;
filters?: string;
query?: string;
size?: number;
from?: number;
}): Promise<any> {
const queryParams = new URLSearchParams();
if (params?.sort) queryParams.append('sort', params.sort);
if (params?.filters) queryParams.append('filters', params.filters);
if (params?.query) queryParams.append('query', params.query);
if (params?.size !== undefined) queryParams.append('size', params.size.toString());
if (params?.from !== undefined) queryParams.append('from', params.from.toString());
const endpoint = `/public-api/contact${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
return this.request(endpoint);
}
}
export const salesBldrClient = new SalesBldrClient();