@oxy-hq/sdk 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -26,7 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  }) : target, mod));
27
27
 
28
28
  //#endregion
29
- const require_postMessage = require('./postMessage-CtL0W-Zt.cjs');
29
+ const require_postMessage = require('./postMessage-CufWf9ji.cjs');
30
30
  let _duckdb_duckdb_wasm = require("@duckdb/duckdb-wasm");
31
31
  _duckdb_duckdb_wasm = __toESM(_duckdb_duckdb_wasm);
32
32
 
@@ -94,7 +94,7 @@ function createConfig(overrides) {
94
94
  * ```
95
95
  */
96
96
  async function createConfigAsync(overrides) {
97
- const { isInIframe: isInIframe$1, requestAuthFromParent: requestAuthFromParent$1 } = await Promise.resolve().then(() => require("./postMessage-DacyukaO.cjs"));
97
+ const { isInIframe: isInIframe$1, requestAuthFromParent: requestAuthFromParent$1 } = await Promise.resolve().then(() => require("./postMessage-CVS3MsL5.cjs"));
98
98
  let baseUrl = overrides?.baseUrl || process.env.OXY_URL;
99
99
  let apiKey = overrides?.apiKey || process.env.OXY_API_KEY;
100
100
  let projectId = overrides?.projectId || process.env.OXY_PROJECT_ID;
@@ -376,7 +376,7 @@ var OxyClient = class OxyClient {
376
376
  "Content-Type": "application/json",
377
377
  ...options.headers || {}
378
378
  };
379
- if (this.config.apiKey) headers["X-API-Key"] = `${this.config.apiKey}`;
379
+ if (this.config.apiKey) headers["Authorization"] = `Bearer ${this.config.apiKey}`;
380
380
  const controller = new AbortController();
381
381
  const timeoutId = setTimeout(() => controller.abort(), this.config.timeout || 3e4);
382
382
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["isInIframe","requestAuthFromParent","duckdb"],"sources":["../src/config.ts","../src/parquet.ts","../src/client.ts"],"sourcesContent":["/**\n * Configuration for the Oxy SDK\n */\nexport interface OxyConfig {\n /**\n * Base URL of the Oxy API (e.g., 'https://api.oxy.tech' or 'http://localhost:3000')\n */\n baseUrl: string;\n\n /**\n * API key for authentication (optional for local development)\n */\n apiKey?: string;\n\n /**\n * Project ID (UUID)\n */\n projectId: string;\n\n /**\n * Optional branch name (defaults to current branch if not specified)\n */\n branch?: string;\n\n /**\n * Request timeout in milliseconds (default: 30000)\n */\n timeout?: number;\n\n /**\n * Parent window origin for postMessage authentication (iframe scenarios)\n * Required when using postMessage auth for security.\n * Example: 'https://app.example.com'\n * Use '*' only in development!\n */\n parentOrigin?: string;\n\n /**\n * Disable automatic postMessage authentication even if in iframe\n * Set to true if you want to provide API key manually in iframe context\n */\n disableAutoAuth?: boolean;\n}\n\n/**\n * Creates an Oxy configuration from environment variables\n *\n * Environment variables:\n * - OXY_URL: Base URL of the Oxy API\n * - OXY_API_KEY: API key for authentication\n * - OXY_PROJECT_ID: Project ID (UUID)\n * - OXY_BRANCH: (Optional) Branch name\n *\n * @param overrides - Optional configuration overrides\n * @returns OxyConfig object\n * @throws Error if required environment variables are missing\n */\nexport function createConfig(overrides?: Partial<OxyConfig>): OxyConfig {\n const baseUrl = overrides?.baseUrl || process.env.OXY_URL;\n const apiKey = overrides?.apiKey || process.env.OXY_API_KEY;\n const projectId = overrides?.projectId || process.env.OXY_PROJECT_ID;\n\n if (!baseUrl) {\n throw new Error('OXY_URL environment variable or baseUrl config is required');\n }\n\n if (!projectId) {\n throw new Error('OXY_PROJECT_ID environment variable or projectId config is required');\n }\n\n return {\n baseUrl: baseUrl.replace(/\\/$/, ''), // Remove trailing slash\n apiKey,\n projectId,\n branch: overrides?.branch || process.env.OXY_BRANCH,\n timeout: overrides?.timeout || 30000,\n parentOrigin: overrides?.parentOrigin,\n disableAutoAuth: overrides?.disableAutoAuth,\n };\n}\n\n/**\n * Creates an Oxy configuration asynchronously with support for postMessage authentication\n *\n * This is the recommended method for iframe scenarios where authentication\n * needs to be obtained from the parent window via postMessage.\n *\n * When running in an iframe without an API key, this function will:\n * 1. Detect the iframe context\n * 2. Send an authentication request to the parent window\n * 3. Wait for the parent to respond with credentials\n * 4. Return the configured client\n *\n * Environment variables (fallback):\n * - OXY_URL: Base URL of the Oxy API\n * - OXY_API_KEY: API key for authentication\n * - OXY_PROJECT_ID: Project ID (UUID)\n * - OXY_BRANCH: (Optional) Branch name\n *\n * @param overrides - Optional configuration overrides\n * @returns Promise resolving to OxyConfig object\n * @throws Error if required configuration is missing\n * @throws PostMessageAuthTimeoutError if parent doesn't respond\n *\n * @example\n * ```typescript\n * // Automatic iframe detection and authentication\n * const config = await createConfigAsync({\n * parentOrigin: 'https://app.example.com',\n * projectId: 'my-project-id',\n * baseUrl: 'https://api.oxy.tech'\n * });\n * ```\n */\nexport async function createConfigAsync(\n overrides?: Partial<OxyConfig>\n): Promise<OxyConfig> {\n // Import postMessage utilities (dynamic to avoid circular deps)\n const { isInIframe, requestAuthFromParent } = await import('./auth/postMessage');\n\n // Start with environment variables and overrides\n let baseUrl = overrides?.baseUrl || process.env.OXY_URL;\n let apiKey = overrides?.apiKey || process.env.OXY_API_KEY;\n let projectId = overrides?.projectId || process.env.OXY_PROJECT_ID;\n\n const disableAutoAuth = overrides?.disableAutoAuth ?? false;\n const parentOrigin = overrides?.parentOrigin;\n\n // Automatic iframe detection and authentication\n if (!disableAutoAuth && isInIframe() && !apiKey) {\n if (!parentOrigin) {\n console.warn(\n '[Oxy SDK] Running in iframe without API key and no parentOrigin specified. ' +\n 'PostMessage authentication will be skipped. ' +\n 'Provide parentOrigin config to enable automatic authentication.'\n );\n } else {\n try {\n const authResult = await requestAuthFromParent({\n parentOrigin,\n timeout: overrides?.timeout || 5000,\n });\n\n apiKey = authResult.apiKey;\n if (authResult.projectId) {\n projectId = authResult.projectId;\n }\n if (authResult.baseUrl) {\n baseUrl = authResult.baseUrl;\n }\n\n console.log('[Oxy SDK] Successfully authenticated via postMessage');\n } catch (error) {\n console.error(\n '[Oxy SDK] Failed to authenticate via postMessage:',\n (error as Error).message\n );\n // Fall through to use environment variables if available\n }\n }\n }\n\n // Validation\n if (!baseUrl) {\n throw new Error('OXY_URL environment variable or baseUrl config is required');\n }\n\n if (!projectId) {\n throw new Error('OXY_PROJECT_ID environment variable or projectId config is required');\n }\n\n return {\n baseUrl: baseUrl.replace(/\\/$/, ''), // Remove trailing slash\n apiKey,\n projectId,\n branch: overrides?.branch || process.env.OXY_BRANCH,\n timeout: overrides?.timeout || 30000,\n parentOrigin,\n disableAutoAuth,\n };\n}\n","import * as duckdb from '@duckdb/duckdb-wasm';\n\nlet dbInstance: duckdb.AsyncDuckDB | null = null;\nlet connection: duckdb.AsyncDuckDBConnection | null = null;\n\n/**\n * Initialize DuckDB-WASM instance\n */\nasync function initializeDuckDB(): Promise<duckdb.AsyncDuckDB> {\n if (dbInstance) {\n return dbInstance;\n }\n\n const JSDELIVR_BUNDLES = duckdb.getJsDelivrBundles();\n\n // Select a bundle based on browser features\n const bundle = await duckdb.selectBundle(JSDELIVR_BUNDLES);\n\n const worker_url = URL.createObjectURL(\n new Blob([`importScripts(\"${bundle.mainWorker}\");`], {\n type: 'text/javascript',\n })\n );\n\n const worker = new Worker(worker_url);\n const logger = new duckdb.ConsoleLogger();\n\n dbInstance = new duckdb.AsyncDuckDB(logger, worker);\n await dbInstance.instantiate(bundle.mainModule, bundle.pthreadWorker);\n URL.revokeObjectURL(worker_url);\n\n return dbInstance;\n}\n\n/**\n * Get or create a DuckDB connection\n */\nasync function getConnection(): Promise<duckdb.AsyncDuckDBConnection> {\n if (connection) {\n return connection;\n }\n\n const db = await initializeDuckDB();\n connection = await db.connect();\n return connection;\n}\n\n/**\n * Query result interface\n */\nexport interface QueryResult {\n columns: string[];\n rows: any[][];\n rowCount: number;\n}\n\n/**\n * ParquetReader provides methods to read and query Parquet files\n */\nexport class ParquetReader {\n private tableName: string;\n private registered: boolean = false;\n\n constructor(tableName: string = 'data') {\n this.tableName = tableName;\n }\n\n /**\n * Register a Parquet file from a Blob\n *\n * @param blob - Parquet file as Blob\n *\n * @example\n * ```typescript\n * const blob = await client.getFile('data/sales.parquet');\n * const reader = new ParquetReader('sales');\n * await reader.registerParquet(blob);\n * ```\n */\n async registerParquet(blob: Blob): Promise<void> {\n const conn = await getConnection();\n const db = await initializeDuckDB();\n\n // Convert blob to Uint8Array\n const arrayBuffer = await blob.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n\n // Register the file with DuckDB\n await db.registerFileBuffer(\n `${this.tableName}.parquet`,\n uint8Array\n );\n\n // Drop table if it exists\n try {\n await conn.query(`DROP TABLE IF EXISTS ${this.tableName}`);\n } catch (e) {\n // Ignore error if table doesn't exist\n }\n\n // Create table from parquet\n await conn.query(\n `CREATE TABLE ${this.tableName} AS SELECT * FROM '${this.tableName}.parquet'`\n );\n\n this.registered = true;\n }\n\n /**\n * Execute a SQL query against the registered Parquet data\n *\n * @param sql - SQL query string\n * @returns Query result with columns and rows\n *\n * @example\n * ```typescript\n * const result = await reader.query('SELECT * FROM sales LIMIT 10');\n * console.log(result.columns);\n * console.log(result.rows);\n * ```\n */\n async query(sql: string): Promise<QueryResult> {\n if (!this.registered) {\n throw new Error('Parquet file not registered. Call registerParquet() first.');\n }\n\n const conn = await getConnection();\n const result = await conn.query(sql);\n\n const columns = result.schema.fields.map((field) => field.name);\n const rows: any[][] = [];\n\n // Convert Arrow table to rows\n for (let i = 0; i < result.numRows; i++) {\n const row: any[] = [];\n for (let j = 0; j < result.numCols; j++) {\n const col = result.getChildAt(j);\n row.push(col?.get(i));\n }\n rows.push(row);\n }\n\n return {\n columns,\n rows,\n rowCount: result.numRows,\n };\n }\n\n /**\n * Get all data from the registered table\n *\n * @param limit - Maximum number of rows to return (default: all)\n * @returns Query result\n *\n * @example\n * ```typescript\n * const allData = await reader.getAll();\n * const first100 = await reader.getAll(100);\n * ```\n */\n async getAll(limit?: number): Promise<QueryResult> {\n const limitClause = limit ? ` LIMIT ${limit}` : '';\n return this.query(`SELECT * FROM ${this.tableName}${limitClause}`);\n }\n\n /**\n * Get table schema information\n *\n * @returns Schema information\n *\n * @example\n * ```typescript\n * const schema = await reader.getSchema();\n * console.log(schema.columns); // ['id', 'name', 'sales']\n * console.log(schema.rows); // [['id', 'INTEGER'], ['name', 'VARCHAR'], ...]\n * ```\n */\n async getSchema(): Promise<QueryResult> {\n return this.query(`DESCRIBE ${this.tableName}`);\n }\n\n /**\n * Get row count\n *\n * @returns Number of rows in the table\n *\n * @example\n * ```typescript\n * const count = await reader.count();\n * console.log(`Total rows: ${count}`);\n * ```\n */\n async count(): Promise<number> {\n const result = await this.query(`SELECT COUNT(*) as count FROM ${this.tableName}`);\n return result.rows[0][0];\n }\n\n /**\n * Close and cleanup resources\n */\n async close(): Promise<void> {\n if (this.registered) {\n const conn = await getConnection();\n const db = await initializeDuckDB();\n\n // Drop the table\n try {\n await conn.query(`DROP TABLE IF EXISTS ${this.tableName}`);\n } catch (e) {\n // Ignore error\n }\n\n // Drop the registered file buffer\n try {\n await db.dropFile(`${this.tableName}.parquet`);\n } catch (e) {\n // Ignore error if file doesn't exist\n }\n\n this.registered = false;\n }\n }\n}\n\n/**\n * Helper function to quickly read a Parquet blob and execute a query\n *\n * @param blob - Parquet file as Blob\n * @param sql - SQL query to execute (optional, defaults to SELECT *)\n * @returns Query result\n *\n * @example\n * ```typescript\n * const blob = await client.getFile('data/sales.parquet');\n * const result = await queryParquet(blob, 'SELECT product, SUM(amount) as total FROM data GROUP BY product');\n * console.log(result);\n * ```\n */\nexport async function queryParquet(\n blob: Blob,\n sql?: string\n): Promise<QueryResult> {\n // Generate unique table name to avoid conflicts\n const uniqueId = `temp_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n const reader = new ParquetReader(uniqueId);\n\n await reader.registerParquet(blob);\n\n const query = sql || `SELECT * FROM ${uniqueId}`;\n const result = await reader.query(query);\n\n await reader.close();\n return result;\n}\n\n/**\n * Helper function to read Parquet file and get all data\n *\n * @param blob - Parquet file as Blob\n * @param limit - Maximum number of rows (optional)\n * @returns Query result\n *\n * @example\n * ```typescript\n * const blob = await client.getFile('data/sales.parquet');\n * const data = await readParquet(blob, 1000);\n * console.log(`Loaded ${data.rowCount} rows`);\n * ```\n */\nexport async function readParquet(\n blob: Blob,\n limit?: number\n): Promise<QueryResult> {\n // Generate unique table name to avoid conflicts\n const uniqueId = `temp_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n const reader = new ParquetReader(uniqueId);\n\n await reader.registerParquet(blob);\n\n const result = await reader.getAll(limit);\n\n await reader.close();\n return result;\n}\n","import { OxyConfig, createConfigAsync } from './config';\nimport {\n AppItem,\n AppDataResponse,\n GetDisplaysResponse,\n ApiError,\n TableData,\n} from './types';\nimport { readParquet } from './parquet';\n\n/**\n * Oxy API Client for interacting with Oxy data\n */\nexport class OxyClient {\n private config: OxyConfig;\n\n constructor(config: OxyConfig) {\n this.config = config;\n }\n\n /**\n * Creates an OxyClient instance asynchronously with support for postMessage authentication\n *\n * This is the recommended method when using the SDK in an iframe that needs to\n * obtain authentication from the parent window via postMessage.\n *\n * @param config - Optional configuration overrides\n * @returns Promise resolving to OxyClient instance\n * @throws Error if required configuration is missing\n * @throws PostMessageAuthTimeoutError if parent doesn't respond\n *\n * @example\n * ```typescript\n * // In an iframe - automatic postMessage auth\n * const client = await OxyClient.create({\n * parentOrigin: 'https://app.example.com',\n * projectId: 'my-project-id',\n * baseUrl: 'https://api.oxy.tech'\n * });\n *\n * // Use the client normally\n * const apps = await client.listApps();\n * ```\n */\n static async create(config?: Partial<OxyConfig>): Promise<OxyClient> {\n const resolvedConfig = await createConfigAsync(config);\n return new OxyClient(resolvedConfig);\n }\n\n /**\n * Encodes a file path to base64 for use in API URLs\n */\n private encodePathBase64(path: string): string {\n if (typeof Buffer !== 'undefined') {\n // Node.js environment\n return Buffer.from(path).toString('base64');\n } else {\n // Browser environment\n return btoa(path);\n }\n }\n\n /**\n * Makes an authenticated HTTP request to the Oxy API\n */\n private async request<T>(\n endpoint: string,\n options: RequestInit = {}\n ): Promise<T> {\n const url = `${this.config.baseUrl}${endpoint}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...((options.headers as Record<string, string>) || {}),\n };\n\n // Only add Authorization header if API key is provided (optional for local dev)\n if (this.config.apiKey) {\n headers['X-API-Key'] = `${this.config.apiKey}`;\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout || 30000);\n\n try {\n const response = await fetch(url, {\n ...options,\n headers,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unknown error');\n const error: ApiError = {\n message: `API request failed: ${response.statusText}`,\n status: response.status,\n details: errorText,\n };\n throw error;\n }\n\n // Handle binary responses\n const acceptHeader =\n typeof options.headers === 'object' && options.headers !== null\n ? (options.headers as Record<string, string>)['Accept']\n : undefined;\n if (acceptHeader === 'application/octet-stream') {\n return response.blob() as Promise<T>;\n }\n\n return response.json();\n } catch (error: any) {\n clearTimeout(timeoutId);\n\n if (error.name === 'AbortError') {\n throw new Error(`Request timeout after ${this.config.timeout || 30000}ms`);\n }\n\n throw error;\n }\n }\n\n /**\n * Builds query parameters including optional branch\n */\n private buildQueryParams(additionalParams: Record<string, string> = {}): string {\n const params: Record<string, string> = { ...additionalParams };\n\n if (this.config.branch) {\n params.branch = this.config.branch;\n }\n\n const searchParams = new URLSearchParams(params);\n const queryString = searchParams.toString();\n return queryString ? `?${queryString}` : '';\n }\n\n /**\n * Lists all apps in the project\n *\n * @returns Array of app items\n *\n * @example\n * ```typescript\n * const apps = await client.listApps();\n * console.log('Available apps:', apps);\n * ```\n */\n async listApps(): Promise<AppItem[]> {\n const query = this.buildQueryParams();\n return this.request<AppItem[]>(`/${this.config.projectId}/app${query}`);\n }\n\n /**\n * Gets data for a specific app\n *\n * @param appPath - Relative path to the app file (e.g., 'my-app.app.yml')\n * @returns App data response\n *\n * @example\n * ```typescript\n * const data = await client.getAppData('dashboard.app.yml');\n * if (data.error) {\n * console.error('Error:', data.error);\n * } else {\n * console.log('App data:', data.data);\n * }\n * ```\n */\n async getAppData(appPath: string): Promise<AppDataResponse> {\n const pathb64 = this.encodePathBase64(appPath);\n const query = this.buildQueryParams();\n return this.request<AppDataResponse>(\n `/${this.config.projectId}/app/${pathb64}${query}`\n );\n }\n\n /**\n * Runs an app and returns fresh data (bypasses cache)\n *\n * @param appPath - Relative path to the app file\n * @returns App data response\n *\n * @example\n * ```typescript\n * const data = await client.runApp('dashboard.app.yml');\n * console.log('Fresh app data:', data.data);\n * ```\n */\n async runApp(appPath: string): Promise<AppDataResponse> {\n const pathb64 = this.encodePathBase64(appPath);\n const query = this.buildQueryParams();\n return this.request<AppDataResponse>(\n `/${this.config.projectId}/app/${pathb64}/run${query}`,\n { method: 'POST' }\n );\n }\n\n /**\n * Gets display configurations for an app\n *\n * @param appPath - Relative path to the app file\n * @returns Display configurations with potential errors\n *\n * @example\n * ```typescript\n * const displays = await client.getDisplays('dashboard.app.yml');\n * displays.displays.forEach(d => {\n * if (d.error) {\n * console.error('Display error:', d.error);\n * } else {\n * console.log('Display:', d.display);\n * }\n * });\n * ```\n */\n async getDisplays(appPath: string): Promise<GetDisplaysResponse> {\n const pathb64 = this.encodePathBase64(appPath);\n const query = this.buildQueryParams();\n return this.request<GetDisplaysResponse>(\n `/${this.config.projectId}/app/${pathb64}/displays${query}`\n );\n }\n\n /**\n * Gets a file from the app state directory (e.g., generated charts, images)\n *\n * This is useful for retrieving generated assets like charts, images, or other\n * files produced by app workflows and stored in the state directory.\n *\n * @param filePath - Relative path to the file in state directory\n * @returns Blob containing the file data\n *\n * @example\n * ```typescript\n * // Get a generated chart image\n * const blob = await client.getFile('charts/sales-chart.png');\n * const imageUrl = URL.createObjectURL(blob);\n *\n * // Use in an img tag\n * document.querySelector('img').src = imageUrl;\n * ```\n *\n * @example\n * ```typescript\n * // Download a file\n * const blob = await client.getFile('exports/data.csv');\n * const a = document.createElement('a');\n * a.href = URL.createObjectURL(blob);\n * a.download = 'data.csv';\n * a.click();\n * ```\n */\n async getFile(filePath: string): Promise<Blob> {\n const pathb64 = this.encodePathBase64(filePath);\n const query = this.buildQueryParams();\n return this.request<Blob>(\n `/${this.config.projectId}/app/file/${pathb64}${query}`,\n {\n headers: {\n 'Accept': 'application/octet-stream',\n },\n }\n );\n }\n\n /**\n * Gets a file URL for direct browser access\n *\n * This returns a URL that can be used directly in img tags, fetch calls, etc.\n * The URL includes authentication via query parameters.\n *\n * @param filePath - Relative path to the file in state directory\n * @returns Full URL to the file\n *\n * @example\n * ```typescript\n * const imageUrl = client.getFileUrl('charts/sales-chart.png');\n *\n * // Use directly in img tag (in environments where query-based auth is supported)\n * document.querySelector('img').src = imageUrl;\n * ```\n */\n getFileUrl(filePath: string): string {\n const pathb64 = this.encodePathBase64(filePath);\n const query = this.buildQueryParams();\n return `${this.config.baseUrl}/${this.config.projectId}/app/file/${pathb64}${query}`;\n }\n\n /**\n * Fetches a parquet file and parses it into table data\n *\n * @param filePath - Relative path to the parquet file\n * @param limit - Maximum number of rows to return (default: 100)\n * @returns TableData with columns and rows\n *\n * @example\n * ```typescript\n * const tableData = await client.getTableData('data/sales.parquet', 50);\n * console.log(tableData.columns);\n * console.log(tableData.rows);\n * console.log(`Total rows: ${tableData.total_rows}`);\n * ```\n */\n async getTableData(filePath: string, limit: number = 100): Promise<TableData> {\n const blob = await this.getFile(filePath);\n const result = await readParquet(blob, limit);\n\n return {\n columns: result.columns,\n rows: result.rows,\n total_rows: result.rowCount,\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["isInIframe","requestAuthFromParent","duckdb"],"sources":["../src/config.ts","../src/parquet.ts","../src/client.ts"],"sourcesContent":["/**\n * Configuration for the Oxy SDK\n */\nexport interface OxyConfig {\n /**\n * Base URL of the Oxy API (e.g., 'https://api.oxy.tech' or 'http://localhost:3000')\n */\n baseUrl: string;\n\n /**\n * API key for authentication (optional for local development)\n */\n apiKey?: string;\n\n /**\n * Project ID (UUID)\n */\n projectId: string;\n\n /**\n * Optional branch name (defaults to current branch if not specified)\n */\n branch?: string;\n\n /**\n * Request timeout in milliseconds (default: 30000)\n */\n timeout?: number;\n\n /**\n * Parent window origin for postMessage authentication (iframe scenarios)\n * Required when using postMessage auth for security.\n * Example: 'https://app.example.com'\n * Use '*' only in development!\n */\n parentOrigin?: string;\n\n /**\n * Disable automatic postMessage authentication even if in iframe\n * Set to true if you want to provide API key manually in iframe context\n */\n disableAutoAuth?: boolean;\n}\n\n/**\n * Creates an Oxy configuration from environment variables\n *\n * Environment variables:\n * - OXY_URL: Base URL of the Oxy API\n * - OXY_API_KEY: API key for authentication\n * - OXY_PROJECT_ID: Project ID (UUID)\n * - OXY_BRANCH: (Optional) Branch name\n *\n * @param overrides - Optional configuration overrides\n * @returns OxyConfig object\n * @throws Error if required environment variables are missing\n */\nexport function createConfig(overrides?: Partial<OxyConfig>): OxyConfig {\n const baseUrl = overrides?.baseUrl || process.env.OXY_URL;\n const apiKey = overrides?.apiKey || process.env.OXY_API_KEY;\n const projectId = overrides?.projectId || process.env.OXY_PROJECT_ID;\n\n if (!baseUrl) {\n throw new Error('OXY_URL environment variable or baseUrl config is required');\n }\n\n if (!projectId) {\n throw new Error('OXY_PROJECT_ID environment variable or projectId config is required');\n }\n\n return {\n baseUrl: baseUrl.replace(/\\/$/, ''), // Remove trailing slash\n apiKey,\n projectId,\n branch: overrides?.branch || process.env.OXY_BRANCH,\n timeout: overrides?.timeout || 30000,\n parentOrigin: overrides?.parentOrigin,\n disableAutoAuth: overrides?.disableAutoAuth,\n };\n}\n\n/**\n * Creates an Oxy configuration asynchronously with support for postMessage authentication\n *\n * This is the recommended method for iframe scenarios where authentication\n * needs to be obtained from the parent window via postMessage.\n *\n * When running in an iframe without an API key, this function will:\n * 1. Detect the iframe context\n * 2. Send an authentication request to the parent window\n * 3. Wait for the parent to respond with credentials\n * 4. Return the configured client\n *\n * Environment variables (fallback):\n * - OXY_URL: Base URL of the Oxy API\n * - OXY_API_KEY: API key for authentication\n * - OXY_PROJECT_ID: Project ID (UUID)\n * - OXY_BRANCH: (Optional) Branch name\n *\n * @param overrides - Optional configuration overrides\n * @returns Promise resolving to OxyConfig object\n * @throws Error if required configuration is missing\n * @throws PostMessageAuthTimeoutError if parent doesn't respond\n *\n * @example\n * ```typescript\n * // Automatic iframe detection and authentication\n * const config = await createConfigAsync({\n * parentOrigin: 'https://app.example.com',\n * projectId: 'my-project-id',\n * baseUrl: 'https://api.oxy.tech'\n * });\n * ```\n */\nexport async function createConfigAsync(\n overrides?: Partial<OxyConfig>\n): Promise<OxyConfig> {\n // Import postMessage utilities (dynamic to avoid circular deps)\n const { isInIframe, requestAuthFromParent } = await import('./auth/postMessage');\n\n // Start with environment variables and overrides\n let baseUrl = overrides?.baseUrl || process.env.OXY_URL;\n let apiKey = overrides?.apiKey || process.env.OXY_API_KEY;\n let projectId = overrides?.projectId || process.env.OXY_PROJECT_ID;\n\n const disableAutoAuth = overrides?.disableAutoAuth ?? false;\n const parentOrigin = overrides?.parentOrigin;\n\n // Automatic iframe detection and authentication\n if (!disableAutoAuth && isInIframe() && !apiKey) {\n if (!parentOrigin) {\n console.warn(\n '[Oxy SDK] Running in iframe without API key and no parentOrigin specified. ' +\n 'PostMessage authentication will be skipped. ' +\n 'Provide parentOrigin config to enable automatic authentication.'\n );\n } else {\n try {\n const authResult = await requestAuthFromParent({\n parentOrigin,\n timeout: overrides?.timeout || 5000,\n });\n\n apiKey = authResult.apiKey;\n if (authResult.projectId) {\n projectId = authResult.projectId;\n }\n if (authResult.baseUrl) {\n baseUrl = authResult.baseUrl;\n }\n\n console.log('[Oxy SDK] Successfully authenticated via postMessage');\n } catch (error) {\n console.error(\n '[Oxy SDK] Failed to authenticate via postMessage:',\n (error as Error).message\n );\n // Fall through to use environment variables if available\n }\n }\n }\n\n // Validation\n if (!baseUrl) {\n throw new Error('OXY_URL environment variable or baseUrl config is required');\n }\n\n if (!projectId) {\n throw new Error('OXY_PROJECT_ID environment variable or projectId config is required');\n }\n\n return {\n baseUrl: baseUrl.replace(/\\/$/, ''), // Remove trailing slash\n apiKey,\n projectId,\n branch: overrides?.branch || process.env.OXY_BRANCH,\n timeout: overrides?.timeout || 30000,\n parentOrigin,\n disableAutoAuth,\n };\n}\n","import * as duckdb from '@duckdb/duckdb-wasm';\n\nlet dbInstance: duckdb.AsyncDuckDB | null = null;\nlet connection: duckdb.AsyncDuckDBConnection | null = null;\n\n/**\n * Initialize DuckDB-WASM instance\n */\nasync function initializeDuckDB(): Promise<duckdb.AsyncDuckDB> {\n if (dbInstance) {\n return dbInstance;\n }\n\n const JSDELIVR_BUNDLES = duckdb.getJsDelivrBundles();\n\n // Select a bundle based on browser features\n const bundle = await duckdb.selectBundle(JSDELIVR_BUNDLES);\n\n const worker_url = URL.createObjectURL(\n new Blob([`importScripts(\"${bundle.mainWorker}\");`], {\n type: 'text/javascript',\n })\n );\n\n const worker = new Worker(worker_url);\n const logger = new duckdb.ConsoleLogger();\n\n dbInstance = new duckdb.AsyncDuckDB(logger, worker);\n await dbInstance.instantiate(bundle.mainModule, bundle.pthreadWorker);\n URL.revokeObjectURL(worker_url);\n\n return dbInstance;\n}\n\n/**\n * Get or create a DuckDB connection\n */\nasync function getConnection(): Promise<duckdb.AsyncDuckDBConnection> {\n if (connection) {\n return connection;\n }\n\n const db = await initializeDuckDB();\n connection = await db.connect();\n return connection;\n}\n\n/**\n * Query result interface\n */\nexport interface QueryResult {\n columns: string[];\n rows: any[][];\n rowCount: number;\n}\n\n/**\n * ParquetReader provides methods to read and query Parquet files\n */\nexport class ParquetReader {\n private tableName: string;\n private registered: boolean = false;\n\n constructor(tableName: string = 'data') {\n this.tableName = tableName;\n }\n\n /**\n * Register a Parquet file from a Blob\n *\n * @param blob - Parquet file as Blob\n *\n * @example\n * ```typescript\n * const blob = await client.getFile('data/sales.parquet');\n * const reader = new ParquetReader('sales');\n * await reader.registerParquet(blob);\n * ```\n */\n async registerParquet(blob: Blob): Promise<void> {\n const conn = await getConnection();\n const db = await initializeDuckDB();\n\n // Convert blob to Uint8Array\n const arrayBuffer = await blob.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n\n // Register the file with DuckDB\n await db.registerFileBuffer(\n `${this.tableName}.parquet`,\n uint8Array\n );\n\n // Drop table if it exists\n try {\n await conn.query(`DROP TABLE IF EXISTS ${this.tableName}`);\n } catch (e) {\n // Ignore error if table doesn't exist\n }\n\n // Create table from parquet\n await conn.query(\n `CREATE TABLE ${this.tableName} AS SELECT * FROM '${this.tableName}.parquet'`\n );\n\n this.registered = true;\n }\n\n /**\n * Execute a SQL query against the registered Parquet data\n *\n * @param sql - SQL query string\n * @returns Query result with columns and rows\n *\n * @example\n * ```typescript\n * const result = await reader.query('SELECT * FROM sales LIMIT 10');\n * console.log(result.columns);\n * console.log(result.rows);\n * ```\n */\n async query(sql: string): Promise<QueryResult> {\n if (!this.registered) {\n throw new Error('Parquet file not registered. Call registerParquet() first.');\n }\n\n const conn = await getConnection();\n const result = await conn.query(sql);\n\n const columns = result.schema.fields.map((field) => field.name);\n const rows: any[][] = [];\n\n // Convert Arrow table to rows\n for (let i = 0; i < result.numRows; i++) {\n const row: any[] = [];\n for (let j = 0; j < result.numCols; j++) {\n const col = result.getChildAt(j);\n row.push(col?.get(i));\n }\n rows.push(row);\n }\n\n return {\n columns,\n rows,\n rowCount: result.numRows,\n };\n }\n\n /**\n * Get all data from the registered table\n *\n * @param limit - Maximum number of rows to return (default: all)\n * @returns Query result\n *\n * @example\n * ```typescript\n * const allData = await reader.getAll();\n * const first100 = await reader.getAll(100);\n * ```\n */\n async getAll(limit?: number): Promise<QueryResult> {\n const limitClause = limit ? ` LIMIT ${limit}` : '';\n return this.query(`SELECT * FROM ${this.tableName}${limitClause}`);\n }\n\n /**\n * Get table schema information\n *\n * @returns Schema information\n *\n * @example\n * ```typescript\n * const schema = await reader.getSchema();\n * console.log(schema.columns); // ['id', 'name', 'sales']\n * console.log(schema.rows); // [['id', 'INTEGER'], ['name', 'VARCHAR'], ...]\n * ```\n */\n async getSchema(): Promise<QueryResult> {\n return this.query(`DESCRIBE ${this.tableName}`);\n }\n\n /**\n * Get row count\n *\n * @returns Number of rows in the table\n *\n * @example\n * ```typescript\n * const count = await reader.count();\n * console.log(`Total rows: ${count}`);\n * ```\n */\n async count(): Promise<number> {\n const result = await this.query(`SELECT COUNT(*) as count FROM ${this.tableName}`);\n return result.rows[0][0];\n }\n\n /**\n * Close and cleanup resources\n */\n async close(): Promise<void> {\n if (this.registered) {\n const conn = await getConnection();\n const db = await initializeDuckDB();\n\n // Drop the table\n try {\n await conn.query(`DROP TABLE IF EXISTS ${this.tableName}`);\n } catch (e) {\n // Ignore error\n }\n\n // Drop the registered file buffer\n try {\n await db.dropFile(`${this.tableName}.parquet`);\n } catch (e) {\n // Ignore error if file doesn't exist\n }\n\n this.registered = false;\n }\n }\n}\n\n/**\n * Helper function to quickly read a Parquet blob and execute a query\n *\n * @param blob - Parquet file as Blob\n * @param sql - SQL query to execute (optional, defaults to SELECT *)\n * @returns Query result\n *\n * @example\n * ```typescript\n * const blob = await client.getFile('data/sales.parquet');\n * const result = await queryParquet(blob, 'SELECT product, SUM(amount) as total FROM data GROUP BY product');\n * console.log(result);\n * ```\n */\nexport async function queryParquet(\n blob: Blob,\n sql?: string\n): Promise<QueryResult> {\n // Generate unique table name to avoid conflicts\n const uniqueId = `temp_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n const reader = new ParquetReader(uniqueId);\n\n await reader.registerParquet(blob);\n\n const query = sql || `SELECT * FROM ${uniqueId}`;\n const result = await reader.query(query);\n\n await reader.close();\n return result;\n}\n\n/**\n * Helper function to read Parquet file and get all data\n *\n * @param blob - Parquet file as Blob\n * @param limit - Maximum number of rows (optional)\n * @returns Query result\n *\n * @example\n * ```typescript\n * const blob = await client.getFile('data/sales.parquet');\n * const data = await readParquet(blob, 1000);\n * console.log(`Loaded ${data.rowCount} rows`);\n * ```\n */\nexport async function readParquet(\n blob: Blob,\n limit?: number\n): Promise<QueryResult> {\n // Generate unique table name to avoid conflicts\n const uniqueId = `temp_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n const reader = new ParquetReader(uniqueId);\n\n await reader.registerParquet(blob);\n\n const result = await reader.getAll(limit);\n\n await reader.close();\n return result;\n}\n","import { OxyConfig, createConfigAsync } from './config';\nimport {\n AppItem,\n AppDataResponse,\n GetDisplaysResponse,\n ApiError,\n TableData,\n} from './types';\nimport { readParquet } from './parquet';\n\n/**\n * Oxy API Client for interacting with Oxy data\n */\nexport class OxyClient {\n private config: OxyConfig;\n\n constructor(config: OxyConfig) {\n this.config = config;\n }\n\n /**\n * Creates an OxyClient instance asynchronously with support for postMessage authentication\n *\n * This is the recommended method when using the SDK in an iframe that needs to\n * obtain authentication from the parent window via postMessage.\n *\n * @param config - Optional configuration overrides\n * @returns Promise resolving to OxyClient instance\n * @throws Error if required configuration is missing\n * @throws PostMessageAuthTimeoutError if parent doesn't respond\n *\n * @example\n * ```typescript\n * // In an iframe - automatic postMessage auth\n * const client = await OxyClient.create({\n * parentOrigin: 'https://app.example.com',\n * projectId: 'my-project-id',\n * baseUrl: 'https://api.oxy.tech'\n * });\n *\n * // Use the client normally\n * const apps = await client.listApps();\n * ```\n */\n static async create(config?: Partial<OxyConfig>): Promise<OxyClient> {\n const resolvedConfig = await createConfigAsync(config);\n return new OxyClient(resolvedConfig);\n }\n\n /**\n * Encodes a file path to base64 for use in API URLs\n */\n private encodePathBase64(path: string): string {\n if (typeof Buffer !== 'undefined') {\n // Node.js environment\n return Buffer.from(path).toString('base64');\n } else {\n // Browser environment\n return btoa(path);\n }\n }\n\n /**\n * Makes an authenticated HTTP request to the Oxy API\n */\n private async request<T>(\n endpoint: string,\n options: RequestInit = {}\n ): Promise<T> {\n const url = `${this.config.baseUrl}${endpoint}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...((options.headers as Record<string, string>) || {}),\n };\n\n // Only add Authorization header if API key is provided (optional for local dev)\n if (this.config.apiKey) {\n headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout || 30000);\n\n try {\n const response = await fetch(url, {\n ...options,\n headers,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unknown error');\n const error: ApiError = {\n message: `API request failed: ${response.statusText}`,\n status: response.status,\n details: errorText,\n };\n throw error;\n }\n\n // Handle binary responses\n const acceptHeader =\n typeof options.headers === 'object' && options.headers !== null\n ? (options.headers as Record<string, string>)['Accept']\n : undefined;\n if (acceptHeader === 'application/octet-stream') {\n return response.blob() as Promise<T>;\n }\n\n return response.json();\n } catch (error: any) {\n clearTimeout(timeoutId);\n\n if (error.name === 'AbortError') {\n throw new Error(`Request timeout after ${this.config.timeout || 30000}ms`);\n }\n\n throw error;\n }\n }\n\n /**\n * Builds query parameters including optional branch\n */\n private buildQueryParams(additionalParams: Record<string, string> = {}): string {\n const params: Record<string, string> = { ...additionalParams };\n\n if (this.config.branch) {\n params.branch = this.config.branch;\n }\n\n const searchParams = new URLSearchParams(params);\n const queryString = searchParams.toString();\n return queryString ? `?${queryString}` : '';\n }\n\n /**\n * Lists all apps in the project\n *\n * @returns Array of app items\n *\n * @example\n * ```typescript\n * const apps = await client.listApps();\n * console.log('Available apps:', apps);\n * ```\n */\n async listApps(): Promise<AppItem[]> {\n const query = this.buildQueryParams();\n return this.request<AppItem[]>(`/${this.config.projectId}/app${query}`);\n }\n\n /**\n * Gets data for a specific app\n *\n * @param appPath - Relative path to the app file (e.g., 'my-app.app.yml')\n * @returns App data response\n *\n * @example\n * ```typescript\n * const data = await client.getAppData('dashboard.app.yml');\n * if (data.error) {\n * console.error('Error:', data.error);\n * } else {\n * console.log('App data:', data.data);\n * }\n * ```\n */\n async getAppData(appPath: string): Promise<AppDataResponse> {\n const pathb64 = this.encodePathBase64(appPath);\n const query = this.buildQueryParams();\n return this.request<AppDataResponse>(\n `/${this.config.projectId}/app/${pathb64}${query}`\n );\n }\n\n /**\n * Runs an app and returns fresh data (bypasses cache)\n *\n * @param appPath - Relative path to the app file\n * @returns App data response\n *\n * @example\n * ```typescript\n * const data = await client.runApp('dashboard.app.yml');\n * console.log('Fresh app data:', data.data);\n * ```\n */\n async runApp(appPath: string): Promise<AppDataResponse> {\n const pathb64 = this.encodePathBase64(appPath);\n const query = this.buildQueryParams();\n return this.request<AppDataResponse>(\n `/${this.config.projectId}/app/${pathb64}/run${query}`,\n { method: 'POST' }\n );\n }\n\n /**\n * Gets display configurations for an app\n *\n * @param appPath - Relative path to the app file\n * @returns Display configurations with potential errors\n *\n * @example\n * ```typescript\n * const displays = await client.getDisplays('dashboard.app.yml');\n * displays.displays.forEach(d => {\n * if (d.error) {\n * console.error('Display error:', d.error);\n * } else {\n * console.log('Display:', d.display);\n * }\n * });\n * ```\n */\n async getDisplays(appPath: string): Promise<GetDisplaysResponse> {\n const pathb64 = this.encodePathBase64(appPath);\n const query = this.buildQueryParams();\n return this.request<GetDisplaysResponse>(\n `/${this.config.projectId}/app/${pathb64}/displays${query}`\n );\n }\n\n /**\n * Gets a file from the app state directory (e.g., generated charts, images)\n *\n * This is useful for retrieving generated assets like charts, images, or other\n * files produced by app workflows and stored in the state directory.\n *\n * @param filePath - Relative path to the file in state directory\n * @returns Blob containing the file data\n *\n * @example\n * ```typescript\n * // Get a generated chart image\n * const blob = await client.getFile('charts/sales-chart.png');\n * const imageUrl = URL.createObjectURL(blob);\n *\n * // Use in an img tag\n * document.querySelector('img').src = imageUrl;\n * ```\n *\n * @example\n * ```typescript\n * // Download a file\n * const blob = await client.getFile('exports/data.csv');\n * const a = document.createElement('a');\n * a.href = URL.createObjectURL(blob);\n * a.download = 'data.csv';\n * a.click();\n * ```\n */\n async getFile(filePath: string): Promise<Blob> {\n const pathb64 = this.encodePathBase64(filePath);\n const query = this.buildQueryParams();\n return this.request<Blob>(\n `/${this.config.projectId}/app/file/${pathb64}${query}`,\n {\n headers: {\n 'Accept': 'application/octet-stream',\n },\n }\n );\n }\n\n /**\n * Gets a file URL for direct browser access\n *\n * This returns a URL that can be used directly in img tags, fetch calls, etc.\n * The URL includes authentication via query parameters.\n *\n * @param filePath - Relative path to the file in state directory\n * @returns Full URL to the file\n *\n * @example\n * ```typescript\n * const imageUrl = client.getFileUrl('charts/sales-chart.png');\n *\n * // Use directly in img tag (in environments where query-based auth is supported)\n * document.querySelector('img').src = imageUrl;\n * ```\n */\n getFileUrl(filePath: string): string {\n const pathb64 = this.encodePathBase64(filePath);\n const query = this.buildQueryParams();\n return `${this.config.baseUrl}/${this.config.projectId}/app/file/${pathb64}${query}`;\n }\n\n /**\n * Fetches a parquet file and parses it into table data\n *\n * @param filePath - Relative path to the parquet file\n * @param limit - Maximum number of rows to return (default: 100)\n * @returns TableData with columns and rows\n *\n * @example\n * ```typescript\n * const tableData = await client.getTableData('data/sales.parquet', 50);\n * console.log(tableData.columns);\n * console.log(tableData.rows);\n * console.log(`Total rows: ${tableData.total_rows}`);\n * ```\n */\n async getTableData(filePath: string, limit: number = 100): Promise<TableData> {\n const blob = await this.getFile(filePath);\n const result = await readParquet(blob, limit);\n\n return {\n columns: result.columns,\n rows: result.rows,\n total_rows: result.rowCount,\n };\n }\n}\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -164,7 +164,7 @@ interface OxyAuthResponseMessage {
164
164
  type: 'OXY_AUTH_RESPONSE';
165
165
  version: '1.0';
166
166
  requestId: string;
167
- apiKey: string;
167
+ apiKey?: string;
168
168
  projectId?: string;
169
169
  baseUrl?: string;
170
170
  }
@@ -183,7 +183,7 @@ interface PostMessageAuthOptions {
183
183
  * Result from successful postMessage authentication
184
184
  */
185
185
  interface PostMessageAuthResult {
186
- apiKey: string;
186
+ apiKey?: string;
187
187
  projectId?: string;
188
188
  baseUrl?: string;
189
189
  source: 'postmessage';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/config.ts","../src/types.ts","../src/client.ts","../src/parquet.ts","../src/auth/postMessage.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/config.ts","../src/types.ts","../src/client.ts","../src/parquet.ts","../src/auth/postMessage.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -164,7 +164,7 @@ interface OxyAuthResponseMessage {
164
164
  type: 'OXY_AUTH_RESPONSE';
165
165
  version: '1.0';
166
166
  requestId: string;
167
- apiKey: string;
167
+ apiKey?: string;
168
168
  projectId?: string;
169
169
  baseUrl?: string;
170
170
  }
@@ -183,7 +183,7 @@ interface PostMessageAuthOptions {
183
183
  * Result from successful postMessage authentication
184
184
  */
185
185
  interface PostMessageAuthResult {
186
- apiKey: string;
186
+ apiKey?: string;
187
187
  projectId?: string;
188
188
  baseUrl?: string;
189
189
  source: 'postmessage';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/config.ts","../src/types.ts","../src/client.ts","../src/parquet.ts","../src/auth/postMessage.ts"],"sourcesContent":[],"mappings":";;;AAGA;AAsDA;AAAiD,UAtDhC,SAAA,CAsDgC;EAAR;;;EAyDnB,OAAA,EAAA,MAAA;EACA;;;EACnB,MAAA,CAAA,EAAA,MAAA;EAAO;;;;ECjHO;AAQjB;AAQA;EAMY,MAAA,CAAA,EAAA,MAAA;EAKK;AAQjB;AAQA;EAQiB,OAAA,CAAA,EAAA,MAAA;EAgBA;AAajB;AAUA;AAYA;AAYA;AAcA;EAoBa,YAAA,CAAA,EAAA,MAAA;EAeA;AAeb;;;;ACxKA;;;;;;;;;;;;;;AAkP2C,iBFtM3B,YAAA,CEsM2B,SAAA,CAAA,EFtMF,OEsME,CFtMM,SEsMN,CAAA,CAAA,EFtMmB,SEsMnB;;;;;;;;AC7M3C;AASA;;;;;;;;;;;;AAoLA;;;;;AA+BA;;;;;;;;ACpPgB,iBJwFM,iBAAA,CIxFI,SAAA,CAAA,EJyFZ,OIzFY,CJyFJ,SIzFI,CAAA,CAAA,EJ0FvB,OI1FuB,CJ0Ff,SI1Fe,CAAA;;;;AJvB1B;AAsDA;AAAiD,UCtDhC,OAAA,CDsDgC;EAAR,IAAA,EAAA,MAAA;EAAqB,IAAA,EAAA,MAAA;;AAyD9D;;;AAEW,UCzGM,aAAA,CDyGN;EAAR,SAAA,EAAA,MAAA;;;;;ACjHH;AAQiB,UAQA,SAAA,CARa;EAQb,OAAA,EAAA,MAAS,EAAA;EAMd,IAAA,EAAA,GAAA,EAAA,EAAA;EAKK,UAAA,CAAA,EAAA,MAAe;AAQhC;AAQiB,KArBL,aAAA,GAAgB,MAqBA,CAAA,MAAA,EArBe,aAqBf,CAAA;AAQ5B;AAgBA;AAaA;AAUiB,UA/DA,eAAA,CA+DsB;EAYtB,IAAA,EA1ET,aA0ES,GAAA,IAAsB;EAYtB,KAAA,EAAA,MAAA,GAAA,IAAA;AAcjB;AAoBA;AAeA;AAeA;UA/IiB,gBAAA;YACL;;AC1BZ;;;;AA+B4D,UDE3C,WAAA,CCF2C;EAAR,IAAA,EAAA,MAAA;EA0GxB,OAAA,EAAA,GAAA;;;;;AAyCK,UDzIhB,mBAAA,CCyIgB;EA2Ba,QAAA,EDnKlC,gBCmKkC,EAAA;;ACxK9C;AASA;;AAoBqC,UFTpB,aAAA,CESoB;EA0CD,OAAA,EAAA,MAAA,EAAA;EAAR,IAAA,EAAA,GAAA,EAAA,EAAA;EAwCY,QAAA,EAAA,MAAA;;;;;;;AA8ExC;AACQ,UF7JS,qBAAA,CE6JT;EAEG,IAAA,EAAA,kBAAA;EAAR,OAAA,EAAA,KAAA;EAAO,SAAA,EAAA,MAAA;EA4BY,SAAA,EAAA,MAAW;;;;;UFjLhB,sBAAA;;;EGnED,SAAA,EAAA,MAAU;EAwKJ,MAAA,EAAA,MAAA;EACX,SAAA,CAAA,EAAA,MAAA;EACA,OAAA,CAAA,EAAA,MAAA;;;;;UH3FM,sBAAA;;;;;;;;;;;UAYA,qBAAA;;;;;;;;;;;;cAcJ,2BAAA,SAAoC,KAAA;;;;;;cAoBpC,iCAAA,SAA0C,KAAA;;;;;;cAe1C,+BAAA,SAAwC,KAAA;;;;;;cAexC,mCAAA,SAA4C,KAAA;;;;;AD5HzD;;;AAA8D,cE5CjD,SAAA,CF4CiD;EAAS,QAAA,MAAA;EAyDjD,WAAA,CAAA,MAAA,EElGA,SFkGiB;EACjB;;;;;;;;AChHtB;AAQA;AAQA;AAMA;AAKA;AAQA;AAQA;AAQA;AAgBA;AAaA;AAUA;AAYA;AAYA;AAcA;AAoBA;AAeA;EAea,OAAA,MAAA,CAAA,MAAoC,CAApC,ECzIkB,ODyIlB,CCzI0B,SDyIU,CAAA,CAAA,ECzIG,ODyIK,CCzIG,SDyIE,CAAA;;;;ECxKjD,QAAA,gBAAS;EAGA;;;EA4BsC,QAAA,OAAA;EAAR;;;EA+HP,QAAA,gBAAA;EAAR;;;;;;;;;;;cArBjB,QAAQ;;ACpG5B;AASA;;;;;;;;;;;;AAoLA;;EAGW,UAAA,CAAA,OAAA,EAAA,MAAA,CAAA,EDvE0B,OCuE1B,CDvEkC,eCuElC,CAAA;EAAR;;AA4BH;;;;;;;;ACpPA;AAwKA;EACW,MAAA,CAAA,OAAA,EAAA,MAAA,CAAA,EFJsB,OEItB,CFJ8B,eEI9B,CAAA;EACA;;;;;;;;;;;;;;;;;;gCFsB2B,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAqCX,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kDAmDkB,QAAQ;;;;;AF/SrE;AAsDA;AAAiD,UGPhC,WAAA,CHOgC;EAAR,OAAA,EAAA,MAAA,EAAA;EAAqB,IAAA,EAAA,GAAA,EAAA,EAAA;EAAS,QAAA,EAAA,MAAA;AAyDvE;;;;AAEG,cGzDU,aAAA,CHyDV;EAAO,QAAA,SAAA;;;;ACjHV;AAQA;AAQA;AAMA;AAKA;AAQA;AAQA;AAQA;AAgBA;AAaA;AAUA;EAYiB,eAAA,CAAA,IAAA,EE1Ba,IF0BS,CAAA,EE1BF,OF0BE,CAAA,IAAA,CAAA;EAYtB;AAcjB;AAoBA;AAeA;AAeA;;;;ACxKA;;;;;EA+BoD,KAAA,CAAA,GAAA,EAAA,MAAA,CAAA,EC6ExB,OD7EwB,CC6EhB,WD7EgB,CAAA;EA0GxB;;;;;;;;;;;;EA4JwC,MAAA,CAAA,KAAA,CAAA,EAAA,MAAA,CAAA,ECjJpC,ODiJoC,CCjJ5B,WDiJ4B,CAAA;;;;AChQpE;AASA;;;;;;;;EAuHqB,SAAA,CAAA,CAAA,EAAA,OAAA,CAAQ,WAAR,CAAA;EAeJ;;;AA8CjB;;;;;AA+BA;;;EAGG,KAAA,CAAA,CAAA,EAhFc,OAgFd,CAAA,MAAA,CAAA;EAAO;;;WAxEO;AC/KjB;AAwKA;;;;;;;;;;;;;;iBD6CsB,YAAA,OACd,qBAEL,QAAQ;;;;;;;;;;;;;;;iBA4BW,WAAA,OACd,uBAEL,QAAQ;;;AH/JX;;;;;AAEU,iBI1FM,UAAA,CAAA,CJ0FN,EAAA,OAAA;ACXV;AAYA;AAcA;AAoBA;AAeA;AAeA;;;;ACxKA;;;;;;;;;;;;;AA6MsC,iBExBhB,qBAAA,CFwBgB,OAAA,CAAA,EEvB3B,sBFuB2B,CAAA,EEtBnC,OFsBmC,CEtB3B,qBFsB2B,CAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/config.ts","../src/types.ts","../src/client.ts","../src/parquet.ts","../src/auth/postMessage.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // @oxy/sdk - TypeScript SDK for Oxy data platform
2
- import { a as PostMessageAuthInvalidOriginError, c as PostMessageAuthTimeoutError, n as isInIframe, o as PostMessageAuthInvalidResponseError, r as requestAuthFromParent, s as PostMessageAuthNotInIframeError } from "./postMessage-Dq9lXKK0.mjs";
2
+ import { a as PostMessageAuthInvalidOriginError, c as PostMessageAuthTimeoutError, n as isInIframe, o as PostMessageAuthInvalidResponseError, r as requestAuthFromParent, s as PostMessageAuthNotInIframeError } from "./postMessage-DLGITn0e.mjs";
3
3
  import * as duckdb from "@duckdb/duckdb-wasm";
4
4
 
5
5
  //#region src/config.ts
@@ -66,7 +66,7 @@ function createConfig(overrides) {
66
66
  * ```
67
67
  */
68
68
  async function createConfigAsync(overrides) {
69
- const { isInIframe: isInIframe$1, requestAuthFromParent: requestAuthFromParent$1 } = await import("./postMessage-DBjb4M8-.mjs");
69
+ const { isInIframe: isInIframe$1, requestAuthFromParent: requestAuthFromParent$1 } = await import("./postMessage-DwfY0HM5.mjs");
70
70
  let baseUrl = overrides?.baseUrl || process.env.OXY_URL;
71
71
  let apiKey = overrides?.apiKey || process.env.OXY_API_KEY;
72
72
  let projectId = overrides?.projectId || process.env.OXY_PROJECT_ID;
@@ -348,7 +348,7 @@ var OxyClient = class OxyClient {
348
348
  "Content-Type": "application/json",
349
349
  ...options.headers || {}
350
350
  };
351
- if (this.config.apiKey) headers["X-API-Key"] = `${this.config.apiKey}`;
351
+ if (this.config.apiKey) headers["Authorization"] = `Bearer ${this.config.apiKey}`;
352
352
  const controller = new AbortController();
353
353
  const timeoutId = setTimeout(() => controller.abort(), this.config.timeout || 3e4);
354
354
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["isInIframe","requestAuthFromParent"],"sources":["../src/config.ts","../src/parquet.ts","../src/client.ts"],"sourcesContent":["/**\n * Configuration for the Oxy SDK\n */\nexport interface OxyConfig {\n /**\n * Base URL of the Oxy API (e.g., 'https://api.oxy.tech' or 'http://localhost:3000')\n */\n baseUrl: string;\n\n /**\n * API key for authentication (optional for local development)\n */\n apiKey?: string;\n\n /**\n * Project ID (UUID)\n */\n projectId: string;\n\n /**\n * Optional branch name (defaults to current branch if not specified)\n */\n branch?: string;\n\n /**\n * Request timeout in milliseconds (default: 30000)\n */\n timeout?: number;\n\n /**\n * Parent window origin for postMessage authentication (iframe scenarios)\n * Required when using postMessage auth for security.\n * Example: 'https://app.example.com'\n * Use '*' only in development!\n */\n parentOrigin?: string;\n\n /**\n * Disable automatic postMessage authentication even if in iframe\n * Set to true if you want to provide API key manually in iframe context\n */\n disableAutoAuth?: boolean;\n}\n\n/**\n * Creates an Oxy configuration from environment variables\n *\n * Environment variables:\n * - OXY_URL: Base URL of the Oxy API\n * - OXY_API_KEY: API key for authentication\n * - OXY_PROJECT_ID: Project ID (UUID)\n * - OXY_BRANCH: (Optional) Branch name\n *\n * @param overrides - Optional configuration overrides\n * @returns OxyConfig object\n * @throws Error if required environment variables are missing\n */\nexport function createConfig(overrides?: Partial<OxyConfig>): OxyConfig {\n const baseUrl = overrides?.baseUrl || process.env.OXY_URL;\n const apiKey = overrides?.apiKey || process.env.OXY_API_KEY;\n const projectId = overrides?.projectId || process.env.OXY_PROJECT_ID;\n\n if (!baseUrl) {\n throw new Error('OXY_URL environment variable or baseUrl config is required');\n }\n\n if (!projectId) {\n throw new Error('OXY_PROJECT_ID environment variable or projectId config is required');\n }\n\n return {\n baseUrl: baseUrl.replace(/\\/$/, ''), // Remove trailing slash\n apiKey,\n projectId,\n branch: overrides?.branch || process.env.OXY_BRANCH,\n timeout: overrides?.timeout || 30000,\n parentOrigin: overrides?.parentOrigin,\n disableAutoAuth: overrides?.disableAutoAuth,\n };\n}\n\n/**\n * Creates an Oxy configuration asynchronously with support for postMessage authentication\n *\n * This is the recommended method for iframe scenarios where authentication\n * needs to be obtained from the parent window via postMessage.\n *\n * When running in an iframe without an API key, this function will:\n * 1. Detect the iframe context\n * 2. Send an authentication request to the parent window\n * 3. Wait for the parent to respond with credentials\n * 4. Return the configured client\n *\n * Environment variables (fallback):\n * - OXY_URL: Base URL of the Oxy API\n * - OXY_API_KEY: API key for authentication\n * - OXY_PROJECT_ID: Project ID (UUID)\n * - OXY_BRANCH: (Optional) Branch name\n *\n * @param overrides - Optional configuration overrides\n * @returns Promise resolving to OxyConfig object\n * @throws Error if required configuration is missing\n * @throws PostMessageAuthTimeoutError if parent doesn't respond\n *\n * @example\n * ```typescript\n * // Automatic iframe detection and authentication\n * const config = await createConfigAsync({\n * parentOrigin: 'https://app.example.com',\n * projectId: 'my-project-id',\n * baseUrl: 'https://api.oxy.tech'\n * });\n * ```\n */\nexport async function createConfigAsync(\n overrides?: Partial<OxyConfig>\n): Promise<OxyConfig> {\n // Import postMessage utilities (dynamic to avoid circular deps)\n const { isInIframe, requestAuthFromParent } = await import('./auth/postMessage');\n\n // Start with environment variables and overrides\n let baseUrl = overrides?.baseUrl || process.env.OXY_URL;\n let apiKey = overrides?.apiKey || process.env.OXY_API_KEY;\n let projectId = overrides?.projectId || process.env.OXY_PROJECT_ID;\n\n const disableAutoAuth = overrides?.disableAutoAuth ?? false;\n const parentOrigin = overrides?.parentOrigin;\n\n // Automatic iframe detection and authentication\n if (!disableAutoAuth && isInIframe() && !apiKey) {\n if (!parentOrigin) {\n console.warn(\n '[Oxy SDK] Running in iframe without API key and no parentOrigin specified. ' +\n 'PostMessage authentication will be skipped. ' +\n 'Provide parentOrigin config to enable automatic authentication.'\n );\n } else {\n try {\n const authResult = await requestAuthFromParent({\n parentOrigin,\n timeout: overrides?.timeout || 5000,\n });\n\n apiKey = authResult.apiKey;\n if (authResult.projectId) {\n projectId = authResult.projectId;\n }\n if (authResult.baseUrl) {\n baseUrl = authResult.baseUrl;\n }\n\n console.log('[Oxy SDK] Successfully authenticated via postMessage');\n } catch (error) {\n console.error(\n '[Oxy SDK] Failed to authenticate via postMessage:',\n (error as Error).message\n );\n // Fall through to use environment variables if available\n }\n }\n }\n\n // Validation\n if (!baseUrl) {\n throw new Error('OXY_URL environment variable or baseUrl config is required');\n }\n\n if (!projectId) {\n throw new Error('OXY_PROJECT_ID environment variable or projectId config is required');\n }\n\n return {\n baseUrl: baseUrl.replace(/\\/$/, ''), // Remove trailing slash\n apiKey,\n projectId,\n branch: overrides?.branch || process.env.OXY_BRANCH,\n timeout: overrides?.timeout || 30000,\n parentOrigin,\n disableAutoAuth,\n };\n}\n","import * as duckdb from '@duckdb/duckdb-wasm';\n\nlet dbInstance: duckdb.AsyncDuckDB | null = null;\nlet connection: duckdb.AsyncDuckDBConnection | null = null;\n\n/**\n * Initialize DuckDB-WASM instance\n */\nasync function initializeDuckDB(): Promise<duckdb.AsyncDuckDB> {\n if (dbInstance) {\n return dbInstance;\n }\n\n const JSDELIVR_BUNDLES = duckdb.getJsDelivrBundles();\n\n // Select a bundle based on browser features\n const bundle = await duckdb.selectBundle(JSDELIVR_BUNDLES);\n\n const worker_url = URL.createObjectURL(\n new Blob([`importScripts(\"${bundle.mainWorker}\");`], {\n type: 'text/javascript',\n })\n );\n\n const worker = new Worker(worker_url);\n const logger = new duckdb.ConsoleLogger();\n\n dbInstance = new duckdb.AsyncDuckDB(logger, worker);\n await dbInstance.instantiate(bundle.mainModule, bundle.pthreadWorker);\n URL.revokeObjectURL(worker_url);\n\n return dbInstance;\n}\n\n/**\n * Get or create a DuckDB connection\n */\nasync function getConnection(): Promise<duckdb.AsyncDuckDBConnection> {\n if (connection) {\n return connection;\n }\n\n const db = await initializeDuckDB();\n connection = await db.connect();\n return connection;\n}\n\n/**\n * Query result interface\n */\nexport interface QueryResult {\n columns: string[];\n rows: any[][];\n rowCount: number;\n}\n\n/**\n * ParquetReader provides methods to read and query Parquet files\n */\nexport class ParquetReader {\n private tableName: string;\n private registered: boolean = false;\n\n constructor(tableName: string = 'data') {\n this.tableName = tableName;\n }\n\n /**\n * Register a Parquet file from a Blob\n *\n * @param blob - Parquet file as Blob\n *\n * @example\n * ```typescript\n * const blob = await client.getFile('data/sales.parquet');\n * const reader = new ParquetReader('sales');\n * await reader.registerParquet(blob);\n * ```\n */\n async registerParquet(blob: Blob): Promise<void> {\n const conn = await getConnection();\n const db = await initializeDuckDB();\n\n // Convert blob to Uint8Array\n const arrayBuffer = await blob.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n\n // Register the file with DuckDB\n await db.registerFileBuffer(\n `${this.tableName}.parquet`,\n uint8Array\n );\n\n // Drop table if it exists\n try {\n await conn.query(`DROP TABLE IF EXISTS ${this.tableName}`);\n } catch (e) {\n // Ignore error if table doesn't exist\n }\n\n // Create table from parquet\n await conn.query(\n `CREATE TABLE ${this.tableName} AS SELECT * FROM '${this.tableName}.parquet'`\n );\n\n this.registered = true;\n }\n\n /**\n * Execute a SQL query against the registered Parquet data\n *\n * @param sql - SQL query string\n * @returns Query result with columns and rows\n *\n * @example\n * ```typescript\n * const result = await reader.query('SELECT * FROM sales LIMIT 10');\n * console.log(result.columns);\n * console.log(result.rows);\n * ```\n */\n async query(sql: string): Promise<QueryResult> {\n if (!this.registered) {\n throw new Error('Parquet file not registered. Call registerParquet() first.');\n }\n\n const conn = await getConnection();\n const result = await conn.query(sql);\n\n const columns = result.schema.fields.map((field) => field.name);\n const rows: any[][] = [];\n\n // Convert Arrow table to rows\n for (let i = 0; i < result.numRows; i++) {\n const row: any[] = [];\n for (let j = 0; j < result.numCols; j++) {\n const col = result.getChildAt(j);\n row.push(col?.get(i));\n }\n rows.push(row);\n }\n\n return {\n columns,\n rows,\n rowCount: result.numRows,\n };\n }\n\n /**\n * Get all data from the registered table\n *\n * @param limit - Maximum number of rows to return (default: all)\n * @returns Query result\n *\n * @example\n * ```typescript\n * const allData = await reader.getAll();\n * const first100 = await reader.getAll(100);\n * ```\n */\n async getAll(limit?: number): Promise<QueryResult> {\n const limitClause = limit ? ` LIMIT ${limit}` : '';\n return this.query(`SELECT * FROM ${this.tableName}${limitClause}`);\n }\n\n /**\n * Get table schema information\n *\n * @returns Schema information\n *\n * @example\n * ```typescript\n * const schema = await reader.getSchema();\n * console.log(schema.columns); // ['id', 'name', 'sales']\n * console.log(schema.rows); // [['id', 'INTEGER'], ['name', 'VARCHAR'], ...]\n * ```\n */\n async getSchema(): Promise<QueryResult> {\n return this.query(`DESCRIBE ${this.tableName}`);\n }\n\n /**\n * Get row count\n *\n * @returns Number of rows in the table\n *\n * @example\n * ```typescript\n * const count = await reader.count();\n * console.log(`Total rows: ${count}`);\n * ```\n */\n async count(): Promise<number> {\n const result = await this.query(`SELECT COUNT(*) as count FROM ${this.tableName}`);\n return result.rows[0][0];\n }\n\n /**\n * Close and cleanup resources\n */\n async close(): Promise<void> {\n if (this.registered) {\n const conn = await getConnection();\n const db = await initializeDuckDB();\n\n // Drop the table\n try {\n await conn.query(`DROP TABLE IF EXISTS ${this.tableName}`);\n } catch (e) {\n // Ignore error\n }\n\n // Drop the registered file buffer\n try {\n await db.dropFile(`${this.tableName}.parquet`);\n } catch (e) {\n // Ignore error if file doesn't exist\n }\n\n this.registered = false;\n }\n }\n}\n\n/**\n * Helper function to quickly read a Parquet blob and execute a query\n *\n * @param blob - Parquet file as Blob\n * @param sql - SQL query to execute (optional, defaults to SELECT *)\n * @returns Query result\n *\n * @example\n * ```typescript\n * const blob = await client.getFile('data/sales.parquet');\n * const result = await queryParquet(blob, 'SELECT product, SUM(amount) as total FROM data GROUP BY product');\n * console.log(result);\n * ```\n */\nexport async function queryParquet(\n blob: Blob,\n sql?: string\n): Promise<QueryResult> {\n // Generate unique table name to avoid conflicts\n const uniqueId = `temp_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n const reader = new ParquetReader(uniqueId);\n\n await reader.registerParquet(blob);\n\n const query = sql || `SELECT * FROM ${uniqueId}`;\n const result = await reader.query(query);\n\n await reader.close();\n return result;\n}\n\n/**\n * Helper function to read Parquet file and get all data\n *\n * @param blob - Parquet file as Blob\n * @param limit - Maximum number of rows (optional)\n * @returns Query result\n *\n * @example\n * ```typescript\n * const blob = await client.getFile('data/sales.parquet');\n * const data = await readParquet(blob, 1000);\n * console.log(`Loaded ${data.rowCount} rows`);\n * ```\n */\nexport async function readParquet(\n blob: Blob,\n limit?: number\n): Promise<QueryResult> {\n // Generate unique table name to avoid conflicts\n const uniqueId = `temp_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n const reader = new ParquetReader(uniqueId);\n\n await reader.registerParquet(blob);\n\n const result = await reader.getAll(limit);\n\n await reader.close();\n return result;\n}\n","import { OxyConfig, createConfigAsync } from './config';\nimport {\n AppItem,\n AppDataResponse,\n GetDisplaysResponse,\n ApiError,\n TableData,\n} from './types';\nimport { readParquet } from './parquet';\n\n/**\n * Oxy API Client for interacting with Oxy data\n */\nexport class OxyClient {\n private config: OxyConfig;\n\n constructor(config: OxyConfig) {\n this.config = config;\n }\n\n /**\n * Creates an OxyClient instance asynchronously with support for postMessage authentication\n *\n * This is the recommended method when using the SDK in an iframe that needs to\n * obtain authentication from the parent window via postMessage.\n *\n * @param config - Optional configuration overrides\n * @returns Promise resolving to OxyClient instance\n * @throws Error if required configuration is missing\n * @throws PostMessageAuthTimeoutError if parent doesn't respond\n *\n * @example\n * ```typescript\n * // In an iframe - automatic postMessage auth\n * const client = await OxyClient.create({\n * parentOrigin: 'https://app.example.com',\n * projectId: 'my-project-id',\n * baseUrl: 'https://api.oxy.tech'\n * });\n *\n * // Use the client normally\n * const apps = await client.listApps();\n * ```\n */\n static async create(config?: Partial<OxyConfig>): Promise<OxyClient> {\n const resolvedConfig = await createConfigAsync(config);\n return new OxyClient(resolvedConfig);\n }\n\n /**\n * Encodes a file path to base64 for use in API URLs\n */\n private encodePathBase64(path: string): string {\n if (typeof Buffer !== 'undefined') {\n // Node.js environment\n return Buffer.from(path).toString('base64');\n } else {\n // Browser environment\n return btoa(path);\n }\n }\n\n /**\n * Makes an authenticated HTTP request to the Oxy API\n */\n private async request<T>(\n endpoint: string,\n options: RequestInit = {}\n ): Promise<T> {\n const url = `${this.config.baseUrl}${endpoint}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...((options.headers as Record<string, string>) || {}),\n };\n\n // Only add Authorization header if API key is provided (optional for local dev)\n if (this.config.apiKey) {\n headers['X-API-Key'] = `${this.config.apiKey}`;\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout || 30000);\n\n try {\n const response = await fetch(url, {\n ...options,\n headers,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unknown error');\n const error: ApiError = {\n message: `API request failed: ${response.statusText}`,\n status: response.status,\n details: errorText,\n };\n throw error;\n }\n\n // Handle binary responses\n const acceptHeader =\n typeof options.headers === 'object' && options.headers !== null\n ? (options.headers as Record<string, string>)['Accept']\n : undefined;\n if (acceptHeader === 'application/octet-stream') {\n return response.blob() as Promise<T>;\n }\n\n return response.json();\n } catch (error: any) {\n clearTimeout(timeoutId);\n\n if (error.name === 'AbortError') {\n throw new Error(`Request timeout after ${this.config.timeout || 30000}ms`);\n }\n\n throw error;\n }\n }\n\n /**\n * Builds query parameters including optional branch\n */\n private buildQueryParams(additionalParams: Record<string, string> = {}): string {\n const params: Record<string, string> = { ...additionalParams };\n\n if (this.config.branch) {\n params.branch = this.config.branch;\n }\n\n const searchParams = new URLSearchParams(params);\n const queryString = searchParams.toString();\n return queryString ? `?${queryString}` : '';\n }\n\n /**\n * Lists all apps in the project\n *\n * @returns Array of app items\n *\n * @example\n * ```typescript\n * const apps = await client.listApps();\n * console.log('Available apps:', apps);\n * ```\n */\n async listApps(): Promise<AppItem[]> {\n const query = this.buildQueryParams();\n return this.request<AppItem[]>(`/${this.config.projectId}/app${query}`);\n }\n\n /**\n * Gets data for a specific app\n *\n * @param appPath - Relative path to the app file (e.g., 'my-app.app.yml')\n * @returns App data response\n *\n * @example\n * ```typescript\n * const data = await client.getAppData('dashboard.app.yml');\n * if (data.error) {\n * console.error('Error:', data.error);\n * } else {\n * console.log('App data:', data.data);\n * }\n * ```\n */\n async getAppData(appPath: string): Promise<AppDataResponse> {\n const pathb64 = this.encodePathBase64(appPath);\n const query = this.buildQueryParams();\n return this.request<AppDataResponse>(\n `/${this.config.projectId}/app/${pathb64}${query}`\n );\n }\n\n /**\n * Runs an app and returns fresh data (bypasses cache)\n *\n * @param appPath - Relative path to the app file\n * @returns App data response\n *\n * @example\n * ```typescript\n * const data = await client.runApp('dashboard.app.yml');\n * console.log('Fresh app data:', data.data);\n * ```\n */\n async runApp(appPath: string): Promise<AppDataResponse> {\n const pathb64 = this.encodePathBase64(appPath);\n const query = this.buildQueryParams();\n return this.request<AppDataResponse>(\n `/${this.config.projectId}/app/${pathb64}/run${query}`,\n { method: 'POST' }\n );\n }\n\n /**\n * Gets display configurations for an app\n *\n * @param appPath - Relative path to the app file\n * @returns Display configurations with potential errors\n *\n * @example\n * ```typescript\n * const displays = await client.getDisplays('dashboard.app.yml');\n * displays.displays.forEach(d => {\n * if (d.error) {\n * console.error('Display error:', d.error);\n * } else {\n * console.log('Display:', d.display);\n * }\n * });\n * ```\n */\n async getDisplays(appPath: string): Promise<GetDisplaysResponse> {\n const pathb64 = this.encodePathBase64(appPath);\n const query = this.buildQueryParams();\n return this.request<GetDisplaysResponse>(\n `/${this.config.projectId}/app/${pathb64}/displays${query}`\n );\n }\n\n /**\n * Gets a file from the app state directory (e.g., generated charts, images)\n *\n * This is useful for retrieving generated assets like charts, images, or other\n * files produced by app workflows and stored in the state directory.\n *\n * @param filePath - Relative path to the file in state directory\n * @returns Blob containing the file data\n *\n * @example\n * ```typescript\n * // Get a generated chart image\n * const blob = await client.getFile('charts/sales-chart.png');\n * const imageUrl = URL.createObjectURL(blob);\n *\n * // Use in an img tag\n * document.querySelector('img').src = imageUrl;\n * ```\n *\n * @example\n * ```typescript\n * // Download a file\n * const blob = await client.getFile('exports/data.csv');\n * const a = document.createElement('a');\n * a.href = URL.createObjectURL(blob);\n * a.download = 'data.csv';\n * a.click();\n * ```\n */\n async getFile(filePath: string): Promise<Blob> {\n const pathb64 = this.encodePathBase64(filePath);\n const query = this.buildQueryParams();\n return this.request<Blob>(\n `/${this.config.projectId}/app/file/${pathb64}${query}`,\n {\n headers: {\n 'Accept': 'application/octet-stream',\n },\n }\n );\n }\n\n /**\n * Gets a file URL for direct browser access\n *\n * This returns a URL that can be used directly in img tags, fetch calls, etc.\n * The URL includes authentication via query parameters.\n *\n * @param filePath - Relative path to the file in state directory\n * @returns Full URL to the file\n *\n * @example\n * ```typescript\n * const imageUrl = client.getFileUrl('charts/sales-chart.png');\n *\n * // Use directly in img tag (in environments where query-based auth is supported)\n * document.querySelector('img').src = imageUrl;\n * ```\n */\n getFileUrl(filePath: string): string {\n const pathb64 = this.encodePathBase64(filePath);\n const query = this.buildQueryParams();\n return `${this.config.baseUrl}/${this.config.projectId}/app/file/${pathb64}${query}`;\n }\n\n /**\n * Fetches a parquet file and parses it into table data\n *\n * @param filePath - Relative path to the parquet file\n * @param limit - Maximum number of rows to return (default: 100)\n * @returns TableData with columns and rows\n *\n * @example\n * ```typescript\n * const tableData = await client.getTableData('data/sales.parquet', 50);\n * console.log(tableData.columns);\n * console.log(tableData.rows);\n * console.log(`Total rows: ${tableData.total_rows}`);\n * ```\n */\n async getTableData(filePath: string, limit: number = 100): Promise<TableData> {\n const blob = await this.getFile(filePath);\n const result = await readParquet(blob, limit);\n\n return {\n columns: result.columns,\n rows: result.rows,\n total_rows: result.rowCount,\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["isInIframe","requestAuthFromParent"],"sources":["../src/config.ts","../src/parquet.ts","../src/client.ts"],"sourcesContent":["/**\n * Configuration for the Oxy SDK\n */\nexport interface OxyConfig {\n /**\n * Base URL of the Oxy API (e.g., 'https://api.oxy.tech' or 'http://localhost:3000')\n */\n baseUrl: string;\n\n /**\n * API key for authentication (optional for local development)\n */\n apiKey?: string;\n\n /**\n * Project ID (UUID)\n */\n projectId: string;\n\n /**\n * Optional branch name (defaults to current branch if not specified)\n */\n branch?: string;\n\n /**\n * Request timeout in milliseconds (default: 30000)\n */\n timeout?: number;\n\n /**\n * Parent window origin for postMessage authentication (iframe scenarios)\n * Required when using postMessage auth for security.\n * Example: 'https://app.example.com'\n * Use '*' only in development!\n */\n parentOrigin?: string;\n\n /**\n * Disable automatic postMessage authentication even if in iframe\n * Set to true if you want to provide API key manually in iframe context\n */\n disableAutoAuth?: boolean;\n}\n\n/**\n * Creates an Oxy configuration from environment variables\n *\n * Environment variables:\n * - OXY_URL: Base URL of the Oxy API\n * - OXY_API_KEY: API key for authentication\n * - OXY_PROJECT_ID: Project ID (UUID)\n * - OXY_BRANCH: (Optional) Branch name\n *\n * @param overrides - Optional configuration overrides\n * @returns OxyConfig object\n * @throws Error if required environment variables are missing\n */\nexport function createConfig(overrides?: Partial<OxyConfig>): OxyConfig {\n const baseUrl = overrides?.baseUrl || process.env.OXY_URL;\n const apiKey = overrides?.apiKey || process.env.OXY_API_KEY;\n const projectId = overrides?.projectId || process.env.OXY_PROJECT_ID;\n\n if (!baseUrl) {\n throw new Error('OXY_URL environment variable or baseUrl config is required');\n }\n\n if (!projectId) {\n throw new Error('OXY_PROJECT_ID environment variable or projectId config is required');\n }\n\n return {\n baseUrl: baseUrl.replace(/\\/$/, ''), // Remove trailing slash\n apiKey,\n projectId,\n branch: overrides?.branch || process.env.OXY_BRANCH,\n timeout: overrides?.timeout || 30000,\n parentOrigin: overrides?.parentOrigin,\n disableAutoAuth: overrides?.disableAutoAuth,\n };\n}\n\n/**\n * Creates an Oxy configuration asynchronously with support for postMessage authentication\n *\n * This is the recommended method for iframe scenarios where authentication\n * needs to be obtained from the parent window via postMessage.\n *\n * When running in an iframe without an API key, this function will:\n * 1. Detect the iframe context\n * 2. Send an authentication request to the parent window\n * 3. Wait for the parent to respond with credentials\n * 4. Return the configured client\n *\n * Environment variables (fallback):\n * - OXY_URL: Base URL of the Oxy API\n * - OXY_API_KEY: API key for authentication\n * - OXY_PROJECT_ID: Project ID (UUID)\n * - OXY_BRANCH: (Optional) Branch name\n *\n * @param overrides - Optional configuration overrides\n * @returns Promise resolving to OxyConfig object\n * @throws Error if required configuration is missing\n * @throws PostMessageAuthTimeoutError if parent doesn't respond\n *\n * @example\n * ```typescript\n * // Automatic iframe detection and authentication\n * const config = await createConfigAsync({\n * parentOrigin: 'https://app.example.com',\n * projectId: 'my-project-id',\n * baseUrl: 'https://api.oxy.tech'\n * });\n * ```\n */\nexport async function createConfigAsync(\n overrides?: Partial<OxyConfig>\n): Promise<OxyConfig> {\n // Import postMessage utilities (dynamic to avoid circular deps)\n const { isInIframe, requestAuthFromParent } = await import('./auth/postMessage');\n\n // Start with environment variables and overrides\n let baseUrl = overrides?.baseUrl || process.env.OXY_URL;\n let apiKey = overrides?.apiKey || process.env.OXY_API_KEY;\n let projectId = overrides?.projectId || process.env.OXY_PROJECT_ID;\n\n const disableAutoAuth = overrides?.disableAutoAuth ?? false;\n const parentOrigin = overrides?.parentOrigin;\n\n // Automatic iframe detection and authentication\n if (!disableAutoAuth && isInIframe() && !apiKey) {\n if (!parentOrigin) {\n console.warn(\n '[Oxy SDK] Running in iframe without API key and no parentOrigin specified. ' +\n 'PostMessage authentication will be skipped. ' +\n 'Provide parentOrigin config to enable automatic authentication.'\n );\n } else {\n try {\n const authResult = await requestAuthFromParent({\n parentOrigin,\n timeout: overrides?.timeout || 5000,\n });\n\n apiKey = authResult.apiKey;\n if (authResult.projectId) {\n projectId = authResult.projectId;\n }\n if (authResult.baseUrl) {\n baseUrl = authResult.baseUrl;\n }\n\n console.log('[Oxy SDK] Successfully authenticated via postMessage');\n } catch (error) {\n console.error(\n '[Oxy SDK] Failed to authenticate via postMessage:',\n (error as Error).message\n );\n // Fall through to use environment variables if available\n }\n }\n }\n\n // Validation\n if (!baseUrl) {\n throw new Error('OXY_URL environment variable or baseUrl config is required');\n }\n\n if (!projectId) {\n throw new Error('OXY_PROJECT_ID environment variable or projectId config is required');\n }\n\n return {\n baseUrl: baseUrl.replace(/\\/$/, ''), // Remove trailing slash\n apiKey,\n projectId,\n branch: overrides?.branch || process.env.OXY_BRANCH,\n timeout: overrides?.timeout || 30000,\n parentOrigin,\n disableAutoAuth,\n };\n}\n","import * as duckdb from '@duckdb/duckdb-wasm';\n\nlet dbInstance: duckdb.AsyncDuckDB | null = null;\nlet connection: duckdb.AsyncDuckDBConnection | null = null;\n\n/**\n * Initialize DuckDB-WASM instance\n */\nasync function initializeDuckDB(): Promise<duckdb.AsyncDuckDB> {\n if (dbInstance) {\n return dbInstance;\n }\n\n const JSDELIVR_BUNDLES = duckdb.getJsDelivrBundles();\n\n // Select a bundle based on browser features\n const bundle = await duckdb.selectBundle(JSDELIVR_BUNDLES);\n\n const worker_url = URL.createObjectURL(\n new Blob([`importScripts(\"${bundle.mainWorker}\");`], {\n type: 'text/javascript',\n })\n );\n\n const worker = new Worker(worker_url);\n const logger = new duckdb.ConsoleLogger();\n\n dbInstance = new duckdb.AsyncDuckDB(logger, worker);\n await dbInstance.instantiate(bundle.mainModule, bundle.pthreadWorker);\n URL.revokeObjectURL(worker_url);\n\n return dbInstance;\n}\n\n/**\n * Get or create a DuckDB connection\n */\nasync function getConnection(): Promise<duckdb.AsyncDuckDBConnection> {\n if (connection) {\n return connection;\n }\n\n const db = await initializeDuckDB();\n connection = await db.connect();\n return connection;\n}\n\n/**\n * Query result interface\n */\nexport interface QueryResult {\n columns: string[];\n rows: any[][];\n rowCount: number;\n}\n\n/**\n * ParquetReader provides methods to read and query Parquet files\n */\nexport class ParquetReader {\n private tableName: string;\n private registered: boolean = false;\n\n constructor(tableName: string = 'data') {\n this.tableName = tableName;\n }\n\n /**\n * Register a Parquet file from a Blob\n *\n * @param blob - Parquet file as Blob\n *\n * @example\n * ```typescript\n * const blob = await client.getFile('data/sales.parquet');\n * const reader = new ParquetReader('sales');\n * await reader.registerParquet(blob);\n * ```\n */\n async registerParquet(blob: Blob): Promise<void> {\n const conn = await getConnection();\n const db = await initializeDuckDB();\n\n // Convert blob to Uint8Array\n const arrayBuffer = await blob.arrayBuffer();\n const uint8Array = new Uint8Array(arrayBuffer);\n\n // Register the file with DuckDB\n await db.registerFileBuffer(\n `${this.tableName}.parquet`,\n uint8Array\n );\n\n // Drop table if it exists\n try {\n await conn.query(`DROP TABLE IF EXISTS ${this.tableName}`);\n } catch (e) {\n // Ignore error if table doesn't exist\n }\n\n // Create table from parquet\n await conn.query(\n `CREATE TABLE ${this.tableName} AS SELECT * FROM '${this.tableName}.parquet'`\n );\n\n this.registered = true;\n }\n\n /**\n * Execute a SQL query against the registered Parquet data\n *\n * @param sql - SQL query string\n * @returns Query result with columns and rows\n *\n * @example\n * ```typescript\n * const result = await reader.query('SELECT * FROM sales LIMIT 10');\n * console.log(result.columns);\n * console.log(result.rows);\n * ```\n */\n async query(sql: string): Promise<QueryResult> {\n if (!this.registered) {\n throw new Error('Parquet file not registered. Call registerParquet() first.');\n }\n\n const conn = await getConnection();\n const result = await conn.query(sql);\n\n const columns = result.schema.fields.map((field) => field.name);\n const rows: any[][] = [];\n\n // Convert Arrow table to rows\n for (let i = 0; i < result.numRows; i++) {\n const row: any[] = [];\n for (let j = 0; j < result.numCols; j++) {\n const col = result.getChildAt(j);\n row.push(col?.get(i));\n }\n rows.push(row);\n }\n\n return {\n columns,\n rows,\n rowCount: result.numRows,\n };\n }\n\n /**\n * Get all data from the registered table\n *\n * @param limit - Maximum number of rows to return (default: all)\n * @returns Query result\n *\n * @example\n * ```typescript\n * const allData = await reader.getAll();\n * const first100 = await reader.getAll(100);\n * ```\n */\n async getAll(limit?: number): Promise<QueryResult> {\n const limitClause = limit ? ` LIMIT ${limit}` : '';\n return this.query(`SELECT * FROM ${this.tableName}${limitClause}`);\n }\n\n /**\n * Get table schema information\n *\n * @returns Schema information\n *\n * @example\n * ```typescript\n * const schema = await reader.getSchema();\n * console.log(schema.columns); // ['id', 'name', 'sales']\n * console.log(schema.rows); // [['id', 'INTEGER'], ['name', 'VARCHAR'], ...]\n * ```\n */\n async getSchema(): Promise<QueryResult> {\n return this.query(`DESCRIBE ${this.tableName}`);\n }\n\n /**\n * Get row count\n *\n * @returns Number of rows in the table\n *\n * @example\n * ```typescript\n * const count = await reader.count();\n * console.log(`Total rows: ${count}`);\n * ```\n */\n async count(): Promise<number> {\n const result = await this.query(`SELECT COUNT(*) as count FROM ${this.tableName}`);\n return result.rows[0][0];\n }\n\n /**\n * Close and cleanup resources\n */\n async close(): Promise<void> {\n if (this.registered) {\n const conn = await getConnection();\n const db = await initializeDuckDB();\n\n // Drop the table\n try {\n await conn.query(`DROP TABLE IF EXISTS ${this.tableName}`);\n } catch (e) {\n // Ignore error\n }\n\n // Drop the registered file buffer\n try {\n await db.dropFile(`${this.tableName}.parquet`);\n } catch (e) {\n // Ignore error if file doesn't exist\n }\n\n this.registered = false;\n }\n }\n}\n\n/**\n * Helper function to quickly read a Parquet blob and execute a query\n *\n * @param blob - Parquet file as Blob\n * @param sql - SQL query to execute (optional, defaults to SELECT *)\n * @returns Query result\n *\n * @example\n * ```typescript\n * const blob = await client.getFile('data/sales.parquet');\n * const result = await queryParquet(blob, 'SELECT product, SUM(amount) as total FROM data GROUP BY product');\n * console.log(result);\n * ```\n */\nexport async function queryParquet(\n blob: Blob,\n sql?: string\n): Promise<QueryResult> {\n // Generate unique table name to avoid conflicts\n const uniqueId = `temp_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n const reader = new ParquetReader(uniqueId);\n\n await reader.registerParquet(blob);\n\n const query = sql || `SELECT * FROM ${uniqueId}`;\n const result = await reader.query(query);\n\n await reader.close();\n return result;\n}\n\n/**\n * Helper function to read Parquet file and get all data\n *\n * @param blob - Parquet file as Blob\n * @param limit - Maximum number of rows (optional)\n * @returns Query result\n *\n * @example\n * ```typescript\n * const blob = await client.getFile('data/sales.parquet');\n * const data = await readParquet(blob, 1000);\n * console.log(`Loaded ${data.rowCount} rows`);\n * ```\n */\nexport async function readParquet(\n blob: Blob,\n limit?: number\n): Promise<QueryResult> {\n // Generate unique table name to avoid conflicts\n const uniqueId = `temp_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n const reader = new ParquetReader(uniqueId);\n\n await reader.registerParquet(blob);\n\n const result = await reader.getAll(limit);\n\n await reader.close();\n return result;\n}\n","import { OxyConfig, createConfigAsync } from './config';\nimport {\n AppItem,\n AppDataResponse,\n GetDisplaysResponse,\n ApiError,\n TableData,\n} from './types';\nimport { readParquet } from './parquet';\n\n/**\n * Oxy API Client for interacting with Oxy data\n */\nexport class OxyClient {\n private config: OxyConfig;\n\n constructor(config: OxyConfig) {\n this.config = config;\n }\n\n /**\n * Creates an OxyClient instance asynchronously with support for postMessage authentication\n *\n * This is the recommended method when using the SDK in an iframe that needs to\n * obtain authentication from the parent window via postMessage.\n *\n * @param config - Optional configuration overrides\n * @returns Promise resolving to OxyClient instance\n * @throws Error if required configuration is missing\n * @throws PostMessageAuthTimeoutError if parent doesn't respond\n *\n * @example\n * ```typescript\n * // In an iframe - automatic postMessage auth\n * const client = await OxyClient.create({\n * parentOrigin: 'https://app.example.com',\n * projectId: 'my-project-id',\n * baseUrl: 'https://api.oxy.tech'\n * });\n *\n * // Use the client normally\n * const apps = await client.listApps();\n * ```\n */\n static async create(config?: Partial<OxyConfig>): Promise<OxyClient> {\n const resolvedConfig = await createConfigAsync(config);\n return new OxyClient(resolvedConfig);\n }\n\n /**\n * Encodes a file path to base64 for use in API URLs\n */\n private encodePathBase64(path: string): string {\n if (typeof Buffer !== 'undefined') {\n // Node.js environment\n return Buffer.from(path).toString('base64');\n } else {\n // Browser environment\n return btoa(path);\n }\n }\n\n /**\n * Makes an authenticated HTTP request to the Oxy API\n */\n private async request<T>(\n endpoint: string,\n options: RequestInit = {}\n ): Promise<T> {\n const url = `${this.config.baseUrl}${endpoint}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...((options.headers as Record<string, string>) || {}),\n };\n\n // Only add Authorization header if API key is provided (optional for local dev)\n if (this.config.apiKey) {\n headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout || 30000);\n\n try {\n const response = await fetch(url, {\n ...options,\n headers,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unknown error');\n const error: ApiError = {\n message: `API request failed: ${response.statusText}`,\n status: response.status,\n details: errorText,\n };\n throw error;\n }\n\n // Handle binary responses\n const acceptHeader =\n typeof options.headers === 'object' && options.headers !== null\n ? (options.headers as Record<string, string>)['Accept']\n : undefined;\n if (acceptHeader === 'application/octet-stream') {\n return response.blob() as Promise<T>;\n }\n\n return response.json();\n } catch (error: any) {\n clearTimeout(timeoutId);\n\n if (error.name === 'AbortError') {\n throw new Error(`Request timeout after ${this.config.timeout || 30000}ms`);\n }\n\n throw error;\n }\n }\n\n /**\n * Builds query parameters including optional branch\n */\n private buildQueryParams(additionalParams: Record<string, string> = {}): string {\n const params: Record<string, string> = { ...additionalParams };\n\n if (this.config.branch) {\n params.branch = this.config.branch;\n }\n\n const searchParams = new URLSearchParams(params);\n const queryString = searchParams.toString();\n return queryString ? `?${queryString}` : '';\n }\n\n /**\n * Lists all apps in the project\n *\n * @returns Array of app items\n *\n * @example\n * ```typescript\n * const apps = await client.listApps();\n * console.log('Available apps:', apps);\n * ```\n */\n async listApps(): Promise<AppItem[]> {\n const query = this.buildQueryParams();\n return this.request<AppItem[]>(`/${this.config.projectId}/app${query}`);\n }\n\n /**\n * Gets data for a specific app\n *\n * @param appPath - Relative path to the app file (e.g., 'my-app.app.yml')\n * @returns App data response\n *\n * @example\n * ```typescript\n * const data = await client.getAppData('dashboard.app.yml');\n * if (data.error) {\n * console.error('Error:', data.error);\n * } else {\n * console.log('App data:', data.data);\n * }\n * ```\n */\n async getAppData(appPath: string): Promise<AppDataResponse> {\n const pathb64 = this.encodePathBase64(appPath);\n const query = this.buildQueryParams();\n return this.request<AppDataResponse>(\n `/${this.config.projectId}/app/${pathb64}${query}`\n );\n }\n\n /**\n * Runs an app and returns fresh data (bypasses cache)\n *\n * @param appPath - Relative path to the app file\n * @returns App data response\n *\n * @example\n * ```typescript\n * const data = await client.runApp('dashboard.app.yml');\n * console.log('Fresh app data:', data.data);\n * ```\n */\n async runApp(appPath: string): Promise<AppDataResponse> {\n const pathb64 = this.encodePathBase64(appPath);\n const query = this.buildQueryParams();\n return this.request<AppDataResponse>(\n `/${this.config.projectId}/app/${pathb64}/run${query}`,\n { method: 'POST' }\n );\n }\n\n /**\n * Gets display configurations for an app\n *\n * @param appPath - Relative path to the app file\n * @returns Display configurations with potential errors\n *\n * @example\n * ```typescript\n * const displays = await client.getDisplays('dashboard.app.yml');\n * displays.displays.forEach(d => {\n * if (d.error) {\n * console.error('Display error:', d.error);\n * } else {\n * console.log('Display:', d.display);\n * }\n * });\n * ```\n */\n async getDisplays(appPath: string): Promise<GetDisplaysResponse> {\n const pathb64 = this.encodePathBase64(appPath);\n const query = this.buildQueryParams();\n return this.request<GetDisplaysResponse>(\n `/${this.config.projectId}/app/${pathb64}/displays${query}`\n );\n }\n\n /**\n * Gets a file from the app state directory (e.g., generated charts, images)\n *\n * This is useful for retrieving generated assets like charts, images, or other\n * files produced by app workflows and stored in the state directory.\n *\n * @param filePath - Relative path to the file in state directory\n * @returns Blob containing the file data\n *\n * @example\n * ```typescript\n * // Get a generated chart image\n * const blob = await client.getFile('charts/sales-chart.png');\n * const imageUrl = URL.createObjectURL(blob);\n *\n * // Use in an img tag\n * document.querySelector('img').src = imageUrl;\n * ```\n *\n * @example\n * ```typescript\n * // Download a file\n * const blob = await client.getFile('exports/data.csv');\n * const a = document.createElement('a');\n * a.href = URL.createObjectURL(blob);\n * a.download = 'data.csv';\n * a.click();\n * ```\n */\n async getFile(filePath: string): Promise<Blob> {\n const pathb64 = this.encodePathBase64(filePath);\n const query = this.buildQueryParams();\n return this.request<Blob>(\n `/${this.config.projectId}/app/file/${pathb64}${query}`,\n {\n headers: {\n 'Accept': 'application/octet-stream',\n },\n }\n );\n }\n\n /**\n * Gets a file URL for direct browser access\n *\n * This returns a URL that can be used directly in img tags, fetch calls, etc.\n * The URL includes authentication via query parameters.\n *\n * @param filePath - Relative path to the file in state directory\n * @returns Full URL to the file\n *\n * @example\n * ```typescript\n * const imageUrl = client.getFileUrl('charts/sales-chart.png');\n *\n * // Use directly in img tag (in environments where query-based auth is supported)\n * document.querySelector('img').src = imageUrl;\n * ```\n */\n getFileUrl(filePath: string): string {\n const pathb64 = this.encodePathBase64(filePath);\n const query = this.buildQueryParams();\n return `${this.config.baseUrl}/${this.config.projectId}/app/file/${pathb64}${query}`;\n }\n\n /**\n * Fetches a parquet file and parses it into table data\n *\n * @param filePath - Relative path to the parquet file\n * @param limit - Maximum number of rows to return (default: 100)\n * @returns TableData with columns and rows\n *\n * @example\n * ```typescript\n * const tableData = await client.getTableData('data/sales.parquet', 50);\n * console.log(tableData.columns);\n * console.log(tableData.rows);\n * console.log(`Total rows: ${tableData.total_rows}`);\n * ```\n */\n async getTableData(filePath: string, limit: number = 100): Promise<TableData> {\n const blob = await this.getFile(filePath);\n const result = await readParquet(blob, limit);\n\n return {\n columns: result.columns,\n rows: result.rows,\n total_rows: result.rowCount,\n };\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  // @oxy/sdk - TypeScript SDK for Oxy data platform
2
- const require_postMessage = require('./postMessage-CtL0W-Zt.cjs');
2
+ const require_postMessage = require('./postMessage-CufWf9ji.cjs');
3
3
 
4
4
  exports.isInIframe = require_postMessage.isInIframe;
5
5
  exports.requestAuthFromParent = require_postMessage.requestAuthFromParent;
@@ -105,12 +105,6 @@ function createAuthListener(requestId, origin, timeout) {
105
105
  if (!event.data || event.data.type !== "OXY_AUTH_RESPONSE") return;
106
106
  const response = event.data;
107
107
  if (response.requestId !== requestId) return;
108
- if (!response.apiKey) {
109
- clearTimeout(timeoutId);
110
- window.removeEventListener("message", listener);
111
- reject(new PostMessageAuthInvalidResponseError("Missing apiKey in response"));
112
- return;
113
- }
114
108
  if (response.version !== "1.0") {
115
109
  clearTimeout(timeoutId);
116
110
  window.removeEventListener("message", listener);
@@ -231,4 +225,4 @@ Object.defineProperty(exports, 'validateOrigin', {
231
225
  return validateOrigin;
232
226
  }
233
227
  });
234
- //# sourceMappingURL=postMessage-CtL0W-Zt.cjs.map
228
+ //# sourceMappingURL=postMessage-CufWf9ji.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postMessage-CufWf9ji.cjs","names":[],"sources":["../src/types.ts","../src/auth/postMessage.ts"],"sourcesContent":["/**\n * Represents an app item in the project\n */\nexport interface AppItem {\n name: string;\n path: string;\n}\n\n/**\n * Reference to a data file (usually parquet)\n */\nexport interface FileReference {\n file_path: string;\n}\n\n/**\n * Table data structure for in-memory tables\n * (used when data is fetched and parsed)\n */\nexport interface TableData {\n columns: string[];\n rows: any[][];\n total_rows?: number;\n}\n\nexport type DataContainer = Record<string, FileReference>;\n\n/**\n * Response from app data endpoints\n */\nexport interface AppDataResponse {\n data: DataContainer | null;\n error: string | null;\n}\n\n/**\n * Display with potential error\n */\nexport interface DisplayWithError {\n display?: DisplayData;\n error?: string;\n}\n\n/**\n * Display data structure\n */\nexport interface DisplayData {\n type: string;\n content: any;\n}\n\n/**\n * Response from get displays endpoint\n */\nexport interface GetDisplaysResponse {\n displays: DisplayWithError[];\n}\n\n/**\n * Error response from the API\n */\nexport interface ApiError {\n message: string;\n status: number;\n details?: any;\n}\n\n/**\n * Query result from ParquetReader\n */\nexport interface QueryResult {\n columns: string[];\n rows: any[][];\n rowCount: number;\n}\n\n/**\n * PostMessage authentication protocol types\n */\n\n/**\n * Request message sent from iframe to parent window\n */\nexport interface OxyAuthRequestMessage {\n type: 'OXY_AUTH_REQUEST';\n version: '1.0';\n timestamp: number;\n requestId: string;\n}\n\n/**\n * Response message sent from parent window to iframe\n */\nexport interface OxyAuthResponseMessage {\n type: 'OXY_AUTH_RESPONSE';\n version: '1.0';\n requestId: string;\n apiKey?: string;\n projectId?: string;\n baseUrl?: string;\n}\n\n/**\n * Options for postMessage authentication\n */\nexport interface PostMessageAuthOptions {\n /** Required parent window origin for security (e.g., 'https://app.example.com'). Use '*' only in development! */\n parentOrigin?: string;\n /** Timeout in milliseconds (default: 5000) */\n timeout?: number;\n /** Number of retry attempts (default: 0) */\n retries?: number;\n}\n\n/**\n * Result from successful postMessage authentication\n */\nexport interface PostMessageAuthResult {\n apiKey?: string;\n projectId?: string;\n baseUrl?: string;\n source: 'postmessage';\n}\n\n/**\n * Custom error classes for postMessage authentication\n */\n\n/**\n * Error thrown when postMessage authentication times out\n */\nexport class PostMessageAuthTimeoutError extends Error {\n constructor(timeout: number) {\n super(\n `Parent window did not respond to authentication request within ${timeout}ms.\\n\\n` +\n `Possible causes:\\n` +\n `- Parent window is not listening for 'OXY_AUTH_REQUEST' messages\\n` +\n `- Parent origin mismatch\\n` +\n `- Network/browser issues\\n\\n` +\n `Troubleshooting:\\n` +\n `1. Verify parent window has message listener set up\\n` +\n `2. Check parentOrigin configuration matches parent window origin\\n` +\n `3. Open browser console in parent window for errors`\n );\n this.name = 'PostMessageAuthTimeoutError';\n }\n}\n\n/**\n * Error thrown when authentication response comes from unauthorized origin\n */\nexport class PostMessageAuthInvalidOriginError extends Error {\n constructor(expected: string, actual: string) {\n super(\n `Received authentication response from unauthorized origin.\\n\\n` +\n `Expected: ${expected}\\n` +\n `Actual: ${actual}\\n\\n` +\n `This is a security error. Verify your parentOrigin configuration.`\n );\n this.name = 'PostMessageAuthInvalidOriginError';\n }\n}\n\n/**\n * Error thrown when postMessage authentication is attempted outside iframe context\n */\nexport class PostMessageAuthNotInIframeError extends Error {\n constructor() {\n super(\n `PostMessage authentication is only available when running in an iframe context.\\n\\n` +\n `Current context: ${typeof window !== 'undefined' ? (window === window.parent ? 'top-level window' : 'iframe') : 'non-browser (Node.js)'}\\n\\n` +\n `If you're running in a regular browser window, use direct configuration instead:\\n` +\n `const client = new OxyClient({ apiKey: 'your-key', ... })`\n );\n this.name = 'PostMessageAuthNotInIframeError';\n }\n}\n\n/**\n * Error thrown when authentication response is malformed or invalid\n */\nexport class PostMessageAuthInvalidResponseError extends Error {\n constructor(reason: string) {\n super(`Invalid authentication response from parent: ${reason}`);\n this.name = 'PostMessageAuthInvalidResponseError';\n }\n}\n","/**\n * PostMessage-based authentication for iframe scenarios\n *\n * This module enables secure cross-origin authentication between an iframe\n * (running the Oxy SDK) and its parent window (holding the API key).\n */\n\nimport type {\n OxyAuthRequestMessage,\n OxyAuthResponseMessage,\n PostMessageAuthOptions,\n PostMessageAuthResult,\n} from '../types';\n\nimport {\n PostMessageAuthTimeoutError,\n PostMessageAuthInvalidOriginError,\n PostMessageAuthNotInIframeError,\n PostMessageAuthInvalidResponseError,\n} from '../types';\n\n/**\n * Check if the current context is running inside an iframe\n *\n * @returns true if running in an iframe, false otherwise (including Node.js)\n */\nexport function isInIframe(): boolean {\n // Check if we're in a browser environment\n if (typeof window === 'undefined') {\n return false;\n }\n\n // Check if window has a parent and it's different from itself\n try {\n return window !== window.parent && window.parent !== null;\n } catch (e) {\n // Cross-origin access might throw an error, but we're still in an iframe\n return true;\n }\n}\n\n/**\n * Generate a unique request ID for tracking auth requests\n *\n * @returns A unique identifier string\n */\nexport function generateRequestId(): string {\n // Use crypto.randomUUID if available (modern browsers)\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n\n // Fallback for older environments: timestamp + random\n return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n}\n\n/**\n * Validate that a message origin matches the expected origin\n *\n * @param messageOrigin - The origin from the message event\n * @param allowedOrigin - The expected/allowed origin\n * @returns true if origin is valid, false otherwise\n */\nexport function validateOrigin(\n messageOrigin: string,\n allowedOrigin?: string\n): boolean {\n // If no allowed origin is specified, reject (security)\n if (!allowedOrigin) {\n return false;\n }\n\n // Wildcard - allow any origin (development only!)\n if (allowedOrigin === '*') {\n return true;\n }\n\n // Exact match\n if (messageOrigin === allowedOrigin) {\n return true;\n }\n\n // Try URL parsing for more flexible matching\n try {\n const messageUrl = new URL(messageOrigin);\n const allowedUrl = new URL(allowedOrigin);\n return messageUrl.origin === allowedUrl.origin;\n } catch (e) {\n // If URL parsing fails, do simple string match\n return messageOrigin === allowedOrigin;\n }\n}\n\n/**\n * Create a promise that listens for an authentication response\n *\n * @param requestId - The request ID to match against\n * @param origin - The expected parent origin\n * @param timeout - Timeout in milliseconds\n * @returns Promise that resolves with the auth response\n */\nfunction createAuthListener(\n requestId: string,\n origin: string | undefined,\n timeout: number\n): Promise<OxyAuthResponseMessage> {\n return new Promise((resolve, reject) => {\n let timeoutId: NodeJS.Timeout;\n let listener: (event: MessageEvent) => void;\n\n // Set up timeout\n timeoutId = setTimeout(() => {\n window.removeEventListener('message', listener);\n reject(new PostMessageAuthTimeoutError(timeout));\n }, timeout);\n\n // Set up message listener\n listener = (event: MessageEvent) => {\n // Validate origin\n if (!validateOrigin(event.origin, origin)) {\n // Don't reject here - might be other postMessage traffic\n // Just ignore messages from wrong origins\n return;\n }\n\n // Check message type\n if (!event.data || event.data.type !== 'OXY_AUTH_RESPONSE') {\n // Not our message type, ignore\n return;\n }\n\n const response = event.data as OxyAuthResponseMessage;\n\n // Validate request ID matches\n if (response.requestId !== requestId) {\n // Wrong request ID, ignore (might be another auth in progress)\n return;\n }\n\n // Validate version\n if (response.version !== '1.0') {\n clearTimeout(timeoutId);\n window.removeEventListener('message', listener);\n reject(\n new PostMessageAuthInvalidResponseError(\n `Unsupported protocol version: ${response.version}`\n )\n );\n return;\n }\n\n // Success!\n clearTimeout(timeoutId);\n window.removeEventListener('message', listener);\n resolve(response);\n };\n\n // Start listening\n window.addEventListener('message', listener);\n });\n}\n\n/**\n * Request authentication from parent window via postMessage\n *\n * This is the main entry point for iframe-based authentication.\n * It sends a request to the parent window and waits for a response.\n *\n * @param options - Configuration options for the auth request\n * @returns Promise that resolves with authentication credentials\n * @throws {PostMessageAuthNotInIframeError} If not in an iframe\n * @throws {PostMessageAuthTimeoutError} If parent doesn't respond in time\n * @throws {PostMessageAuthInvalidOriginError} If response from wrong origin\n * @throws {PostMessageAuthInvalidResponseError} If response is malformed\n *\n * @example\n * ```typescript\n * const auth = await requestAuthFromParent({\n * parentOrigin: 'https://app.example.com',\n * timeout: 5000\n * });\n * console.log('Received API key:', auth.apiKey);\n * ```\n */\nexport async function requestAuthFromParent(\n options: PostMessageAuthOptions = {}\n): Promise<PostMessageAuthResult> {\n const {\n parentOrigin,\n timeout = 5000,\n retries = 0,\n } = options;\n\n // Validate we're in an iframe\n if (!isInIframe()) {\n throw new PostMessageAuthNotInIframeError();\n }\n\n // Validate we're in a browser environment\n if (typeof window === 'undefined') {\n throw new PostMessageAuthNotInIframeError();\n }\n\n // Generate request ID\n const requestId = generateRequestId();\n\n // Create request message\n const request: OxyAuthRequestMessage = {\n type: 'OXY_AUTH_REQUEST',\n version: '1.0',\n timestamp: Date.now(),\n requestId,\n };\n\n // Attempt authentication with retries\n let lastError: Error | null = null;\n const maxAttempts = retries + 1;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n // Set up listener before sending request to avoid race condition\n const responsePromise = createAuthListener(requestId, parentOrigin, timeout);\n\n // Send request to parent\n const targetOrigin = parentOrigin || '*';\n window.parent.postMessage(request, targetOrigin);\n\n // Wait for response\n const response = await responsePromise;\n\n // Return successful result\n return {\n apiKey: response.apiKey,\n projectId: response.projectId,\n baseUrl: response.baseUrl,\n source: 'postmessage',\n };\n } catch (error) {\n lastError = error as Error;\n\n // If this isn't a timeout, don't retry\n if (!(error instanceof PostMessageAuthTimeoutError)) {\n throw error;\n }\n\n // If we have more attempts, continue\n if (attempt < maxAttempts - 1) {\n // Optional: Add a small delay before retry\n await new Promise((resolve) => setTimeout(resolve, 100));\n continue;\n }\n\n // All retries exhausted\n throw error;\n }\n }\n\n // Should never reach here, but TypeScript needs this\n throw lastError || new Error('Authentication failed');\n}\n"],"mappings":";;;;;;;;;AAmIA,IAAa,8BAAb,cAAiD,MAAM;CACrD,YAAY,SAAiB;AAC3B,QACE,kEAAkE,QAAQ,+UAS3E;AACD,OAAK,OAAO;;;;;;AAOhB,IAAa,oCAAb,cAAuD,MAAM;CAC3D,YAAY,UAAkB,QAAgB;AAC5C,QACE,2EACa,SAAS,YACX,OAAO,uEAEnB;AACD,OAAK,OAAO;;;;;;AAOhB,IAAa,kCAAb,cAAqD,MAAM;CACzD,cAAc;AACZ,QACE,uGACoB,OAAO,WAAW,cAAe,WAAW,OAAO,SAAS,qBAAqB,WAAY,wBAAwB,iJAG1I;AACD,OAAK,OAAO;;;;;;AAOhB,IAAa,sCAAb,cAAyD,MAAM;CAC7D,YAAY,QAAgB;AAC1B,QAAM,gDAAgD,SAAS;AAC/D,OAAK,OAAO;;;;;;;;;;;AC9JhB,SAAgB,aAAsB;AAEpC,KAAI,OAAO,WAAW,YACpB,QAAO;AAIT,KAAI;AACF,SAAO,WAAW,OAAO,UAAU,OAAO,WAAW;UAC9C,GAAG;AAEV,SAAO;;;;;;;;AASX,SAAgB,oBAA4B;AAE1C,KAAI,OAAO,WAAW,eAAe,OAAO,WAC1C,QAAO,OAAO,YAAY;AAI5B,QAAO,GAAG,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,UAAU,GAAG,GAAG;;;;;;;;;AAUrE,SAAgB,eACd,eACA,eACS;AAET,KAAI,CAAC,cACH,QAAO;AAIT,KAAI,kBAAkB,IACpB,QAAO;AAIT,KAAI,kBAAkB,cACpB,QAAO;AAIT,KAAI;EACF,MAAM,aAAa,IAAI,IAAI,cAAc;EACzC,MAAM,aAAa,IAAI,IAAI,cAAc;AACzC,SAAO,WAAW,WAAW,WAAW;UACjC,GAAG;AAEV,SAAO,kBAAkB;;;;;;;;;;;AAY7B,SAAS,mBACP,WACA,QACA,SACiC;AACjC,QAAO,IAAI,SAAS,SAAS,WAAW;EACtC,IAAI;EACJ,IAAI;AAGJ,cAAY,iBAAiB;AAC3B,UAAO,oBAAoB,WAAW,SAAS;AAC/C,UAAO,IAAI,4BAA4B,QAAQ,CAAC;KAC/C,QAAQ;AAGX,cAAY,UAAwB;AAElC,OAAI,CAAC,eAAe,MAAM,QAAQ,OAAO,CAGvC;AAIF,OAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,SAAS,oBAErC;GAGF,MAAM,WAAW,MAAM;AAGvB,OAAI,SAAS,cAAc,UAEzB;AAIF,OAAI,SAAS,YAAY,OAAO;AAC9B,iBAAa,UAAU;AACvB,WAAO,oBAAoB,WAAW,SAAS;AAC/C,WACE,IAAI,oCACF,iCAAiC,SAAS,UAC3C,CACF;AACD;;AAIF,gBAAa,UAAU;AACvB,UAAO,oBAAoB,WAAW,SAAS;AAC/C,WAAQ,SAAS;;AAInB,SAAO,iBAAiB,WAAW,SAAS;GAC5C;;;;;;;;;;;;;;;;;;;;;;;;AAyBJ,eAAsB,sBACpB,UAAkC,EAAE,EACJ;CAChC,MAAM,EACJ,cACA,UAAU,KACV,UAAU,MACR;AAGJ,KAAI,CAAC,YAAY,CACf,OAAM,IAAI,iCAAiC;AAI7C,KAAI,OAAO,WAAW,YACpB,OAAM,IAAI,iCAAiC;CAI7C,MAAM,YAAY,mBAAmB;CAGrC,MAAM,UAAiC;EACrC,MAAM;EACN,SAAS;EACT,WAAW,KAAK,KAAK;EACrB;EACD;CAGD,IAAI,YAA0B;CAC9B,MAAM,cAAc,UAAU;AAE9B,MAAK,IAAI,UAAU,GAAG,UAAU,aAAa,UAC3C,KAAI;EAEF,MAAM,kBAAkB,mBAAmB,WAAW,cAAc,QAAQ;EAG5E,MAAM,eAAe,gBAAgB;AACrC,SAAO,OAAO,YAAY,SAAS,aAAa;EAGhD,MAAM,WAAW,MAAM;AAGvB,SAAO;GACL,QAAQ,SAAS;GACjB,WAAW,SAAS;GACpB,SAAS,SAAS;GAClB,QAAQ;GACT;UACM,OAAO;AACd,cAAY;AAGZ,MAAI,EAAE,iBAAiB,6BACrB,OAAM;AAIR,MAAI,UAAU,cAAc,GAAG;AAE7B,SAAM,IAAI,SAAS,YAAY,WAAW,SAAS,IAAI,CAAC;AACxD;;AAIF,QAAM;;AAKV,OAAM,6BAAa,IAAI,MAAM,wBAAwB"}
@@ -104,12 +104,6 @@ function createAuthListener(requestId, origin, timeout) {
104
104
  if (!event.data || event.data.type !== "OXY_AUTH_RESPONSE") return;
105
105
  const response = event.data;
106
106
  if (response.requestId !== requestId) return;
107
- if (!response.apiKey) {
108
- clearTimeout(timeoutId);
109
- window.removeEventListener("message", listener);
110
- reject(new PostMessageAuthInvalidResponseError("Missing apiKey in response"));
111
- return;
112
- }
113
107
  if (response.version !== "1.0") {
114
108
  clearTimeout(timeoutId);
115
109
  window.removeEventListener("message", listener);
@@ -183,4 +177,4 @@ async function requestAuthFromParent(options = {}) {
183
177
 
184
178
  //#endregion
185
179
  export { PostMessageAuthInvalidOriginError as a, PostMessageAuthTimeoutError as c, validateOrigin as i, isInIframe as n, PostMessageAuthInvalidResponseError as o, requestAuthFromParent as r, PostMessageAuthNotInIframeError as s, generateRequestId as t };
186
- //# sourceMappingURL=postMessage-Dq9lXKK0.mjs.map
180
+ //# sourceMappingURL=postMessage-DLGITn0e.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postMessage-DLGITn0e.mjs","names":[],"sources":["../src/types.ts","../src/auth/postMessage.ts"],"sourcesContent":["/**\n * Represents an app item in the project\n */\nexport interface AppItem {\n name: string;\n path: string;\n}\n\n/**\n * Reference to a data file (usually parquet)\n */\nexport interface FileReference {\n file_path: string;\n}\n\n/**\n * Table data structure for in-memory tables\n * (used when data is fetched and parsed)\n */\nexport interface TableData {\n columns: string[];\n rows: any[][];\n total_rows?: number;\n}\n\nexport type DataContainer = Record<string, FileReference>;\n\n/**\n * Response from app data endpoints\n */\nexport interface AppDataResponse {\n data: DataContainer | null;\n error: string | null;\n}\n\n/**\n * Display with potential error\n */\nexport interface DisplayWithError {\n display?: DisplayData;\n error?: string;\n}\n\n/**\n * Display data structure\n */\nexport interface DisplayData {\n type: string;\n content: any;\n}\n\n/**\n * Response from get displays endpoint\n */\nexport interface GetDisplaysResponse {\n displays: DisplayWithError[];\n}\n\n/**\n * Error response from the API\n */\nexport interface ApiError {\n message: string;\n status: number;\n details?: any;\n}\n\n/**\n * Query result from ParquetReader\n */\nexport interface QueryResult {\n columns: string[];\n rows: any[][];\n rowCount: number;\n}\n\n/**\n * PostMessage authentication protocol types\n */\n\n/**\n * Request message sent from iframe to parent window\n */\nexport interface OxyAuthRequestMessage {\n type: 'OXY_AUTH_REQUEST';\n version: '1.0';\n timestamp: number;\n requestId: string;\n}\n\n/**\n * Response message sent from parent window to iframe\n */\nexport interface OxyAuthResponseMessage {\n type: 'OXY_AUTH_RESPONSE';\n version: '1.0';\n requestId: string;\n apiKey?: string;\n projectId?: string;\n baseUrl?: string;\n}\n\n/**\n * Options for postMessage authentication\n */\nexport interface PostMessageAuthOptions {\n /** Required parent window origin for security (e.g., 'https://app.example.com'). Use '*' only in development! */\n parentOrigin?: string;\n /** Timeout in milliseconds (default: 5000) */\n timeout?: number;\n /** Number of retry attempts (default: 0) */\n retries?: number;\n}\n\n/**\n * Result from successful postMessage authentication\n */\nexport interface PostMessageAuthResult {\n apiKey?: string;\n projectId?: string;\n baseUrl?: string;\n source: 'postmessage';\n}\n\n/**\n * Custom error classes for postMessage authentication\n */\n\n/**\n * Error thrown when postMessage authentication times out\n */\nexport class PostMessageAuthTimeoutError extends Error {\n constructor(timeout: number) {\n super(\n `Parent window did not respond to authentication request within ${timeout}ms.\\n\\n` +\n `Possible causes:\\n` +\n `- Parent window is not listening for 'OXY_AUTH_REQUEST' messages\\n` +\n `- Parent origin mismatch\\n` +\n `- Network/browser issues\\n\\n` +\n `Troubleshooting:\\n` +\n `1. Verify parent window has message listener set up\\n` +\n `2. Check parentOrigin configuration matches parent window origin\\n` +\n `3. Open browser console in parent window for errors`\n );\n this.name = 'PostMessageAuthTimeoutError';\n }\n}\n\n/**\n * Error thrown when authentication response comes from unauthorized origin\n */\nexport class PostMessageAuthInvalidOriginError extends Error {\n constructor(expected: string, actual: string) {\n super(\n `Received authentication response from unauthorized origin.\\n\\n` +\n `Expected: ${expected}\\n` +\n `Actual: ${actual}\\n\\n` +\n `This is a security error. Verify your parentOrigin configuration.`\n );\n this.name = 'PostMessageAuthInvalidOriginError';\n }\n}\n\n/**\n * Error thrown when postMessage authentication is attempted outside iframe context\n */\nexport class PostMessageAuthNotInIframeError extends Error {\n constructor() {\n super(\n `PostMessage authentication is only available when running in an iframe context.\\n\\n` +\n `Current context: ${typeof window !== 'undefined' ? (window === window.parent ? 'top-level window' : 'iframe') : 'non-browser (Node.js)'}\\n\\n` +\n `If you're running in a regular browser window, use direct configuration instead:\\n` +\n `const client = new OxyClient({ apiKey: 'your-key', ... })`\n );\n this.name = 'PostMessageAuthNotInIframeError';\n }\n}\n\n/**\n * Error thrown when authentication response is malformed or invalid\n */\nexport class PostMessageAuthInvalidResponseError extends Error {\n constructor(reason: string) {\n super(`Invalid authentication response from parent: ${reason}`);\n this.name = 'PostMessageAuthInvalidResponseError';\n }\n}\n","/**\n * PostMessage-based authentication for iframe scenarios\n *\n * This module enables secure cross-origin authentication between an iframe\n * (running the Oxy SDK) and its parent window (holding the API key).\n */\n\nimport type {\n OxyAuthRequestMessage,\n OxyAuthResponseMessage,\n PostMessageAuthOptions,\n PostMessageAuthResult,\n} from '../types';\n\nimport {\n PostMessageAuthTimeoutError,\n PostMessageAuthInvalidOriginError,\n PostMessageAuthNotInIframeError,\n PostMessageAuthInvalidResponseError,\n} from '../types';\n\n/**\n * Check if the current context is running inside an iframe\n *\n * @returns true if running in an iframe, false otherwise (including Node.js)\n */\nexport function isInIframe(): boolean {\n // Check if we're in a browser environment\n if (typeof window === 'undefined') {\n return false;\n }\n\n // Check if window has a parent and it's different from itself\n try {\n return window !== window.parent && window.parent !== null;\n } catch (e) {\n // Cross-origin access might throw an error, but we're still in an iframe\n return true;\n }\n}\n\n/**\n * Generate a unique request ID for tracking auth requests\n *\n * @returns A unique identifier string\n */\nexport function generateRequestId(): string {\n // Use crypto.randomUUID if available (modern browsers)\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n\n // Fallback for older environments: timestamp + random\n return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n}\n\n/**\n * Validate that a message origin matches the expected origin\n *\n * @param messageOrigin - The origin from the message event\n * @param allowedOrigin - The expected/allowed origin\n * @returns true if origin is valid, false otherwise\n */\nexport function validateOrigin(\n messageOrigin: string,\n allowedOrigin?: string\n): boolean {\n // If no allowed origin is specified, reject (security)\n if (!allowedOrigin) {\n return false;\n }\n\n // Wildcard - allow any origin (development only!)\n if (allowedOrigin === '*') {\n return true;\n }\n\n // Exact match\n if (messageOrigin === allowedOrigin) {\n return true;\n }\n\n // Try URL parsing for more flexible matching\n try {\n const messageUrl = new URL(messageOrigin);\n const allowedUrl = new URL(allowedOrigin);\n return messageUrl.origin === allowedUrl.origin;\n } catch (e) {\n // If URL parsing fails, do simple string match\n return messageOrigin === allowedOrigin;\n }\n}\n\n/**\n * Create a promise that listens for an authentication response\n *\n * @param requestId - The request ID to match against\n * @param origin - The expected parent origin\n * @param timeout - Timeout in milliseconds\n * @returns Promise that resolves with the auth response\n */\nfunction createAuthListener(\n requestId: string,\n origin: string | undefined,\n timeout: number\n): Promise<OxyAuthResponseMessage> {\n return new Promise((resolve, reject) => {\n let timeoutId: NodeJS.Timeout;\n let listener: (event: MessageEvent) => void;\n\n // Set up timeout\n timeoutId = setTimeout(() => {\n window.removeEventListener('message', listener);\n reject(new PostMessageAuthTimeoutError(timeout));\n }, timeout);\n\n // Set up message listener\n listener = (event: MessageEvent) => {\n // Validate origin\n if (!validateOrigin(event.origin, origin)) {\n // Don't reject here - might be other postMessage traffic\n // Just ignore messages from wrong origins\n return;\n }\n\n // Check message type\n if (!event.data || event.data.type !== 'OXY_AUTH_RESPONSE') {\n // Not our message type, ignore\n return;\n }\n\n const response = event.data as OxyAuthResponseMessage;\n\n // Validate request ID matches\n if (response.requestId !== requestId) {\n // Wrong request ID, ignore (might be another auth in progress)\n return;\n }\n\n // Validate version\n if (response.version !== '1.0') {\n clearTimeout(timeoutId);\n window.removeEventListener('message', listener);\n reject(\n new PostMessageAuthInvalidResponseError(\n `Unsupported protocol version: ${response.version}`\n )\n );\n return;\n }\n\n // Success!\n clearTimeout(timeoutId);\n window.removeEventListener('message', listener);\n resolve(response);\n };\n\n // Start listening\n window.addEventListener('message', listener);\n });\n}\n\n/**\n * Request authentication from parent window via postMessage\n *\n * This is the main entry point for iframe-based authentication.\n * It sends a request to the parent window and waits for a response.\n *\n * @param options - Configuration options for the auth request\n * @returns Promise that resolves with authentication credentials\n * @throws {PostMessageAuthNotInIframeError} If not in an iframe\n * @throws {PostMessageAuthTimeoutError} If parent doesn't respond in time\n * @throws {PostMessageAuthInvalidOriginError} If response from wrong origin\n * @throws {PostMessageAuthInvalidResponseError} If response is malformed\n *\n * @example\n * ```typescript\n * const auth = await requestAuthFromParent({\n * parentOrigin: 'https://app.example.com',\n * timeout: 5000\n * });\n * console.log('Received API key:', auth.apiKey);\n * ```\n */\nexport async function requestAuthFromParent(\n options: PostMessageAuthOptions = {}\n): Promise<PostMessageAuthResult> {\n const {\n parentOrigin,\n timeout = 5000,\n retries = 0,\n } = options;\n\n // Validate we're in an iframe\n if (!isInIframe()) {\n throw new PostMessageAuthNotInIframeError();\n }\n\n // Validate we're in a browser environment\n if (typeof window === 'undefined') {\n throw new PostMessageAuthNotInIframeError();\n }\n\n // Generate request ID\n const requestId = generateRequestId();\n\n // Create request message\n const request: OxyAuthRequestMessage = {\n type: 'OXY_AUTH_REQUEST',\n version: '1.0',\n timestamp: Date.now(),\n requestId,\n };\n\n // Attempt authentication with retries\n let lastError: Error | null = null;\n const maxAttempts = retries + 1;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n // Set up listener before sending request to avoid race condition\n const responsePromise = createAuthListener(requestId, parentOrigin, timeout);\n\n // Send request to parent\n const targetOrigin = parentOrigin || '*';\n window.parent.postMessage(request, targetOrigin);\n\n // Wait for response\n const response = await responsePromise;\n\n // Return successful result\n return {\n apiKey: response.apiKey,\n projectId: response.projectId,\n baseUrl: response.baseUrl,\n source: 'postmessage',\n };\n } catch (error) {\n lastError = error as Error;\n\n // If this isn't a timeout, don't retry\n if (!(error instanceof PostMessageAuthTimeoutError)) {\n throw error;\n }\n\n // If we have more attempts, continue\n if (attempt < maxAttempts - 1) {\n // Optional: Add a small delay before retry\n await new Promise((resolve) => setTimeout(resolve, 100));\n continue;\n }\n\n // All retries exhausted\n throw error;\n }\n }\n\n // Should never reach here, but TypeScript needs this\n throw lastError || new Error('Authentication failed');\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  // @oxy/sdk - TypeScript SDK for Oxy data platform
2
- import { i as validateOrigin, n as isInIframe, r as requestAuthFromParent, t as generateRequestId } from "./postMessage-Dq9lXKK0.mjs";
2
+ import { i as validateOrigin, n as isInIframe, r as requestAuthFromParent, t as generateRequestId } from "./postMessage-DLGITn0e.mjs";
3
3
 
4
4
  export { isInIframe, requestAuthFromParent };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxy-hq/sdk",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "TypeScript SDK for interacting with Oxy data platform",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -26,7 +26,7 @@
26
26
  "lint": "eslint src --ext .ts",
27
27
  "test": "vitest run",
28
28
  "test:watch": "vitest",
29
- "prepublishOnly": "npm run build",
29
+ "prepublishOnly": "pnpm build",
30
30
  "publish:beta": "npm publish --tag beta",
31
31
  "publish:latest": "npm publish --tag latest",
32
32
  "demo:react": "cd examples/react-vite-demo && pnpm install --ignore-workspace && pnpm dev",
@@ -1 +0,0 @@
1
- {"version":3,"file":"postMessage-CtL0W-Zt.cjs","names":[],"sources":["../src/types.ts","../src/auth/postMessage.ts"],"sourcesContent":["/**\n * Represents an app item in the project\n */\nexport interface AppItem {\n name: string;\n path: string;\n}\n\n/**\n * Reference to a data file (usually parquet)\n */\nexport interface FileReference {\n file_path: string;\n}\n\n/**\n * Table data structure for in-memory tables\n * (used when data is fetched and parsed)\n */\nexport interface TableData {\n columns: string[];\n rows: any[][];\n total_rows?: number;\n}\n\nexport type DataContainer = Record<string, FileReference>;\n\n/**\n * Response from app data endpoints\n */\nexport interface AppDataResponse {\n data: DataContainer | null;\n error: string | null;\n}\n\n/**\n * Display with potential error\n */\nexport interface DisplayWithError {\n display?: DisplayData;\n error?: string;\n}\n\n/**\n * Display data structure\n */\nexport interface DisplayData {\n type: string;\n content: any;\n}\n\n/**\n * Response from get displays endpoint\n */\nexport interface GetDisplaysResponse {\n displays: DisplayWithError[];\n}\n\n/**\n * Error response from the API\n */\nexport interface ApiError {\n message: string;\n status: number;\n details?: any;\n}\n\n/**\n * Query result from ParquetReader\n */\nexport interface QueryResult {\n columns: string[];\n rows: any[][];\n rowCount: number;\n}\n\n/**\n * PostMessage authentication protocol types\n */\n\n/**\n * Request message sent from iframe to parent window\n */\nexport interface OxyAuthRequestMessage {\n type: 'OXY_AUTH_REQUEST';\n version: '1.0';\n timestamp: number;\n requestId: string;\n}\n\n/**\n * Response message sent from parent window to iframe\n */\nexport interface OxyAuthResponseMessage {\n type: 'OXY_AUTH_RESPONSE';\n version: '1.0';\n requestId: string;\n apiKey: string;\n projectId?: string;\n baseUrl?: string;\n}\n\n/**\n * Options for postMessage authentication\n */\nexport interface PostMessageAuthOptions {\n /** Required parent window origin for security (e.g., 'https://app.example.com'). Use '*' only in development! */\n parentOrigin?: string;\n /** Timeout in milliseconds (default: 5000) */\n timeout?: number;\n /** Number of retry attempts (default: 0) */\n retries?: number;\n}\n\n/**\n * Result from successful postMessage authentication\n */\nexport interface PostMessageAuthResult {\n apiKey: string;\n projectId?: string;\n baseUrl?: string;\n source: 'postmessage';\n}\n\n/**\n * Custom error classes for postMessage authentication\n */\n\n/**\n * Error thrown when postMessage authentication times out\n */\nexport class PostMessageAuthTimeoutError extends Error {\n constructor(timeout: number) {\n super(\n `Parent window did not respond to authentication request within ${timeout}ms.\\n\\n` +\n `Possible causes:\\n` +\n `- Parent window is not listening for 'OXY_AUTH_REQUEST' messages\\n` +\n `- Parent origin mismatch\\n` +\n `- Network/browser issues\\n\\n` +\n `Troubleshooting:\\n` +\n `1. Verify parent window has message listener set up\\n` +\n `2. Check parentOrigin configuration matches parent window origin\\n` +\n `3. Open browser console in parent window for errors`\n );\n this.name = 'PostMessageAuthTimeoutError';\n }\n}\n\n/**\n * Error thrown when authentication response comes from unauthorized origin\n */\nexport class PostMessageAuthInvalidOriginError extends Error {\n constructor(expected: string, actual: string) {\n super(\n `Received authentication response from unauthorized origin.\\n\\n` +\n `Expected: ${expected}\\n` +\n `Actual: ${actual}\\n\\n` +\n `This is a security error. Verify your parentOrigin configuration.`\n );\n this.name = 'PostMessageAuthInvalidOriginError';\n }\n}\n\n/**\n * Error thrown when postMessage authentication is attempted outside iframe context\n */\nexport class PostMessageAuthNotInIframeError extends Error {\n constructor() {\n super(\n `PostMessage authentication is only available when running in an iframe context.\\n\\n` +\n `Current context: ${typeof window !== 'undefined' ? (window === window.parent ? 'top-level window' : 'iframe') : 'non-browser (Node.js)'}\\n\\n` +\n `If you're running in a regular browser window, use direct configuration instead:\\n` +\n `const client = new OxyClient({ apiKey: 'your-key', ... })`\n );\n this.name = 'PostMessageAuthNotInIframeError';\n }\n}\n\n/**\n * Error thrown when authentication response is malformed or invalid\n */\nexport class PostMessageAuthInvalidResponseError extends Error {\n constructor(reason: string) {\n super(`Invalid authentication response from parent: ${reason}`);\n this.name = 'PostMessageAuthInvalidResponseError';\n }\n}\n","/**\n * PostMessage-based authentication for iframe scenarios\n *\n * This module enables secure cross-origin authentication between an iframe\n * (running the Oxy SDK) and its parent window (holding the API key).\n */\n\nimport type {\n OxyAuthRequestMessage,\n OxyAuthResponseMessage,\n PostMessageAuthOptions,\n PostMessageAuthResult,\n} from '../types';\n\nimport {\n PostMessageAuthTimeoutError,\n PostMessageAuthInvalidOriginError,\n PostMessageAuthNotInIframeError,\n PostMessageAuthInvalidResponseError,\n} from '../types';\n\n/**\n * Check if the current context is running inside an iframe\n *\n * @returns true if running in an iframe, false otherwise (including Node.js)\n */\nexport function isInIframe(): boolean {\n // Check if we're in a browser environment\n if (typeof window === 'undefined') {\n return false;\n }\n\n // Check if window has a parent and it's different from itself\n try {\n return window !== window.parent && window.parent !== null;\n } catch (e) {\n // Cross-origin access might throw an error, but we're still in an iframe\n return true;\n }\n}\n\n/**\n * Generate a unique request ID for tracking auth requests\n *\n * @returns A unique identifier string\n */\nexport function generateRequestId(): string {\n // Use crypto.randomUUID if available (modern browsers)\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n\n // Fallback for older environments: timestamp + random\n return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n}\n\n/**\n * Validate that a message origin matches the expected origin\n *\n * @param messageOrigin - The origin from the message event\n * @param allowedOrigin - The expected/allowed origin\n * @returns true if origin is valid, false otherwise\n */\nexport function validateOrigin(\n messageOrigin: string,\n allowedOrigin?: string\n): boolean {\n // If no allowed origin is specified, reject (security)\n if (!allowedOrigin) {\n return false;\n }\n\n // Wildcard - allow any origin (development only!)\n if (allowedOrigin === '*') {\n return true;\n }\n\n // Exact match\n if (messageOrigin === allowedOrigin) {\n return true;\n }\n\n // Try URL parsing for more flexible matching\n try {\n const messageUrl = new URL(messageOrigin);\n const allowedUrl = new URL(allowedOrigin);\n return messageUrl.origin === allowedUrl.origin;\n } catch (e) {\n // If URL parsing fails, do simple string match\n return messageOrigin === allowedOrigin;\n }\n}\n\n/**\n * Create a promise that listens for an authentication response\n *\n * @param requestId - The request ID to match against\n * @param origin - The expected parent origin\n * @param timeout - Timeout in milliseconds\n * @returns Promise that resolves with the auth response\n */\nfunction createAuthListener(\n requestId: string,\n origin: string | undefined,\n timeout: number\n): Promise<OxyAuthResponseMessage> {\n return new Promise((resolve, reject) => {\n let timeoutId: NodeJS.Timeout;\n let listener: (event: MessageEvent) => void;\n\n // Set up timeout\n timeoutId = setTimeout(() => {\n window.removeEventListener('message', listener);\n reject(new PostMessageAuthTimeoutError(timeout));\n }, timeout);\n\n // Set up message listener\n listener = (event: MessageEvent) => {\n // Validate origin\n if (!validateOrigin(event.origin, origin)) {\n // Don't reject here - might be other postMessage traffic\n // Just ignore messages from wrong origins\n return;\n }\n\n // Check message type\n if (!event.data || event.data.type !== 'OXY_AUTH_RESPONSE') {\n // Not our message type, ignore\n return;\n }\n\n const response = event.data as OxyAuthResponseMessage;\n\n // Validate request ID matches\n if (response.requestId !== requestId) {\n // Wrong request ID, ignore (might be another auth in progress)\n return;\n }\n\n // Validate response structure\n if (!response.apiKey) {\n clearTimeout(timeoutId);\n window.removeEventListener('message', listener);\n reject(\n new PostMessageAuthInvalidResponseError('Missing apiKey in response')\n );\n return;\n }\n\n // Validate version\n if (response.version !== '1.0') {\n clearTimeout(timeoutId);\n window.removeEventListener('message', listener);\n reject(\n new PostMessageAuthInvalidResponseError(\n `Unsupported protocol version: ${response.version}`\n )\n );\n return;\n }\n\n // Success!\n clearTimeout(timeoutId);\n window.removeEventListener('message', listener);\n resolve(response);\n };\n\n // Start listening\n window.addEventListener('message', listener);\n });\n}\n\n/**\n * Request authentication from parent window via postMessage\n *\n * This is the main entry point for iframe-based authentication.\n * It sends a request to the parent window and waits for a response.\n *\n * @param options - Configuration options for the auth request\n * @returns Promise that resolves with authentication credentials\n * @throws {PostMessageAuthNotInIframeError} If not in an iframe\n * @throws {PostMessageAuthTimeoutError} If parent doesn't respond in time\n * @throws {PostMessageAuthInvalidOriginError} If response from wrong origin\n * @throws {PostMessageAuthInvalidResponseError} If response is malformed\n *\n * @example\n * ```typescript\n * const auth = await requestAuthFromParent({\n * parentOrigin: 'https://app.example.com',\n * timeout: 5000\n * });\n * console.log('Received API key:', auth.apiKey);\n * ```\n */\nexport async function requestAuthFromParent(\n options: PostMessageAuthOptions = {}\n): Promise<PostMessageAuthResult> {\n const {\n parentOrigin,\n timeout = 5000,\n retries = 0,\n } = options;\n\n // Validate we're in an iframe\n if (!isInIframe()) {\n throw new PostMessageAuthNotInIframeError();\n }\n\n // Validate we're in a browser environment\n if (typeof window === 'undefined') {\n throw new PostMessageAuthNotInIframeError();\n }\n\n // Generate request ID\n const requestId = generateRequestId();\n\n // Create request message\n const request: OxyAuthRequestMessage = {\n type: 'OXY_AUTH_REQUEST',\n version: '1.0',\n timestamp: Date.now(),\n requestId,\n };\n\n // Attempt authentication with retries\n let lastError: Error | null = null;\n const maxAttempts = retries + 1;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n // Set up listener before sending request to avoid race condition\n const responsePromise = createAuthListener(requestId, parentOrigin, timeout);\n\n // Send request to parent\n const targetOrigin = parentOrigin || '*';\n window.parent.postMessage(request, targetOrigin);\n\n // Wait for response\n const response = await responsePromise;\n\n // Return successful result\n return {\n apiKey: response.apiKey,\n projectId: response.projectId,\n baseUrl: response.baseUrl,\n source: 'postmessage',\n };\n } catch (error) {\n lastError = error as Error;\n\n // If this isn't a timeout, don't retry\n if (!(error instanceof PostMessageAuthTimeoutError)) {\n throw error;\n }\n\n // If we have more attempts, continue\n if (attempt < maxAttempts - 1) {\n // Optional: Add a small delay before retry\n await new Promise((resolve) => setTimeout(resolve, 100));\n continue;\n }\n\n // All retries exhausted\n throw error;\n }\n }\n\n // Should never reach here, but TypeScript needs this\n throw lastError || new Error('Authentication failed');\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"postMessage-Dq9lXKK0.mjs","names":[],"sources":["../src/types.ts","../src/auth/postMessage.ts"],"sourcesContent":["/**\n * Represents an app item in the project\n */\nexport interface AppItem {\n name: string;\n path: string;\n}\n\n/**\n * Reference to a data file (usually parquet)\n */\nexport interface FileReference {\n file_path: string;\n}\n\n/**\n * Table data structure for in-memory tables\n * (used when data is fetched and parsed)\n */\nexport interface TableData {\n columns: string[];\n rows: any[][];\n total_rows?: number;\n}\n\nexport type DataContainer = Record<string, FileReference>;\n\n/**\n * Response from app data endpoints\n */\nexport interface AppDataResponse {\n data: DataContainer | null;\n error: string | null;\n}\n\n/**\n * Display with potential error\n */\nexport interface DisplayWithError {\n display?: DisplayData;\n error?: string;\n}\n\n/**\n * Display data structure\n */\nexport interface DisplayData {\n type: string;\n content: any;\n}\n\n/**\n * Response from get displays endpoint\n */\nexport interface GetDisplaysResponse {\n displays: DisplayWithError[];\n}\n\n/**\n * Error response from the API\n */\nexport interface ApiError {\n message: string;\n status: number;\n details?: any;\n}\n\n/**\n * Query result from ParquetReader\n */\nexport interface QueryResult {\n columns: string[];\n rows: any[][];\n rowCount: number;\n}\n\n/**\n * PostMessage authentication protocol types\n */\n\n/**\n * Request message sent from iframe to parent window\n */\nexport interface OxyAuthRequestMessage {\n type: 'OXY_AUTH_REQUEST';\n version: '1.0';\n timestamp: number;\n requestId: string;\n}\n\n/**\n * Response message sent from parent window to iframe\n */\nexport interface OxyAuthResponseMessage {\n type: 'OXY_AUTH_RESPONSE';\n version: '1.0';\n requestId: string;\n apiKey: string;\n projectId?: string;\n baseUrl?: string;\n}\n\n/**\n * Options for postMessage authentication\n */\nexport interface PostMessageAuthOptions {\n /** Required parent window origin for security (e.g., 'https://app.example.com'). Use '*' only in development! */\n parentOrigin?: string;\n /** Timeout in milliseconds (default: 5000) */\n timeout?: number;\n /** Number of retry attempts (default: 0) */\n retries?: number;\n}\n\n/**\n * Result from successful postMessage authentication\n */\nexport interface PostMessageAuthResult {\n apiKey: string;\n projectId?: string;\n baseUrl?: string;\n source: 'postmessage';\n}\n\n/**\n * Custom error classes for postMessage authentication\n */\n\n/**\n * Error thrown when postMessage authentication times out\n */\nexport class PostMessageAuthTimeoutError extends Error {\n constructor(timeout: number) {\n super(\n `Parent window did not respond to authentication request within ${timeout}ms.\\n\\n` +\n `Possible causes:\\n` +\n `- Parent window is not listening for 'OXY_AUTH_REQUEST' messages\\n` +\n `- Parent origin mismatch\\n` +\n `- Network/browser issues\\n\\n` +\n `Troubleshooting:\\n` +\n `1. Verify parent window has message listener set up\\n` +\n `2. Check parentOrigin configuration matches parent window origin\\n` +\n `3. Open browser console in parent window for errors`\n );\n this.name = 'PostMessageAuthTimeoutError';\n }\n}\n\n/**\n * Error thrown when authentication response comes from unauthorized origin\n */\nexport class PostMessageAuthInvalidOriginError extends Error {\n constructor(expected: string, actual: string) {\n super(\n `Received authentication response from unauthorized origin.\\n\\n` +\n `Expected: ${expected}\\n` +\n `Actual: ${actual}\\n\\n` +\n `This is a security error. Verify your parentOrigin configuration.`\n );\n this.name = 'PostMessageAuthInvalidOriginError';\n }\n}\n\n/**\n * Error thrown when postMessage authentication is attempted outside iframe context\n */\nexport class PostMessageAuthNotInIframeError extends Error {\n constructor() {\n super(\n `PostMessage authentication is only available when running in an iframe context.\\n\\n` +\n `Current context: ${typeof window !== 'undefined' ? (window === window.parent ? 'top-level window' : 'iframe') : 'non-browser (Node.js)'}\\n\\n` +\n `If you're running in a regular browser window, use direct configuration instead:\\n` +\n `const client = new OxyClient({ apiKey: 'your-key', ... })`\n );\n this.name = 'PostMessageAuthNotInIframeError';\n }\n}\n\n/**\n * Error thrown when authentication response is malformed or invalid\n */\nexport class PostMessageAuthInvalidResponseError extends Error {\n constructor(reason: string) {\n super(`Invalid authentication response from parent: ${reason}`);\n this.name = 'PostMessageAuthInvalidResponseError';\n }\n}\n","/**\n * PostMessage-based authentication for iframe scenarios\n *\n * This module enables secure cross-origin authentication between an iframe\n * (running the Oxy SDK) and its parent window (holding the API key).\n */\n\nimport type {\n OxyAuthRequestMessage,\n OxyAuthResponseMessage,\n PostMessageAuthOptions,\n PostMessageAuthResult,\n} from '../types';\n\nimport {\n PostMessageAuthTimeoutError,\n PostMessageAuthInvalidOriginError,\n PostMessageAuthNotInIframeError,\n PostMessageAuthInvalidResponseError,\n} from '../types';\n\n/**\n * Check if the current context is running inside an iframe\n *\n * @returns true if running in an iframe, false otherwise (including Node.js)\n */\nexport function isInIframe(): boolean {\n // Check if we're in a browser environment\n if (typeof window === 'undefined') {\n return false;\n }\n\n // Check if window has a parent and it's different from itself\n try {\n return window !== window.parent && window.parent !== null;\n } catch (e) {\n // Cross-origin access might throw an error, but we're still in an iframe\n return true;\n }\n}\n\n/**\n * Generate a unique request ID for tracking auth requests\n *\n * @returns A unique identifier string\n */\nexport function generateRequestId(): string {\n // Use crypto.randomUUID if available (modern browsers)\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n\n // Fallback for older environments: timestamp + random\n return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n}\n\n/**\n * Validate that a message origin matches the expected origin\n *\n * @param messageOrigin - The origin from the message event\n * @param allowedOrigin - The expected/allowed origin\n * @returns true if origin is valid, false otherwise\n */\nexport function validateOrigin(\n messageOrigin: string,\n allowedOrigin?: string\n): boolean {\n // If no allowed origin is specified, reject (security)\n if (!allowedOrigin) {\n return false;\n }\n\n // Wildcard - allow any origin (development only!)\n if (allowedOrigin === '*') {\n return true;\n }\n\n // Exact match\n if (messageOrigin === allowedOrigin) {\n return true;\n }\n\n // Try URL parsing for more flexible matching\n try {\n const messageUrl = new URL(messageOrigin);\n const allowedUrl = new URL(allowedOrigin);\n return messageUrl.origin === allowedUrl.origin;\n } catch (e) {\n // If URL parsing fails, do simple string match\n return messageOrigin === allowedOrigin;\n }\n}\n\n/**\n * Create a promise that listens for an authentication response\n *\n * @param requestId - The request ID to match against\n * @param origin - The expected parent origin\n * @param timeout - Timeout in milliseconds\n * @returns Promise that resolves with the auth response\n */\nfunction createAuthListener(\n requestId: string,\n origin: string | undefined,\n timeout: number\n): Promise<OxyAuthResponseMessage> {\n return new Promise((resolve, reject) => {\n let timeoutId: NodeJS.Timeout;\n let listener: (event: MessageEvent) => void;\n\n // Set up timeout\n timeoutId = setTimeout(() => {\n window.removeEventListener('message', listener);\n reject(new PostMessageAuthTimeoutError(timeout));\n }, timeout);\n\n // Set up message listener\n listener = (event: MessageEvent) => {\n // Validate origin\n if (!validateOrigin(event.origin, origin)) {\n // Don't reject here - might be other postMessage traffic\n // Just ignore messages from wrong origins\n return;\n }\n\n // Check message type\n if (!event.data || event.data.type !== 'OXY_AUTH_RESPONSE') {\n // Not our message type, ignore\n return;\n }\n\n const response = event.data as OxyAuthResponseMessage;\n\n // Validate request ID matches\n if (response.requestId !== requestId) {\n // Wrong request ID, ignore (might be another auth in progress)\n return;\n }\n\n // Validate response structure\n if (!response.apiKey) {\n clearTimeout(timeoutId);\n window.removeEventListener('message', listener);\n reject(\n new PostMessageAuthInvalidResponseError('Missing apiKey in response')\n );\n return;\n }\n\n // Validate version\n if (response.version !== '1.0') {\n clearTimeout(timeoutId);\n window.removeEventListener('message', listener);\n reject(\n new PostMessageAuthInvalidResponseError(\n `Unsupported protocol version: ${response.version}`\n )\n );\n return;\n }\n\n // Success!\n clearTimeout(timeoutId);\n window.removeEventListener('message', listener);\n resolve(response);\n };\n\n // Start listening\n window.addEventListener('message', listener);\n });\n}\n\n/**\n * Request authentication from parent window via postMessage\n *\n * This is the main entry point for iframe-based authentication.\n * It sends a request to the parent window and waits for a response.\n *\n * @param options - Configuration options for the auth request\n * @returns Promise that resolves with authentication credentials\n * @throws {PostMessageAuthNotInIframeError} If not in an iframe\n * @throws {PostMessageAuthTimeoutError} If parent doesn't respond in time\n * @throws {PostMessageAuthInvalidOriginError} If response from wrong origin\n * @throws {PostMessageAuthInvalidResponseError} If response is malformed\n *\n * @example\n * ```typescript\n * const auth = await requestAuthFromParent({\n * parentOrigin: 'https://app.example.com',\n * timeout: 5000\n * });\n * console.log('Received API key:', auth.apiKey);\n * ```\n */\nexport async function requestAuthFromParent(\n options: PostMessageAuthOptions = {}\n): Promise<PostMessageAuthResult> {\n const {\n parentOrigin,\n timeout = 5000,\n retries = 0,\n } = options;\n\n // Validate we're in an iframe\n if (!isInIframe()) {\n throw new PostMessageAuthNotInIframeError();\n }\n\n // Validate we're in a browser environment\n if (typeof window === 'undefined') {\n throw new PostMessageAuthNotInIframeError();\n }\n\n // Generate request ID\n const requestId = generateRequestId();\n\n // Create request message\n const request: OxyAuthRequestMessage = {\n type: 'OXY_AUTH_REQUEST',\n version: '1.0',\n timestamp: Date.now(),\n requestId,\n };\n\n // Attempt authentication with retries\n let lastError: Error | null = null;\n const maxAttempts = retries + 1;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n // Set up listener before sending request to avoid race condition\n const responsePromise = createAuthListener(requestId, parentOrigin, timeout);\n\n // Send request to parent\n const targetOrigin = parentOrigin || '*';\n window.parent.postMessage(request, targetOrigin);\n\n // Wait for response\n const response = await responsePromise;\n\n // Return successful result\n return {\n apiKey: response.apiKey,\n projectId: response.projectId,\n baseUrl: response.baseUrl,\n source: 'postmessage',\n };\n } catch (error) {\n lastError = error as Error;\n\n // If this isn't a timeout, don't retry\n if (!(error instanceof PostMessageAuthTimeoutError)) {\n throw error;\n }\n\n // If we have more attempts, continue\n if (attempt < maxAttempts - 1) {\n // Optional: Add a small delay before retry\n await new Promise((resolve) => setTimeout(resolve, 100));\n continue;\n }\n\n // All retries exhausted\n throw error;\n }\n }\n\n // Should never reach here, but TypeScript needs this\n throw lastError || new Error('Authentication failed');\n}\n"],"mappings":"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"}