seamless-cloud
Version:
JavaScript client for Seamless.cloud (web and node)
126 lines (104 loc) • 3.1 kB
text/typescript
import { fetchJSON } from '../shared/fetch';
/**
* Seamless.cloud client
*/
export type SeamlessClientConfig = {
account: string;
apiKey: string;
project: string;
region?: string;
debug?: boolean;
};
export type SeamlessQuery = {
querySql: string;
queryVars?: { [key: string]: any };
};
export type SeamlessQueryResult = {
meta: {
success: boolean;
statusCode: number;
dtResponse: string;
};
data: {
results?: any[];
rowCount?: number;
timeMs?: number;
};
};
export interface ISeamlessClient {
cfg: SeamlessClientConfig;
fetchFn: any;
debug: boolean;
}
export class SeamlessClient implements ISeamlessClient {
debug: boolean;
constructor(public cfg: SeamlessClientConfig, public fetchFn: any) {
this.cfg = cfg;
this.fetchFn = fetchFn;
this.debug = cfg.debug || false;
if (!this.cfg.region) {
this.cfg.region = 'us-east-2';
}
}
getBaseUrl() {
return `https://${this.cfg.region}.sqlapi.seamless.cloud/sqlapi`;
}
/**
* Find and return a single row. No result throws Error with optional custom message.
*/
async findOneOrThrow(queryKey: string, query: SeamlessQuery, errorMsg?: string): Promise<any> {
const response = await this.query(queryKey, query);
const rows = response?.data?.results;
if (!rows || rows.length === 0) {
throw new Error(errorMsg || 'Record not found');
}
return rows[0];
}
/**
* Find and return a single row. No result returns boolean false.
*/
async findOne(queryKey: string, query: SeamlessQuery): Promise<any | boolean> {
const response = await this.query(queryKey, query);
const rows = response?.data?.results;
if (!rows || rows.length === 0) {
return false;
}
return rows[0];
}
/**
* Find many rows (Always returns an array. No results = empty array)
*/
async findMany(queryKey: string, query: SeamlessQuery): Promise<Array<any>> {
const response = await this.query(queryKey, query);
const rows = response?.data?.results;
return rows || [];
}
/**
* Run SQL Query
*/
async query(queryKey: string, queryObject: SeamlessQuery): Promise<SeamlessQueryResult> {
const { querySql, queryVars } = queryObject;
const seamlessUrl = this.getBaseUrl();
const queryParams = {
account: this.cfg.account,
apiKey: this.cfg.apiKey,
project: this.cfg.project,
queryKey,
querySql,
queryVars,
};
if (this.debug) {
const { apiKey, ...logParams } = queryParams; // Don't log out apiKey
console.log('[seamless-cloud query]: ', seamlessUrl, logParams);
}
const beforeQueryMs = Date.now();
const results = await fetchJSON(this.fetchFn, 'POST', seamlessUrl, queryParams);
const afterQueryMs = Date.now();
if (this.debug) {
console.log('[seamless-cloud timeMs]: ', results?.data?.timeMs);
console.log('[seamless-cloud rowCount]: ', results?.data?.rowCount);
console.log('[seamless-cloud responseTimeMs]: ', afterQueryMs - beforeQueryMs);
}
return results;
}
}