UNPKG

@gftdcojp/gftd-orm

Version:

Enterprise-grade real-time data platform with ksqlDB, inspired by Supabase architecture

259 lines 8.64 kB
"use strict"; /** * クライアントサイド用HTTPクライアント(ブラウザ環境) */ Object.defineProperty(exports, "__esModule", { value: true }); exports.KsqlDbClientBrowser = exports.HttpClient = void 0; exports.createKsqlDbClientBrowser = createKsqlDbClientBrowser; const env_1 = require("./utils/env"); const ksqldb_client_1 = require("./ksqldb-client"); /** * ブラウザ環境用HTTPクライアント */ class HttpClient { constructor(config) { if (!(0, env_1.isBrowser)()) { throw new Error('HttpClient can only be used in browser environment'); } this.config = config; this.defaultHeaders = { 'Content-Type': 'application/json', ...config.headers, }; // 認証情報がある場合は Authorization ヘッダーを追加 if (config.apiKey && config.apiSecret) { const credentials = btoa(`${config.apiKey}:${config.apiSecret}`); this.defaultHeaders['Authorization'] = `Basic ${credentials}`; } } /** * GET リクエストを送信 */ async get(path, params) { const url = new URL(path, this.config.url); if (params) { Object.keys(params).forEach(key => { url.searchParams.append(key, params[key]); }); } const response = await this.fetch(url.toString(), { method: 'GET', headers: this.defaultHeaders, }); return this.handleResponse(response); } /** * POST リクエストを送信 */ async post(path, data) { const url = new URL(path, this.config.url); const response = await this.fetch(url.toString(), { method: 'POST', headers: this.defaultHeaders, body: data ? JSON.stringify(data) : undefined, }); return this.handleResponse(response); } /** * PUT リクエストを送信 */ async put(path, data) { const url = new URL(path, this.config.url); const response = await this.fetch(url.toString(), { method: 'PUT', headers: this.defaultHeaders, body: data ? JSON.stringify(data) : undefined, }); return this.handleResponse(response); } /** * DELETE リクエストを送信 */ async delete(path) { const url = new URL(path, this.config.url); const response = await this.fetch(url.toString(), { method: 'DELETE', headers: this.defaultHeaders, }); return this.handleResponse(response); } /** * ksqlDB クエリを実行 */ async executeQuery(sql) { const response = await this.post('/ksql', { ksql: sql, streamsProperties: {}, }); return response; } /** * Pull Query を実行(ブラウザ用) * @param sql - 実行するSQL文 * @param options - Pull Queryのオプション */ async executePullQuery(sql, options = {}) { const { format = 'object' } = options; const response = await this.post('/query-stream', { sql, properties: {}, }); // ブラウザ環境では、レスポンスの形式が異なる可能性があるため、 // 基本的な変換処理を実装 if (format === 'object' && response && Array.isArray(response.data) && response.columnNames) { const transformedData = (0, ksqldb_client_1.transformArrayRowsToObjects)(response.data, response.columnNames); return { ...response, data: transformedData }; } return response; } async fetch(url, options) { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), this.config.timeout || 30000); try { const response = await fetch(url, { ...options, signal: controller.signal, }); clearTimeout(timeoutId); return response; } catch (error) { clearTimeout(timeoutId); if (error instanceof Error && error.name === 'AbortError') { throw new Error('Request timeout'); } throw error; } } async handleResponse(response) { if (!response.ok) { const errorText = await response.text(); throw new Error(`HTTP ${response.status}: ${errorText}`); } const contentType = response.headers.get('content-type'); if (contentType && contentType.includes('application/json')) { return response.json(); } return response.text(); } } exports.HttpClient = HttpClient; /** * ブラウザ環境用ksqlDBクライアント */ class KsqlDbClientBrowser { constructor(config) { this.config = config; this.httpClient = new HttpClient({ url: config.url, apiKey: config.apiKey, apiSecret: config.apiSecret, headers: config.headers, timeout: 30000, }); } /** * クエリを実行 */ async executeQuery(sql) { try { const response = await this.httpClient.executeQuery(sql); return response; } catch (error) { throw new Error(`ksqlDB query failed: ${error.message}`); } } /** * Pull Query を実行 * @param sql - 実行するSQL文 * @param options - Pull Queryのオプション(デフォルトでオブジェクト形式を返す) */ async executePullQuery(sql, options = {}) { console.log(`[DEBUG] KsqlDbClientBrowser.executePullQuery - SQL: ${sql}`); console.log(`[DEBUG] KsqlDbClientBrowser.executePullQuery - Options:`, options); console.log(`[DEBUG] KsqlDbClientBrowser.executePullQuery - Config:`, this.config); try { const response = await this.httpClient.executePullQuery(sql, options); console.log(`[DEBUG] KsqlDbClientBrowser.executePullQuery - Response:`, response); return response; } catch (error) { console.error(`[ERROR] KsqlDbClientBrowser.executePullQuery failed:`, error); // ストリーム vs テーブルの問題を特定しやすくする if (error.message && (error.message.includes('stream') || error.message.includes('table'))) { console.error(`[ERROR] KsqlDbClientBrowser.executePullQuery - Possible stream/table issue. SQL: ${sql}`); console.error(`[ERROR] KsqlDbClientBrowser.executePullQuery - Remember: Pull queries work only on TABLES, not STREAMS`); } throw new Error(`ksqlDB pull query failed: ${error.message || 'Unknown error'}`); } } /** * DDL文を実行 */ async executeDDL(ddl) { try { const response = await this.httpClient.executeQuery(ddl); if (response && response[0] && response[0].errorMessage) { throw new Error(`DDL execution failed: ${response[0].errorMessage.message}`); } return response; } catch (error) { throw new Error(`ksqlDB DDL failed: ${error.message}`); } } /** * ストリーム/テーブル一覧を取得 */ async listStreams() { return this.executeQuery('LIST STREAMS;'); } async listTables() { return this.executeQuery('LIST TABLES;'); } /** * トピック一覧を取得 */ async listTopics() { return this.executeQuery('LIST TOPICS;'); } /** * スキーマ情報を取得 */ async describeStream(streamName) { return this.executeQuery(`DESCRIBE ${streamName};`); } async describeTable(tableName) { return this.executeQuery(`DESCRIBE ${tableName};`); } /** * 接続状態を確認 */ async isConnected() { try { await this.executeQuery('SHOW QUERIES;'); return true; } catch { return false; } } /** * クライアント設定を取得 */ getConfig() { return this.config; } } exports.KsqlDbClientBrowser = KsqlDbClientBrowser; /** * ブラウザ環境用ksqlDBクライアントを作成 */ function createKsqlDbClientBrowser(config) { return new KsqlDbClientBrowser(config); } //# sourceMappingURL=http-client.js.map