UNPKG

@rivetkit/core

Version:

1,138 lines (1,099 loc) 164 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } var _chunk5YH3BFI6cjs = require('../chunk-5YH3BFI6.cjs'); var _chunkAXTFLZYFcjs = require('../chunk-AXTFLZYF.cjs'); require('../chunk-MDVDLD3K.cjs'); var _chunkZCUB7MR5cjs = require('../chunk-ZCUB7MR5.cjs'); var _chunkQAYICQKZcjs = require('../chunk-QAYICQKZ.cjs'); var _chunkDSGTB57Jcjs = require('../chunk-DSGTB57J.cjs'); var _chunkOBXZ7YJ7cjs = require('../chunk-OBXZ7YJ7.cjs'); require('../chunk-ON577KND.cjs'); var _chunk4KRNEW7Dcjs = require('../chunk-4KRNEW7D.cjs'); require('../chunk-HIB3AS73.cjs'); var _chunk53LWTTEXcjs = require('../chunk-53LWTTEX.cjs'); // src/driver-test-suite/mod.ts var _nodeserver = require('@hono/node-server'); var _nodews = require('@hono/node-ws'); var _bundlerequire = require('bundle-require'); var _invariant = require('invariant'); var _invariant2 = _interopRequireDefault(_invariant); var _vitest = require('vitest'); // src/driver-test-suite/tests/action-features.ts // src/driver-test-suite/utils.ts var _path = require('path'); // src/driver-test-suite/test-inline-client-driver.ts var _cborx = require('cbor-x'); var cbor = _interopRequireWildcard(_cborx); // src/driver-test-suite/log.ts var LOGGER_NAME = "test-suite"; function logger() { return _chunk4KRNEW7Dcjs.getLogger.call(void 0, LOGGER_NAME); } // src/driver-test-suite/test-inline-client-driver.ts function createTestInlineClientDriver(endpoint, transport) { return { action: async (c, actorQuery, encoding, params, name, args) => { return makeInlineRequest( endpoint, encoding, transport, "action", [void 0, actorQuery, encoding, params, name, args] ); }, resolveActorId: async (c, actorQuery, encodingKind, params) => { return makeInlineRequest( endpoint, encodingKind, transport, "resolveActorId", [void 0, actorQuery, encodingKind, params] ); }, connectWebSocket: async (c, actorQuery, encodingKind, params) => { const WebSocket2 = await _chunkQAYICQKZcjs.importWebSocket.call(void 0, ); logger().debug("creating websocket connection via test inline driver", { actorQuery, encodingKind }); const wsUrl = new URL( `${endpoint}/registry/.test/inline-driver/connect-websocket` ); wsUrl.searchParams.set("actorQuery", JSON.stringify(actorQuery)); if (params !== void 0) wsUrl.searchParams.set("params", JSON.stringify(params)); wsUrl.searchParams.set("encodingKind", encodingKind); const wsProtocol = wsUrl.protocol === "https:" ? "wss:" : "ws:"; const finalWsUrl = `${wsProtocol}//${wsUrl.host}${wsUrl.pathname}${wsUrl.search}`; logger().debug("connecting to websocket", { url: finalWsUrl }); const ws = new WebSocket2(finalWsUrl, [ // HACK: See packages/drivers/cloudflare-workers/src/websocket.ts "rivetkit" ]); return ws; }, connectSse: async (c, actorQuery, encodingKind, params) => { logger().debug("creating sse connection via test inline driver", { actorQuery, encodingKind, params }); const EventSourceImport = await Promise.resolve().then(() => _interopRequireWildcard(require("eventsource"))); const EventSourceConstructor = EventSourceImport.default || EventSourceImport; const actorQueryParam = encodeURIComponent(JSON.stringify(actorQuery)); const encodingParam = encodeURIComponent(encodingKind); const paramsParam = params ? encodeURIComponent(JSON.stringify(params)) : null; const sseUrl = new URL( `${endpoint}/registry/.test/inline-driver/connect-sse` ); sseUrl.searchParams.set("actorQueryRaw", actorQueryParam); sseUrl.searchParams.set("encodingKind", encodingParam); if (paramsParam) { sseUrl.searchParams.set("params", paramsParam); } logger().debug("connecting to sse", { url: sseUrl.toString() }); const eventSource = new EventSourceConstructor(sseUrl.toString()); await new Promise((resolve2, reject) => { eventSource.onopen = () => { logger().debug("sse connection established"); resolve2(); }; eventSource.onerror = (event) => { logger().error("sse connection failed", { event }); reject(new Error("Failed to establish SSE connection")); }; setTimeout(() => { if (eventSource.readyState !== EventSourceConstructor.OPEN) { reject(new Error("SSE connection timed out")); } }, 1e4); }); return eventSource; }, sendHttpMessage: async (c, actorId, encoding, connectionId, connectionToken, message) => { logger().debug("sending http message via test inline driver", { actorId, encoding, connectionId, transport }); const result = await fetch( `${endpoint}/registry/.test/inline-driver/call`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ encoding, transport, method: "sendHttpMessage", args: [ void 0, actorId, encoding, connectionId, connectionToken, message ] }) } ); if (!result.ok) { throw new Error(`Failed to send HTTP message: ${result.statusText}`); } return new Response(await result.text(), { status: result.status, statusText: result.statusText, headers: result.headers }); }, rawHttpRequest: async (c, actorQuery, encoding, params, path, init) => { var _a; const normalizedPath = path.startsWith("/") ? path.slice(1) : path; logger().debug("sending raw http request via test inline driver", { actorQuery, encoding, path: normalizedPath }); const url = `${endpoint}/registry/.test/inline-driver/raw-http/${normalizedPath}`; logger().debug("rewriting http url", { from: path, to: url }); const headers = new Headers(init.headers); headers.set(_chunkOBXZ7YJ7cjs.HEADER_ACTOR_QUERY, JSON.stringify(actorQuery)); headers.set(_chunkOBXZ7YJ7cjs.HEADER_ENCODING, encoding); if (params !== void 0) { headers.set(_chunkOBXZ7YJ7cjs.HEADER_CONN_PARAMS, JSON.stringify(params)); } const response = await fetch(url, { ...init, headers }); if (!response.ok && ((_a = response.headers.get("content-type")) == null ? void 0 : _a.includes("application/json"))) { try { const clonedResponse = response.clone(); const errorData = await clonedResponse.json(); if (errorData.error) { if (typeof errorData.error === "object") { throw new (0, _chunkDSGTB57Jcjs.ActorError)( errorData.error.code, errorData.error.message, errorData.error.metadata ); } } } catch (e) { if (!(e instanceof _chunkDSGTB57Jcjs.ActorError)) { return response; } throw e; } } return response; }, rawWebSocket: async (_c, actorQuery, encoding, params, path, protocols) => { logger().debug("test inline driver rawWebSocket called"); const WebSocket2 = await _chunkQAYICQKZcjs.importWebSocket.call(void 0, ); const normalizedPath = path.startsWith("/") ? path.slice(1) : path; logger().debug( "creating raw websocket connection via test inline driver", { actorQuery, encoding, path: normalizedPath, protocols } ); const wsUrl = new URL( `${endpoint}/registry/.test/inline-driver/raw-websocket` ); wsUrl.searchParams.set("actorQuery", JSON.stringify(actorQuery)); if (params !== void 0) wsUrl.searchParams.set("params", JSON.stringify(params)); wsUrl.searchParams.set("encodingKind", encoding); wsUrl.searchParams.set("path", normalizedPath); if (protocols !== void 0) wsUrl.searchParams.set("protocols", JSON.stringify(protocols)); const wsProtocol = wsUrl.protocol === "https:" ? "wss:" : "ws:"; const finalWsUrl = `${wsProtocol}//${wsUrl.host}${wsUrl.pathname}${wsUrl.search}`; logger().debug("connecting to raw websocket", { url: finalWsUrl }); logger().debug("rewriting websocket url", { from: path, to: finalWsUrl }); const ws = new WebSocket2(finalWsUrl, [ // HACK: See packages/drivers/cloudflare-workers/src/websocket.ts "rivetkit" ]); logger().debug("test inline driver created websocket", { readyState: ws.readyState, url: ws.url }); return ws; } }; } async function makeInlineRequest(endpoint, encoding, transport, method, args) { logger().debug("sending inline request", { encoding, transport, method, args }); const response = await fetch( `${endpoint}/registry/.test/inline-driver/call`, { method: "POST", headers: { "Content-Type": "application/json" }, body: cbor.encode({ encoding, transport, method, args }) } ); if (!response.ok) { throw new Error(`Failed to call inline ${method}: ${response.statusText}`); } const buffer = await response.arrayBuffer(); const callResponse = cbor.decode( new Uint8Array(buffer) ); if ("ok" in callResponse) { return callResponse.ok; } else if ("err" in callResponse) { throw new (0, _chunkDSGTB57Jcjs.ActorError)( callResponse.err.code, callResponse.err.message, callResponse.err.metadata ); } else { _chunkOBXZ7YJ7cjs.assertUnreachable.call(void 0, callResponse); } } // src/driver-test-suite/utils.ts async function setupDriverTest(c, driverTestConfig) { if (!driverTestConfig.useRealTimers) { _vitest.vi.useFakeTimers(); } const projectPath = _path.resolve.call(void 0, __dirname, "../../fixtures/driver-test-suite"); const { endpoint, cleanup } = await driverTestConfig.start(projectPath); c.onTestFinished(cleanup); let client; if (driverTestConfig.clientType === "http") { client = _chunkZCUB7MR5cjs.createClient.call(void 0, endpoint, { transport: driverTestConfig.transport }); } else if (driverTestConfig.clientType === "inline") { const clientDriver = createTestInlineClientDriver( endpoint, _nullishCoalesce(driverTestConfig.transport, () => ( "websocket")) ); client = _chunkDSGTB57Jcjs.createClientWithDriver.call(void 0, clientDriver); } else { _chunkOBXZ7YJ7cjs.assertUnreachable.call(void 0, driverTestConfig.clientType); } if (!driverTestConfig.HACK_skipCleanupNet) { c.onTestFinished(async () => await client.dispose()); } return { client, endpoint }; } async function waitFor(driverTestConfig, ms) { if (driverTestConfig.useRealTimers) { return new Promise((resolve2) => setTimeout(resolve2, ms)); } else { _vitest.vi.advanceTimersByTime(ms); return Promise.resolve(); } } // src/driver-test-suite/tests/action-features.ts function runActionFeaturesTests(driverTestConfig) { _vitest.describe.call(void 0, "Action Features", () => { _vitest.describe.skip("Action Timeouts", () => { const usesFakeTimers = !driverTestConfig.useRealTimers; _vitest.test.call(void 0, "should timeout actions that exceed the configured timeout", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const quickResult = await client.shortTimeoutActor.getOrCreate().quickAction(); _vitest.expect.call(void 0, quickResult).toBe("quick response"); await _vitest.expect.call(void 0, client.shortTimeoutActor.getOrCreate().slowAction() ).rejects.toThrow("Action timed out"); }); _vitest.test.call(void 0, "should respect the default timeout", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const result = await client.defaultTimeoutActor.getOrCreate().normalAction(); _vitest.expect.call(void 0, result).toBe("normal response"); }); _vitest.test.call(void 0, "non-promise action results should not be affected by timeout", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const result = await client.syncTimeoutActor.getOrCreate().syncAction(); _vitest.expect.call(void 0, result).toBe("sync response"); }); _vitest.test.call(void 0, "should allow configuring different timeouts for different actors", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); await _vitest.expect.call(void 0, client.shortTimeoutActor.getOrCreate().slowAction() ).rejects.toThrow("Action timed out"); const result = await client.longTimeoutActor.getOrCreate().delayedAction(); _vitest.expect.call(void 0, result).toBe("delayed response"); }); }); _vitest.describe.call(void 0, "Action Sync & Async", () => { _vitest.test.call(void 0, "should support synchronous actions", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.syncActionActor.getOrCreate(); let result = await instance.increment(5); _vitest.expect.call(void 0, result).toBe(5); result = await instance.increment(3); _vitest.expect.call(void 0, result).toBe(8); const info = await instance.getInfo(); _vitest.expect.call(void 0, info.currentValue).toBe(8); _vitest.expect.call(void 0, typeof info.timestamp).toBe("number"); await instance.reset(); result = await instance.increment(0); _vitest.expect.call(void 0, result).toBe(0); }); _vitest.test.call(void 0, "should support asynchronous actions", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.asyncActionActor.getOrCreate(); const result = await instance.delayedIncrement(5); _vitest.expect.call(void 0, result).toBe(5); const data = await instance.fetchData("test-123"); _vitest.expect.call(void 0, data.id).toBe("test-123"); _vitest.expect.call(void 0, typeof data.timestamp).toBe("number"); const success = await instance.asyncWithError(false); _vitest.expect.call(void 0, success).toBe("Success"); try { await instance.asyncWithError(true); _vitest.expect.fail("did not error"); } catch (error) { _vitest.expect.call(void 0, error.message).toBe("Intentional error"); } }); _vitest.test.call(void 0, "should handle promises returned from actions correctly", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.promiseActor.getOrCreate(); const resolvedValue = await instance.resolvedPromise(); _vitest.expect.call(void 0, resolvedValue).toBe("resolved value"); const delayedValue = await instance.delayedPromise(); _vitest.expect.call(void 0, delayedValue).toBe("delayed value"); await _vitest.expect.call(void 0, instance.rejectedPromise()).rejects.toThrow( "promised rejection" ); const results = await instance.getResults(); _vitest.expect.call(void 0, results).toContain("delayed"); }); }); }); } // src/driver-test-suite/tests/actor-auth.ts function runActorAuthTests(driverTestConfig) { _vitest.describe.call(void 0, "Actor Authentication Tests", () => { _vitest.describe.call(void 0, "Basic Authentication", () => { _vitest.test.call(void 0, "should allow access with valid auth", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.authActor.getOrCreate(void 0, { params: { apiKey: "valid-api-key" } }); const authData = await instance.getUserAuth(); if (driverTestConfig.clientType === "inline") { _vitest.expect.call(void 0, authData).toBeUndefined(); } else { _vitest.expect.call(void 0, authData).toEqual({ userId: "user123", token: "valid-api-key" }); } const requests = await instance.getRequests(); _vitest.expect.call(void 0, requests).toBe(1); }); _vitest.test.call(void 0, "should deny access with invalid auth", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.authActor.getOrCreate(); if (driverTestConfig.clientType === "inline") { const requests = await instance.getRequests(); _vitest.expect.call(void 0, typeof requests).toBe("number"); } else { try { await instance.getRequests(); _vitest.expect.fail("Expected authentication error"); } catch (error) { _vitest.expect.call(void 0, error.code).toBe("missing_auth"); } } }); _vitest.test.call(void 0, "should expose auth data on connection", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.authActor.getOrCreate(void 0, { params: { apiKey: "valid-api-key" } }); const authData = await instance.getUserAuth(); if (driverTestConfig.clientType === "inline") { _vitest.expect.call(void 0, authData).toBeUndefined(); } else { _vitest.expect.call(void 0, authData).toBeDefined(); _vitest.expect.call(void 0, authData.userId).toBe("user123"); _vitest.expect.call(void 0, authData.token).toBe("valid-api-key"); } }); }); _vitest.describe.call(void 0, "Intent-Based Authentication", () => { _vitest.test.call(void 0, "should allow get operations for any role", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const createdInstance = await client.intentAuthActor.create(["foo"], { params: { role: "admin" } }); const actorId = await createdInstance.resolve(); if (driverTestConfig.clientType === "inline") { const instance = client.intentAuthActor.getForId(actorId); const value = await instance.getValue(); _vitest.expect.call(void 0, value).toBe(0); } else { const instance = client.intentAuthActor.getForId(actorId, { params: { role: "user" } // Actions require user or admin role }); const value = await instance.getValue(); _vitest.expect.call(void 0, value).toBe(0); } }); _vitest.test.call(void 0, "should require admin role for create operations", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); if (driverTestConfig.clientType === "inline") { const instance = client.intentAuthActor.getOrCreate(void 0, { params: { role: "user" } }); const value = await instance.getValue(); _vitest.expect.call(void 0, value).toBe(0); } else { try { const instance = client.intentAuthActor.getOrCreate(void 0, { params: { role: "user" } }); await instance.getValue(); _vitest.expect.fail("Expected permission error for create operation"); } catch (error) { _vitest.expect.call(void 0, error.code).toBe("insufficient_permissions"); _vitest.expect.call(void 0, error.message).toContain( "Admin role required" ); } } }); _vitest.test.call(void 0, "should allow actions for user and admin roles", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const createdInstance = await client.intentAuthActor.create(["foo"], { params: { role: "admin" } }); const actorId = await createdInstance.resolve(); const instance = client.intentAuthActor.getForId(actorId, { params: { role: "guest" } }); if (driverTestConfig.clientType === "inline") { const result = await instance.setValue(42); _vitest.expect.call(void 0, result).toBe(42); } else { try { await instance.setValue(42); _vitest.expect.fail("Expected permission error for action"); } catch (error) { _vitest.expect.call(void 0, error.code).toBe("insufficient_permissions"); _vitest.expect.call(void 0, error.message).toContain( "User or admin role required" ); } } }); }); _vitest.describe.call(void 0, "Public Access", () => { _vitest.test.call(void 0, "should allow access with empty onAuth", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.publicActor.getOrCreate(); const visitors = await instance.visit(); _vitest.expect.call(void 0, visitors).toBe(1); const visitors2 = await instance.visit(); _vitest.expect.call(void 0, visitors2).toBe(2); }); _vitest.test.call(void 0, "should deny access without onAuth defined", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.noAuthActor.getOrCreate(); if (driverTestConfig.clientType === "inline") { const value = await instance.getValue(); _vitest.expect.call(void 0, value).toBe(42); } else { try { await instance.getValue(); _vitest.expect.fail( "Expected access to be denied for actor without onAuth" ); } catch (error) { _vitest.expect.call(void 0, error.code).toBe("forbidden"); } } }); }); _vitest.describe.call(void 0, "Async Authentication", () => { _vitest.test.call(void 0, "should handle promise-based auth", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.asyncAuthActor.getOrCreate(void 0, { params: { token: "valid" } }); const result = await instance.increment(); _vitest.expect.call(void 0, result).toBe(1); const authData = await instance.getAuthData(); if (driverTestConfig.clientType === "inline") { _vitest.expect.call(void 0, authData).toBeUndefined(); } else { _vitest.expect.call(void 0, authData).toBeDefined(); _vitest.expect.call(void 0, authData.userId).toBe("user-valid"); _vitest.expect.call(void 0, authData.validated).toBe(true); } }); _vitest.test.call(void 0, "should handle async auth failures", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.asyncAuthActor.getOrCreate(); if (driverTestConfig.clientType === "inline") { const result = await instance.increment(); _vitest.expect.call(void 0, result).toBe(1); } else { try { await instance.increment(); _vitest.expect.fail("Expected async auth failure"); } catch (error) { _vitest.expect.call(void 0, error.code).toBe("missing_token"); } } }); }); _vitest.describe.call(void 0, "Authentication Across Transports", () => { if (driverTestConfig.transport === "websocket") { _vitest.test.call(void 0, "should authenticate WebSocket connections", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.authActor.getOrCreate(void 0, { params: { apiKey: "valid-api-key" } }); const authData = await instance.getUserAuth(); _vitest.expect.call(void 0, authData).toBeDefined(); _vitest.expect.call(void 0, authData.userId).toBe("user123"); }); } _vitest.test.call(void 0, "should authenticate HTTP actions", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.authActor.getOrCreate(void 0, { params: { apiKey: "valid-api-key" } }); const requests = await instance.getRequests(); _vitest.expect.call(void 0, typeof requests).toBe("number"); }); }); _vitest.describe.call(void 0, "Error Handling", () => { _vitest.test.call(void 0, "should handle auth errors gracefully", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.authActor.getOrCreate(); if (driverTestConfig.clientType === "inline") { const requests = await instance.getRequests(); _vitest.expect.call(void 0, typeof requests).toBe("number"); } else { try { await instance.getRequests(); _vitest.expect.fail("Expected authentication error"); } catch (error) { const actorError = error; _vitest.expect.call(void 0, actorError.code).toBeDefined(); _vitest.expect.call(void 0, actorError.message).toBeDefined(); } } }); _vitest.test.call(void 0, "should preserve error details for debugging", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.asyncAuthActor.getOrCreate(); if (driverTestConfig.clientType === "inline") { const result = await instance.increment(); _vitest.expect.call(void 0, result).toBe(1); } else { try { await instance.increment(); _vitest.expect.fail("Expected token error"); } catch (error) { const actorError = error; _vitest.expect.call(void 0, actorError.code).toBe("missing_token"); _vitest.expect.call(void 0, actorError.message).toBe("Token required"); } } }); }); _vitest.describe.call(void 0, "Raw HTTP Authentication", () => { _vitest.test.call(void 0, "should allow raw HTTP access with valid auth", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.rawHttpAuthActor.getOrCreate(void 0, { params: { apiKey: "valid-api-key" } }); const response = await instance.fetch("api/auth-info"); _vitest.expect.call(void 0, response.ok).toBe(true); const data = await response.json(); _vitest.expect.call(void 0, data.message).toBe("Authenticated request"); _vitest.expect.call(void 0, data.requestCount).toBe(1); const count = await instance.getRequestCount(); _vitest.expect.call(void 0, count).toBe(1); }); _vitest.test.call(void 0, "should deny raw HTTP access without auth", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.rawHttpAuthActor.getOrCreate(); const response = await instance.fetch("api/protected"); if (driverTestConfig.clientType === "inline") { _vitest.expect.call(void 0, response.ok).toBe(true); _vitest.expect.call(void 0, response.status).toBe(200); } else { _vitest.expect.call(void 0, response.ok).toBe(false); _vitest.expect.call(void 0, response.status).toBe(400); } try { const errorData = await response.json(); _vitest.expect.call(void 0, errorData.c || errorData.code).toBe("missing_auth"); } catch (e2) { } }); _vitest.test.call(void 0, "should deny raw HTTP for actors without onAuth", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.rawHttpNoAuthActor.getOrCreate(); const response = await instance.fetch("api/test"); if (driverTestConfig.clientType === "inline") { _vitest.expect.call(void 0, response.ok).toBe(true); _vitest.expect.call(void 0, response.status).toBe(200); } else { _vitest.expect.call(void 0, response.ok).toBe(false); _vitest.expect.call(void 0, response.status).toBe(403); } try { const errorData = await response.json(); _vitest.expect.call(void 0, errorData.c || errorData.code).toBe("forbidden"); } catch (e3) { } }); _vitest.test.call(void 0, "should allow public raw HTTP access", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.rawHttpPublicActor.getOrCreate(); const response = await instance.fetch("api/visit"); _vitest.expect.call(void 0, response.ok).toBe(true); const data = await response.json(); _vitest.expect.call(void 0, data.message).toBe("Welcome visitor!"); _vitest.expect.call(void 0, data.count).toBe(1); const response2 = await instance.fetch("api/visit"); const data2 = await response2.json(); _vitest.expect.call(void 0, data2.count).toBe(2); }); _vitest.test.call(void 0, "should handle custom auth in onFetch", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.rawHttpCustomAuthActor.getOrCreate(); const response1 = await instance.fetch("api/data"); _vitest.expect.call(void 0, response1.ok).toBe(false); _vitest.expect.call(void 0, response1.status).toBe(401); const error1 = await response1.json(); _vitest.expect.call(void 0, error1.error).toBe("Unauthorized"); const response2 = await instance.fetch("api/data", { headers: { Authorization: "Bearer wrong-token" } }); _vitest.expect.call(void 0, response2.ok).toBe(false); _vitest.expect.call(void 0, response2.status).toBe(403); const response3 = await instance.fetch("api/data", { headers: { Authorization: "Bearer custom-token" } }); _vitest.expect.call(void 0, response3.ok).toBe(true); const data = await response3.json(); _vitest.expect.call(void 0, data.message).toBe("Authorized!"); _vitest.expect.call(void 0, data.authorized).toBe(1); const stats = await instance.getStats(); _vitest.expect.call(void 0, stats.authorized).toBe(1); _vitest.expect.call(void 0, stats.unauthorized).toBe(2); }); }); _vitest.describe.call(void 0, "Raw WebSocket Authentication", () => { _vitest.test.call(void 0, "should allow raw WebSocket access with valid auth", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.rawWebSocketAuthActor.getOrCreate(void 0, { params: { apiKey: "valid-api-key" } }); const ws = await instance.websocket(); const welcomePromise = new Promise((resolve2, reject) => { ws.addEventListener("message", (event) => { const data = JSON.parse(event.data); if (data.type === "welcome") { resolve2(data); } }); ws.addEventListener("close", () => reject("closed")); }); const welcomeData = await welcomePromise; _vitest.expect.call(void 0, welcomeData.message).toBe("Authenticated WebSocket connection"); _vitest.expect.call(void 0, welcomeData.connectionCount).toBe(1); ws.close(); }); _vitest.test.call(void 0, "should deny raw WebSocket access without auth", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.rawWebSocketAuthActor.getOrCreate(); try { await instance.websocket(); _vitest.expect.fail("Expected authentication error"); } catch (error) { _vitest.expect.call(void 0, error).toBeDefined(); } }); _vitest.test.call(void 0, "should deny raw WebSocket for actors without onAuth", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.rawWebSocketNoAuthActor.getOrCreate(); try { await instance.websocket(); _vitest.expect.fail("Expected forbidden error"); } catch (error) { _vitest.expect.call(void 0, error).toBeDefined(); } }); _vitest.test.call(void 0, "should allow public raw WebSocket access", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.rawWebSocketPublicActor.getOrCreate(); const ws = await instance.websocket(); const welcomePromise = new Promise((resolve2, reject) => { ws.addEventListener("message", (event) => { const data = JSON.parse(event.data); if (data.type === "welcome") { resolve2(data); } }); ws.addEventListener("close", reject); }); const welcomeData = await welcomePromise; _vitest.expect.call(void 0, welcomeData.message).toBe("Public WebSocket connection"); _vitest.expect.call(void 0, welcomeData.visitorNumber).toBe(1); ws.close(); }); _vitest.test.call(void 0, "should handle custom auth in onWebSocket", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const instance = client.rawWebSocketCustomAuthActor.getOrCreate(); try { const ws1 = await instance.websocket(); const errorPromise = new Promise((resolve2, reject) => { ws1.addEventListener("message", (event) => { const data = JSON.parse(event.data); if (data.type === "error") { resolve2(data); } }); ws1.addEventListener("close", reject); }); const errorData = await errorPromise; _vitest.expect.call(void 0, errorData.type).toBe("error"); _vitest.expect.call(void 0, errorData.message).toBe("Unauthorized"); } catch (error) { _vitest.expect.call(void 0, error).toBeDefined(); } const ws2 = await instance.websocket("?token=custom-ws-token"); const authPromise = new Promise((resolve2, reject) => { ws2.addEventListener("message", (event) => { const data = JSON.parse(event.data); if (data.type === "authorized") { resolve2(data); } }); ws2.addEventListener("close", reject); }); const authData = await authPromise; _vitest.expect.call(void 0, authData.message).toBe("Welcome authenticated user!"); ws2.close(); const stats = await instance.getStats(); _vitest.expect.call(void 0, stats.authorized).toBeGreaterThanOrEqual(1); _vitest.expect.call(void 0, stats.unauthorized).toBeGreaterThanOrEqual(1); }); }); }); } // src/driver-test-suite/tests/actor-conn.ts function runActorConnTests(driverTestConfig) { _vitest.describe.call(void 0, "Actor Connection Tests", () => { _vitest.describe.call(void 0, "Connection Methods", () => { _vitest.test.call(void 0, "should connect using .get().connect()", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); await client.counter.create(["test-get"]); const handle = client.counter.get(["test-get"]); const connection = handle.connect(); const count = await connection.increment(5); _vitest.expect.call(void 0, count).toBe(5); await connection.dispose(); }); _vitest.test.call(void 0, "should connect using .getForId().connect()", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const handle = client.counter.getOrCreate(["test-get-for-id"]); await handle.increment(3); const actorId = await handle.resolve(); const idHandle = client.counter.getForId(actorId); const connection = idHandle.connect(); const count = await connection.getCount(); _vitest.expect.call(void 0, count).toBe(3); await connection.dispose(); }); _vitest.test.call(void 0, "should connect using .getOrCreate().connect()", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const handle = client.counter.getOrCreate(["test-get-or-create"]); const connection = handle.connect(); const count = await connection.increment(7); _vitest.expect.call(void 0, count).toBe(7); await connection.dispose(); }); _vitest.test.call(void 0, "should connect using (await create()).connect()", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const handle = await client.counter.create(["test-create"]); const connection = handle.connect(); const count = await connection.increment(9); _vitest.expect.call(void 0, count).toBe(9); await connection.dispose(); }); }); _vitest.describe.call(void 0, "Event Communication", () => { _vitest.test.call(void 0, "should mix RPC calls and WebSocket events", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const handle = client.counter.getOrCreate(["test-mixed-rpc-ws"]); const connection = handle.connect(); const receivedEvents = []; connection.on("newCount", (count) => { receivedEvents.push(count); }); await connection.increment(1); await handle.increment(5); await handle.increment(3); _vitest.expect.call(void 0, receivedEvents).toContain(1); _vitest.expect.call(void 0, receivedEvents).toContain(6); _vitest.expect.call(void 0, receivedEvents).toContain(9); await connection.dispose(); }); _vitest.test.call(void 0, "should receive events via broadcast", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const handle = client.counter.getOrCreate(["test-broadcast"]); const connection = handle.connect(); const receivedEvents = []; connection.on("newCount", (count) => { receivedEvents.push(count); }); await connection.increment(5); await connection.increment(3); _vitest.expect.call(void 0, receivedEvents).toContain(5); _vitest.expect.call(void 0, receivedEvents).toContain(8); await connection.dispose(); }); _vitest.test.call(void 0, "should handle one-time events with once()", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const handle = client.counter.getOrCreate(["test-once"]); const connection = handle.connect(); const receivedEvents = []; connection.once("newCount", (count) => { receivedEvents.push(count); }); await connection.increment(5); await connection.increment(3); _vitest.expect.call(void 0, receivedEvents).toEqual([5]); _vitest.expect.call(void 0, receivedEvents).not.toContain(8); await connection.dispose(); }); _vitest.test.call(void 0, "should unsubscribe from events", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const handle = client.counter.getOrCreate(["test-unsubscribe"]); const connection = handle.connect(); const receivedEvents = []; const unsubscribe = connection.on("newCount", (count) => { receivedEvents.push(count); }); await connection.increment(5); unsubscribe(); await connection.increment(3); _vitest.expect.call(void 0, receivedEvents).toEqual([5]); _vitest.expect.call(void 0, receivedEvents).not.toContain(8); await connection.dispose(); }); }); _vitest.describe.call(void 0, "Connection Parameters", () => { _vitest.test.call(void 0, "should pass connection parameters", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const handle1 = client.counterWithParams.getOrCreate(["test-params"], { params: { name: "user1" } }); const handle2 = client.counterWithParams.getOrCreate(["test-params"], { params: { name: "user2" } }); const conn1 = handle1.connect(); const conn2 = handle2.connect(); await conn1.getInitializers(); await conn2.getInitializers(); const initializers = await conn1.getInitializers(); _vitest.expect.call(void 0, initializers).toContain("user1"); _vitest.expect.call(void 0, initializers).toContain("user2"); await conn1.dispose(); await conn2.dispose(); }); }); _vitest.describe.call(void 0, "Lifecycle Hooks", () => { _vitest.test.call(void 0, "should trigger lifecycle hooks", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const connHandle = client.counterWithLifecycle.getOrCreate( ["test-lifecycle"], { params: { trackLifecycle: true } } ); const connection = connHandle.connect(); const events = await connection.getEvents(); _vitest.expect.call(void 0, events).toEqual(["onStart", "onBeforeConnect", "onConnect"]); await connection.dispose(); const handle = client.counterWithLifecycle.getOrCreate([ "test-lifecycle" ]); const finalEvents = await handle.getEvents(); _vitest.expect.call(void 0, finalEvents).toBeOneOf([ // Still active ["onStart", "onBeforeConnect", "onConnect", "onDisconnect"], // Went to sleep and woke back up [ "onStart", "onBeforeConnect", "onConnect", "onDisconnect", "onStart" ] ]); }); }); }); } // src/driver-test-suite/tests/actor-conn-state.ts function runActorConnStateTests(driverTestConfig) { _vitest.describe.call(void 0, "Actor Connection State Tests", () => { _vitest.describe.call(void 0, "Connection State Initialization", () => { _vitest.test.call(void 0, "should retrieve connection state", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const connection = client.connStateActor.getOrCreate().connect(); const connState = await connection.getConnectionState(); _vitest.expect.call(void 0, connState.id).toBeDefined(); _vitest.expect.call(void 0, connState.username).toBeDefined(); _vitest.expect.call(void 0, connState.role).toBeDefined(); _vitest.expect.call(void 0, connState.counter).toBeDefined(); _vitest.expect.call(void 0, connState.createdAt).toBeDefined(); await connection.dispose(); }); _vitest.test.call(void 0, "should initialize connection state with custom parameters", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const connection = client.connStateActor.getOrCreate([], { params: { username: "testuser", role: "admin" } }).connect(); const connState = await connection.getConnectionState(); _vitest.expect.call(void 0, connState.username).toBe("testuser"); _vitest.expect.call(void 0, connState.role).toBe("admin"); await connection.dispose(); }); }); _vitest.describe.call(void 0, "Connection State Management", () => { _vitest.test.call(void 0, "should maintain unique state for each connection", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const conn1 = client.connStateActor.getOrCreate([], { params: { username: "user1" } }).connect(); const conn2 = client.connStateActor.getOrCreate([], { params: { username: "user2" } }).connect(); await conn1.incrementConnCounter(5); await conn2.incrementConnCounter(10); const state1 = await conn1.getConnectionState(); const state2 = await conn2.getConnectionState(); _vitest.expect.call(void 0, state1.counter).toBe(5); _vitest.expect.call(void 0, state2.counter).toBe(10); _vitest.expect.call(void 0, state1.username).toBe("user1"); _vitest.expect.call(void 0, state2.username).toBe("user2"); await conn1.dispose(); await conn2.dispose(); }); _vitest.test.call(void 0, "should track connections in shared state", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const handle = client.connStateActor.getOrCreate(); const conn1 = handle.connect(); const conn2 = handle.connect(); const state1 = await conn1.getConnectionState(); const connectionIds = await conn1.getConnectionIds(); _vitest.expect.call(void 0, connectionIds.length).toBeGreaterThanOrEqual(2); _vitest.expect.call(void 0, connectionIds).toContain(state1.id); await conn1.dispose(); await conn2.dispose(); }); _vitest.test.call(void 0, "should identify different connections in the same actor", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const handle = client.connStateActor.getOrCreate(); const conn1 = handle.connect(); const conn2 = handle.connect(); const allStates = await conn1.getAllConnectionStates(); _vitest.expect.call(void 0, allStates.length).toBeGreaterThanOrEqual(2); const ids = allStates.map((state) => state.id); const uniqueIds = [...new Set(ids)]; _vitest.expect.call(void 0, uniqueIds.length).toBe(ids.length); await conn1.dispose(); await conn2.dispose(); }); }); _vitest.describe.call(void 0, "Connection Lifecycle", () => { _vitest.test.call(void 0, "should track connection and disconnection events", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const handle = client.connStateActor.getOrCreate(); const conn = handle.connect(); const connState = await conn.getConnectionState(); const connectionIds = await conn.getConnectionIds(); _vitest.expect.call(void 0, connectionIds).toContain(connState.id); const initialDisconnections = await conn.getDisconnectionCount(); await conn.dispose(); const newConn = handle.connect(); await _vitest.vi.waitFor(async () => { const newDisconnections = await newConn.getDisconnectionCount(); _vitest.expect.call(void 0, newDisconnections).toBeGreaterThan(initialDisconnections); }); await newConn.dispose(); }); _vitest.test.call(void 0, "should update connection state", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const conn = client.connStateActor.getOrCreate().connect(); const initialState = await conn.getConnectionState(); _vitest.expect.call(void 0, initialState.username).toBe("anonymous"); const updatedState = await conn.updateConnection({ username: "newname", role: "moderator" }); _vitest.expect.call(void 0, updatedState.username).toBe("newname"); _vitest.expect.call(void 0, updatedState.role).toBe("moderator"); const latestState = await conn.getConnectionState(); _vitest.expect.call(void 0, latestState.username).toBe("newname"); _vitest.expect.call(void 0, latestState.role).toBe("moderator"); await conn.dispose(); }); }); _vitest.describe.call(void 0, "Connection Communication", () => { _vitest.test.call(void 0, "should send messages to specific connections", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); const handle = client.connStateActor.getOrCreate(); const conn1 = handle.connect(); const conn2 = handle.connect(); const state1 = await conn1.getConnectionState(); const state2 = await conn2.getConnectionState(); const receivedMessages = []; conn2.on("directMessage", (data) => { receivedMessages.push(data); }); const success = await conn1.sendToConnection( state2.id, "Hello from conn1" ); _vitest.expect.call(void 0, success).toBe(true); _vitest.expect.call(void 0, receivedMessages.length).toBe(1);