@oxy-hq/sdk 1.0.0 → 2.0.0

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/package.json CHANGED
@@ -1,78 +1,73 @@
1
- {
2
- "name": "@oxy-hq/sdk",
3
- "version": "1.0.0",
4
- "description": "TypeScript SDK for interacting with Oxy data platform",
5
- "main": "./dist/index.js",
6
- "module": "./dist/index.mjs",
7
- "types": "./dist/index.d.ts",
8
- "type": "module",
9
- "exports": {
10
- ".": {
11
- "types": "./dist/index.d.ts",
12
- "require": "./dist/index.js",
13
- "import": "./dist/index.mjs"
14
- }
15
- },
16
- "files": [
17
- "dist",
18
- "README.md",
19
- "LICENSE"
20
- ],
21
- "scripts": {
22
- "build": "tsdown",
23
- "build:watch": "tsdown --watch",
24
- "dev": "tsdown --watch",
25
- "typecheck": "tsc --noEmit",
26
- "lint": "ESLINT_USE_FLAT_CONFIG=false eslint src --ext .ts",
27
- "test": "vitest run",
28
- "test:watch": "vitest",
29
- "prepublishOnly": "pnpm build",
30
- "publish:beta": "npm publish --tag beta",
31
- "publish:latest": "npm publish --tag latest",
32
- "demo:react": "cd examples/react-vite-demo && pnpm install --ignore-workspace && pnpm dev",
33
- "demo:setup": "cd examples/react-vite-demo && pnpm install --ignore-workspace"
34
- },
35
- "keywords": [
36
- "oxy",
37
- "data",
38
- "analytics",
39
- "sdk",
40
- "parquet",
41
- "duckdb"
42
- ],
43
- "author": "Oxy Team",
44
- "license": "MIT",
45
- "repository": {
46
- "type": "git",
47
- "url": "https://github.com/dataframehq/oxy-internal.git",
48
- "directory": "sdk/typescript"
49
- },
50
- "bugs": {
51
- "url": "https://github.com/dataframehq/oxy-internal/issues"
52
- },
53
- "homepage": "https://oxy.tech",
54
- "peerDependencies": {
55
- "@duckdb/duckdb-wasm": "^1.29.0",
56
- "react": "^19.0.0"
57
- },
58
- "peerDependenciesMeta": {
59
- "react": {
60
- "optional": true
61
- }
62
- },
63
- "devDependencies": {
64
- "@duckdb/duckdb-wasm": "^1.32.0",
65
- "@types/node": "^25.2.3",
66
- "@types/react": "^19.2.14",
67
- "@typescript-eslint/eslint-plugin": "^8.55.0",
68
- "@typescript-eslint/parser": "^8.55.0",
69
- "eslint": "^10.0.0",
70
- "react": "^19.2.4",
71
- "tsdown": "^0.20.3",
72
- "typescript": "^5.9.3",
73
- "vitest": "^4.0.18"
74
- },
75
- "engines": {
76
- "node": ">=18.0.0"
77
- }
78
- }
1
+ {
2
+ "name": "@oxy-hq/sdk",
3
+ "version": "2.0.0",
4
+ "description": "React SDK for building customer-app bundles on the Oxy platform",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "type": "module",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "require": "./dist/index.js",
13
+ "import": "./dist/index.mjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md",
19
+ "LICENSE"
20
+ ],
21
+ "publishConfig": {
22
+ "registry": "https://registry.npmjs.org",
23
+ "access": "public"
24
+ },
25
+ "scripts": {
26
+ "build": "tsdown",
27
+ "build:watch": "tsdown --watch",
28
+ "dev": "tsdown --watch",
29
+ "typecheck": "tsc --noEmit",
30
+ "lint": "ESLINT_USE_FLAT_CONFIG=false eslint src --ext .ts",
31
+ "test": "vitest run",
32
+ "test:watch": "vitest",
33
+ "prepublishOnly": "pnpm build",
34
+ "publish:beta": "npm publish --tag beta",
35
+ "publish:latest": "npm publish --tag latest"
36
+ },
37
+ "keywords": [
38
+ "oxy",
39
+ "data",
40
+ "analytics",
41
+ "sdk",
42
+ "react",
43
+ "customer-apps"
44
+ ],
45
+ "author": "Oxy Team",
46
+ "license": "MIT",
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "https://github.com/oxy-hq/oxy-internal.git",
50
+ "directory": "sdk/typescript"
51
+ },
52
+ "bugs": {
53
+ "url": "https://github.com/oxy-hq/oxy-internal/issues"
54
+ },
55
+ "homepage": "https://oxy.tech",
56
+ "peerDependencies": {
57
+ "react": "^19.0.0"
58
+ },
59
+ "devDependencies": {
60
+ "@types/node": "^25.9.1",
61
+ "@types/react": "^19.2.15",
62
+ "@typescript-eslint/eslint-plugin": "^8.60.0",
63
+ "@typescript-eslint/parser": "^8.60.0",
64
+ "eslint": "^10.4.0",
65
+ "react": "^19.2.6",
66
+ "tsdown": "^0.22.0",
67
+ "typescript": "^6.0.3",
68
+ "vitest": "^4.1.7"
69
+ },
70
+ "engines": {
71
+ "node": ">=18.0.0"
72
+ }
73
+ }
@@ -1,233 +0,0 @@
1
- // @oxy/sdk - TypeScript SDK for Oxy data platform
2
- const require_index = require('./index.cjs');
3
-
4
- //#region src/types.ts
5
- /**
6
- * Custom error classes for postMessage authentication
7
- */
8
- /**
9
- * Error thrown when postMessage authentication times out
10
- */
11
- var PostMessageAuthTimeoutError = class extends Error {
12
- constructor(timeout) {
13
- super(`Parent window did not respond to authentication request within ${timeout}ms.\n\nPossible causes:\n- Parent window is not listening for 'OXY_AUTH_REQUEST' messages\n- Parent origin mismatch\n- Network/browser issues\n\nTroubleshooting:\n1. Verify parent window has message listener set up\n2. Check parentOrigin configuration matches parent window origin\n3. Open browser console in parent window for errors`);
14
- this.name = "PostMessageAuthTimeoutError";
15
- }
16
- };
17
- /**
18
- * Error thrown when authentication response comes from unauthorized origin
19
- */
20
- var PostMessageAuthInvalidOriginError = class extends Error {
21
- constructor(expected, actual) {
22
- super(`Received authentication response from unauthorized origin.\n\nExpected: ${expected}\nActual: ${actual}\n\nThis is a security error. Verify your parentOrigin configuration.`);
23
- this.name = "PostMessageAuthInvalidOriginError";
24
- }
25
- };
26
- /**
27
- * Error thrown when postMessage authentication is attempted outside iframe context
28
- */
29
- var PostMessageAuthNotInIframeError = class extends Error {
30
- constructor() {
31
- const currentContext = getCurrentContext();
32
- super(`PostMessage authentication is only available when running in an iframe context.\n\nCurrent context: ${currentContext}\n\nIf you're running in a regular browser window, use direct configuration instead:\nconst client = new OxyClient({ apiKey: 'your-key', ... })`);
33
- this.name = "PostMessageAuthNotInIframeError";
34
- }
35
- };
36
- function getCurrentContext() {
37
- if (typeof window === "undefined") return "non-browser (Node.js)";
38
- if (window === window.parent) return "top-level window";
39
- return "iframe";
40
- }
41
- /**
42
- * Error thrown when authentication response is malformed or invalid
43
- */
44
- var PostMessageAuthInvalidResponseError = class extends Error {
45
- constructor(reason) {
46
- super(`Invalid authentication response from parent: ${reason}`);
47
- this.name = "PostMessageAuthInvalidResponseError";
48
- }
49
- };
50
-
51
- //#endregion
52
- //#region src/auth/postMessage.ts
53
- var postMessage_exports = /* @__PURE__ */ require_index.__exportAll({
54
- generateRequestId: () => generateRequestId,
55
- isInIframe: () => isInIframe,
56
- requestAuthFromParent: () => requestAuthFromParent,
57
- validateOrigin: () => validateOrigin
58
- });
59
- /**
60
- * Check if the current context is running inside an iframe
61
- *
62
- * @returns true if running in an iframe, false otherwise (including Node.js)
63
- */
64
- function isInIframe() {
65
- if (typeof window === "undefined") return false;
66
- try {
67
- return window !== window.parent && window.parent !== null;
68
- } catch {
69
- return true;
70
- }
71
- }
72
- /**
73
- * Generate a unique request ID for tracking auth requests
74
- *
75
- * @returns A unique identifier string
76
- */
77
- function generateRequestId() {
78
- if (typeof crypto !== "undefined" && crypto.randomUUID) return crypto.randomUUID();
79
- return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
80
- }
81
- /**
82
- * Validate that a message origin matches the expected origin
83
- *
84
- * @param messageOrigin - The origin from the message event
85
- * @param allowedOrigin - The expected/allowed origin
86
- * @returns true if origin is valid, false otherwise
87
- */
88
- function validateOrigin(messageOrigin, allowedOrigin) {
89
- if (!allowedOrigin) return false;
90
- if (allowedOrigin === "*") return true;
91
- if (messageOrigin === allowedOrigin) return true;
92
- try {
93
- const messageUrl = new URL(messageOrigin);
94
- const allowedUrl = new URL(allowedOrigin);
95
- return messageUrl.origin === allowedUrl.origin;
96
- } catch {
97
- return messageOrigin === allowedOrigin;
98
- }
99
- }
100
- /**
101
- * Create a promise that listens for an authentication response
102
- *
103
- * @param requestId - The request ID to match against
104
- * @param origin - The expected parent origin
105
- * @param timeout - Timeout in milliseconds
106
- * @returns Promise that resolves with the auth response
107
- */
108
- function createAuthListener(requestId, origin, timeout) {
109
- return new Promise((resolve, reject) => {
110
- const listener = (event) => {
111
- if (!validateOrigin(event.origin, origin)) return;
112
- if (!event.data || event.data.type !== "OXY_AUTH_RESPONSE") return;
113
- const response = event.data;
114
- if (response.requestId !== requestId) return;
115
- if (response.version !== "1.0") {
116
- clearTimeout(timeoutId);
117
- window.removeEventListener("message", listener);
118
- reject(new PostMessageAuthInvalidResponseError(`Unsupported protocol version: ${response.version}`));
119
- return;
120
- }
121
- clearTimeout(timeoutId);
122
- window.removeEventListener("message", listener);
123
- resolve(response);
124
- };
125
- const timeoutId = setTimeout(() => {
126
- window.removeEventListener("message", listener);
127
- reject(new PostMessageAuthTimeoutError(timeout));
128
- }, timeout);
129
- window.addEventListener("message", listener);
130
- });
131
- }
132
- /**
133
- * Request authentication from parent window via postMessage
134
- *
135
- * This is the main entry point for iframe-based authentication.
136
- * It sends a request to the parent window and waits for a response.
137
- *
138
- * @param options - Configuration options for the auth request
139
- * @returns Promise that resolves with authentication credentials
140
- * @throws {PostMessageAuthNotInIframeError} If not in an iframe
141
- * @throws {PostMessageAuthTimeoutError} If parent doesn't respond in time
142
- * @throws {PostMessageAuthInvalidOriginError} If response from wrong origin
143
- * @throws {PostMessageAuthInvalidResponseError} If response is malformed
144
- *
145
- * @example
146
- * ```typescript
147
- * const auth = await requestAuthFromParent({
148
- * parentOrigin: 'https://app.example.com',
149
- * timeout: 5000
150
- * });
151
- * console.log('Received API key:', auth.apiKey);
152
- * ```
153
- */
154
- async function requestAuthFromParent(options = {}) {
155
- const { parentOrigin, timeout = 5e3, retries = 0 } = options;
156
- if (!isInIframe()) throw new PostMessageAuthNotInIframeError();
157
- if (typeof window === "undefined") throw new PostMessageAuthNotInIframeError();
158
- const requestId = generateRequestId();
159
- const request = {
160
- type: "OXY_AUTH_REQUEST",
161
- version: "1.0",
162
- timestamp: Date.now(),
163
- requestId
164
- };
165
- let lastError = null;
166
- const maxAttempts = retries + 1;
167
- for (let attempt = 0; attempt < maxAttempts; attempt++) try {
168
- const responsePromise = createAuthListener(requestId, parentOrigin, timeout);
169
- const targetOrigin = parentOrigin || "*";
170
- window.parent.postMessage(request, targetOrigin);
171
- const response = await responsePromise;
172
- return {
173
- apiKey: response.apiKey,
174
- projectId: response.projectId,
175
- baseUrl: response.baseUrl,
176
- source: "postmessage"
177
- };
178
- } catch (error) {
179
- lastError = error;
180
- if (!(error instanceof PostMessageAuthTimeoutError)) throw error;
181
- if (attempt < maxAttempts - 1) {
182
- await new Promise((resolve) => setTimeout(resolve, 100));
183
- continue;
184
- }
185
- throw error;
186
- }
187
- throw lastError || /* @__PURE__ */ new Error("Authentication failed");
188
- }
189
-
190
- //#endregion
191
- Object.defineProperty(exports, 'PostMessageAuthInvalidOriginError', {
192
- enumerable: true,
193
- get: function () {
194
- return PostMessageAuthInvalidOriginError;
195
- }
196
- });
197
- Object.defineProperty(exports, 'PostMessageAuthInvalidResponseError', {
198
- enumerable: true,
199
- get: function () {
200
- return PostMessageAuthInvalidResponseError;
201
- }
202
- });
203
- Object.defineProperty(exports, 'PostMessageAuthNotInIframeError', {
204
- enumerable: true,
205
- get: function () {
206
- return PostMessageAuthNotInIframeError;
207
- }
208
- });
209
- Object.defineProperty(exports, 'PostMessageAuthTimeoutError', {
210
- enumerable: true,
211
- get: function () {
212
- return PostMessageAuthTimeoutError;
213
- }
214
- });
215
- Object.defineProperty(exports, 'isInIframe', {
216
- enumerable: true,
217
- get: function () {
218
- return isInIframe;
219
- }
220
- });
221
- Object.defineProperty(exports, 'postMessage_exports', {
222
- enumerable: true,
223
- get: function () {
224
- return postMessage_exports;
225
- }
226
- });
227
- Object.defineProperty(exports, 'requestAuthFromParent', {
228
- enumerable: true,
229
- get: function () {
230
- return requestAuthFromParent;
231
- }
232
- });
233
- //# sourceMappingURL=postMessage-Cb5PCtcE.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"postMessage-Cb5PCtcE.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: unknown[][];\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: unknown;\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?: unknown;\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 const currentContext = getCurrentContext();\n super(\n `PostMessage authentication is only available when running in an iframe context.\\n\\n` +\n `Current context: ${currentContext}\\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\nfunction getCurrentContext(): string {\n if (typeof window === \"undefined\") {\n return \"non-browser (Node.js)\";\n }\n if (window === window.parent) {\n return \"top-level window\";\n }\n return \"iframe\";\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 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 {\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 // Note: Math.random() is used here as a fallback for environments without crypto.randomUUID\n // This is acceptable for non-security-critical request IDs (used only for message correlation)\n /* eslint-disable sonarjs/pseudo-random */\n return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n /* eslint-enable sonarjs/pseudo-random */\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 {\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 // Set up message listener\n const 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 // Set up timeout\n const timeoutId = setTimeout(() => {\n window.removeEventListener(\"message\", listener);\n reject(new PostMessageAuthTimeoutError(timeout));\n }, timeout);\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 { parentOrigin, timeout = 5000, retries = 0 } = 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(\n requestId,\n parentOrigin,\n timeout,\n );\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":";;;;;;;;;;AA0HA,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,2EACe,SAAS,YACX,OAAO,uEAErB;AACD,OAAK,OAAO;;;;;;AAOhB,IAAa,kCAAb,cAAqD,MAAM;CACzD,cAAc;EACZ,MAAM,iBAAiB,mBAAmB;AAC1C,QACE,uGACsB,eAAe,iJAGtC;AACD,OAAK,OAAO;;;AAIhB,SAAS,oBAA4B;AACnC,KAAI,OAAO,WAAW,YACpB,QAAO;AAET,KAAI,WAAW,OAAO,OACpB,QAAO;AAET,QAAO;;;;;AAMT,IAAa,sCAAb,cAAyD,MAAM;CAC7D,YAAY,QAAgB;AAC1B,QAAM,gDAAgD,SAAS;AAC/D,OAAK,OAAO;;;;;;;;;;;;;;;;;ACjKhB,SAAgB,aAAsB;AAEpC,KAAI,OAAO,WAAW,YACpB,QAAO;AAIT,KAAI;AACF,SAAO,WAAW,OAAO,UAAU,OAAO,WAAW;SAC/C;AAEN,SAAO;;;;;;;;AASX,SAAgB,oBAA4B;AAE1C,KAAI,OAAO,WAAW,eAAe,OAAO,WAC1C,QAAO,OAAO,YAAY;AAO5B,QAAO,GAAG,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,UAAU,GAAG,GAAG;;;;;;;;;AAWrE,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;SAClC;AAEN,SAAO,kBAAkB;;;;;;;;;;;AAY7B,SAAS,mBACP,WACA,QACA,SACiC;AACjC,QAAO,IAAI,SAAS,SAAS,WAAW;EAEtC,MAAM,YAAY,UAAwB;AAExC,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;;EAInB,MAAM,YAAY,iBAAiB;AACjC,UAAO,oBAAoB,WAAW,SAAS;AAC/C,UAAO,IAAI,4BAA4B,QAAQ,CAAC;KAC/C,QAAQ;AAGX,SAAO,iBAAiB,WAAW,SAAS;GAC5C;;;;;;;;;;;;;;;;;;;;;;;;AAyBJ,eAAsB,sBACpB,UAAkC,EAAE,EACJ;CAChC,MAAM,EAAE,cAAc,UAAU,KAAM,UAAU,MAAM;AAGtD,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,mBACtB,WACA,cACA,QACD;EAGD,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"}
@@ -1,207 +0,0 @@
1
- // @oxy/sdk - TypeScript SDK for Oxy data platform
2
- //#region \0rolldown/runtime.js
3
- var __defProp = Object.defineProperty;
4
- var __exportAll = (all, no_symbols) => {
5
- let target = {};
6
- for (var name in all) {
7
- __defProp(target, name, {
8
- get: all[name],
9
- enumerable: true
10
- });
11
- }
12
- if (!no_symbols) {
13
- __defProp(target, Symbol.toStringTag, { value: "Module" });
14
- }
15
- return target;
16
- };
17
-
18
- //#endregion
19
- //#region src/types.ts
20
- /**
21
- * Custom error classes for postMessage authentication
22
- */
23
- /**
24
- * Error thrown when postMessage authentication times out
25
- */
26
- var PostMessageAuthTimeoutError = class extends Error {
27
- constructor(timeout) {
28
- super(`Parent window did not respond to authentication request within ${timeout}ms.\n\nPossible causes:\n- Parent window is not listening for 'OXY_AUTH_REQUEST' messages\n- Parent origin mismatch\n- Network/browser issues\n\nTroubleshooting:\n1. Verify parent window has message listener set up\n2. Check parentOrigin configuration matches parent window origin\n3. Open browser console in parent window for errors`);
29
- this.name = "PostMessageAuthTimeoutError";
30
- }
31
- };
32
- /**
33
- * Error thrown when authentication response comes from unauthorized origin
34
- */
35
- var PostMessageAuthInvalidOriginError = class extends Error {
36
- constructor(expected, actual) {
37
- super(`Received authentication response from unauthorized origin.\n\nExpected: ${expected}\nActual: ${actual}\n\nThis is a security error. Verify your parentOrigin configuration.`);
38
- this.name = "PostMessageAuthInvalidOriginError";
39
- }
40
- };
41
- /**
42
- * Error thrown when postMessage authentication is attempted outside iframe context
43
- */
44
- var PostMessageAuthNotInIframeError = class extends Error {
45
- constructor() {
46
- const currentContext = getCurrentContext();
47
- super(`PostMessage authentication is only available when running in an iframe context.\n\nCurrent context: ${currentContext}\n\nIf you're running in a regular browser window, use direct configuration instead:\nconst client = new OxyClient({ apiKey: 'your-key', ... })`);
48
- this.name = "PostMessageAuthNotInIframeError";
49
- }
50
- };
51
- function getCurrentContext() {
52
- if (typeof window === "undefined") return "non-browser (Node.js)";
53
- if (window === window.parent) return "top-level window";
54
- return "iframe";
55
- }
56
- /**
57
- * Error thrown when authentication response is malformed or invalid
58
- */
59
- var PostMessageAuthInvalidResponseError = class extends Error {
60
- constructor(reason) {
61
- super(`Invalid authentication response from parent: ${reason}`);
62
- this.name = "PostMessageAuthInvalidResponseError";
63
- }
64
- };
65
-
66
- //#endregion
67
- //#region src/auth/postMessage.ts
68
- var postMessage_exports = /* @__PURE__ */ __exportAll({
69
- generateRequestId: () => generateRequestId,
70
- isInIframe: () => isInIframe,
71
- requestAuthFromParent: () => requestAuthFromParent,
72
- validateOrigin: () => validateOrigin
73
- });
74
- /**
75
- * Check if the current context is running inside an iframe
76
- *
77
- * @returns true if running in an iframe, false otherwise (including Node.js)
78
- */
79
- function isInIframe() {
80
- if (typeof window === "undefined") return false;
81
- try {
82
- return window !== window.parent && window.parent !== null;
83
- } catch {
84
- return true;
85
- }
86
- }
87
- /**
88
- * Generate a unique request ID for tracking auth requests
89
- *
90
- * @returns A unique identifier string
91
- */
92
- function generateRequestId() {
93
- if (typeof crypto !== "undefined" && crypto.randomUUID) return crypto.randomUUID();
94
- return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
95
- }
96
- /**
97
- * Validate that a message origin matches the expected origin
98
- *
99
- * @param messageOrigin - The origin from the message event
100
- * @param allowedOrigin - The expected/allowed origin
101
- * @returns true if origin is valid, false otherwise
102
- */
103
- function validateOrigin(messageOrigin, allowedOrigin) {
104
- if (!allowedOrigin) return false;
105
- if (allowedOrigin === "*") return true;
106
- if (messageOrigin === allowedOrigin) return true;
107
- try {
108
- const messageUrl = new URL(messageOrigin);
109
- const allowedUrl = new URL(allowedOrigin);
110
- return messageUrl.origin === allowedUrl.origin;
111
- } catch {
112
- return messageOrigin === allowedOrigin;
113
- }
114
- }
115
- /**
116
- * Create a promise that listens for an authentication response
117
- *
118
- * @param requestId - The request ID to match against
119
- * @param origin - The expected parent origin
120
- * @param timeout - Timeout in milliseconds
121
- * @returns Promise that resolves with the auth response
122
- */
123
- function createAuthListener(requestId, origin, timeout) {
124
- return new Promise((resolve, reject) => {
125
- const listener = (event) => {
126
- if (!validateOrigin(event.origin, origin)) return;
127
- if (!event.data || event.data.type !== "OXY_AUTH_RESPONSE") return;
128
- const response = event.data;
129
- if (response.requestId !== requestId) return;
130
- if (response.version !== "1.0") {
131
- clearTimeout(timeoutId);
132
- window.removeEventListener("message", listener);
133
- reject(new PostMessageAuthInvalidResponseError(`Unsupported protocol version: ${response.version}`));
134
- return;
135
- }
136
- clearTimeout(timeoutId);
137
- window.removeEventListener("message", listener);
138
- resolve(response);
139
- };
140
- const timeoutId = setTimeout(() => {
141
- window.removeEventListener("message", listener);
142
- reject(new PostMessageAuthTimeoutError(timeout));
143
- }, timeout);
144
- window.addEventListener("message", listener);
145
- });
146
- }
147
- /**
148
- * Request authentication from parent window via postMessage
149
- *
150
- * This is the main entry point for iframe-based authentication.
151
- * It sends a request to the parent window and waits for a response.
152
- *
153
- * @param options - Configuration options for the auth request
154
- * @returns Promise that resolves with authentication credentials
155
- * @throws {PostMessageAuthNotInIframeError} If not in an iframe
156
- * @throws {PostMessageAuthTimeoutError} If parent doesn't respond in time
157
- * @throws {PostMessageAuthInvalidOriginError} If response from wrong origin
158
- * @throws {PostMessageAuthInvalidResponseError} If response is malformed
159
- *
160
- * @example
161
- * ```typescript
162
- * const auth = await requestAuthFromParent({
163
- * parentOrigin: 'https://app.example.com',
164
- * timeout: 5000
165
- * });
166
- * console.log('Received API key:', auth.apiKey);
167
- * ```
168
- */
169
- async function requestAuthFromParent(options = {}) {
170
- const { parentOrigin, timeout = 5e3, retries = 0 } = options;
171
- if (!isInIframe()) throw new PostMessageAuthNotInIframeError();
172
- if (typeof window === "undefined") throw new PostMessageAuthNotInIframeError();
173
- const requestId = generateRequestId();
174
- const request = {
175
- type: "OXY_AUTH_REQUEST",
176
- version: "1.0",
177
- timestamp: Date.now(),
178
- requestId
179
- };
180
- let lastError = null;
181
- const maxAttempts = retries + 1;
182
- for (let attempt = 0; attempt < maxAttempts; attempt++) try {
183
- const responsePromise = createAuthListener(requestId, parentOrigin, timeout);
184
- const targetOrigin = parentOrigin || "*";
185
- window.parent.postMessage(request, targetOrigin);
186
- const response = await responsePromise;
187
- return {
188
- apiKey: response.apiKey,
189
- projectId: response.projectId,
190
- baseUrl: response.baseUrl,
191
- source: "postmessage"
192
- };
193
- } catch (error) {
194
- lastError = error;
195
- if (!(error instanceof PostMessageAuthTimeoutError)) throw error;
196
- if (attempt < maxAttempts - 1) {
197
- await new Promise((resolve) => setTimeout(resolve, 100));
198
- continue;
199
- }
200
- throw error;
201
- }
202
- throw lastError || /* @__PURE__ */ new Error("Authentication failed");
203
- }
204
-
205
- //#endregion
206
- export { PostMessageAuthInvalidResponseError as a, PostMessageAuthInvalidOriginError as i, postMessage_exports as n, PostMessageAuthNotInIframeError as o, requestAuthFromParent as r, PostMessageAuthTimeoutError as s, isInIframe as t };
207
- //# sourceMappingURL=postMessage-Gnhr_wnw.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"postMessage-Gnhr_wnw.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: unknown[][];\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: unknown;\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?: unknown;\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 const currentContext = getCurrentContext();\n super(\n `PostMessage authentication is only available when running in an iframe context.\\n\\n` +\n `Current context: ${currentContext}\\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\nfunction getCurrentContext(): string {\n if (typeof window === \"undefined\") {\n return \"non-browser (Node.js)\";\n }\n if (window === window.parent) {\n return \"top-level window\";\n }\n return \"iframe\";\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 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 {\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 // Note: Math.random() is used here as a fallback for environments without crypto.randomUUID\n // This is acceptable for non-security-critical request IDs (used only for message correlation)\n /* eslint-disable sonarjs/pseudo-random */\n return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n /* eslint-enable sonarjs/pseudo-random */\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 {\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 // Set up message listener\n const 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 // Set up timeout\n const timeoutId = setTimeout(() => {\n window.removeEventListener(\"message\", listener);\n reject(new PostMessageAuthTimeoutError(timeout));\n }, timeout);\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 { parentOrigin, timeout = 5000, retries = 0 } = 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(\n requestId,\n parentOrigin,\n timeout,\n );\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":";;;;;;;;;;;;;;;;;;;;;;;;;AA0HA,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,2EACe,SAAS,YACX,OAAO,uEAErB;AACD,OAAK,OAAO;;;;;;AAOhB,IAAa,kCAAb,cAAqD,MAAM;CACzD,cAAc;EACZ,MAAM,iBAAiB,mBAAmB;AAC1C,QACE,uGACsB,eAAe,iJAGtC;AACD,OAAK,OAAO;;;AAIhB,SAAS,oBAA4B;AACnC,KAAI,OAAO,WAAW,YACpB,QAAO;AAET,KAAI,WAAW,OAAO,OACpB,QAAO;AAET,QAAO;;;;;AAMT,IAAa,sCAAb,cAAyD,MAAM;CAC7D,YAAY,QAAgB;AAC1B,QAAM,gDAAgD,SAAS;AAC/D,OAAK,OAAO;;;;;;;;;;;;;;;;;ACjKhB,SAAgB,aAAsB;AAEpC,KAAI,OAAO,WAAW,YACpB,QAAO;AAIT,KAAI;AACF,SAAO,WAAW,OAAO,UAAU,OAAO,WAAW;SAC/C;AAEN,SAAO;;;;;;;;AASX,SAAgB,oBAA4B;AAE1C,KAAI,OAAO,WAAW,eAAe,OAAO,WAC1C,QAAO,OAAO,YAAY;AAO5B,QAAO,GAAG,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,UAAU,GAAG,GAAG;;;;;;;;;AAWrE,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;SAClC;AAEN,SAAO,kBAAkB;;;;;;;;;;;AAY7B,SAAS,mBACP,WACA,QACA,SACiC;AACjC,QAAO,IAAI,SAAS,SAAS,WAAW;EAEtC,MAAM,YAAY,UAAwB;AAExC,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;;EAInB,MAAM,YAAY,iBAAiB;AACjC,UAAO,oBAAoB,WAAW,SAAS;AAC/C,UAAO,IAAI,4BAA4B,QAAQ,CAAC;KAC/C,QAAQ;AAGX,SAAO,iBAAiB,WAAW,SAAS;GAC5C;;;;;;;;;;;;;;;;;;;;;;;;AAyBJ,eAAsB,sBACpB,UAAkC,EAAE,EACJ;CAChC,MAAM,EAAE,cAAc,UAAU,KAAM,UAAU,MAAM;AAGtD,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,mBACtB,WACA,cACA,QACD;EAGD,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"}