effect 4.0.6 → 4.0.7

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 (480) hide show
  1. package/dist/Arbitrary.d.ts +10 -2
  2. package/dist/Arbitrary.d.ts.map +1 -1
  3. package/dist/Arbitrary.js +2 -1
  4. package/dist/Arbitrary.js.map +1 -1
  5. package/dist/Channel.d.ts.map +1 -1
  6. package/dist/Channel.js +21 -6
  7. package/dist/Channel.js.map +1 -1
  8. package/dist/Data.d.ts +54 -235
  9. package/dist/Data.d.ts.map +1 -1
  10. package/dist/Data.js.map +1 -1
  11. package/dist/Effect.d.ts +1 -1
  12. package/dist/Effect.js +1 -1
  13. package/dist/Equal.d.ts.map +1 -1
  14. package/dist/Equal.js +8 -1
  15. package/dist/Equal.js.map +1 -1
  16. package/dist/Exit.d.ts +3 -3
  17. package/dist/Exit.d.ts.map +1 -1
  18. package/dist/Exit.js.map +1 -1
  19. package/dist/Formatter.d.ts.map +1 -1
  20. package/dist/Formatter.js +27 -13
  21. package/dist/Formatter.js.map +1 -1
  22. package/dist/Hash.d.ts.map +1 -1
  23. package/dist/Hash.js +4 -1
  24. package/dist/Hash.js.map +1 -1
  25. package/dist/JsonPatch.js +4 -0
  26. package/dist/JsonPatch.js.map +1 -1
  27. package/dist/JsonSchema.d.ts.map +1 -1
  28. package/dist/JsonSchema.js +13 -40
  29. package/dist/JsonSchema.js.map +1 -1
  30. package/dist/Metric.d.ts +3 -3
  31. package/dist/MutableList.d.ts +5 -2
  32. package/dist/MutableList.d.ts.map +1 -1
  33. package/dist/MutableList.js +7 -5
  34. package/dist/MutableList.js.map +1 -1
  35. package/dist/MutableRef.d.ts.map +1 -1
  36. package/dist/MutableRef.js +7 -0
  37. package/dist/MutableRef.js.map +1 -1
  38. package/dist/PartitionedSemaphore.d.ts +2 -1
  39. package/dist/PartitionedSemaphore.d.ts.map +1 -1
  40. package/dist/PartitionedSemaphore.js +22 -12
  41. package/dist/PartitionedSemaphore.js.map +1 -1
  42. package/dist/Pool.d.ts.map +1 -1
  43. package/dist/Pool.js +77 -27
  44. package/dist/Pool.js.map +1 -1
  45. package/dist/PubSub.d.ts.map +1 -1
  46. package/dist/PubSub.js +5 -6
  47. package/dist/PubSub.js.map +1 -1
  48. package/dist/Ref.d.ts.map +1 -1
  49. package/dist/Ref.js +8 -0
  50. package/dist/Ref.js.map +1 -1
  51. package/dist/Schedule.js +1 -1
  52. package/dist/Schedule.js.map +1 -1
  53. package/dist/Schema.d.ts +24 -8
  54. package/dist/Schema.d.ts.map +1 -1
  55. package/dist/Schema.js +37 -28
  56. package/dist/Schema.js.map +1 -1
  57. package/dist/SchemaAST.d.ts +4 -2
  58. package/dist/SchemaAST.d.ts.map +1 -1
  59. package/dist/SchemaAST.js +14 -17
  60. package/dist/SchemaAST.js.map +1 -1
  61. package/dist/SchemaParser.d.ts.map +1 -1
  62. package/dist/SchemaParser.js +48 -22
  63. package/dist/SchemaParser.js.map +1 -1
  64. package/dist/SchemaRepresentation.d.ts +19 -10
  65. package/dist/SchemaRepresentation.d.ts.map +1 -1
  66. package/dist/SchemaRepresentation.js +23 -13
  67. package/dist/SchemaRepresentation.js.map +1 -1
  68. package/dist/SchemaTransformation.d.ts +4 -1
  69. package/dist/SchemaTransformation.d.ts.map +1 -1
  70. package/dist/SchemaTransformation.js +9 -2
  71. package/dist/SchemaTransformation.js.map +1 -1
  72. package/dist/Semaphore.d.ts.map +1 -1
  73. package/dist/Semaphore.js +54 -35
  74. package/dist/Semaphore.js.map +1 -1
  75. package/dist/Sink.d.ts.map +1 -1
  76. package/dist/Sink.js +7 -2
  77. package/dist/Sink.js.map +1 -1
  78. package/dist/Stream.d.ts.map +1 -1
  79. package/dist/Stream.js +22 -10
  80. package/dist/Stream.js.map +1 -1
  81. package/dist/String.d.ts +3 -0
  82. package/dist/String.d.ts.map +1 -1
  83. package/dist/String.js +3 -0
  84. package/dist/String.js.map +1 -1
  85. package/dist/Tracer.d.ts +11 -1
  86. package/dist/Tracer.d.ts.map +1 -1
  87. package/dist/Tracer.js +6 -1
  88. package/dist/Tracer.js.map +1 -1
  89. package/dist/ai/LanguageModel.d.ts.map +1 -1
  90. package/dist/ai/LanguageModel.js +9 -0
  91. package/dist/ai/LanguageModel.js.map +1 -1
  92. package/dist/ai/McpSchema.d.ts +110 -110
  93. package/dist/ai/McpSchema.d.ts.map +1 -1
  94. package/dist/ai/McpServer.d.ts.map +1 -1
  95. package/dist/ai/McpServer.js +21 -15
  96. package/dist/ai/McpServer.js.map +1 -1
  97. package/dist/ai/Prompt.d.ts +52 -0
  98. package/dist/ai/Prompt.d.ts.map +1 -1
  99. package/dist/ai/Prompt.js +38 -0
  100. package/dist/ai/Prompt.js.map +1 -1
  101. package/dist/ai/Response.d.ts +16 -3
  102. package/dist/ai/Response.d.ts.map +1 -1
  103. package/dist/ai/Response.js +4 -0
  104. package/dist/ai/Response.js.map +1 -1
  105. package/dist/ai/Tool.d.ts +24 -0
  106. package/dist/ai/Tool.d.ts.map +1 -1
  107. package/dist/ai/Tool.js +5 -2
  108. package/dist/ai/Tool.js.map +1 -1
  109. package/dist/ai/Toolkit.d.ts.map +1 -1
  110. package/dist/ai/Toolkit.js +8 -1
  111. package/dist/ai/Toolkit.js.map +1 -1
  112. package/dist/cli/Argument.d.ts +15 -0
  113. package/dist/cli/Argument.d.ts.map +1 -1
  114. package/dist/cli/Argument.js +5 -0
  115. package/dist/cli/Argument.js.map +1 -1
  116. package/dist/cli/CliError.d.ts +78 -0
  117. package/dist/cli/CliError.d.ts.map +1 -1
  118. package/dist/cli/CliError.js +65 -3
  119. package/dist/cli/CliError.js.map +1 -1
  120. package/dist/cli/CliOutput.d.ts +155 -6
  121. package/dist/cli/CliOutput.d.ts.map +1 -1
  122. package/dist/cli/CliOutput.js +62 -6
  123. package/dist/cli/CliOutput.js.map +1 -1
  124. package/dist/cli/Command.d.ts +24 -16
  125. package/dist/cli/Command.d.ts.map +1 -1
  126. package/dist/cli/Command.js +59 -29
  127. package/dist/cli/Command.js.map +1 -1
  128. package/dist/cli/Completions.d.ts +58 -0
  129. package/dist/cli/Completions.d.ts.map +1 -1
  130. package/dist/cli/Completions.js +49 -9
  131. package/dist/cli/Completions.js.map +1 -1
  132. package/dist/cli/Flag.d.ts +15 -0
  133. package/dist/cli/Flag.d.ts.map +1 -1
  134. package/dist/cli/Flag.js +5 -0
  135. package/dist/cli/Flag.js.map +1 -1
  136. package/dist/cli/GlobalFlag.d.ts.map +1 -1
  137. package/dist/cli/GlobalFlag.js +15 -7
  138. package/dist/cli/GlobalFlag.js.map +1 -1
  139. package/dist/cli/Param.d.ts +9 -0
  140. package/dist/cli/Param.d.ts.map +1 -1
  141. package/dist/cli/Param.js +21 -2
  142. package/dist/cli/Param.js.map +1 -1
  143. package/dist/cli/TerminalCapabilities.d.ts +3 -2
  144. package/dist/cli/TerminalCapabilities.d.ts.map +1 -1
  145. package/dist/cli/TerminalCapabilities.js +3 -1
  146. package/dist/cli/TerminalCapabilities.js.map +1 -1
  147. package/dist/cli/internal/completions/bash.js +73 -27
  148. package/dist/cli/internal/completions/bash.js.map +1 -1
  149. package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
  150. package/dist/cluster/ClusterWorkflowEngine.js +45 -10
  151. package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
  152. package/dist/cluster/MessageStorage.d.ts +23 -45
  153. package/dist/cluster/MessageStorage.d.ts.map +1 -1
  154. package/dist/cluster/MessageStorage.js +6 -7
  155. package/dist/cluster/MessageStorage.js.map +1 -1
  156. package/dist/cluster/Sharding.d.ts.map +1 -1
  157. package/dist/cluster/Sharding.js +61 -21
  158. package/dist/cluster/Sharding.js.map +1 -1
  159. package/dist/cluster/ShardingConfig.d.ts +10 -0
  160. package/dist/cluster/ShardingConfig.d.ts.map +1 -1
  161. package/dist/cluster/ShardingConfig.js.map +1 -1
  162. package/dist/cluster/Snowflake.d.ts.map +1 -1
  163. package/dist/cluster/Snowflake.js +3 -7
  164. package/dist/cluster/Snowflake.js.map +1 -1
  165. package/dist/cluster/SqlRunnerStorage.d.ts.map +1 -1
  166. package/dist/cluster/SqlRunnerStorage.js +87 -39
  167. package/dist/cluster/SqlRunnerStorage.js.map +1 -1
  168. package/dist/cluster/internal/entityManager.js +54 -20
  169. package/dist/cluster/internal/entityManager.js.map +1 -1
  170. package/dist/devtools/DevToolsClient.d.ts.map +1 -1
  171. package/dist/devtools/DevToolsClient.js +2 -0
  172. package/dist/devtools/DevToolsClient.js.map +1 -1
  173. package/dist/encoding/Base64.js +36 -0
  174. package/dist/encoding/Base64.js.map +1 -1
  175. package/dist/encoding/Sse.d.ts.map +1 -1
  176. package/dist/encoding/Sse.js +3 -3
  177. package/dist/encoding/Sse.js.map +1 -1
  178. package/dist/encoding/Toml.d.ts.map +1 -1
  179. package/dist/encoding/Toml.js +21 -16
  180. package/dist/encoding/Toml.js.map +1 -1
  181. package/dist/eventlog/SqlEventJournal.d.ts.map +1 -1
  182. package/dist/eventlog/SqlEventJournal.js +47 -27
  183. package/dist/eventlog/SqlEventJournal.js.map +1 -1
  184. package/dist/eventlog/internal/conflicts.d.ts +0 -1
  185. package/dist/eventlog/internal/conflicts.d.ts.map +1 -1
  186. package/dist/eventlog/internal/conflicts.js +0 -3
  187. package/dist/eventlog/internal/conflicts.js.map +1 -1
  188. package/dist/http/Cookies.d.ts.map +1 -1
  189. package/dist/http/Cookies.js +10 -9
  190. package/dist/http/Cookies.js.map +1 -1
  191. package/dist/http/HttpClient.d.ts +423 -0
  192. package/dist/http/HttpClient.d.ts.map +1 -1
  193. package/dist/http/HttpClient.js +231 -7
  194. package/dist/http/HttpClient.js.map +1 -1
  195. package/dist/http/HttpClientError.d.ts +8 -1
  196. package/dist/http/HttpClientError.d.ts.map +1 -1
  197. package/dist/http/HttpClientError.js +37 -1
  198. package/dist/http/HttpClientError.js.map +1 -1
  199. package/dist/http/HttpClientRequest.d.ts.map +1 -1
  200. package/dist/http/HttpClientRequest.js +1 -1
  201. package/dist/http/HttpClientRequest.js.map +1 -1
  202. package/dist/http/HttpMiddleware.d.ts +1 -1
  203. package/dist/http/HttpMiddleware.d.ts.map +1 -1
  204. package/dist/http/HttpMiddleware.js +14 -16
  205. package/dist/http/HttpMiddleware.js.map +1 -1
  206. package/dist/http/HttpRouter.d.ts.map +1 -1
  207. package/dist/http/HttpRouter.js +2 -1
  208. package/dist/http/HttpRouter.js.map +1 -1
  209. package/dist/http/HttpServerError.js +2 -2
  210. package/dist/http/HttpServerError.js.map +1 -1
  211. package/dist/http/HttpServerRequest.d.ts +6 -1
  212. package/dist/http/HttpServerRequest.d.ts.map +1 -1
  213. package/dist/http/HttpServerRequest.js +73 -10
  214. package/dist/http/HttpServerRequest.js.map +1 -1
  215. package/dist/http/HttpStaticServer.d.ts.map +1 -1
  216. package/dist/http/HttpStaticServer.js +48 -21
  217. package/dist/http/HttpStaticServer.js.map +1 -1
  218. package/dist/http/MultipartParser/internal/contentType.js +3 -3
  219. package/dist/http/UrlParams.d.ts +3 -1
  220. package/dist/http/UrlParams.d.ts.map +1 -1
  221. package/dist/http/UrlParams.js +4 -2
  222. package/dist/http/UrlParams.js.map +1 -1
  223. package/dist/http/internal/compression.js +4 -5
  224. package/dist/http/internal/compression.js.map +1 -1
  225. package/dist/http/internal/decompression.js +3 -0
  226. package/dist/http/internal/decompression.js.map +1 -1
  227. package/dist/http/internal/httpBody.js +8 -1
  228. package/dist/http/internal/httpBody.js.map +1 -1
  229. package/dist/http/internal/urlParams.js +25 -0
  230. package/dist/http/internal/urlParams.js.map +1 -1
  231. package/dist/http-api/HttpApi.d.ts +3 -6
  232. package/dist/http-api/HttpApi.d.ts.map +1 -1
  233. package/dist/http-api/HttpApi.js +3 -6
  234. package/dist/http-api/HttpApi.js.map +1 -1
  235. package/dist/http-api/HttpApiBuilder.d.ts.map +1 -1
  236. package/dist/http-api/HttpApiBuilder.js +27 -11
  237. package/dist/http-api/HttpApiBuilder.js.map +1 -1
  238. package/dist/http-api/HttpApiClient.d.ts +77 -7
  239. package/dist/http-api/HttpApiClient.d.ts.map +1 -1
  240. package/dist/http-api/HttpApiClient.js +142 -44
  241. package/dist/http-api/HttpApiClient.js.map +1 -1
  242. package/dist/http-api/HttpApiEndpoint.d.ts +24 -7
  243. package/dist/http-api/HttpApiEndpoint.d.ts.map +1 -1
  244. package/dist/http-api/HttpApiEndpoint.js +109 -27
  245. package/dist/http-api/HttpApiEndpoint.js.map +1 -1
  246. package/dist/http-api/HttpApiSchema.d.ts +76 -29
  247. package/dist/http-api/HttpApiSchema.d.ts.map +1 -1
  248. package/dist/http-api/HttpApiSchema.js +70 -59
  249. package/dist/http-api/HttpApiSchema.js.map +1 -1
  250. package/dist/http-api/HttpApiTest.d.ts.map +1 -1
  251. package/dist/http-api/HttpApiTest.js +3 -2
  252. package/dist/http-api/HttpApiTest.js.map +1 -1
  253. package/dist/http-api/OpenApi.d.ts.map +1 -1
  254. package/dist/http-api/OpenApi.js +25 -16
  255. package/dist/http-api/OpenApi.js.map +1 -1
  256. package/dist/http-api/internal/toCodecHttpProperties.d.ts +2 -0
  257. package/dist/http-api/internal/toCodecHttpProperties.d.ts.map +1 -0
  258. package/dist/http-api/internal/toCodecHttpProperties.js +38 -0
  259. package/dist/http-api/internal/toCodecHttpProperties.js.map +1 -0
  260. package/dist/internal/arbitrary/runner.d.ts.map +1 -1
  261. package/dist/internal/arbitrary/runner.js +120 -44
  262. package/dist/internal/arbitrary/runner.js.map +1 -1
  263. package/dist/internal/core.js +2 -0
  264. package/dist/internal/core.js.map +1 -1
  265. package/dist/internal/effect.js +21 -13
  266. package/dist/internal/effect.js.map +1 -1
  267. package/dist/internal/equal.js +14 -0
  268. package/dist/internal/equal.js.map +1 -1
  269. package/dist/internal/jsonSchema.d.ts +2 -0
  270. package/dist/internal/jsonSchema.d.ts.map +1 -0
  271. package/dist/internal/jsonSchema.js +28 -0
  272. package/dist/internal/jsonSchema.js.map +1 -0
  273. package/dist/internal/matcher.js +1 -1
  274. package/dist/internal/matcher.js.map +1 -1
  275. package/dist/internal/schema/compilerRegistry.js +4 -1
  276. package/dist/internal/schema/compilerRegistry.js.map +1 -1
  277. package/dist/internal/schema/content.d.ts +2 -0
  278. package/dist/internal/schema/content.d.ts.map +1 -0
  279. package/dist/internal/schema/content.js +13 -0
  280. package/dist/internal/schema/content.js.map +1 -0
  281. package/dist/internal/schema/fromJsonSchemaDocument.js +173 -185
  282. package/dist/internal/schema/fromJsonSchemaDocument.js.map +1 -1
  283. package/dist/internal/schema/fromRepresentation.js +2 -1
  284. package/dist/internal/schema/fromRepresentation.js.map +1 -1
  285. package/dist/internal/schema/standardSchema.js +8 -2
  286. package/dist/internal/schema/standardSchema.js.map +1 -1
  287. package/dist/internal/schema/toCodeDocument.js +3 -3
  288. package/dist/internal/schema/toCodeDocument.js.map +1 -1
  289. package/dist/internal/schema/toCodec.js +21 -24
  290. package/dist/internal/schema/toCodec.js.map +1 -1
  291. package/dist/internal/schema/toJsonSchemaDocument.js +205 -140
  292. package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
  293. package/dist/internal/schema/toRepresentation.js +107 -129
  294. package/dist/internal/schema/toRepresentation.js.map +1 -1
  295. package/dist/internal/sql.d.ts +2 -0
  296. package/dist/internal/sql.d.ts.map +1 -0
  297. package/dist/internal/sql.js +13 -0
  298. package/dist/internal/sql.js.map +1 -0
  299. package/dist/internal/version.js +1 -1
  300. package/dist/observability/OtlpProxy.d.ts +154 -0
  301. package/dist/observability/OtlpProxy.d.ts.map +1 -0
  302. package/dist/observability/OtlpProxy.js +235 -0
  303. package/dist/observability/OtlpProxy.js.map +1 -0
  304. package/dist/observability/OtlpTracer.d.ts.map +1 -1
  305. package/dist/observability/OtlpTracer.js +4 -0
  306. package/dist/observability/OtlpTracer.js.map +1 -1
  307. package/dist/observability/index.d.ts +5 -0
  308. package/dist/observability/index.d.ts.map +1 -1
  309. package/dist/observability/index.js +5 -0
  310. package/dist/observability/index.js.map +1 -1
  311. package/dist/persistence/CircuitBreaker.d.ts +897 -0
  312. package/dist/persistence/CircuitBreaker.d.ts.map +1 -0
  313. package/dist/persistence/CircuitBreaker.js +1165 -0
  314. package/dist/persistence/CircuitBreaker.js.map +1 -0
  315. package/dist/persistence/Redis.d.ts +78 -2
  316. package/dist/persistence/Redis.d.ts.map +1 -1
  317. package/dist/persistence/Redis.js +62 -7
  318. package/dist/persistence/Redis.js.map +1 -1
  319. package/dist/persistence/index.d.ts +5 -0
  320. package/dist/persistence/index.d.ts.map +1 -1
  321. package/dist/persistence/index.js +5 -0
  322. package/dist/persistence/index.js.map +1 -1
  323. package/dist/process/ChildProcess.d.ts +30 -4
  324. package/dist/process/ChildProcess.d.ts.map +1 -1
  325. package/dist/process/ChildProcess.js.map +1 -1
  326. package/dist/process/ChildProcessSpawner.d.ts +30 -0
  327. package/dist/process/ChildProcessSpawner.d.ts.map +1 -1
  328. package/dist/process/ChildProcessSpawner.js +5 -2
  329. package/dist/process/ChildProcessSpawner.js.map +1 -1
  330. package/dist/reactivity/AsyncResult.d.ts +1 -1
  331. package/dist/reactivity/AsyncResult.d.ts.map +1 -1
  332. package/dist/rpc/RpcClient.d.ts.map +1 -1
  333. package/dist/rpc/RpcClient.js +9 -8
  334. package/dist/rpc/RpcClient.js.map +1 -1
  335. package/dist/rpc/RpcSerialization.d.ts +14 -0
  336. package/dist/rpc/RpcSerialization.d.ts.map +1 -1
  337. package/dist/rpc/RpcSerialization.js +20 -8
  338. package/dist/rpc/RpcSerialization.js.map +1 -1
  339. package/dist/rpc/RpcServer.d.ts.map +1 -1
  340. package/dist/rpc/RpcServer.js +11 -1
  341. package/dist/rpc/RpcServer.js.map +1 -1
  342. package/dist/rpc/RpcTest.d.ts +1 -0
  343. package/dist/rpc/RpcTest.d.ts.map +1 -1
  344. package/dist/rpc/RpcTest.js +1 -0
  345. package/dist/rpc/RpcTest.js.map +1 -1
  346. package/dist/sql/Migrator.d.ts +2 -1
  347. package/dist/sql/Migrator.d.ts.map +1 -1
  348. package/dist/sql/Migrator.js +11 -8
  349. package/dist/sql/Migrator.js.map +1 -1
  350. package/dist/sql/SqlClient.d.ts +9 -4
  351. package/dist/sql/SqlClient.d.ts.map +1 -1
  352. package/dist/sql/SqlClient.js +8 -1
  353. package/dist/sql/SqlClient.js.map +1 -1
  354. package/dist/sql/SqlResolver.d.ts +4 -0
  355. package/dist/sql/SqlResolver.d.ts.map +1 -1
  356. package/dist/sql/SqlResolver.js +18 -4
  357. package/dist/sql/SqlResolver.js.map +1 -1
  358. package/dist/sql/Statement.d.ts +7 -0
  359. package/dist/sql/Statement.d.ts.map +1 -1
  360. package/dist/sql/Statement.js +21 -2
  361. package/dist/sql/Statement.js.map +1 -1
  362. package/dist/workflow/DurableDeferred.d.ts.map +1 -1
  363. package/dist/workflow/DurableDeferred.js +21 -2
  364. package/dist/workflow/DurableDeferred.js.map +1 -1
  365. package/package.json +1 -1
  366. package/src/Arbitrary.ts +10 -2
  367. package/src/Channel.ts +47 -18
  368. package/src/Data.ts +60 -265
  369. package/src/Effect.ts +1 -1
  370. package/src/Equal.ts +8 -1
  371. package/src/Exit.ts +3 -3
  372. package/src/Formatter.ts +28 -13
  373. package/src/Hash.ts +4 -1
  374. package/src/JsonPatch.ts +4 -0
  375. package/src/JsonSchema.ts +12 -40
  376. package/src/Metric.ts +3 -3
  377. package/src/MutableList.ts +7 -5
  378. package/src/MutableRef.ts +8 -1
  379. package/src/PartitionedSemaphore.ts +24 -13
  380. package/src/Pool.ts +109 -37
  381. package/src/PubSub.ts +5 -6
  382. package/src/Ref.ts +8 -0
  383. package/src/Schedule.ts +1 -1
  384. package/src/Schema.ts +48 -25
  385. package/src/SchemaAST.ts +20 -20
  386. package/src/SchemaParser.ts +51 -18
  387. package/src/SchemaRepresentation.ts +31 -34
  388. package/src/SchemaTransformation.ts +9 -2
  389. package/src/Semaphore.ts +67 -40
  390. package/src/Sink.ts +15 -2
  391. package/src/Stream.ts +33 -16
  392. package/src/String.ts +3 -0
  393. package/src/Tracer.ts +15 -1
  394. package/src/ai/LanguageModel.ts +9 -0
  395. package/src/ai/McpServer.ts +14 -13
  396. package/src/ai/Prompt.ts +65 -0
  397. package/src/ai/Response.ts +34 -9
  398. package/src/ai/Tool.ts +38 -2
  399. package/src/ai/Toolkit.ts +4 -1
  400. package/src/cli/Argument.ts +15 -0
  401. package/src/cli/CliError.ts +90 -3
  402. package/src/cli/CliOutput.ts +183 -6
  403. package/src/cli/Command.ts +53 -41
  404. package/src/cli/Completions.ts +51 -0
  405. package/src/cli/Flag.ts +15 -0
  406. package/src/cli/GlobalFlag.ts +6 -7
  407. package/src/cli/Param.ts +29 -6
  408. package/src/cli/TerminalCapabilities.ts +6 -3
  409. package/src/cli/internal/completions/bash.ts +79 -29
  410. package/src/cluster/ClusterWorkflowEngine.ts +46 -16
  411. package/src/cluster/MessageStorage.ts +19 -14
  412. package/src/cluster/Sharding.ts +83 -21
  413. package/src/cluster/ShardingConfig.ts +5 -0
  414. package/src/cluster/Snowflake.ts +3 -7
  415. package/src/cluster/SqlRunnerStorage.ts +110 -47
  416. package/src/cluster/internal/entityManager.ts +75 -22
  417. package/src/devtools/DevToolsClient.ts +2 -0
  418. package/src/encoding/Base64.ts +38 -0
  419. package/src/encoding/Sse.ts +4 -3
  420. package/src/encoding/Toml.ts +33 -16
  421. package/src/eventlog/SqlEventJournal.ts +68 -45
  422. package/src/eventlog/internal/conflicts.ts +0 -4
  423. package/src/http/Cookies.ts +10 -11
  424. package/src/http/HttpClient.ts +547 -7
  425. package/src/http/HttpClientError.ts +35 -1
  426. package/src/http/HttpClientRequest.ts +9 -1
  427. package/src/http/HttpMiddleware.ts +15 -18
  428. package/src/http/HttpRouter.ts +2 -1
  429. package/src/http/HttpServerError.ts +2 -2
  430. package/src/http/HttpServerRequest.ts +102 -16
  431. package/src/http/HttpStaticServer.ts +51 -22
  432. package/src/http/MultipartParser/internal/contentType.ts +3 -3
  433. package/src/http/UrlParams.ts +6 -1
  434. package/src/http/internal/compression.ts +4 -5
  435. package/src/http/internal/decompression.ts +6 -0
  436. package/src/http/internal/httpBody.ts +10 -2
  437. package/src/http/internal/urlParams.ts +29 -0
  438. package/src/http-api/HttpApi.ts +3 -6
  439. package/src/http-api/HttpApiBuilder.ts +45 -15
  440. package/src/http-api/HttpApiClient.ts +218 -72
  441. package/src/http-api/HttpApiEndpoint.ts +121 -30
  442. package/src/http-api/HttpApiSchema.ts +141 -48
  443. package/src/http-api/HttpApiTest.ts +3 -2
  444. package/src/http-api/OpenApi.ts +20 -17
  445. package/src/http-api/internal/toCodecHttpProperties.ts +56 -0
  446. package/src/internal/arbitrary/runner.ts +133 -36
  447. package/src/internal/core.ts +2 -0
  448. package/src/internal/effect.ts +24 -16
  449. package/src/internal/equal.ts +17 -0
  450. package/src/internal/jsonSchema.ts +27 -0
  451. package/src/internal/matcher.ts +1 -1
  452. package/src/internal/schema/compilerRegistry.ts +6 -1
  453. package/src/internal/schema/content.ts +18 -0
  454. package/src/internal/schema/fromJsonSchemaDocument.ts +228 -190
  455. package/src/internal/schema/fromRepresentation.ts +2 -1
  456. package/src/internal/schema/standardSchema.ts +2 -2
  457. package/src/internal/schema/toCodeDocument.ts +4 -4
  458. package/src/internal/schema/toCodec.ts +26 -22
  459. package/src/internal/schema/toJsonSchemaDocument.ts +189 -167
  460. package/src/internal/schema/toRepresentation.ts +122 -140
  461. package/src/internal/sql.ts +14 -0
  462. package/src/internal/version.ts +1 -1
  463. package/src/observability/OtlpProxy.ts +314 -0
  464. package/src/observability/OtlpTracer.ts +4 -0
  465. package/src/observability/index.ts +6 -0
  466. package/src/persistence/CircuitBreaker.ts +1678 -0
  467. package/src/persistence/Redis.ts +129 -8
  468. package/src/persistence/index.ts +6 -0
  469. package/src/process/ChildProcess.ts +30 -4
  470. package/src/process/ChildProcessSpawner.ts +41 -2
  471. package/src/reactivity/AsyncResult.ts +1 -1
  472. package/src/rpc/RpcClient.ts +13 -10
  473. package/src/rpc/RpcSerialization.ts +32 -9
  474. package/src/rpc/RpcServer.ts +16 -1
  475. package/src/rpc/RpcTest.ts +3 -0
  476. package/src/sql/Migrator.ts +12 -7
  477. package/src/sql/SqlClient.ts +11 -4
  478. package/src/sql/SqlResolver.ts +23 -9
  479. package/src/sql/Statement.ts +30 -2
  480. package/src/workflow/DurableDeferred.ts +23 -6
@@ -1273,7 +1273,15 @@ export const compressBody: {
1273
1273
  }
1274
1274
  return Effect.map(
1275
1275
  compression.compressBody(self.body, algorithm, options),
1276
- (body) => body === self.body ? self : setHeader(setBody(self, body), "content-encoding", algorithm)
1276
+ (body) =>
1277
+ body === self.body ? self : makeWith(
1278
+ self.method,
1279
+ self.url,
1280
+ self.urlParams,
1281
+ self.hash,
1282
+ Headers.set(bodyInternal.updateContentLength(self.headers, body), "content-encoding", algorithm),
1283
+ body
1284
+ )
1277
1285
  )
1278
1286
  }
1279
1287
  )
@@ -44,6 +44,7 @@ import * as decompressionInternal from "./internal/decompression.ts"
44
44
  import * as bodyInternal from "./internal/httpBody.ts"
45
45
  import { appendPreResponseHandlerUnsafe, CurrentRequestState } from "./internal/requestState.ts"
46
46
  import * as tracing from "./internal/tracing.ts"
47
+ import * as internalUrlParams from "./internal/urlParams.ts"
47
48
  import * as UrlParams from "./UrlParams.ts"
48
49
 
49
50
  /**
@@ -135,19 +136,6 @@ export declare namespace HttpMiddleware {
135
136
  */
136
137
  export const make = <M extends HttpMiddleware>(middleware: M): M => middleware
137
138
 
138
- const stripSearchAndHash = (url: string): string => {
139
- const queryIndex = url.indexOf("?")
140
- const hashIndex = url.indexOf("#")
141
-
142
- if (queryIndex === -1) {
143
- return hashIndex === -1 ? url : url.slice(0, hashIndex)
144
- }
145
- if (hashIndex === -1) {
146
- return url.slice(0, queryIndex)
147
- }
148
- return url.slice(0, Math.min(queryIndex, hashIndex))
149
- }
150
-
151
139
  /**
152
140
  * Runs an effect with HTTP response logging disabled for the current server request.
153
141
  *
@@ -232,7 +220,7 @@ export const logger: <E, R>(
232
220
  Effect.withFiber((fiber) => {
233
221
  const request = Context.getUnsafe(fiber.context, HttpServerRequest)
234
222
  const state = Context.getOrUndefined(fiber.context, CurrentRequestState)
235
- const path = stripSearchAndHash(request.url)
223
+ const path = internalUrlParams.stripSearchAndHash(request.url)
236
224
  return Effect.withLogSpan(
237
225
  Effect.flatMap(Effect.exit(httpApp), (exit) => {
238
226
  if (state?.loggerDisabled) {
@@ -278,12 +266,19 @@ export const isTracerDisabledUnsafe = (
278
266
 
279
267
  // OpenTelemetry requires failed server spans for 5xx responses.
280
268
  const responseSpanExit = (
269
+ fiber: Fiber.Fiber<unknown, unknown>,
281
270
  request: HttpServerRequest,
282
271
  response: HttpServerResponse
283
272
  ): Exit.Exit<HttpServerResponse, HttpServerError> => {
284
273
  if (!(response.status >= 500 && response.status < 600)) {
285
274
  return Exit.succeed(response)
286
275
  }
276
+ // The message is path-only, but exporters can still read `error.request.url`
277
+ // after the request-scoped redacted names are gone.
278
+ const url = UrlParams.redactUrl(request.url, fiber.getRef(UrlParams.CurrentRedactedNames))
279
+ if (url !== request.url) {
280
+ request = request.modify({ url })
281
+ }
287
282
  const stackTraceLimit = getStackTraceLimit()
288
283
  setStackTraceLimit(0)
289
284
  try {
@@ -319,7 +314,7 @@ export const tracer: <E, R>(
319
314
  fiber.setContext(prevServices)
320
315
  const endTime = fiber.getRef(Clock).currentTimeNanosUnsafe()
321
316
  if (Exit.isSuccess(exit) && (!span.sampled || fiber.getRef(Tracer) === nativeTracer)) {
322
- span.end(endTime, responseSpanExit(request, exit.value))
317
+ span.end(endTime, responseSpanExit(fiber, request, exit.value))
323
318
  return undefined
324
319
  }
325
320
  const redactedHeaderNames = fiber.getRef(Headers.CurrentRedactedNames)
@@ -333,10 +328,10 @@ export const tracer: <E, R>(
333
328
  // OpenTelemetry only treats 5xx responses as server span errors; interrupts still fail the span.
334
329
  spanExit = Option.isSome(cause) && (response.status >= 500 || Cause.hasInterrupts(cause.value))
335
330
  ? Exit.failCause(cause.value)
336
- : responseSpanExit(request, response)
331
+ : responseSpanExit(fiber, request, response)
337
332
  } else {
338
333
  response = exit.value
339
- spanExit = responseSpanExit(request, response)
334
+ spanExit = responseSpanExit(fiber, request, response)
340
335
  }
341
336
  if (span.sampled) {
342
337
  span.attribute("http.request.method", request.method)
@@ -434,7 +429,9 @@ export interface TrustedProxyOptions {
434
429
  * @category proxying
435
430
  * @since 4.0.0
436
431
  */
437
- export const xForwardedHeaders = (options: TrustedProxyOptions): HttpMiddleware => {
432
+ export const xForwardedHeaders = (options: TrustedProxyOptions): <E, R>(
433
+ httpApp: Effect.Effect<HttpServerResponse, E, HttpServerRequest | R>
434
+ ) => Effect.Effect<HttpServerResponse, E, HttpServerRequest | R> => {
438
435
  const { trustedProxies } = options
439
436
  const isTrusted: Predicate<NetAddress.IpAddress> = typeof trustedProxies === "function"
440
437
  ? trustedProxies
@@ -284,7 +284,8 @@ function sliceRequestUrl(
284
284
  }
285
285
  while (index < url.length && !"/?;#".includes(url[index])) index++
286
286
  }
287
- return request.modify({ url: index < url.length ? url.slice(index) : "/" })
287
+ const rest = url.slice(index)
288
+ return request.modify({ url: rest.startsWith("/") ? rest : "/" + rest })
288
289
  }
289
290
 
290
291
  function countSegments(prefix: string, ignoreDuplicateSlashes: boolean) {
@@ -23,7 +23,7 @@ import { hasProperty } from "../Predicate.ts"
23
23
  import type * as Request from "./HttpServerRequest.ts"
24
24
  import * as Respondable from "./HttpServerRespondable.ts"
25
25
  import * as Response from "./HttpServerResponse.ts"
26
- import * as UrlParams from "./UrlParams.ts"
26
+ import * as internalUrlParams from "./internal/urlParams.ts"
27
27
 
28
28
  const TypeId = "~effect/http/HttpServerError"
29
29
 
@@ -280,7 +280,7 @@ export class ClientAbort extends Context.Service<ClientAbort, true>()("effect/ht
280
280
  }
281
281
 
282
282
  const formatMethodAndUrl = (request: Request.HttpServerRequest) =>
283
- `${request.method} ${UrlParams.redactUrl(request.url)}`
283
+ `${request.method} ${internalUrlParams.toPath(request.url)}`
284
284
 
285
285
  const formatRequestMessage = (reason: string, description: string | undefined, info: string) => {
286
286
  const prefix = `${reason} (${info})`
@@ -77,7 +77,9 @@ export const TypeId = "~effect/http/HttpServerRequest"
77
77
  * creating adjusted request views. `upgrade` completes a WebSocket handshake
78
78
  * for `Upgrade: websocket`. Platforms that can hand over the connection, such
79
79
  * as Node, answer other protocols with `101 Switching Protocols` and expose
80
- * the raw connection.
80
+ * the raw connection. `upgradeWith` does the same and adds custom headers to
81
+ * the `101` response; `upgrade` is `upgradeWith({})`. WebSocket upgrades fail
82
+ * when custom headers are given.
81
83
  *
82
84
  * @stability unstable
83
85
  * @category models
@@ -99,6 +101,9 @@ export interface HttpServerRequest extends HttpIncomingMessage.HttpIncomingMessa
99
101
  readonly multipartStream: Stream.Stream<Multipart.Part, Multipart.MultipartError>
100
102
 
101
103
  readonly upgrade: Effect.Effect<Socket.Socket, HttpServerError>
104
+ readonly upgradeWith: (options: {
105
+ readonly headers?: Headers.Input | undefined
106
+ }) => Effect.Effect<Socket.Socket, HttpServerError>
102
107
 
103
108
  /**
104
109
  * Address of the directly connected peer. Trusted proxy middleware replaces
@@ -610,18 +615,23 @@ class ServerRequestImpl extends Inspectable.Class implements HttpServerRequest {
610
615
  if (this.textEffect) {
611
616
  return this.textEffect
612
617
  }
613
- this.textEffect = Effect.runSync(Effect.cached(
614
- Effect.tryPromise({
615
- try: () => this.source.text(),
616
- catch: (cause) =>
617
- new HttpServerError({
618
- reason: new RequestParseError({
619
- request: this,
620
- cause
618
+ this.textEffect = Effect.withFiber((fiber) =>
619
+ fiber.getRef(HttpIncomingMessage.MaxBodySize) === undefined
620
+ ? Effect.tryPromise({
621
+ try: () => this.source.text(),
622
+ catch: (cause) =>
623
+ new HttpServerError({
624
+ reason: new RequestParseError({
625
+ request: this,
626
+ cause
627
+ })
621
628
  })
622
- })
623
- })
624
- ))
629
+ })
630
+ : Effect.map(this.arrayBuffer, (buffer) => textDecoder.decode(buffer))
631
+ ).pipe(
632
+ Effect.cached,
633
+ Effect.runSync
634
+ )
625
635
  return this.textEffect
626
636
  }
627
637
 
@@ -686,22 +696,36 @@ class ServerRequestImpl extends Inspectable.Class implements HttpServerRequest {
686
696
  if (this.arrayBufferEffect) {
687
697
  return this.arrayBufferEffect
688
698
  }
689
- this.arrayBufferEffect = Effect.runSync(Effect.cached(
690
- Effect.tryPromise({
691
- try: () => this.source.arrayBuffer(),
699
+ this.arrayBufferEffect = Effect.withFiber((fiber) => {
700
+ const maxBodySize = fiber.getRef(HttpIncomingMessage.MaxBodySize)
701
+ return Effect.tryPromise({
702
+ try: (signal) =>
703
+ maxBodySize === undefined
704
+ ? this.source.arrayBuffer()
705
+ : readArrayBufferLimited(this.source, Number(maxBodySize), signal),
692
706
  catch: (cause) =>
693
707
  new HttpServerError({
694
708
  reason: new RequestParseError({
695
709
  request: this,
710
+ reason: cause instanceof BodyTooLargeError ? "BodyTooLarge" : "Parse",
696
711
  cause
697
712
  })
698
713
  })
699
714
  })
700
- ))
715
+ }).pipe(
716
+ Effect.cached,
717
+ Effect.runSync
718
+ )
701
719
  return this.arrayBufferEffect
702
720
  }
703
721
 
704
722
  get upgrade(): Effect.Effect<Socket.Socket, HttpServerError> {
723
+ return this.upgradeWith({})
724
+ }
725
+
726
+ upgradeWith(
727
+ _options: { readonly headers?: Headers.Input | undefined }
728
+ ): Effect.Effect<Socket.Socket, HttpServerError> {
705
729
  return Effect.fail(
706
730
  new HttpServerError({
707
731
  reason: new RequestParseError({
@@ -916,6 +940,12 @@ class ClientRequestImpl extends Inspectable.Class implements HttpServerRequest {
916
940
  }
917
941
 
918
942
  get upgrade(): Effect.Effect<Socket.Socket, HttpServerError> {
943
+ return this.upgradeWith({})
944
+ }
945
+
946
+ upgradeWith(
947
+ _options: { readonly headers?: Headers.Input | undefined }
948
+ ): Effect.Effect<Socket.Socket, HttpServerError> {
919
949
  return Effect.fail(requestParseError(this, "Not an upgradeable ServerRequest"))
920
950
  }
921
951
  }
@@ -1080,6 +1110,62 @@ const isBodyInit = (u: unknown): u is BodyInit =>
1080
1110
 
1081
1111
  const textDecoder = new TextDecoder()
1082
1112
 
1113
+ class BodyTooLargeError extends Error {
1114
+ constructor(maxBytes: number) {
1115
+ super(`Request body exceeds ${maxBytes} bytes`)
1116
+ }
1117
+ }
1118
+
1119
+ const readArrayBufferLimited = async (
1120
+ source: Request,
1121
+ maxBytes: number,
1122
+ signal: AbortSignal
1123
+ ): Promise<ArrayBuffer> => {
1124
+ const header = source.headers.get("content-length")
1125
+ const contentLength = header !== null && /^\d+$/.test(header) ? Number(header) : undefined
1126
+ if (contentLength !== undefined && contentLength > maxBytes) {
1127
+ throw new BodyTooLargeError(maxBytes)
1128
+ }
1129
+ if (source.body === null) {
1130
+ return new ArrayBuffer(0)
1131
+ }
1132
+ // A constructed request can understate its content-length, so bytes are
1133
+ // counted on every runtime. Cancellation is not awaited, as the source's
1134
+ // cleanup may never settle.
1135
+ const limit = contentLength ?? maxBytes
1136
+ const reader = source.body.getReader()
1137
+ const cancel = () => {
1138
+ reader.cancel().catch(() => {})
1139
+ }
1140
+ signal.addEventListener("abort", cancel, { once: true })
1141
+ const chunks: Array<Uint8Array> = []
1142
+ let bytes = 0
1143
+ try {
1144
+ while (true) {
1145
+ const { done, value } = await reader.read()
1146
+ if (done) break
1147
+ bytes += value.byteLength
1148
+ if (bytes > limit) {
1149
+ cancel()
1150
+ throw bytes > maxBytes
1151
+ ? new BodyTooLargeError(maxBytes)
1152
+ : new Error(`Request body is longer than its content-length of ${contentLength}`)
1153
+ }
1154
+ chunks.push(value)
1155
+ }
1156
+ } finally {
1157
+ signal.removeEventListener("abort", cancel)
1158
+ reader.releaseLock()
1159
+ }
1160
+ const buffer = new Uint8Array(bytes)
1161
+ let offset = 0
1162
+ for (const chunk of chunks) {
1163
+ buffer.set(chunk, offset)
1164
+ offset += chunk.byteLength
1165
+ }
1166
+ return buffer.buffer
1167
+ }
1168
+
1083
1169
  /**
1084
1170
  * Attempts to construct an absolute `URL` for a server request safely.
1085
1171
  *
@@ -121,7 +121,9 @@ export const make: (options: {
121
121
  ) => Effect.Effect<HttpServerResponse.HttpServerResponse, HttpServerError.HttpServerError> = Effect.fnUntraced(
122
122
  function*(request, filePath, fileSize) {
123
123
  const rangeHeader = request.method === "GET" ? request.headers["range"] : undefined
124
- const shouldEvaluateConditionals = request.headers["if-none-match"] !== undefined ||
124
+ const shouldEvaluateConditionals = request.headers["if-match"] !== undefined ||
125
+ request.headers["if-unmodified-since"] !== undefined ||
126
+ request.headers["if-none-match"] !== undefined ||
125
127
  request.headers["if-modified-since"] !== undefined
126
128
 
127
129
  let fullResponse: HttpServerResponse.HttpServerResponse | undefined
@@ -446,6 +448,22 @@ const stripWeakEtagPrefix = (value: string): string => {
446
448
  return /^w\//i.test(trimmed) ? trimmed.slice(2) : trimmed;
447
449
  }
448
450
 
451
+ // If-Match uses strong comparison (RFC 9110 §13.1.1), so weak tags never
452
+ // match. Tags may contain commas, so the list is validated whole rather than
453
+ // split, and a malformed list matches nothing.
454
+ const entityTagList = /^[\s,]*(?:(?:W\/)?"[^"]*"\s*(?:,[\s,]*|$))*$/
455
+ const entityTag = /(?:W\/)?"[^"]*"/g
456
+
457
+ const matchesIfMatch = (ifMatch: string, etag: string | undefined): boolean => {
458
+ if (ifMatch.trim() === "*") {
459
+ return true
460
+ }
461
+ if (etag === undefined || !etag.startsWith("\"") || !entityTagList.test(ifMatch)) {
462
+ return false
463
+ }
464
+ return ifMatch.match(entityTag)?.includes(etag) ?? false
465
+ }
466
+
449
467
  const matchesIfNoneMatch = (ifNoneMatch: string, etag: string | undefined): boolean => {
450
468
  const normalizedEtag = etag === undefined ? undefined : stripWeakEtagPrefix(etag)
451
469
  for (const candidate of ifNoneMatch.split(",")) {
@@ -463,18 +481,19 @@ const matchesIfNoneMatch = (ifNoneMatch: string, etag: string | undefined): bool
463
481
  return false
464
482
  }
465
483
 
466
- // An invalid date on either side disables the precondition (RFC 9110 §13.1.3).
467
- const isNotModifiedSince = (ifModifiedSince: string, lastModified: string | undefined): boolean => {
484
+ // An invalid date on either side disables the precondition (RFC 9110 §13.1.3–4).
485
+ const isModifiedSince = (since: string, lastModified: string | undefined): boolean | undefined => {
468
486
  if (lastModified === undefined) {
469
- return false
487
+ return undefined
470
488
  }
471
- const ifModifiedSinceDate = Headers.parseHttpDate(ifModifiedSince)
472
- if (Result.isFailure(ifModifiedSinceDate)) {
473
- return false
489
+ const sinceDate = Headers.parseHttpDate(since)
490
+ if (Result.isFailure(sinceDate)) {
491
+ return undefined
474
492
  }
475
493
  const lastModifiedDate = Headers.parseHttpDate(lastModified)
476
- return Result.isSuccess(lastModifiedDate) &&
477
- DateTime.toEpochMillis(lastModifiedDate.success) <= DateTime.toEpochMillis(ifModifiedSinceDate.success)
494
+ return Result.isSuccess(lastModifiedDate)
495
+ ? DateTime.toEpochMillis(lastModifiedDate.success) > DateTime.toEpochMillis(sinceDate.success)
496
+ : undefined
478
497
  }
479
498
 
480
499
  // Only a strong entity-tag can match (RFC 9110 §13.1.5). Weak tags start
@@ -485,21 +504,18 @@ const matchesIfRange = (ifRange: string, etag: string | undefined): boolean => {
485
504
  return value.startsWith("\"") && value === etag
486
505
  }
487
506
 
507
+ // Headers a 304 must repeat from the 200 response (RFC 9110 §15.4.5), plus Last-Modified for revalidation.
508
+ const notModifiedHeaders = ["cache-control", "content-location", "date", "etag", "expires", "last-modified", "vary"]
509
+
488
510
  const notModifiedResponse = (
489
511
  response: HttpServerResponse.HttpServerResponse
490
512
  ): HttpServerResponse.HttpServerResponse => {
491
513
  const headers: Record<string, string> = {}
492
- const etag = response.headers["etag"]
493
- if (etag !== undefined) {
494
- headers["ETag"] = etag
495
- }
496
- const cacheControl = response.headers["cache-control"]
497
- if (cacheControl !== undefined) {
498
- headers["Cache-Control"] = cacheControl
499
- }
500
- const lastModified = response.headers["last-modified"]
501
- if (lastModified !== undefined) {
502
- headers["Last-Modified"] = lastModified
514
+ for (const name of notModifiedHeaders) {
515
+ const value = response.headers[name]
516
+ if (value !== undefined) {
517
+ headers[name] = value
518
+ }
503
519
  }
504
520
  return HttpServerResponse.empty({
505
521
  status: 304,
@@ -511,12 +527,25 @@ const evaluateConditionalRequest = (
511
527
  request: HttpServerRequest.HttpServerRequest,
512
528
  response: HttpServerResponse.HttpServerResponse
513
529
  ): HttpServerResponse.HttpServerResponse | undefined => {
530
+ const etag = response.headers["etag"]
531
+ const lastModified = response.headers["last-modified"]
532
+ const ifMatch = request.headers["if-match"]
533
+ if (ifMatch !== undefined) {
534
+ if (!matchesIfMatch(ifMatch, etag)) {
535
+ return HttpServerResponse.empty({ status: 412 })
536
+ }
537
+ } else {
538
+ const ifUnmodifiedSince = request.headers["if-unmodified-since"]
539
+ if (ifUnmodifiedSince !== undefined && isModifiedSince(ifUnmodifiedSince, lastModified) === true) {
540
+ return HttpServerResponse.empty({ status: 412 })
541
+ }
542
+ }
514
543
  const ifNoneMatch = request.headers["if-none-match"]
515
544
  if (ifNoneMatch !== undefined) {
516
- return matchesIfNoneMatch(ifNoneMatch, response.headers["etag"]) ? notModifiedResponse(response) : undefined
545
+ return matchesIfNoneMatch(ifNoneMatch, etag) ? notModifiedResponse(response) : undefined
517
546
  }
518
547
  const ifModifiedSince = request.headers["if-modified-since"]
519
- if (ifModifiedSince !== undefined && isNotModifiedSince(ifModifiedSince, response.headers["last-modified"])) {
548
+ if (ifModifiedSince !== undefined && isModifiedSince(ifModifiedSince, lastModified) === false) {
520
549
  return notModifiedResponse(response)
521
550
  }
522
551
  return undefined
@@ -16,14 +16,14 @@
16
16
  * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
17
17
  */
18
18
  const paramRE =
19
- /; *([!#$%&'*+.^\w`|~-]+)=("(?:[\v\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u{10ffff}]|\\[\v\u0020-\u{10ffff}])*"|[!#$%&'*+.^\w`|~-]+) */gu
19
+ /; *([!#$%&'*+.^\w`|~-]+)=("(?:[\t\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u{10ffff}]|\\[\t\u0020-\u{10ffff}])*"|[!#$%&'*+.^\w`|~-]+) */gu
20
20
 
21
21
  /**
22
22
  * RegExp to match *( ";" disposition-parm ) in RFC 6266 sec 4.1, which allows
23
23
  * optional whitespace around separators
24
24
  */
25
25
  const dispositionParamRE =
26
- /;[ \t]*([!#$%&'*+.^\w`|~-]+)[ \t]*=[ \t]*("(?:[\v\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u{10ffff}]|\\[\v\u0020-\u{10ffff}])*"|[!#$%&'*+.^\w`|~-]+)[ \t]*/gu
26
+ /;[ \t]*([!#$%&'*+.^\w`|~-]+)[ \t]*=[ \t]*("(?:[\t\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u{10ffff}]|\\[\t\u0020-\u{10ffff}])*"|[!#$%&'*+.^\w`|~-]+)[ \t]*/gu
27
27
 
28
28
  /**
29
29
  * RegExp to match quoted-pair in RFC 7230 sec 3.2.6
@@ -31,7 +31,7 @@ const dispositionParamRE =
31
31
  * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
32
32
  * obs-text = %x80-FF
33
33
  */
34
- const quotedPairRE = /\\([\v\u0020-\u{10ffff}])/gu
34
+ const quotedPairRE = /\\([\t\u0020-\u{10ffff}])/gu
35
35
 
36
36
  /**
37
37
  * RegExp to match type in RFC 7231 sec 3.1.1.1
@@ -870,7 +870,9 @@ const currentRedactedNames = (): ReadonlyArray<string | RegExp> =>
870
870
  *
871
871
  * **Details**
872
872
  *
873
- * Defaults include `AWSAccessKeyId`, `Signature`, `sig` and `X-Goog-Signature`.
873
+ * Defaults match the OpenTelemetry `url.full` list: `X-Amz-Signature`,
874
+ * `X-Amz-Credential`, `X-Amz-Security-Token`, `AWSAccessKeyId`, `Signature`,
875
+ * `sig` and `X-Goog-Signature`.
874
876
  * A custom list replaces the defaults. Matching uses `isRedactedName`.
875
877
  * Redaction leaves request URLs and parameter values unchanged. `Redacted`
876
878
  * values are redacted regardless of this list.
@@ -883,6 +885,9 @@ export const CurrentRedactedNames = Context.Reference<
883
885
  ReadonlyArray<string | RegExp>
884
886
  >("effect/http/UrlParams/CurrentRedactedNames", {
885
887
  defaultValue: () => [
888
+ "X-Amz-Signature",
889
+ "X-Amz-Credential",
890
+ "X-Amz-Security-Token",
886
891
  "AWSAccessKeyId",
887
892
  "Signature",
888
893
  "sig",
@@ -155,13 +155,12 @@ const acceptMember = /^([a-z0-9!#$%&'*+.^_`|~-]+)(?:;q=(0(?:\.[0-9]{0,3})?|1(?:\
155
155
  * @internal
156
156
  */
157
157
  export const parseAcceptEncoding = (header: string): ReadonlyMap<string, number> | undefined => {
158
- const trimmed = header.trim()
159
- if (trimmed === "") {
160
- return undefined
161
- }
162
158
  const accepted = new Map<string, number>()
163
- for (const part of trimmed.split(",")) {
159
+ for (const part of header.split(",")) {
164
160
  const member = part.trim().toLowerCase().replace(/[ \t]*;[ \t]*/g, ";")
161
+ if (member === "") {
162
+ continue
163
+ }
165
164
  const match = acceptMember.exec(member)
166
165
  if (match === null) {
167
166
  return undefined
@@ -124,6 +124,12 @@ export class DecompressedRequest extends Inspectable.Class implements HttpServer
124
124
  return this.inner.upgrade
125
125
  }
126
126
 
127
+ upgradeWith(
128
+ options: { readonly headers?: Headers.Input | undefined }
129
+ ): Effect.Effect<Socket.Socket, HttpServerError> {
130
+ return this.inner.upgradeWith(options)
131
+ }
132
+
127
133
  // Platform accessors such as `NodeHttpServerRequest.toServerResponse` read
128
134
  // the response handle from the request.
129
135
  get response(): unknown {
@@ -11,9 +11,17 @@ export const updateHeaders = (headers: Headers.Headers, body: HttpBody.HttpBody)
11
11
  headers = body.contentType === undefined
12
12
  ? Headers.remove(headers, "content-type")
13
13
  : Headers.set(headers, "content-type", body.contentType)
14
- return body.contentLength === undefined
14
+ return updateContentLength(headers, body)
15
+ }
16
+
17
+ /**
18
+ * @internal
19
+ */
20
+ export const updateContentLength = (headers: Headers.Headers, body: HttpBody.HttpBody): Headers.Headers => {
21
+ const contentLength = body._tag === "Empty" || body._tag === "FormData" ? undefined : body.contentLength
22
+ return contentLength === undefined
15
23
  ? Headers.remove(headers, "content-length")
16
- : Headers.set(headers, "content-length", body.contentLength.toString())
24
+ : Headers.set(headers, "content-length", contentLength.toString())
17
25
  }
18
26
 
19
27
  /**
@@ -3,3 +3,32 @@ import * as Redacted from "../../Redacted.ts"
3
3
  /** @internal */
4
4
  export const unwrap = (value: string | Redacted.Redacted): string =>
5
5
  typeof value === "string" ? value : Redacted.value(value)
6
+
7
+ /** @internal */
8
+ export const stripSearchAndHash = (url: string): string => {
9
+ const queryIndex = url.indexOf("?")
10
+ const hashIndex = url.indexOf("#")
11
+
12
+ if (queryIndex === -1) {
13
+ return hashIndex === -1 ? url : url.slice(0, hashIndex)
14
+ }
15
+ if (hashIndex === -1) {
16
+ return url.slice(0, queryIndex)
17
+ }
18
+ return url.slice(0, Math.min(queryIndex, hashIndex))
19
+ }
20
+
21
+ const originForm = /^\/(?![/\\])/
22
+
23
+ /** @internal */
24
+ export const toPath = (url: string): string => {
25
+ // Origin-form targets and "*" are already paths; absolute URLs can carry credentials.
26
+ if (url === "*" || originForm.test(url)) {
27
+ return stripSearchAndHash(url)
28
+ }
29
+ try {
30
+ return new URL(url, "http://localhost").pathname
31
+ } catch {
32
+ return "<invalid URL>"
33
+ }
34
+ }
@@ -371,12 +371,9 @@ export class AdditionalSchemas extends Context.Service<
371
371
  *
372
372
  * Header codecs receive all HTTP headers, including undeclared transport
373
373
  * headers such as `content-type`, `content-length`, `host`, `user-agent` and
374
- * proxy headers. Without `HeadersParseOptions`, headers use `ParseOptions`:
375
- *
376
- * - `onExcessProperty: "error"` rejects real requests and `WithHeaders`
377
- * responses with transport headers.
378
- * - `onExcessProperty: "preserve"` includes transport headers in the decoded
379
- * value.
374
+ * proxy headers. Without `HeadersParseOptions`, headers use `ParseOptions`, so
375
+ * `onExcessProperty: "error"` rejects real requests and `WithHeaders` responses
376
+ * with transport headers.
380
377
  *
381
378
  * Set `HeadersParseOptions` to `{}` at the API level to use Schema defaults for
382
379
  * headers, even if an endpoint sets `ParseOptions`.