rivetkit 2.0.1 → 2.0.3

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.
Files changed (253) hide show
  1. package/dist/schemas/actor-persist/v1.ts +228 -0
  2. package/dist/schemas/client-protocol/v1.ts +429 -0
  3. package/dist/schemas/file-system-driver/v1.ts +102 -0
  4. package/dist/tsup/actor/errors.cjs +69 -0
  5. package/dist/tsup/actor/errors.cjs.map +1 -0
  6. package/dist/tsup/actor/errors.d.cts +143 -0
  7. package/dist/tsup/actor/errors.d.ts +143 -0
  8. package/dist/tsup/actor/errors.js +69 -0
  9. package/dist/tsup/actor/errors.js.map +1 -0
  10. package/dist/tsup/chunk-2CRLFV6Z.cjs +202 -0
  11. package/dist/tsup/chunk-2CRLFV6Z.cjs.map +1 -0
  12. package/dist/tsup/chunk-3H7O2A7I.js +525 -0
  13. package/dist/tsup/chunk-3H7O2A7I.js.map +1 -0
  14. package/dist/tsup/chunk-42I3OZ3Q.js +15 -0
  15. package/dist/tsup/chunk-42I3OZ3Q.js.map +1 -0
  16. package/dist/tsup/chunk-4NSUQZ2H.js +1790 -0
  17. package/dist/tsup/chunk-4NSUQZ2H.js.map +1 -0
  18. package/dist/tsup/chunk-6PDXBYI5.js +132 -0
  19. package/dist/tsup/chunk-6PDXBYI5.js.map +1 -0
  20. package/dist/tsup/chunk-6WKQDDUD.cjs +1790 -0
  21. package/dist/tsup/chunk-6WKQDDUD.cjs.map +1 -0
  22. package/dist/tsup/chunk-CTBOSFUH.cjs +116 -0
  23. package/dist/tsup/chunk-CTBOSFUH.cjs.map +1 -0
  24. package/dist/tsup/chunk-EGVZZFE2.js +2857 -0
  25. package/dist/tsup/chunk-EGVZZFE2.js.map +1 -0
  26. package/dist/tsup/chunk-FCCPJNMA.cjs +132 -0
  27. package/dist/tsup/chunk-FCCPJNMA.cjs.map +1 -0
  28. package/dist/tsup/chunk-FLMTTN27.js +244 -0
  29. package/dist/tsup/chunk-FLMTTN27.js.map +1 -0
  30. package/dist/tsup/chunk-GIR3AFFI.cjs +315 -0
  31. package/dist/tsup/chunk-GIR3AFFI.cjs.map +1 -0
  32. package/dist/tsup/chunk-INGJP237.js +315 -0
  33. package/dist/tsup/chunk-INGJP237.js.map +1 -0
  34. package/dist/tsup/chunk-KJCJLKRM.js +116 -0
  35. package/dist/tsup/chunk-KJCJLKRM.js.map +1 -0
  36. package/dist/tsup/chunk-KUPQZYUQ.cjs +15 -0
  37. package/dist/tsup/chunk-KUPQZYUQ.cjs.map +1 -0
  38. package/dist/tsup/chunk-O2MBYIXO.cjs +2857 -0
  39. package/dist/tsup/chunk-O2MBYIXO.cjs.map +1 -0
  40. package/dist/tsup/chunk-OGAPU3UG.cjs +525 -0
  41. package/dist/tsup/chunk-OGAPU3UG.cjs.map +1 -0
  42. package/dist/tsup/chunk-OV6AYD4S.js +4406 -0
  43. package/dist/tsup/chunk-OV6AYD4S.js.map +1 -0
  44. package/dist/tsup/chunk-PO4VLDWA.js +47 -0
  45. package/dist/tsup/chunk-PO4VLDWA.js.map +1 -0
  46. package/dist/tsup/chunk-R2OPSKIV.cjs +244 -0
  47. package/dist/tsup/chunk-R2OPSKIV.cjs.map +1 -0
  48. package/dist/tsup/chunk-TZJKSBUQ.cjs +47 -0
  49. package/dist/tsup/chunk-TZJKSBUQ.cjs.map +1 -0
  50. package/dist/tsup/chunk-UBUC5C3G.cjs +189 -0
  51. package/dist/tsup/chunk-UBUC5C3G.cjs.map +1 -0
  52. package/dist/tsup/chunk-UIM22YJL.cjs +4406 -0
  53. package/dist/tsup/chunk-UIM22YJL.cjs.map +1 -0
  54. package/dist/tsup/chunk-URVFQMYI.cjs +230 -0
  55. package/dist/tsup/chunk-URVFQMYI.cjs.map +1 -0
  56. package/dist/tsup/chunk-UVUPOS46.js +230 -0
  57. package/dist/tsup/chunk-UVUPOS46.js.map +1 -0
  58. package/dist/tsup/chunk-VRRHBNJC.js +189 -0
  59. package/dist/tsup/chunk-VRRHBNJC.js.map +1 -0
  60. package/dist/tsup/chunk-XFSS33EQ.js +202 -0
  61. package/dist/tsup/chunk-XFSS33EQ.js.map +1 -0
  62. package/dist/tsup/client/mod.cjs +32 -0
  63. package/dist/tsup/client/mod.cjs.map +1 -0
  64. package/dist/tsup/client/mod.d.cts +26 -0
  65. package/dist/tsup/client/mod.d.ts +26 -0
  66. package/dist/tsup/client/mod.js +32 -0
  67. package/dist/tsup/client/mod.js.map +1 -0
  68. package/dist/tsup/common/log.cjs +13 -0
  69. package/dist/tsup/common/log.cjs.map +1 -0
  70. package/dist/tsup/common/log.d.cts +20 -0
  71. package/dist/tsup/common/log.d.ts +20 -0
  72. package/dist/tsup/common/log.js +13 -0
  73. package/dist/tsup/common/log.js.map +1 -0
  74. package/dist/tsup/common/websocket.cjs +10 -0
  75. package/dist/tsup/common/websocket.cjs.map +1 -0
  76. package/dist/tsup/common/websocket.d.cts +3 -0
  77. package/dist/tsup/common/websocket.d.ts +3 -0
  78. package/dist/tsup/common/websocket.js +10 -0
  79. package/dist/tsup/common/websocket.js.map +1 -0
  80. package/dist/tsup/common-CpqORuCq.d.cts +218 -0
  81. package/dist/tsup/common-CpqORuCq.d.ts +218 -0
  82. package/dist/tsup/connection-BR_Ve4ku.d.cts +2117 -0
  83. package/dist/tsup/connection-BwUMoe6n.d.ts +2117 -0
  84. package/dist/tsup/driver-helpers/mod.cjs +33 -0
  85. package/dist/tsup/driver-helpers/mod.cjs.map +1 -0
  86. package/dist/tsup/driver-helpers/mod.d.cts +18 -0
  87. package/dist/tsup/driver-helpers/mod.d.ts +18 -0
  88. package/dist/tsup/driver-helpers/mod.js +33 -0
  89. package/dist/tsup/driver-helpers/mod.js.map +1 -0
  90. package/dist/tsup/driver-test-suite/mod.cjs +4619 -0
  91. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -0
  92. package/dist/tsup/driver-test-suite/mod.d.cts +57 -0
  93. package/dist/tsup/driver-test-suite/mod.d.ts +57 -0
  94. package/dist/tsup/driver-test-suite/mod.js +4619 -0
  95. package/dist/tsup/driver-test-suite/mod.js.map +1 -0
  96. package/dist/tsup/inspector/mod.cjs +53 -0
  97. package/dist/tsup/inspector/mod.cjs.map +1 -0
  98. package/dist/tsup/inspector/mod.d.cts +408 -0
  99. package/dist/tsup/inspector/mod.d.ts +408 -0
  100. package/dist/tsup/inspector/mod.js +53 -0
  101. package/dist/tsup/inspector/mod.js.map +1 -0
  102. package/dist/tsup/mod.cjs +73 -0
  103. package/dist/tsup/mod.cjs.map +1 -0
  104. package/dist/tsup/mod.d.cts +100 -0
  105. package/dist/tsup/mod.d.ts +100 -0
  106. package/dist/tsup/mod.js +73 -0
  107. package/dist/tsup/mod.js.map +1 -0
  108. package/dist/tsup/router-endpoints-AYkXG8Tl.d.cts +66 -0
  109. package/dist/tsup/router-endpoints-DAbqVFx2.d.ts +66 -0
  110. package/dist/tsup/test/mod.cjs +21 -0
  111. package/dist/tsup/test/mod.cjs.map +1 -0
  112. package/dist/tsup/test/mod.d.cts +27 -0
  113. package/dist/tsup/test/mod.d.ts +27 -0
  114. package/dist/tsup/test/mod.js +21 -0
  115. package/dist/tsup/test/mod.js.map +1 -0
  116. package/dist/tsup/utils-CT0cv4jd.d.cts +17 -0
  117. package/dist/tsup/utils-CT0cv4jd.d.ts +17 -0
  118. package/dist/tsup/utils.cjs +26 -0
  119. package/dist/tsup/utils.cjs.map +1 -0
  120. package/dist/tsup/utils.d.cts +36 -0
  121. package/dist/tsup/utils.d.ts +36 -0
  122. package/dist/tsup/utils.js +26 -0
  123. package/dist/tsup/utils.js.map +1 -0
  124. package/package.json +208 -5
  125. package/src/actor/action.ts +182 -0
  126. package/src/actor/config.ts +765 -0
  127. package/src/actor/connection.ts +260 -0
  128. package/src/actor/context.ts +171 -0
  129. package/src/actor/database.ts +23 -0
  130. package/src/actor/definition.ts +86 -0
  131. package/src/actor/driver.ts +84 -0
  132. package/src/actor/errors.ts +360 -0
  133. package/src/actor/generic-conn-driver.ts +234 -0
  134. package/src/actor/instance.ts +1800 -0
  135. package/src/actor/log.ts +15 -0
  136. package/src/actor/mod.ts +113 -0
  137. package/src/actor/persisted.ts +42 -0
  138. package/src/actor/protocol/old.ts +281 -0
  139. package/src/actor/protocol/serde.ts +131 -0
  140. package/src/actor/router-endpoints.ts +685 -0
  141. package/src/actor/router.ts +263 -0
  142. package/src/actor/schedule.ts +17 -0
  143. package/src/actor/unstable-react.ts +110 -0
  144. package/src/actor/utils.ts +98 -0
  145. package/src/client/actor-common.ts +30 -0
  146. package/src/client/actor-conn.ts +804 -0
  147. package/src/client/actor-handle.ts +208 -0
  148. package/src/client/client.ts +623 -0
  149. package/src/client/errors.ts +41 -0
  150. package/src/client/http-client-driver.ts +326 -0
  151. package/src/client/log.ts +7 -0
  152. package/src/client/mod.ts +56 -0
  153. package/src/client/raw-utils.ts +92 -0
  154. package/src/client/test.ts +44 -0
  155. package/src/client/utils.ts +150 -0
  156. package/src/common/eventsource-interface.ts +47 -0
  157. package/src/common/eventsource.ts +80 -0
  158. package/src/common/fake-event-source.ts +266 -0
  159. package/src/common/inline-websocket-adapter2.ts +445 -0
  160. package/src/common/log-levels.ts +27 -0
  161. package/src/common/log.ts +139 -0
  162. package/src/common/logfmt.ts +228 -0
  163. package/src/common/network.ts +2 -0
  164. package/src/common/router.ts +87 -0
  165. package/src/common/utils.ts +322 -0
  166. package/src/common/versioned-data.ts +95 -0
  167. package/src/common/websocket-interface.ts +49 -0
  168. package/src/common/websocket.ts +43 -0
  169. package/src/driver-helpers/mod.ts +22 -0
  170. package/src/driver-helpers/utils.ts +17 -0
  171. package/src/driver-test-suite/log.ts +7 -0
  172. package/src/driver-test-suite/mod.ts +213 -0
  173. package/src/driver-test-suite/test-inline-client-driver.ts +402 -0
  174. package/src/driver-test-suite/tests/action-features.ts +136 -0
  175. package/src/driver-test-suite/tests/actor-auth.ts +591 -0
  176. package/src/driver-test-suite/tests/actor-conn-state.ts +249 -0
  177. package/src/driver-test-suite/tests/actor-conn.ts +349 -0
  178. package/src/driver-test-suite/tests/actor-driver.ts +25 -0
  179. package/src/driver-test-suite/tests/actor-error-handling.ts +158 -0
  180. package/src/driver-test-suite/tests/actor-handle.ts +259 -0
  181. package/src/driver-test-suite/tests/actor-inline-client.ts +152 -0
  182. package/src/driver-test-suite/tests/actor-inspector.ts +570 -0
  183. package/src/driver-test-suite/tests/actor-metadata.ts +116 -0
  184. package/src/driver-test-suite/tests/actor-onstatechange.ts +95 -0
  185. package/src/driver-test-suite/tests/actor-schedule.ts +108 -0
  186. package/src/driver-test-suite/tests/actor-sleep.ts +413 -0
  187. package/src/driver-test-suite/tests/actor-state.ts +54 -0
  188. package/src/driver-test-suite/tests/actor-vars.ts +93 -0
  189. package/src/driver-test-suite/tests/manager-driver.ts +365 -0
  190. package/src/driver-test-suite/tests/raw-http-direct-registry.ts +226 -0
  191. package/src/driver-test-suite/tests/raw-http-request-properties.ts +414 -0
  192. package/src/driver-test-suite/tests/raw-http.ts +347 -0
  193. package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +392 -0
  194. package/src/driver-test-suite/tests/raw-websocket.ts +484 -0
  195. package/src/driver-test-suite/tests/request-access.ts +244 -0
  196. package/src/driver-test-suite/utils.ts +68 -0
  197. package/src/drivers/default.ts +31 -0
  198. package/src/drivers/engine/actor-driver.ts +360 -0
  199. package/src/drivers/engine/api-endpoints.ts +128 -0
  200. package/src/drivers/engine/api-utils.ts +70 -0
  201. package/src/drivers/engine/config.ts +39 -0
  202. package/src/drivers/engine/keys.test.ts +266 -0
  203. package/src/drivers/engine/keys.ts +89 -0
  204. package/src/drivers/engine/kv.ts +3 -0
  205. package/src/drivers/engine/log.ts +7 -0
  206. package/src/drivers/engine/manager-driver.ts +391 -0
  207. package/src/drivers/engine/mod.ts +36 -0
  208. package/src/drivers/engine/ws-proxy.ts +170 -0
  209. package/src/drivers/file-system/actor.ts +91 -0
  210. package/src/drivers/file-system/global-state.ts +673 -0
  211. package/src/drivers/file-system/log.ts +7 -0
  212. package/src/drivers/file-system/manager.ts +306 -0
  213. package/src/drivers/file-system/mod.ts +48 -0
  214. package/src/drivers/file-system/utils.ts +109 -0
  215. package/src/globals.d.ts +6 -0
  216. package/src/inline-client-driver/log.ts +7 -0
  217. package/src/inline-client-driver/mod.ts +385 -0
  218. package/src/inspector/actor.ts +298 -0
  219. package/src/inspector/config.ts +83 -0
  220. package/src/inspector/log.ts +5 -0
  221. package/src/inspector/manager.ts +86 -0
  222. package/src/inspector/mod.ts +2 -0
  223. package/src/inspector/protocol/actor.ts +10 -0
  224. package/src/inspector/protocol/common.ts +196 -0
  225. package/src/inspector/protocol/manager.ts +10 -0
  226. package/src/inspector/protocol/mod.ts +2 -0
  227. package/src/inspector/utils.ts +76 -0
  228. package/src/manager/auth.ts +121 -0
  229. package/src/manager/driver.ts +80 -0
  230. package/src/manager/hono-websocket-adapter.ts +333 -0
  231. package/src/manager/log.ts +7 -0
  232. package/src/manager/mod.ts +2 -0
  233. package/src/manager/protocol/mod.ts +24 -0
  234. package/src/manager/protocol/query.ts +89 -0
  235. package/src/manager/router.ts +1792 -0
  236. package/src/mod.ts +20 -0
  237. package/src/registry/config.ts +32 -0
  238. package/src/registry/log.ts +7 -0
  239. package/src/registry/mod.ts +124 -0
  240. package/src/registry/run-config.ts +54 -0
  241. package/src/registry/serve.ts +53 -0
  242. package/src/schemas/actor-persist/mod.ts +1 -0
  243. package/src/schemas/actor-persist/versioned.ts +25 -0
  244. package/src/schemas/client-protocol/mod.ts +1 -0
  245. package/src/schemas/client-protocol/versioned.ts +63 -0
  246. package/src/schemas/file-system-driver/mod.ts +1 -0
  247. package/src/schemas/file-system-driver/versioned.ts +28 -0
  248. package/src/serde.ts +84 -0
  249. package/src/test/config.ts +16 -0
  250. package/src/test/log.ts +7 -0
  251. package/src/test/mod.ts +153 -0
  252. package/src/utils.ts +172 -0
  253. package/README.md +0 -13
@@ -0,0 +1,347 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import type { DriverTestConfig } from "../mod";
3
+ import { setupDriverTest } from "../utils";
4
+
5
+ export function runRawHttpTests(driverTestConfig: DriverTestConfig) {
6
+ describe("raw http", () => {
7
+ test("should handle raw HTTP GET requests", async (c) => {
8
+ const { client } = await setupDriverTest(c, driverTestConfig);
9
+ const actor = client.rawHttpActor.getOrCreate(["test"]);
10
+
11
+ // Test the hello endpoint
12
+ const helloResponse = await actor.fetch("api/hello");
13
+ expect(helloResponse.ok).toBe(true);
14
+ const helloData = await helloResponse.json();
15
+ expect(helloData).toEqual({ message: "Hello from actor!" });
16
+ });
17
+
18
+ test("should handle raw HTTP POST requests with echo", async (c) => {
19
+ const { client } = await setupDriverTest(c, driverTestConfig);
20
+ const actor = client.rawHttpActor.getOrCreate(["test"]);
21
+
22
+ const testData = { test: "data", number: 123 };
23
+ const echoResponse = await actor.fetch("api/echo", {
24
+ method: "POST",
25
+ headers: {
26
+ "Content-Type": "application/json",
27
+ },
28
+ body: JSON.stringify(testData),
29
+ });
30
+
31
+ expect(echoResponse.ok).toBe(true);
32
+ const echoData = await echoResponse.json();
33
+ expect(echoData).toEqual(testData);
34
+ });
35
+
36
+ test("should track state across raw HTTP requests", async (c) => {
37
+ const { client } = await setupDriverTest(c, driverTestConfig);
38
+ const actor = client.rawHttpActor.getOrCreate(["state-test"]);
39
+
40
+ // Make a few requests
41
+ await actor.fetch("api/hello");
42
+ await actor.fetch("api/hello");
43
+ await actor.fetch("api/state");
44
+
45
+ // Check the state endpoint
46
+ const stateResponse = await actor.fetch("api/state");
47
+ expect(stateResponse.ok).toBe(true);
48
+ const stateData = (await stateResponse.json()) as {
49
+ requestCount: number;
50
+ };
51
+ expect(stateData.requestCount).toBe(4); // 4 total requests
52
+ });
53
+
54
+ test("should pass headers correctly", async (c) => {
55
+ const { client } = await setupDriverTest(c, driverTestConfig);
56
+ const actor = client.rawHttpActor.getOrCreate(["headers-test"]);
57
+
58
+ const customHeaders = {
59
+ "X-Custom-Header": "test-value",
60
+ "X-Another-Header": "another-value",
61
+ };
62
+
63
+ const response = await actor.fetch("api/headers", {
64
+ headers: customHeaders,
65
+ });
66
+
67
+ expect(response.ok).toBe(true);
68
+ const headers = (await response.json()) as Record<string, string>;
69
+ expect(headers["x-custom-header"]).toBe("test-value");
70
+ expect(headers["x-another-header"]).toBe("another-value");
71
+ });
72
+
73
+ test("should return 404 for unhandled paths", async (c) => {
74
+ const { client } = await setupDriverTest(c, driverTestConfig);
75
+ const actor = client.rawHttpActor.getOrCreate(["404-test"]);
76
+
77
+ const response = await actor.fetch("api/nonexistent");
78
+ expect(response.ok).toBe(false);
79
+ expect(response.status).toBe(404);
80
+ });
81
+
82
+ test("should return 404 when no onFetch handler defined", async (c) => {
83
+ const { client } = await setupDriverTest(c, driverTestConfig);
84
+ const actor = client.rawHttpNoHandlerActor.getOrCreate(["no-handler"]);
85
+
86
+ const response = await actor.fetch("api/anything");
87
+ expect(response.ok).toBe(false);
88
+ expect(response.status).toBe(404);
89
+
90
+ // No actions available without onFetch handler
91
+ });
92
+
93
+ test("should return 500 error when onFetch returns void", async (c) => {
94
+ const { client } = await setupDriverTest(c, driverTestConfig);
95
+ const actor = client.rawHttpVoidReturnActor.getOrCreate(["void-return"]);
96
+
97
+ const response = await actor.fetch("api/anything");
98
+ expect(response.ok).toBe(false);
99
+ expect(response.status).toBe(500);
100
+
101
+ // Check error message - response might be CBOR encoded
102
+ try {
103
+ const errorData = (await response.json()) as { message: string };
104
+ expect(errorData.message).toContain(
105
+ "onFetch handler must return a Response",
106
+ );
107
+ } catch {
108
+ // If JSON parsing fails, just check that we got a 500 error
109
+ // The error details are already validated by the status code
110
+ }
111
+
112
+ // No actions available when onFetch returns void
113
+ });
114
+
115
+ test("should handle different HTTP methods", async (c) => {
116
+ const { client } = await setupDriverTest(c, driverTestConfig);
117
+ const actor = client.rawHttpActor.getOrCreate(["methods-test"]);
118
+
119
+ // Test various HTTP methods
120
+ const methods = ["GET", "POST", "PUT", "DELETE", "PATCH"];
121
+
122
+ for (const method of methods) {
123
+ const response = await actor.fetch("api/echo", {
124
+ method,
125
+ body: ["POST", "PUT", "PATCH"].includes(method)
126
+ ? JSON.stringify({ method })
127
+ : undefined,
128
+ });
129
+
130
+ // Echo endpoint only handles POST, others should fall through to 404
131
+ if (method === "POST") {
132
+ expect(response.ok).toBe(true);
133
+ const data = await response.json();
134
+ expect(data).toEqual({ method });
135
+ } else if (method === "GET") {
136
+ // GET to echo should return 404
137
+ expect(response.status).toBe(404);
138
+ } else {
139
+ // Other methods with body should also return 404
140
+ expect(response.status).toBe(404);
141
+ }
142
+ }
143
+ });
144
+
145
+ test("should handle binary data", async (c) => {
146
+ const { client } = await setupDriverTest(c, driverTestConfig);
147
+ const actor = client.rawHttpActor.getOrCreate(["binary-test"]);
148
+
149
+ // Send binary data
150
+ const binaryData = new Uint8Array([1, 2, 3, 4, 5]);
151
+ const response = await actor.fetch("api/echo", {
152
+ method: "POST",
153
+ headers: {
154
+ "Content-Type": "application/octet-stream",
155
+ },
156
+ body: binaryData,
157
+ });
158
+
159
+ expect(response.ok).toBe(true);
160
+ const responseBuffer = await response.arrayBuffer();
161
+ const responseArray = new Uint8Array(responseBuffer);
162
+ expect(Array.from(responseArray)).toEqual([1, 2, 3, 4, 5]);
163
+ });
164
+
165
+ test("should work with Hono router using createVars", async (c) => {
166
+ const { client } = await setupDriverTest(c, driverTestConfig);
167
+ const actor = client.rawHttpHonoActor.getOrCreate(["hono-test"]);
168
+
169
+ // Test root endpoint
170
+ const rootResponse = await actor.fetch("/");
171
+ expect(rootResponse.ok).toBe(true);
172
+ const rootData = await rootResponse.json();
173
+ expect(rootData).toEqual({ message: "Welcome to Hono actor!" });
174
+
175
+ // Test GET all users
176
+ const usersResponse = await actor.fetch("/users");
177
+ expect(usersResponse.ok).toBe(true);
178
+ const users = await usersResponse.json();
179
+ expect(users).toEqual([
180
+ { id: 1, name: "Alice" },
181
+ { id: 2, name: "Bob" },
182
+ ]);
183
+
184
+ // Test GET single user
185
+ const userResponse = await actor.fetch("/users/1");
186
+ expect(userResponse.ok).toBe(true);
187
+ const user = await userResponse.json();
188
+ expect(user).toEqual({ id: 1, name: "Alice" });
189
+
190
+ // Test POST new user
191
+ const newUser = { name: "Charlie" };
192
+ const createResponse = await actor.fetch("/users", {
193
+ method: "POST",
194
+ headers: { "Content-Type": "application/json" },
195
+ body: JSON.stringify(newUser),
196
+ });
197
+ expect(createResponse.ok).toBe(true);
198
+ expect(createResponse.status).toBe(201);
199
+ const createdUser = await createResponse.json();
200
+ expect(createdUser).toEqual({ id: 3, name: "Charlie" });
201
+
202
+ // Test PUT update user
203
+ const updateData = { name: "Alice Updated" };
204
+ const updateResponse = await actor.fetch("/users/1", {
205
+ method: "PUT",
206
+ headers: { "Content-Type": "application/json" },
207
+ body: JSON.stringify(updateData),
208
+ });
209
+ expect(updateResponse.ok).toBe(true);
210
+ const updatedUser = await updateResponse.json();
211
+ expect(updatedUser).toEqual({ id: 1, name: "Alice Updated" });
212
+
213
+ // Test DELETE user
214
+ const deleteResponse = await actor.fetch("/users/2", {
215
+ method: "DELETE",
216
+ });
217
+ expect(deleteResponse.ok).toBe(true);
218
+ const deleteResult = await deleteResponse.json();
219
+ expect(deleteResult).toEqual({ message: "User 2 deleted" });
220
+
221
+ // Test 404 for non-existent route
222
+ const notFoundResponse = await actor.fetch("/api/unknown");
223
+ expect(notFoundResponse.ok).toBe(false);
224
+ expect(notFoundResponse.status).toBe(404);
225
+
226
+ // No actions available on Hono actor
227
+ });
228
+
229
+ test("should handle paths with and without leading slashes", async (c) => {
230
+ const { client } = await setupDriverTest(c, driverTestConfig);
231
+ const actor = client.rawHttpActor.getOrCreate(["path-test"]);
232
+
233
+ // Test path without leading slash
234
+ const responseWithoutSlash = await actor.fetch("api/hello");
235
+ expect(responseWithoutSlash.ok).toBe(true);
236
+ const dataWithoutSlash = await responseWithoutSlash.json();
237
+ expect(dataWithoutSlash).toEqual({ message: "Hello from actor!" });
238
+
239
+ // Test path with leading slash
240
+ const responseWithSlash = await actor.fetch("/api/hello");
241
+ expect(responseWithSlash.ok).toBe(true);
242
+ const dataWithSlash = await responseWithSlash.json();
243
+ expect(dataWithSlash).toEqual({ message: "Hello from actor!" });
244
+
245
+ // Both should work the same way
246
+ });
247
+
248
+ test("should not create double slashes in request URLs", async (c) => {
249
+ const { client } = await setupDriverTest(c, driverTestConfig);
250
+ // Create a special actor that logs the request URL
251
+ const actor = client.rawHttpHonoActor.getOrCreate(["url-test"]);
252
+
253
+ // Test with leading slash - this was causing double slashes
254
+ const response = await actor.fetch("/users");
255
+ expect(response.ok).toBe(true);
256
+
257
+ // The Hono router should receive a clean path without double slashes
258
+ // If there were double slashes, Hono would not match the route correctly
259
+ const data = await response.json();
260
+ expect(data).toEqual([
261
+ { id: 1, name: "Alice" },
262
+ { id: 2, name: "Bob" },
263
+ ]);
264
+ });
265
+
266
+ test("should handle forwarded requests correctly without double slashes", async (c) => {
267
+ const { client } = await setupDriverTest(c, driverTestConfig);
268
+ const actor = client.rawHttpHonoActor.getOrCreate(["forward-test"]);
269
+
270
+ // Simulate what the example does - pass path as string and Request as init
271
+ const truncatedPath = "/users";
272
+ const url = new URL(truncatedPath, "http://example.com");
273
+ const newRequest = new Request(url, {
274
+ method: "GET",
275
+ });
276
+
277
+ // This simulates calling actor.fetch(truncatedPath, newRequest)
278
+ // which was causing double slashes in the example
279
+ const response = await actor.fetch(truncatedPath, newRequest as any);
280
+ expect(response.ok).toBe(true);
281
+ const users = await response.json();
282
+ expect(users).toEqual([
283
+ { id: 1, name: "Alice" },
284
+ { id: 2, name: "Bob" },
285
+ ]);
286
+ });
287
+
288
+ test("example fix: should properly forward requests using just Request object", async (c) => {
289
+ const { client } = await setupDriverTest(c, driverTestConfig);
290
+ const actor = client.rawHttpHonoActor.getOrCreate(["forward-fix"]);
291
+
292
+ // The correct way - just pass the Request object
293
+ const truncatedPath = "/users/1";
294
+ const url = new URL(truncatedPath, "http://example.com");
295
+ const newRequest = new Request(url, {
296
+ method: "GET",
297
+ });
298
+
299
+ // Correct usage - just pass the Request
300
+ const response = await actor.fetch(newRequest);
301
+ expect(response.ok).toBe(true);
302
+ const user = await response.json();
303
+ expect(user).toEqual({ id: 1, name: "Alice" });
304
+ });
305
+
306
+ test("should support standard fetch API with URL and Request objects", async (c) => {
307
+ const { client } = await setupDriverTest(c, driverTestConfig);
308
+ const actor = client.rawHttpActor.getOrCreate(["fetch-api-test"]);
309
+
310
+ // Test with URL object
311
+ const url = new URL("/api/echo", "http://example.com");
312
+ const urlResponse = await actor.fetch(url, {
313
+ method: "POST",
314
+ headers: { "Content-Type": "application/json" },
315
+ body: JSON.stringify({ from: "URL object" }),
316
+ });
317
+ expect(urlResponse.ok).toBe(true);
318
+ const urlData = await urlResponse.json();
319
+ expect(urlData).toEqual({ from: "URL object" });
320
+
321
+ // Test with Request object
322
+ const request = new Request("http://example.com/api/echo", {
323
+ method: "POST",
324
+ headers: { "Content-Type": "application/json" },
325
+ body: JSON.stringify({ from: "Request object" }),
326
+ });
327
+ const requestResponse = await actor.fetch(request);
328
+ expect(requestResponse.ok).toBe(true);
329
+ const requestData = await requestResponse.json();
330
+ expect(requestData).toEqual({ from: "Request object" });
331
+
332
+ // Test with Request object and additional init params
333
+ const request2 = new Request("http://example.com/api/headers", {
334
+ method: "GET",
335
+ headers: { "X-Original": "request-header" },
336
+ });
337
+ const overrideResponse = await actor.fetch(request2, {
338
+ headers: { "X-Override": "init-header" },
339
+ });
340
+ expect(overrideResponse.ok).toBe(true);
341
+ const headers = (await overrideResponse.json()) as Record<string, string>;
342
+ expect(headers["x-override"]).toBe("init-header");
343
+ // Original headers should be present too
344
+ expect(headers["x-original"]).toBe("request-header");
345
+ });
346
+ });
347
+ }