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.
- package/dist/Arbitrary.d.ts +10 -2
- package/dist/Arbitrary.d.ts.map +1 -1
- package/dist/Arbitrary.js +2 -1
- package/dist/Arbitrary.js.map +1 -1
- package/dist/Channel.d.ts.map +1 -1
- package/dist/Channel.js +21 -6
- package/dist/Channel.js.map +1 -1
- package/dist/Data.d.ts +54 -235
- package/dist/Data.d.ts.map +1 -1
- package/dist/Data.js.map +1 -1
- package/dist/Effect.d.ts +1 -1
- package/dist/Effect.js +1 -1
- package/dist/Equal.d.ts.map +1 -1
- package/dist/Equal.js +8 -1
- package/dist/Equal.js.map +1 -1
- package/dist/Exit.d.ts +3 -3
- package/dist/Exit.d.ts.map +1 -1
- package/dist/Exit.js.map +1 -1
- package/dist/Formatter.d.ts.map +1 -1
- package/dist/Formatter.js +27 -13
- package/dist/Formatter.js.map +1 -1
- package/dist/Hash.d.ts.map +1 -1
- package/dist/Hash.js +4 -1
- package/dist/Hash.js.map +1 -1
- package/dist/JsonPatch.js +4 -0
- package/dist/JsonPatch.js.map +1 -1
- package/dist/JsonSchema.d.ts.map +1 -1
- package/dist/JsonSchema.js +13 -40
- package/dist/JsonSchema.js.map +1 -1
- package/dist/Metric.d.ts +3 -3
- package/dist/MutableList.d.ts +5 -2
- package/dist/MutableList.d.ts.map +1 -1
- package/dist/MutableList.js +7 -5
- package/dist/MutableList.js.map +1 -1
- package/dist/MutableRef.d.ts.map +1 -1
- package/dist/MutableRef.js +7 -0
- package/dist/MutableRef.js.map +1 -1
- package/dist/PartitionedSemaphore.d.ts +2 -1
- package/dist/PartitionedSemaphore.d.ts.map +1 -1
- package/dist/PartitionedSemaphore.js +22 -12
- package/dist/PartitionedSemaphore.js.map +1 -1
- package/dist/Pool.d.ts.map +1 -1
- package/dist/Pool.js +77 -27
- package/dist/Pool.js.map +1 -1
- package/dist/PubSub.d.ts.map +1 -1
- package/dist/PubSub.js +5 -6
- package/dist/PubSub.js.map +1 -1
- package/dist/Ref.d.ts.map +1 -1
- package/dist/Ref.js +8 -0
- package/dist/Ref.js.map +1 -1
- package/dist/Schedule.js +1 -1
- package/dist/Schedule.js.map +1 -1
- package/dist/Schema.d.ts +24 -8
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +37 -28
- package/dist/Schema.js.map +1 -1
- package/dist/SchemaAST.d.ts +4 -2
- package/dist/SchemaAST.d.ts.map +1 -1
- package/dist/SchemaAST.js +14 -17
- package/dist/SchemaAST.js.map +1 -1
- package/dist/SchemaParser.d.ts.map +1 -1
- package/dist/SchemaParser.js +48 -22
- package/dist/SchemaParser.js.map +1 -1
- package/dist/SchemaRepresentation.d.ts +19 -10
- package/dist/SchemaRepresentation.d.ts.map +1 -1
- package/dist/SchemaRepresentation.js +23 -13
- package/dist/SchemaRepresentation.js.map +1 -1
- package/dist/SchemaTransformation.d.ts +4 -1
- package/dist/SchemaTransformation.d.ts.map +1 -1
- package/dist/SchemaTransformation.js +9 -2
- package/dist/SchemaTransformation.js.map +1 -1
- package/dist/Semaphore.d.ts.map +1 -1
- package/dist/Semaphore.js +54 -35
- package/dist/Semaphore.js.map +1 -1
- package/dist/Sink.d.ts.map +1 -1
- package/dist/Sink.js +7 -2
- package/dist/Sink.js.map +1 -1
- package/dist/Stream.d.ts.map +1 -1
- package/dist/Stream.js +22 -10
- package/dist/Stream.js.map +1 -1
- package/dist/String.d.ts +3 -0
- package/dist/String.d.ts.map +1 -1
- package/dist/String.js +3 -0
- package/dist/String.js.map +1 -1
- package/dist/Tracer.d.ts +11 -1
- package/dist/Tracer.d.ts.map +1 -1
- package/dist/Tracer.js +6 -1
- package/dist/Tracer.js.map +1 -1
- package/dist/ai/LanguageModel.d.ts.map +1 -1
- package/dist/ai/LanguageModel.js +9 -0
- package/dist/ai/LanguageModel.js.map +1 -1
- package/dist/ai/McpSchema.d.ts +110 -110
- package/dist/ai/McpSchema.d.ts.map +1 -1
- package/dist/ai/McpServer.d.ts.map +1 -1
- package/dist/ai/McpServer.js +21 -15
- package/dist/ai/McpServer.js.map +1 -1
- package/dist/ai/Prompt.d.ts +52 -0
- package/dist/ai/Prompt.d.ts.map +1 -1
- package/dist/ai/Prompt.js +38 -0
- package/dist/ai/Prompt.js.map +1 -1
- package/dist/ai/Response.d.ts +16 -3
- package/dist/ai/Response.d.ts.map +1 -1
- package/dist/ai/Response.js +4 -0
- package/dist/ai/Response.js.map +1 -1
- package/dist/ai/Tool.d.ts +24 -0
- package/dist/ai/Tool.d.ts.map +1 -1
- package/dist/ai/Tool.js +5 -2
- package/dist/ai/Tool.js.map +1 -1
- package/dist/ai/Toolkit.d.ts.map +1 -1
- package/dist/ai/Toolkit.js +8 -1
- package/dist/ai/Toolkit.js.map +1 -1
- package/dist/cli/Argument.d.ts +15 -0
- package/dist/cli/Argument.d.ts.map +1 -1
- package/dist/cli/Argument.js +5 -0
- package/dist/cli/Argument.js.map +1 -1
- package/dist/cli/CliError.d.ts +78 -0
- package/dist/cli/CliError.d.ts.map +1 -1
- package/dist/cli/CliError.js +65 -3
- package/dist/cli/CliError.js.map +1 -1
- package/dist/cli/CliOutput.d.ts +155 -6
- package/dist/cli/CliOutput.d.ts.map +1 -1
- package/dist/cli/CliOutput.js +62 -6
- package/dist/cli/CliOutput.js.map +1 -1
- package/dist/cli/Command.d.ts +24 -16
- package/dist/cli/Command.d.ts.map +1 -1
- package/dist/cli/Command.js +59 -29
- package/dist/cli/Command.js.map +1 -1
- package/dist/cli/Completions.d.ts +58 -0
- package/dist/cli/Completions.d.ts.map +1 -1
- package/dist/cli/Completions.js +49 -9
- package/dist/cli/Completions.js.map +1 -1
- package/dist/cli/Flag.d.ts +15 -0
- package/dist/cli/Flag.d.ts.map +1 -1
- package/dist/cli/Flag.js +5 -0
- package/dist/cli/Flag.js.map +1 -1
- package/dist/cli/GlobalFlag.d.ts.map +1 -1
- package/dist/cli/GlobalFlag.js +15 -7
- package/dist/cli/GlobalFlag.js.map +1 -1
- package/dist/cli/Param.d.ts +9 -0
- package/dist/cli/Param.d.ts.map +1 -1
- package/dist/cli/Param.js +21 -2
- package/dist/cli/Param.js.map +1 -1
- package/dist/cli/TerminalCapabilities.d.ts +3 -2
- package/dist/cli/TerminalCapabilities.d.ts.map +1 -1
- package/dist/cli/TerminalCapabilities.js +3 -1
- package/dist/cli/TerminalCapabilities.js.map +1 -1
- package/dist/cli/internal/completions/bash.js +73 -27
- package/dist/cli/internal/completions/bash.js.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.js +45 -10
- package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
- package/dist/cluster/MessageStorage.d.ts +23 -45
- package/dist/cluster/MessageStorage.d.ts.map +1 -1
- package/dist/cluster/MessageStorage.js +6 -7
- package/dist/cluster/MessageStorage.js.map +1 -1
- package/dist/cluster/Sharding.d.ts.map +1 -1
- package/dist/cluster/Sharding.js +61 -21
- package/dist/cluster/Sharding.js.map +1 -1
- package/dist/cluster/ShardingConfig.d.ts +10 -0
- package/dist/cluster/ShardingConfig.d.ts.map +1 -1
- package/dist/cluster/ShardingConfig.js.map +1 -1
- package/dist/cluster/Snowflake.d.ts.map +1 -1
- package/dist/cluster/Snowflake.js +3 -7
- package/dist/cluster/Snowflake.js.map +1 -1
- package/dist/cluster/SqlRunnerStorage.d.ts.map +1 -1
- package/dist/cluster/SqlRunnerStorage.js +87 -39
- package/dist/cluster/SqlRunnerStorage.js.map +1 -1
- package/dist/cluster/internal/entityManager.js +54 -20
- package/dist/cluster/internal/entityManager.js.map +1 -1
- package/dist/devtools/DevToolsClient.d.ts.map +1 -1
- package/dist/devtools/DevToolsClient.js +2 -0
- package/dist/devtools/DevToolsClient.js.map +1 -1
- package/dist/encoding/Base64.js +36 -0
- package/dist/encoding/Base64.js.map +1 -1
- package/dist/encoding/Sse.d.ts.map +1 -1
- package/dist/encoding/Sse.js +3 -3
- package/dist/encoding/Sse.js.map +1 -1
- package/dist/encoding/Toml.d.ts.map +1 -1
- package/dist/encoding/Toml.js +21 -16
- package/dist/encoding/Toml.js.map +1 -1
- package/dist/eventlog/SqlEventJournal.d.ts.map +1 -1
- package/dist/eventlog/SqlEventJournal.js +47 -27
- package/dist/eventlog/SqlEventJournal.js.map +1 -1
- package/dist/eventlog/internal/conflicts.d.ts +0 -1
- package/dist/eventlog/internal/conflicts.d.ts.map +1 -1
- package/dist/eventlog/internal/conflicts.js +0 -3
- package/dist/eventlog/internal/conflicts.js.map +1 -1
- package/dist/http/Cookies.d.ts.map +1 -1
- package/dist/http/Cookies.js +10 -9
- package/dist/http/Cookies.js.map +1 -1
- package/dist/http/HttpClient.d.ts +423 -0
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/http/HttpClient.js +231 -7
- package/dist/http/HttpClient.js.map +1 -1
- package/dist/http/HttpClientError.d.ts +8 -1
- package/dist/http/HttpClientError.d.ts.map +1 -1
- package/dist/http/HttpClientError.js +37 -1
- package/dist/http/HttpClientError.js.map +1 -1
- package/dist/http/HttpClientRequest.d.ts.map +1 -1
- package/dist/http/HttpClientRequest.js +1 -1
- package/dist/http/HttpClientRequest.js.map +1 -1
- package/dist/http/HttpMiddleware.d.ts +1 -1
- package/dist/http/HttpMiddleware.d.ts.map +1 -1
- package/dist/http/HttpMiddleware.js +14 -16
- package/dist/http/HttpMiddleware.js.map +1 -1
- package/dist/http/HttpRouter.d.ts.map +1 -1
- package/dist/http/HttpRouter.js +2 -1
- package/dist/http/HttpRouter.js.map +1 -1
- package/dist/http/HttpServerError.js +2 -2
- package/dist/http/HttpServerError.js.map +1 -1
- package/dist/http/HttpServerRequest.d.ts +6 -1
- package/dist/http/HttpServerRequest.d.ts.map +1 -1
- package/dist/http/HttpServerRequest.js +73 -10
- package/dist/http/HttpServerRequest.js.map +1 -1
- package/dist/http/HttpStaticServer.d.ts.map +1 -1
- package/dist/http/HttpStaticServer.js +48 -21
- package/dist/http/HttpStaticServer.js.map +1 -1
- package/dist/http/MultipartParser/internal/contentType.js +3 -3
- package/dist/http/UrlParams.d.ts +3 -1
- package/dist/http/UrlParams.d.ts.map +1 -1
- package/dist/http/UrlParams.js +4 -2
- package/dist/http/UrlParams.js.map +1 -1
- package/dist/http/internal/compression.js +4 -5
- package/dist/http/internal/compression.js.map +1 -1
- package/dist/http/internal/decompression.js +3 -0
- package/dist/http/internal/decompression.js.map +1 -1
- package/dist/http/internal/httpBody.js +8 -1
- package/dist/http/internal/httpBody.js.map +1 -1
- package/dist/http/internal/urlParams.js +25 -0
- package/dist/http/internal/urlParams.js.map +1 -1
- package/dist/http-api/HttpApi.d.ts +3 -6
- package/dist/http-api/HttpApi.d.ts.map +1 -1
- package/dist/http-api/HttpApi.js +3 -6
- package/dist/http-api/HttpApi.js.map +1 -1
- package/dist/http-api/HttpApiBuilder.d.ts.map +1 -1
- package/dist/http-api/HttpApiBuilder.js +27 -11
- package/dist/http-api/HttpApiBuilder.js.map +1 -1
- package/dist/http-api/HttpApiClient.d.ts +77 -7
- package/dist/http-api/HttpApiClient.d.ts.map +1 -1
- package/dist/http-api/HttpApiClient.js +142 -44
- package/dist/http-api/HttpApiClient.js.map +1 -1
- package/dist/http-api/HttpApiEndpoint.d.ts +24 -7
- package/dist/http-api/HttpApiEndpoint.d.ts.map +1 -1
- package/dist/http-api/HttpApiEndpoint.js +109 -27
- package/dist/http-api/HttpApiEndpoint.js.map +1 -1
- package/dist/http-api/HttpApiSchema.d.ts +76 -29
- package/dist/http-api/HttpApiSchema.d.ts.map +1 -1
- package/dist/http-api/HttpApiSchema.js +70 -59
- package/dist/http-api/HttpApiSchema.js.map +1 -1
- package/dist/http-api/HttpApiTest.d.ts.map +1 -1
- package/dist/http-api/HttpApiTest.js +3 -2
- package/dist/http-api/HttpApiTest.js.map +1 -1
- package/dist/http-api/OpenApi.d.ts.map +1 -1
- package/dist/http-api/OpenApi.js +25 -16
- package/dist/http-api/OpenApi.js.map +1 -1
- package/dist/http-api/internal/toCodecHttpProperties.d.ts +2 -0
- package/dist/http-api/internal/toCodecHttpProperties.d.ts.map +1 -0
- package/dist/http-api/internal/toCodecHttpProperties.js +38 -0
- package/dist/http-api/internal/toCodecHttpProperties.js.map +1 -0
- package/dist/internal/arbitrary/runner.d.ts.map +1 -1
- package/dist/internal/arbitrary/runner.js +120 -44
- package/dist/internal/arbitrary/runner.js.map +1 -1
- package/dist/internal/core.js +2 -0
- package/dist/internal/core.js.map +1 -1
- package/dist/internal/effect.js +21 -13
- package/dist/internal/effect.js.map +1 -1
- package/dist/internal/equal.js +14 -0
- package/dist/internal/equal.js.map +1 -1
- package/dist/internal/jsonSchema.d.ts +2 -0
- package/dist/internal/jsonSchema.d.ts.map +1 -0
- package/dist/internal/jsonSchema.js +28 -0
- package/dist/internal/jsonSchema.js.map +1 -0
- package/dist/internal/matcher.js +1 -1
- package/dist/internal/matcher.js.map +1 -1
- package/dist/internal/schema/compilerRegistry.js +4 -1
- package/dist/internal/schema/compilerRegistry.js.map +1 -1
- package/dist/internal/schema/content.d.ts +2 -0
- package/dist/internal/schema/content.d.ts.map +1 -0
- package/dist/internal/schema/content.js +13 -0
- package/dist/internal/schema/content.js.map +1 -0
- package/dist/internal/schema/fromJsonSchemaDocument.js +173 -185
- package/dist/internal/schema/fromJsonSchemaDocument.js.map +1 -1
- package/dist/internal/schema/fromRepresentation.js +2 -1
- package/dist/internal/schema/fromRepresentation.js.map +1 -1
- package/dist/internal/schema/standardSchema.js +8 -2
- package/dist/internal/schema/standardSchema.js.map +1 -1
- package/dist/internal/schema/toCodeDocument.js +3 -3
- package/dist/internal/schema/toCodeDocument.js.map +1 -1
- package/dist/internal/schema/toCodec.js +21 -24
- package/dist/internal/schema/toCodec.js.map +1 -1
- package/dist/internal/schema/toJsonSchemaDocument.js +205 -140
- package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
- package/dist/internal/schema/toRepresentation.js +107 -129
- package/dist/internal/schema/toRepresentation.js.map +1 -1
- package/dist/internal/sql.d.ts +2 -0
- package/dist/internal/sql.d.ts.map +1 -0
- package/dist/internal/sql.js +13 -0
- package/dist/internal/sql.js.map +1 -0
- package/dist/internal/version.js +1 -1
- package/dist/observability/OtlpProxy.d.ts +154 -0
- package/dist/observability/OtlpProxy.d.ts.map +1 -0
- package/dist/observability/OtlpProxy.js +235 -0
- package/dist/observability/OtlpProxy.js.map +1 -0
- package/dist/observability/OtlpTracer.d.ts.map +1 -1
- package/dist/observability/OtlpTracer.js +4 -0
- package/dist/observability/OtlpTracer.js.map +1 -1
- package/dist/observability/index.d.ts +5 -0
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/index.js +5 -0
- package/dist/observability/index.js.map +1 -1
- package/dist/persistence/CircuitBreaker.d.ts +897 -0
- package/dist/persistence/CircuitBreaker.d.ts.map +1 -0
- package/dist/persistence/CircuitBreaker.js +1165 -0
- package/dist/persistence/CircuitBreaker.js.map +1 -0
- package/dist/persistence/Redis.d.ts +78 -2
- package/dist/persistence/Redis.d.ts.map +1 -1
- package/dist/persistence/Redis.js +62 -7
- package/dist/persistence/Redis.js.map +1 -1
- package/dist/persistence/index.d.ts +5 -0
- package/dist/persistence/index.d.ts.map +1 -1
- package/dist/persistence/index.js +5 -0
- package/dist/persistence/index.js.map +1 -1
- package/dist/process/ChildProcess.d.ts +30 -4
- package/dist/process/ChildProcess.d.ts.map +1 -1
- package/dist/process/ChildProcess.js.map +1 -1
- package/dist/process/ChildProcessSpawner.d.ts +30 -0
- package/dist/process/ChildProcessSpawner.d.ts.map +1 -1
- package/dist/process/ChildProcessSpawner.js +5 -2
- package/dist/process/ChildProcessSpawner.js.map +1 -1
- package/dist/reactivity/AsyncResult.d.ts +1 -1
- package/dist/reactivity/AsyncResult.d.ts.map +1 -1
- package/dist/rpc/RpcClient.d.ts.map +1 -1
- package/dist/rpc/RpcClient.js +9 -8
- package/dist/rpc/RpcClient.js.map +1 -1
- package/dist/rpc/RpcSerialization.d.ts +14 -0
- package/dist/rpc/RpcSerialization.d.ts.map +1 -1
- package/dist/rpc/RpcSerialization.js +20 -8
- package/dist/rpc/RpcSerialization.js.map +1 -1
- package/dist/rpc/RpcServer.d.ts.map +1 -1
- package/dist/rpc/RpcServer.js +11 -1
- package/dist/rpc/RpcServer.js.map +1 -1
- package/dist/rpc/RpcTest.d.ts +1 -0
- package/dist/rpc/RpcTest.d.ts.map +1 -1
- package/dist/rpc/RpcTest.js +1 -0
- package/dist/rpc/RpcTest.js.map +1 -1
- package/dist/sql/Migrator.d.ts +2 -1
- package/dist/sql/Migrator.d.ts.map +1 -1
- package/dist/sql/Migrator.js +11 -8
- package/dist/sql/Migrator.js.map +1 -1
- package/dist/sql/SqlClient.d.ts +9 -4
- package/dist/sql/SqlClient.d.ts.map +1 -1
- package/dist/sql/SqlClient.js +8 -1
- package/dist/sql/SqlClient.js.map +1 -1
- package/dist/sql/SqlResolver.d.ts +4 -0
- package/dist/sql/SqlResolver.d.ts.map +1 -1
- package/dist/sql/SqlResolver.js +18 -4
- package/dist/sql/SqlResolver.js.map +1 -1
- package/dist/sql/Statement.d.ts +7 -0
- package/dist/sql/Statement.d.ts.map +1 -1
- package/dist/sql/Statement.js +21 -2
- package/dist/sql/Statement.js.map +1 -1
- package/dist/workflow/DurableDeferred.d.ts.map +1 -1
- package/dist/workflow/DurableDeferred.js +21 -2
- package/dist/workflow/DurableDeferred.js.map +1 -1
- package/package.json +1 -1
- package/src/Arbitrary.ts +10 -2
- package/src/Channel.ts +47 -18
- package/src/Data.ts +60 -265
- package/src/Effect.ts +1 -1
- package/src/Equal.ts +8 -1
- package/src/Exit.ts +3 -3
- package/src/Formatter.ts +28 -13
- package/src/Hash.ts +4 -1
- package/src/JsonPatch.ts +4 -0
- package/src/JsonSchema.ts +12 -40
- package/src/Metric.ts +3 -3
- package/src/MutableList.ts +7 -5
- package/src/MutableRef.ts +8 -1
- package/src/PartitionedSemaphore.ts +24 -13
- package/src/Pool.ts +109 -37
- package/src/PubSub.ts +5 -6
- package/src/Ref.ts +8 -0
- package/src/Schedule.ts +1 -1
- package/src/Schema.ts +48 -25
- package/src/SchemaAST.ts +20 -20
- package/src/SchemaParser.ts +51 -18
- package/src/SchemaRepresentation.ts +31 -34
- package/src/SchemaTransformation.ts +9 -2
- package/src/Semaphore.ts +67 -40
- package/src/Sink.ts +15 -2
- package/src/Stream.ts +33 -16
- package/src/String.ts +3 -0
- package/src/Tracer.ts +15 -1
- package/src/ai/LanguageModel.ts +9 -0
- package/src/ai/McpServer.ts +14 -13
- package/src/ai/Prompt.ts +65 -0
- package/src/ai/Response.ts +34 -9
- package/src/ai/Tool.ts +38 -2
- package/src/ai/Toolkit.ts +4 -1
- package/src/cli/Argument.ts +15 -0
- package/src/cli/CliError.ts +90 -3
- package/src/cli/CliOutput.ts +183 -6
- package/src/cli/Command.ts +53 -41
- package/src/cli/Completions.ts +51 -0
- package/src/cli/Flag.ts +15 -0
- package/src/cli/GlobalFlag.ts +6 -7
- package/src/cli/Param.ts +29 -6
- package/src/cli/TerminalCapabilities.ts +6 -3
- package/src/cli/internal/completions/bash.ts +79 -29
- package/src/cluster/ClusterWorkflowEngine.ts +46 -16
- package/src/cluster/MessageStorage.ts +19 -14
- package/src/cluster/Sharding.ts +83 -21
- package/src/cluster/ShardingConfig.ts +5 -0
- package/src/cluster/Snowflake.ts +3 -7
- package/src/cluster/SqlRunnerStorage.ts +110 -47
- package/src/cluster/internal/entityManager.ts +75 -22
- package/src/devtools/DevToolsClient.ts +2 -0
- package/src/encoding/Base64.ts +38 -0
- package/src/encoding/Sse.ts +4 -3
- package/src/encoding/Toml.ts +33 -16
- package/src/eventlog/SqlEventJournal.ts +68 -45
- package/src/eventlog/internal/conflicts.ts +0 -4
- package/src/http/Cookies.ts +10 -11
- package/src/http/HttpClient.ts +547 -7
- package/src/http/HttpClientError.ts +35 -1
- package/src/http/HttpClientRequest.ts +9 -1
- package/src/http/HttpMiddleware.ts +15 -18
- package/src/http/HttpRouter.ts +2 -1
- package/src/http/HttpServerError.ts +2 -2
- package/src/http/HttpServerRequest.ts +102 -16
- package/src/http/HttpStaticServer.ts +51 -22
- package/src/http/MultipartParser/internal/contentType.ts +3 -3
- package/src/http/UrlParams.ts +6 -1
- package/src/http/internal/compression.ts +4 -5
- package/src/http/internal/decompression.ts +6 -0
- package/src/http/internal/httpBody.ts +10 -2
- package/src/http/internal/urlParams.ts +29 -0
- package/src/http-api/HttpApi.ts +3 -6
- package/src/http-api/HttpApiBuilder.ts +45 -15
- package/src/http-api/HttpApiClient.ts +218 -72
- package/src/http-api/HttpApiEndpoint.ts +121 -30
- package/src/http-api/HttpApiSchema.ts +141 -48
- package/src/http-api/HttpApiTest.ts +3 -2
- package/src/http-api/OpenApi.ts +20 -17
- package/src/http-api/internal/toCodecHttpProperties.ts +56 -0
- package/src/internal/arbitrary/runner.ts +133 -36
- package/src/internal/core.ts +2 -0
- package/src/internal/effect.ts +24 -16
- package/src/internal/equal.ts +17 -0
- package/src/internal/jsonSchema.ts +27 -0
- package/src/internal/matcher.ts +1 -1
- package/src/internal/schema/compilerRegistry.ts +6 -1
- package/src/internal/schema/content.ts +18 -0
- package/src/internal/schema/fromJsonSchemaDocument.ts +228 -190
- package/src/internal/schema/fromRepresentation.ts +2 -1
- package/src/internal/schema/standardSchema.ts +2 -2
- package/src/internal/schema/toCodeDocument.ts +4 -4
- package/src/internal/schema/toCodec.ts +26 -22
- package/src/internal/schema/toJsonSchemaDocument.ts +189 -167
- package/src/internal/schema/toRepresentation.ts +122 -140
- package/src/internal/sql.ts +14 -0
- package/src/internal/version.ts +1 -1
- package/src/observability/OtlpProxy.ts +314 -0
- package/src/observability/OtlpTracer.ts +4 -0
- package/src/observability/index.ts +6 -0
- package/src/persistence/CircuitBreaker.ts +1678 -0
- package/src/persistence/Redis.ts +129 -8
- package/src/persistence/index.ts +6 -0
- package/src/process/ChildProcess.ts +30 -4
- package/src/process/ChildProcessSpawner.ts +41 -2
- package/src/reactivity/AsyncResult.ts +1 -1
- package/src/rpc/RpcClient.ts +13 -10
- package/src/rpc/RpcSerialization.ts +32 -9
- package/src/rpc/RpcServer.ts +16 -1
- package/src/rpc/RpcTest.ts +3 -0
- package/src/sql/Migrator.ts +12 -7
- package/src/sql/SqlClient.ts +11 -4
- package/src/sql/SqlResolver.ts +23 -9
- package/src/sql/Statement.ts +30 -2
- package/src/workflow/DurableDeferred.ts +23 -6
|
@@ -9,6 +9,62 @@
|
|
|
9
9
|
* constructors, payload and response schema helpers, and type utilities used by
|
|
10
10
|
* builders and generated clients.
|
|
11
11
|
*
|
|
12
|
+
* **Request variants**
|
|
13
|
+
*
|
|
14
|
+
* A server needs a distinct method and path per endpoint.
|
|
15
|
+
* `HttpApiBuilder.layer` rejects two endpoints that share them, even when their
|
|
16
|
+
* query, headers or payload differ. Declare the variants of one operation as a
|
|
17
|
+
* single endpoint instead:
|
|
18
|
+
*
|
|
19
|
+
* - discriminate with a `query` or `headers` field, such as `stream: Schema.Boolean`
|
|
20
|
+
* - list several `payload` schemas, chosen by the request `Content-Type`
|
|
21
|
+
* - list several `success` schemas with distinct content types or statuses. One
|
|
22
|
+
* of them can be a stream. The server encodes whichever value the handler
|
|
23
|
+
* returns, and the client decodes by the response `Content-Type`
|
|
24
|
+
*
|
|
25
|
+
* The handler branches on the decoded request, and OpenAPI documents one
|
|
26
|
+
* operation with every alternative. The generated client returns the union of
|
|
27
|
+
* the success types. Wrap the client method to narrow the result per variant
|
|
28
|
+
* when callers need it.
|
|
29
|
+
*
|
|
30
|
+
* **Example** (Buffered and streaming variants of one operation)
|
|
31
|
+
*
|
|
32
|
+
* ```ts import.meta.vitest
|
|
33
|
+
* import { Effect, Schema, Stream } from "effect"
|
|
34
|
+
* import { HttpApi, HttpApiBuilder, HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from "effect/http-api"
|
|
35
|
+
*
|
|
36
|
+
* const Stats = Schema.Struct({ cpu: Schema.Number })
|
|
37
|
+
*
|
|
38
|
+
* const Api = HttpApi.make("Docker").add(
|
|
39
|
+
* HttpApiGroup.make("containers").add(
|
|
40
|
+
* // GET /stats?stream=false returns JSON, ?stream=true returns NDJSON
|
|
41
|
+
* HttpApiEndpoint.get("stats", "/stats", {
|
|
42
|
+
* query: { stream: Schema.Boolean },
|
|
43
|
+
* success: [Stats, HttpApiSchema.StreamNdjson({ schema: Stats })]
|
|
44
|
+
* }),
|
|
45
|
+
* // POST /images accepts a JSON pull request or a tar archive
|
|
46
|
+
* HttpApiEndpoint.post("createImage", "/images", {
|
|
47
|
+
* payload: [
|
|
48
|
+
* Schema.Struct({ fromImage: Schema.String }),
|
|
49
|
+
* HttpApiSchema.StreamUint8Array({ contentType: "application/x-tar" })
|
|
50
|
+
* ],
|
|
51
|
+
* success: Schema.String
|
|
52
|
+
* })
|
|
53
|
+
* )
|
|
54
|
+
* )
|
|
55
|
+
*
|
|
56
|
+
* const ContainersLive = HttpApiBuilder.group(Api, "containers", (handlers) =>
|
|
57
|
+
* handlers
|
|
58
|
+
* .handle("stats", ({ query }) =>
|
|
59
|
+
* Effect.succeed(query.stream ? Stream.make({ cpu: 1 }, { cpu: 2 }) : { cpu: 1 })
|
|
60
|
+
* )
|
|
61
|
+
* .handle("createImage", ({ payload }) =>
|
|
62
|
+
* Stream.isStream(payload)
|
|
63
|
+
* ? Effect.as(Stream.runDrain(payload), "imported")
|
|
64
|
+
* : Effect.succeed(`pulled ${payload.fromImage}`)
|
|
65
|
+
* ))
|
|
66
|
+
* ```
|
|
67
|
+
*
|
|
12
68
|
* @stability unstable
|
|
13
69
|
* @since 4.0.0
|
|
14
70
|
*/
|
|
@@ -36,6 +92,7 @@ import type * as HttpApiGroup from "./HttpApiGroup.ts"
|
|
|
36
92
|
import type * as HttpApiMiddleware from "./HttpApiMiddleware.ts"
|
|
37
93
|
import * as HttpApiSchema from "./HttpApiSchema.ts"
|
|
38
94
|
import * as MediaType from "./internal/mediaType.ts"
|
|
95
|
+
import { toCodecHttpProperties } from "./internal/toCodecHttpProperties.ts"
|
|
39
96
|
|
|
40
97
|
const TypeId = "~effect/http-api/HttpApiEndpoint"
|
|
41
98
|
|
|
@@ -71,6 +128,7 @@ type SuccessEncodingServices<S> = S extends HttpApiSchema.StreamSse<
|
|
|
71
128
|
> ? _Events["EncodingServices"] | _Error["EncodingServices"]
|
|
72
129
|
: S extends HttpApiSchema.StreamUint8Array ? never
|
|
73
130
|
: S extends HttpApiSchema.StreamNdjson<infer _S> ? _S["EncodingServices"]
|
|
131
|
+
: S extends HttpApiSchema.Upgrade<infer _Headers> ? _Headers["EncodingServices"]
|
|
74
132
|
: S extends Schema.Constraint ? S["EncodingServices"]
|
|
75
133
|
: never
|
|
76
134
|
|
|
@@ -81,6 +139,7 @@ type SuccessDecodingServices<S> = S extends HttpApiSchema.StreamSse<
|
|
|
81
139
|
> ? _Events["DecodingServices"] | _Error["DecodingServices"]
|
|
82
140
|
: S extends HttpApiSchema.StreamUint8Array ? never
|
|
83
141
|
: S extends HttpApiSchema.StreamNdjson<infer _S> ? _S["DecodingServices"]
|
|
142
|
+
: S extends HttpApiSchema.Upgrade<infer _Headers> ? _Headers["DecodingServices"]
|
|
84
143
|
: S extends Schema.Constraint ? S["DecodingServices"]
|
|
85
144
|
: never
|
|
86
145
|
|
|
@@ -95,10 +154,19 @@ type ExtractStreamSuccess<S extends SuccessConstraint> = UnwrapReadonlyArray<S>
|
|
|
95
154
|
Success extends HttpApiSchema.StreamSchema ? Success : never
|
|
96
155
|
: never
|
|
97
156
|
|
|
98
|
-
type ExtractUpgradeSuccess<S extends SuccessConstraint> =
|
|
157
|
+
type ExtractUpgradeSuccess<S extends SuccessConstraint> = UnwrapReadonlyArray<S> extends infer Success ?
|
|
158
|
+
Success extends HttpApiSchema.Upgrade<infer _Headers> ?
|
|
159
|
+
[_Headers] extends [never] ? Success : HttpApiSchema.Upgrade<Schema.toCodecStringTree<_Headers>>
|
|
160
|
+
: never
|
|
161
|
+
: never
|
|
162
|
+
|
|
163
|
+
type UpgradeRequest<Success> = [Extract<Success, HttpApiSchema.Upgrade>] extends [never] ? {}
|
|
164
|
+
: { readonly upgrade: UpgradeFunction<Extract<Success, HttpApiSchema.Upgrade>> }
|
|
99
165
|
|
|
100
|
-
type
|
|
101
|
-
|
|
166
|
+
type UpgradeFunction<S> = S extends HttpApiSchema.Upgrade<infer _Headers> ?
|
|
167
|
+
[_Headers] extends [never] ? () => Effect<Socket.Socket>
|
|
168
|
+
: (options: { readonly headers: _Headers["Type"] }) => Effect<Socket.Socket>
|
|
169
|
+
: never
|
|
102
170
|
|
|
103
171
|
type ExtractWithHeadersSuccess<S extends SuccessConstraint> = UnwrapReadonlyArray<S> extends infer Success ?
|
|
104
172
|
Success extends HttpApiSchema.WithHeaders<infer _Inner, infer _Headers> ? HttpApiSchema.WithHeaders<
|
|
@@ -148,7 +216,7 @@ type PayloadError<Payload> = Payload extends HttpApiSchema.StreamUint8Array ? Ht
|
|
|
148
216
|
: never
|
|
149
217
|
|
|
150
218
|
type RequestFromParts<Endpoint, ParamsType, QueryType, Payload, HeadersType, Success> =
|
|
151
|
-
&
|
|
219
|
+
& UpgradeRequest<Success>
|
|
152
220
|
& ([ParamsType] extends [never] ? {} : { readonly params: Simplify<ParamsType> })
|
|
153
221
|
& ([QueryType] extends [never] ? {} : { readonly query: Simplify<QueryType> })
|
|
154
222
|
& ([Payload] extends [never] ? {} : { readonly payload: RequestPayload<Payload> })
|
|
@@ -160,7 +228,7 @@ type RequestFromParts<Endpoint, ParamsType, QueryType, Payload, HeadersType, Suc
|
|
|
160
228
|
}
|
|
161
229
|
|
|
162
230
|
type RequestRawFromParts<Endpoint, ParamsType, QueryType, HeadersType, Success> =
|
|
163
|
-
&
|
|
231
|
+
& UpgradeRequest<Success>
|
|
164
232
|
& ([ParamsType] extends [never] ? {} : { readonly params: Simplify<ParamsType> })
|
|
165
233
|
& ([QueryType] extends [never] ? {} : { readonly query: Simplify<QueryType> })
|
|
166
234
|
& ([HeadersType] extends [never] ? {} : { readonly headers: Simplify<HeadersType> })
|
|
@@ -1111,6 +1179,16 @@ type ErrorNoStream<S extends ErrorConstraint> = [
|
|
|
1111
1179
|
* and response schemas, applying automatic JSON or string-tree codecs unless
|
|
1112
1180
|
* `disableCodecs` is enabled.
|
|
1113
1181
|
*
|
|
1182
|
+
* **Gotchas**
|
|
1183
|
+
*
|
|
1184
|
+
* URL parameters are flat on the server: each `query` field, each field of a
|
|
1185
|
+
* no-body `payload` and each field of a form-urlencoded `payload` should encode
|
|
1186
|
+
* to a string or an array of strings. A field that encodes to a nested object
|
|
1187
|
+
* is sent as bracket keys (`meta[k]=v`) that the server does not read back, so
|
|
1188
|
+
* it is dropped, or reported missing when required. Send structured values with
|
|
1189
|
+
* an explicit codec such as `Schema.fromJsonString(...)`, or declare bracket
|
|
1190
|
+
* keys literally, for example `"page[size]": Schema.String`.
|
|
1191
|
+
*
|
|
1114
1192
|
* @stability unstable
|
|
1115
1193
|
* @category constructors
|
|
1116
1194
|
* @since 4.0.0
|
|
@@ -1217,16 +1295,17 @@ export const make = <Method extends HttpMethod>(method: Method): {
|
|
|
1217
1295
|
Error extends ReadonlyArray<Schema.Constraint> ? Error[number] : Error
|
|
1218
1296
|
> => {
|
|
1219
1297
|
const disableCodecs = options?.disableCodecs ?? false
|
|
1220
|
-
const
|
|
1298
|
+
const transformProperties = disableCodecs ? identity : toCodecHttpProperties
|
|
1299
|
+
const payload = getPayload(options?.payload, method, disableCodecs)
|
|
1221
1300
|
return makeProto({
|
|
1222
1301
|
identifier,
|
|
1223
1302
|
path,
|
|
1224
1303
|
method,
|
|
1225
|
-
params: ensureStruct(options?.params,
|
|
1226
|
-
query: ensureStruct(options?.query,
|
|
1227
|
-
headers: ensureStruct(options?.headers,
|
|
1228
|
-
payload
|
|
1229
|
-
success: getSuccessResponse(options?.success, method,
|
|
1304
|
+
params: ensureStruct(options?.params, transformProperties),
|
|
1305
|
+
query: ensureStruct(options?.query, transformProperties),
|
|
1306
|
+
headers: ensureStruct(options?.headers, transformProperties),
|
|
1307
|
+
payload,
|
|
1308
|
+
success: getSuccessResponse(options?.success, method, payload, disableCodecs),
|
|
1230
1309
|
error: getErrorResponse(options?.error, disableCodecs),
|
|
1231
1310
|
annotations: Context.empty(),
|
|
1232
1311
|
middlewares: new Set(),
|
|
@@ -1281,11 +1360,13 @@ function getPayload(
|
|
|
1281
1360
|
throw new Error("Multiple streaming payloads are not supported")
|
|
1282
1361
|
}
|
|
1283
1362
|
hasStream = true
|
|
1284
|
-
const
|
|
1285
|
-
|
|
1286
|
-
|
|
1363
|
+
for (const declared of schema.contentTypes) {
|
|
1364
|
+
const contentType = MediaType.normalize(declared)
|
|
1365
|
+
if (result.has(contentType)) {
|
|
1366
|
+
throw new Error(`Cannot combine buffered and streaming payloads for content-type: ${declared}`)
|
|
1367
|
+
}
|
|
1368
|
+
result.set(contentType, { encoding: { _tag: "Stream", contentType: declared }, schemas: [schema] })
|
|
1287
1369
|
}
|
|
1288
|
-
result.set(contentType, { encoding: { _tag: "Stream", contentType: schema.contentType }, schemas: [schema] })
|
|
1289
1370
|
continue
|
|
1290
1371
|
}
|
|
1291
1372
|
const encoding = HttpApiSchema.getPayloadEncoding(schema.ast, method)
|
|
@@ -1314,22 +1395,27 @@ const reservedStreamFailureEvent = "effect/http-api/stream/failure"
|
|
|
1314
1395
|
function getSuccessResponse(
|
|
1315
1396
|
success: Schema.Top | ReadonlyArray<Schema.Top> | undefined,
|
|
1316
1397
|
method: HttpMethod,
|
|
1317
|
-
|
|
1398
|
+
payload: PayloadMap,
|
|
1318
1399
|
disableCodecs: boolean
|
|
1319
1400
|
): Set<Schema.Top> {
|
|
1320
1401
|
if (success === undefined) return new Set()
|
|
1321
1402
|
const schemas = Arr.ensure(success)
|
|
1322
|
-
validateSuccessResponse(schemas, method,
|
|
1403
|
+
validateSuccessResponse(schemas, method, payload)
|
|
1323
1404
|
return new Set(disableCodecs ? schemas : schemas.map(transformResponseSchema))
|
|
1324
1405
|
}
|
|
1325
1406
|
|
|
1326
1407
|
const transformResponseSchema = memoize((schema: Schema.Top): Schema.Top => {
|
|
1327
|
-
if (HttpApiSchema.isStreamSchema(schema)
|
|
1408
|
+
if (HttpApiSchema.isStreamSchema(schema)) return schema
|
|
1409
|
+
if (HttpApiSchema.isUpgrade(schema)) {
|
|
1410
|
+
return schema.headers === undefined
|
|
1411
|
+
? schema
|
|
1412
|
+
: HttpApiSchema.rebuildUpgrade(schema.protocol, toCodecHttpProperties(schema.headers))
|
|
1413
|
+
}
|
|
1328
1414
|
if (HttpApiSchema.isWithHeaders(schema)) {
|
|
1329
1415
|
const inner = HttpApiSchema.isStreamSchema(schema.schema)
|
|
1330
1416
|
? schema.schema
|
|
1331
1417
|
: applyResponseEncoding(schema.schema, HttpApiSchema.getResponseEncodingSchema(schema))
|
|
1332
|
-
return HttpApiSchema.rebuildWithHeaders(schema, inner,
|
|
1418
|
+
return HttpApiSchema.rebuildWithHeaders(schema, inner, toCodecHttpProperties(schema.headers))
|
|
1333
1419
|
}
|
|
1334
1420
|
return transformResponse(schema)
|
|
1335
1421
|
})
|
|
@@ -1353,7 +1439,7 @@ function getErrorResponse(
|
|
|
1353
1439
|
return new Set(disableCodecs ? schemas : schemas.map(transformResponseSchema))
|
|
1354
1440
|
}
|
|
1355
1441
|
|
|
1356
|
-
function validateSuccessResponse(schemas: ReadonlyArray<Schema.Constraint>, method: HttpMethod,
|
|
1442
|
+
function validateSuccessResponse(schemas: ReadonlyArray<Schema.Constraint>, method: HttpMethod, payload: PayloadMap) {
|
|
1357
1443
|
if (schemas.some(HttpApiSchema.isUpgrade)) {
|
|
1358
1444
|
if (schemas.length > 1) {
|
|
1359
1445
|
throw new Error("Cannot combine an upgrade with other success responses")
|
|
@@ -1361,8 +1447,11 @@ function validateSuccessResponse(schemas: ReadonlyArray<Schema.Constraint>, meth
|
|
|
1361
1447
|
if (method === "HEAD") {
|
|
1362
1448
|
throw new Error("HEAD endpoints cannot declare an upgrade")
|
|
1363
1449
|
}
|
|
1364
|
-
|
|
1365
|
-
|
|
1450
|
+
// The 101 can only follow the end of the request, so the body is read before the upgrade.
|
|
1451
|
+
for (const { encoding } of payload.values()) {
|
|
1452
|
+
if (encoding._tag === "Stream" || (encoding._tag === "Multipart" && encoding.mode === "stream")) {
|
|
1453
|
+
throw new Error("Upgrade endpoints cannot declare a streaming payload")
|
|
1454
|
+
}
|
|
1366
1455
|
}
|
|
1367
1456
|
return
|
|
1368
1457
|
}
|
|
@@ -1386,10 +1475,12 @@ function validateSuccessResponse(schemas: ReadonlyArray<Schema.Constraint>, meth
|
|
|
1386
1475
|
if (entry.noContent) {
|
|
1387
1476
|
throw new Error(`Cannot combine no-content and streaming success responses for status: ${status}`)
|
|
1388
1477
|
}
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1478
|
+
for (const declared of inner.contentTypes) {
|
|
1479
|
+
if (entry.bufferedContentTypes.has(MediaType.normalize(declared))) {
|
|
1480
|
+
throw new Error(
|
|
1481
|
+
`Cannot combine buffered and streaming success responses for status ${status} and content-type: ${declared}`
|
|
1482
|
+
)
|
|
1483
|
+
}
|
|
1393
1484
|
}
|
|
1394
1485
|
statuses.set(status, { ...entry, stream: inner })
|
|
1395
1486
|
} else {
|
|
@@ -1400,9 +1491,8 @@ function validateSuccessResponse(schemas: ReadonlyArray<Schema.Constraint>, meth
|
|
|
1400
1491
|
throw new Error(`Cannot combine no-content and streaming success responses for status: ${status}`)
|
|
1401
1492
|
}
|
|
1402
1493
|
const encoding = HttpApiSchema.getResponseEncodingSchema(schema)
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
) {
|
|
1494
|
+
const contentType = MediaType.normalize(encoding.contentType)
|
|
1495
|
+
if (entry.stream.contentTypes.some((declared) => MediaType.normalize(declared) === contentType)) {
|
|
1406
1496
|
throw new Error(
|
|
1407
1497
|
`Cannot combine buffered and streaming success responses for status ${status} and content-type: ${encoding.contentType}`
|
|
1408
1498
|
)
|
|
@@ -1535,7 +1625,7 @@ function transformResponse(schema: Schema.Top): Schema.Top {
|
|
|
1535
1625
|
"~httpApiWithHeaders": {
|
|
1536
1626
|
...withHeaders,
|
|
1537
1627
|
bodyCodec: applyResponseEncoding(withHeaders.body, encoding),
|
|
1538
|
-
headersCodec:
|
|
1628
|
+
headersCodec: toCodecHttpProperties(withHeaders.headers)
|
|
1539
1629
|
}
|
|
1540
1630
|
})
|
|
1541
1631
|
}
|
|
@@ -1553,6 +1643,7 @@ function applyResponseEncoding(schema: Schema.Top, encoding: HttpApiSchema.Respo
|
|
|
1553
1643
|
}
|
|
1554
1644
|
|
|
1555
1645
|
function transformPayload(schema: Schema.Top, method: HttpMethod): Schema.Top {
|
|
1646
|
+
if (!hasBody(method)) return toCodecHttpProperties(schema)
|
|
1556
1647
|
const encoding = HttpApiSchema.getPayloadEncoding(schema.ast, method)
|
|
1557
1648
|
switch (encoding._tag) {
|
|
1558
1649
|
case "Json":
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* @stability unstable
|
|
11
11
|
* @since 4.0.0
|
|
12
12
|
*/
|
|
13
|
+
import * as Arr from "../Array.ts"
|
|
13
14
|
import * as ByteSize from "../ByteSize.ts"
|
|
14
15
|
import * as Sse from "../encoding/Sse.ts"
|
|
15
16
|
import { constVoid, type LazyArg } from "../Function.ts"
|
|
@@ -22,6 +23,7 @@ import * as SchemaAST from "../SchemaAST.ts"
|
|
|
22
23
|
import * as SchemaTransformation from "../SchemaTransformation.ts"
|
|
23
24
|
import * as Socket from "../socket/Socket.ts"
|
|
24
25
|
import * as Stream from "../Stream.ts"
|
|
26
|
+
import * as MediaType from "./internal/mediaType.ts"
|
|
25
27
|
|
|
26
28
|
declare module "../Schema.ts" {
|
|
27
29
|
namespace Annotations {
|
|
@@ -122,13 +124,15 @@ export type StatusLiteral = HttpStatus.Literal
|
|
|
122
124
|
*
|
|
123
125
|
* **Details**
|
|
124
126
|
*
|
|
125
|
-
*
|
|
126
|
-
* schema
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
* status
|
|
131
|
-
*
|
|
127
|
+
* Stores the status with `.annotateKey({ httpApiStatus: code })` unless the
|
|
128
|
+
* schema or any of its checks already has an ordinary `httpApiStatus`
|
|
129
|
+
* annotation, including an explicit `undefined`. In that case, uses
|
|
130
|
+
* `.annotate({ httpApiStatus: code })` instead.
|
|
131
|
+
*
|
|
132
|
+
* Ordinary status annotations take precedence over key annotations. Checks
|
|
133
|
+
* without a status annotation preserve the existing status. You can pass
|
|
134
|
+
* either a numeric code (for example, `201`) or a common literal name
|
|
135
|
+
* (for example, `"Created"`).
|
|
132
136
|
*
|
|
133
137
|
* @stability unstable
|
|
134
138
|
* @category schemas
|
|
@@ -149,9 +153,9 @@ export function status(code: StatusLiteral): {
|
|
|
149
153
|
export function status(code: number | StatusLiteral) {
|
|
150
154
|
const statusCode = typeof code === "string" ? HttpStatus.fromLiteral(code) : code
|
|
151
155
|
return <S extends Schema.Top>(self: S): S["Rebuild"] =>
|
|
152
|
-
self.ast
|
|
153
|
-
? self.
|
|
154
|
-
: self.
|
|
156
|
+
findHttpApiStatusAnnotation(self.ast) === undefined
|
|
157
|
+
? self.annotateKey({ httpApiStatus: statusCode })
|
|
158
|
+
: self.annotate({ httpApiStatus: statusCode })
|
|
155
159
|
}
|
|
156
160
|
|
|
157
161
|
/**
|
|
@@ -321,6 +325,7 @@ export interface StreamSse<
|
|
|
321
325
|
readonly mode: "sse"
|
|
322
326
|
readonly sseMode: StreamSseMode
|
|
323
327
|
readonly contentType: string
|
|
328
|
+
readonly contentTypes: Arr.NonEmptyReadonlyArray<string>
|
|
324
329
|
readonly events: Events
|
|
325
330
|
readonly error: Error
|
|
326
331
|
readonly "~Value"?: Value | undefined
|
|
@@ -379,6 +384,7 @@ export interface StreamUint8Array extends
|
|
|
379
384
|
readonly _tag: "StreamUint8Array"
|
|
380
385
|
readonly mode: "uint8array"
|
|
381
386
|
readonly contentType: string
|
|
387
|
+
readonly contentTypes: Arr.NonEmptyReadonlyArray<string>
|
|
382
388
|
readonly maxBytes: ByteSize.ByteSize | undefined
|
|
383
389
|
}
|
|
384
390
|
|
|
@@ -430,6 +436,7 @@ export interface StreamNdjson<S extends Schema.Constraint> extends
|
|
|
430
436
|
readonly _tag: "StreamNdjson"
|
|
431
437
|
readonly mode: "ndjson"
|
|
432
438
|
readonly contentType: string
|
|
439
|
+
readonly contentTypes: Arr.NonEmptyReadonlyArray<string>
|
|
433
440
|
readonly schema: S
|
|
434
441
|
readonly maxBytes: ByteSize.ByteSize | undefined
|
|
435
442
|
readonly maxElementBytes: ByteSize.ByteSize
|
|
@@ -523,7 +530,7 @@ export const StreamSse: {
|
|
|
523
530
|
_tag: "StreamSse",
|
|
524
531
|
mode: "sse",
|
|
525
532
|
sseMode: options.events === undefined ? "data" : "events",
|
|
526
|
-
|
|
533
|
+
...streamContentTypes(options.contentType, "sse"),
|
|
527
534
|
events,
|
|
528
535
|
error: options.error ?? Schema.Never
|
|
529
536
|
})
|
|
@@ -534,22 +541,24 @@ export const StreamSse: {
|
|
|
534
541
|
*
|
|
535
542
|
* **Details**
|
|
536
543
|
*
|
|
537
|
-
* `contentType` defaults to `application/octet-stream`.
|
|
538
|
-
*
|
|
544
|
+
* `contentType` defaults to `application/octet-stream`. Pass a list when the
|
|
545
|
+
* same stream is sent under several media types. The first entry is the
|
|
546
|
+
* default response type, and payloads are accepted under every entry.
|
|
547
|
+
* `maxBytes` only applies to request payloads and has no default.
|
|
539
548
|
*
|
|
540
549
|
* @stability unstable
|
|
541
550
|
* @category constructors
|
|
542
551
|
* @since 4.0.0
|
|
543
552
|
*/
|
|
544
553
|
export const StreamUint8Array = (options?: {
|
|
545
|
-
readonly contentType?: string | undefined
|
|
554
|
+
readonly contentType?: string | ReadonlyArray<string> | undefined
|
|
546
555
|
readonly maxBytes?: ByteSize.Input | undefined
|
|
547
556
|
}): StreamUint8Array =>
|
|
548
557
|
Schema.make<StreamUint8Array>(streamSchema.ast, {
|
|
549
558
|
[StreamSchemaTypeId]: StreamSchemaTypeId,
|
|
550
559
|
_tag: "StreamUint8Array",
|
|
551
560
|
mode: "uint8array",
|
|
552
|
-
|
|
561
|
+
...streamContentTypes(options?.contentType, "uint8array"),
|
|
553
562
|
maxBytes: options?.maxBytes === undefined ? undefined : ByteSize.fromInputUnsafe(options.maxBytes)
|
|
554
563
|
})
|
|
555
564
|
|
|
@@ -559,7 +568,8 @@ export const StreamUint8Array = (options?: {
|
|
|
559
568
|
* **Details**
|
|
560
569
|
*
|
|
561
570
|
* `contentType` defaults to `application/x-ndjson` and `maxElementBytes` to 1
|
|
562
|
-
* MiB. `maxBytes` has no default.
|
|
571
|
+
* MiB. `maxBytes` has no default. Pass a list of content types to accept
|
|
572
|
+
* aliases such as `application/jsonl`. The first entry is the default.
|
|
563
573
|
*
|
|
564
574
|
* **Example** (Declaring an NDJSON request payload)
|
|
565
575
|
*
|
|
@@ -587,7 +597,7 @@ export const StreamUint8Array = (options?: {
|
|
|
587
597
|
*/
|
|
588
598
|
export const StreamNdjson = <S extends Schema.Constraint>(options: {
|
|
589
599
|
readonly schema: S
|
|
590
|
-
readonly contentType?: string | undefined
|
|
600
|
+
readonly contentType?: string | ReadonlyArray<string> | undefined
|
|
591
601
|
readonly maxBytes?: ByteSize.Input | undefined
|
|
592
602
|
readonly maxElementBytes?: ByteSize.Input | undefined
|
|
593
603
|
}): StreamNdjson<S> =>
|
|
@@ -595,7 +605,7 @@ export const StreamNdjson = <S extends Schema.Constraint>(options: {
|
|
|
595
605
|
[StreamSchemaTypeId]: StreamSchemaTypeId,
|
|
596
606
|
_tag: "StreamNdjson",
|
|
597
607
|
mode: "ndjson",
|
|
598
|
-
|
|
608
|
+
...streamContentTypes(options.contentType, "ndjson"),
|
|
599
609
|
schema: options.schema,
|
|
600
610
|
maxBytes: options.maxBytes === undefined ? undefined : ByteSize.fromInputUnsafe(options.maxBytes),
|
|
601
611
|
maxElementBytes: options.maxElementBytes === undefined
|
|
@@ -637,24 +647,27 @@ const UpgradeTypeId = "~effect/http-api/HttpApiSchema/Upgrade"
|
|
|
637
647
|
*
|
|
638
648
|
* Created with {@link Upgrade}. The response is `101 Switching Protocols`, and
|
|
639
649
|
* the connection then carries raw bytes in both directions as a `Socket`.
|
|
650
|
+
* `Headers` is the schema of the custom `101` headers, or `never` when the
|
|
651
|
+
* upgrade declares none.
|
|
640
652
|
*
|
|
641
653
|
* @stability unstable
|
|
642
654
|
* @category models
|
|
643
655
|
* @since 4.0.6
|
|
644
656
|
*/
|
|
645
|
-
export interface Upgrade extends
|
|
657
|
+
export interface Upgrade<Headers extends Schema.Top = Schema.Top> extends
|
|
646
658
|
Schema.Bottom<
|
|
647
659
|
Socket.Socket,
|
|
648
660
|
Socket.Socket,
|
|
649
661
|
never,
|
|
650
662
|
never,
|
|
651
663
|
SchemaAST.Declaration,
|
|
652
|
-
Upgrade
|
|
664
|
+
Upgrade<Headers>
|
|
653
665
|
>
|
|
654
666
|
{
|
|
655
|
-
readonly "Rebuild": Upgrade
|
|
667
|
+
readonly "Rebuild": Upgrade<Headers>
|
|
656
668
|
readonly [UpgradeTypeId]: typeof UpgradeTypeId
|
|
657
669
|
readonly protocol: string
|
|
670
|
+
readonly headers: Headers | undefined
|
|
658
671
|
}
|
|
659
672
|
|
|
660
673
|
const upgradeSchema = Schema.declare(Socket.isSocket).pipe(status(101))
|
|
@@ -672,26 +685,41 @@ const upgradeSchema = Schema.declare(Socket.isSocket).pipe(status(101))
|
|
|
672
685
|
*
|
|
673
686
|
* **Details**
|
|
674
687
|
*
|
|
675
|
-
* The handler receives
|
|
676
|
-
* sent when the handler acquires the socket's reader,
|
|
677
|
-
* fail with a declared error before then. Requests
|
|
678
|
-
* `protocol` get `426 Upgrade Required`.
|
|
688
|
+
* The handler receives an `upgrade` function that returns the connection.
|
|
689
|
+
* The `101` response is sent when the handler acquires the socket's reader,
|
|
690
|
+
* so a handler can still fail with a declared error before then. Requests
|
|
691
|
+
* that do not ask for `protocol` get `426 Upgrade Required`.
|
|
679
692
|
*
|
|
680
|
-
*
|
|
681
|
-
*
|
|
682
|
-
* the
|
|
693
|
+
* `headers` declares custom `101` response headers, encoded like
|
|
694
|
+
* `WithHeaders` headers. The handler passes them to `upgrade`, so they can
|
|
695
|
+
* depend on the decoded request. `Connection`, `Upgrade`, `Content-Length`
|
|
696
|
+
* and `Transfer-Encoding` cannot be set.
|
|
697
|
+
*
|
|
698
|
+
* The endpoint may declare a buffered payload, which is decoded before the
|
|
699
|
+
* handler runs. Streaming payloads are rejected.
|
|
683
700
|
*
|
|
684
|
-
* The
|
|
701
|
+
* The client sends `Connection: Upgrade` and `Upgrade: protocol`, and returns
|
|
702
|
+
* the response headers with the connection, decoded with `headers` when
|
|
703
|
+
* declared. Other responses are decoded as the endpoint's errors.
|
|
685
704
|
*
|
|
686
|
-
* **Example** (Declaring an
|
|
705
|
+
* **Example** (Declaring an exec start endpoint)
|
|
687
706
|
*
|
|
688
707
|
* ```ts
|
|
689
708
|
* import { Schema } from "effect"
|
|
690
709
|
* import { HttpApiEndpoint, HttpApiSchema } from "effect/http-api"
|
|
691
710
|
*
|
|
692
|
-
* const
|
|
711
|
+
* const start = HttpApiEndpoint.post("start", "/exec/:id/start", {
|
|
693
712
|
* params: { id: Schema.String },
|
|
694
|
-
*
|
|
713
|
+
* payload: Schema.Struct({ Detach: Schema.Boolean, Tty: Schema.Boolean }),
|
|
714
|
+
* success: HttpApiSchema.Upgrade({
|
|
715
|
+
* protocol: "tcp",
|
|
716
|
+
* headers: {
|
|
717
|
+
* "content-type": Schema.Literals([
|
|
718
|
+
* "application/vnd.docker.raw-stream",
|
|
719
|
+
* "application/vnd.docker.multiplexed-stream"
|
|
720
|
+
* ])
|
|
721
|
+
* }
|
|
722
|
+
* })
|
|
695
723
|
* })
|
|
696
724
|
* ```
|
|
697
725
|
*
|
|
@@ -699,23 +727,72 @@ const upgradeSchema = Schema.declare(Socket.isSocket).pipe(status(101))
|
|
|
699
727
|
* @category constructors
|
|
700
728
|
* @since 4.0.6
|
|
701
729
|
*/
|
|
702
|
-
export
|
|
730
|
+
export function Upgrade(options: { readonly protocol: string }): Upgrade<never>
|
|
731
|
+
/**
|
|
732
|
+
* @stability unstable
|
|
733
|
+
*/
|
|
734
|
+
export function Upgrade<H extends Schema.Struct.Fields>(options: {
|
|
735
|
+
readonly protocol: string
|
|
736
|
+
readonly headers: H
|
|
737
|
+
}): Upgrade<Schema.Struct<H>>
|
|
738
|
+
/**
|
|
739
|
+
* @stability unstable
|
|
740
|
+
*/
|
|
741
|
+
export function Upgrade<H extends Schema.Top>(options: {
|
|
703
742
|
readonly protocol: string
|
|
704
|
-
|
|
743
|
+
readonly headers: H
|
|
744
|
+
}): Upgrade<H>
|
|
745
|
+
/**
|
|
746
|
+
* @stability unstable
|
|
747
|
+
*/
|
|
748
|
+
export function Upgrade(options: {
|
|
749
|
+
readonly protocol: string
|
|
750
|
+
readonly headers?: Schema.Top | Schema.Struct.Fields | undefined
|
|
751
|
+
}): Upgrade {
|
|
705
752
|
if (options.protocol.toLowerCase() === "websocket") {
|
|
706
753
|
throw new Error("Upgrade does not support WebSocket")
|
|
707
754
|
}
|
|
708
|
-
|
|
755
|
+
const headers = options.headers === undefined || Schema.isSchema(options.headers)
|
|
756
|
+
? options.headers
|
|
757
|
+
: Schema.Struct(options.headers)
|
|
758
|
+
return rebuildUpgrade(options.protocol, headers)
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/**
|
|
762
|
+
* @internal
|
|
763
|
+
*/
|
|
764
|
+
export const rebuildUpgrade = (protocol: string, headers: Schema.Top | undefined): Upgrade =>
|
|
765
|
+
Schema.make<Upgrade>(upgradeSchema.ast, {
|
|
709
766
|
[UpgradeTypeId]: UpgradeTypeId,
|
|
710
|
-
protocol
|
|
767
|
+
protocol,
|
|
768
|
+
headers
|
|
711
769
|
})
|
|
712
|
-
}
|
|
713
770
|
|
|
714
771
|
/**
|
|
715
772
|
* @internal
|
|
716
773
|
*/
|
|
717
774
|
export const isUpgrade = (u: unknown): u is Upgrade => Schema.isSchema(u) && Predicate.hasProperty(u, UpgradeTypeId)
|
|
718
775
|
|
|
776
|
+
function streamContentTypes(
|
|
777
|
+
contentType: string | ReadonlyArray<string> | undefined,
|
|
778
|
+
mode: StreamMode
|
|
779
|
+
): { readonly contentType: string; readonly contentTypes: Arr.NonEmptyReadonlyArray<string> } {
|
|
780
|
+
if (contentType === undefined) contentType = defaultStreamContentType(mode)
|
|
781
|
+
if (typeof contentType === "string") return { contentType, contentTypes: [contentType] }
|
|
782
|
+
if (!Arr.isReadonlyArrayNonEmpty(contentType)) {
|
|
783
|
+
throw new Error("Stream schemas require at least one content type")
|
|
784
|
+
}
|
|
785
|
+
const seen = new Set<string>()
|
|
786
|
+
for (const entry of contentType) {
|
|
787
|
+
const normalized = MediaType.normalize(entry)
|
|
788
|
+
if (seen.has(normalized)) {
|
|
789
|
+
throw new Error(`Duplicate stream content type: ${entry}`)
|
|
790
|
+
}
|
|
791
|
+
seen.add(normalized)
|
|
792
|
+
}
|
|
793
|
+
return { contentType: contentType[0], contentTypes: contentType }
|
|
794
|
+
}
|
|
795
|
+
|
|
719
796
|
function defaultStreamContentType(mode: StreamMode): string {
|
|
720
797
|
switch (mode) {
|
|
721
798
|
case "sse":
|
|
@@ -779,8 +856,8 @@ export type WithHeadersValueTypeId = typeof WithHeadersValueTypeId
|
|
|
779
856
|
* `StreamSse` and `StreamUint8Array`; error responses remain non-streaming.
|
|
780
857
|
* Nesting `WithHeaders` is rejected at construction.
|
|
781
858
|
* - `headers` is any schema; endpoint construction applies
|
|
782
|
-
*
|
|
783
|
-
*
|
|
859
|
+
* a StringTree codec unless codecs are disabled. Optional headers that encode
|
|
860
|
+
* to `undefined` are omitted from the response.
|
|
784
861
|
* - Status and response-encoding annotations are resolved from the wrapper
|
|
785
862
|
* first, falling through to the inner schema.
|
|
786
863
|
* - A header-carrying response cannot share its status and content type with
|
|
@@ -1224,6 +1301,12 @@ export function asJson(options?: {
|
|
|
1224
1301
|
*
|
|
1225
1302
|
* The schema's encoded side must be a record of strings.
|
|
1226
1303
|
*
|
|
1304
|
+
* **Gotchas**
|
|
1305
|
+
*
|
|
1306
|
+
* Fields are flat on the server. A field that encodes to a nested object is
|
|
1307
|
+
* sent as bracket keys that the server does not read back; use an explicit
|
|
1308
|
+
* codec such as `Schema.fromJsonString(...)` for structured values.
|
|
1309
|
+
*
|
|
1227
1310
|
* @stability unstable
|
|
1228
1311
|
* @category encoding
|
|
1229
1312
|
* @since 4.0.0
|
|
@@ -1299,18 +1382,28 @@ const resolveHttpApiEncoding = SchemaAST.resolveAt<Encoding>("~httpApiEncoding")
|
|
|
1299
1382
|
*/
|
|
1300
1383
|
export const getWithHeadersAnnotation = SchemaAST.resolveAt<WithHeadersAnnotation>("~httpApiWithHeaders")
|
|
1301
1384
|
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1385
|
+
function findHttpApiStatusAnnotation(
|
|
1386
|
+
ast: SchemaAST.AST | SchemaAST.FilterGroup<any>
|
|
1387
|
+
): Schema.Annotations.Annotations | undefined {
|
|
1388
|
+
if (ast.checks) {
|
|
1389
|
+
for (let i = ast.checks.length - 1; i >= 0; i--) {
|
|
1390
|
+
const check = ast.checks[i]
|
|
1391
|
+
if (check.annotations && "httpApiStatus" in check.annotations) return check.annotations
|
|
1392
|
+
if (check._tag === "FilterGroup") {
|
|
1393
|
+
const annotations = findHttpApiStatusAnnotation(check)
|
|
1394
|
+
if (annotations !== undefined) return annotations
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
const annotations = ast.annotations
|
|
1399
|
+
return annotations && "httpApiStatus" in annotations ? annotations : undefined
|
|
1307
1400
|
}
|
|
1308
1401
|
|
|
1309
|
-
// An `httpApiStatus` annotation, even `undefined`, overrides the key context set by
|
|
1310
|
-
// `status`, which a later check drops, matching annotations
|
|
1311
1402
|
function resolveHttpApiStatus(ast: SchemaAST.AST): number | undefined {
|
|
1312
|
-
|
|
1313
|
-
|
|
1403
|
+
const annotations = findHttpApiStatusAnnotation(ast)
|
|
1404
|
+
// An explicit undefined clears the status instead of falling back to key context.
|
|
1405
|
+
if (annotations !== undefined) return annotations.httpApiStatus as number | undefined
|
|
1406
|
+
return ast.context?.annotations?.httpApiStatus
|
|
1314
1407
|
}
|
|
1315
1408
|
|
|
1316
1409
|
const defaultJsonEncoding: Encoding = {
|
|
@@ -25,7 +25,7 @@ import * as Layer from "../Layer.ts"
|
|
|
25
25
|
import type { Path } from "../Path.ts"
|
|
26
26
|
import * as Scope from "../Scope.ts"
|
|
27
27
|
import type * as HttpApi from "./HttpApi.ts"
|
|
28
|
-
import type { HandlerRuntime } from "./HttpApiBuilder.ts"
|
|
28
|
+
import type { GroupService, HandlerRuntime } from "./HttpApiBuilder.ts"
|
|
29
29
|
import * as HttpApiBuilder from "./HttpApiBuilder.ts"
|
|
30
30
|
import * as HttpApiClient from "./HttpApiClient.ts"
|
|
31
31
|
import type * as HttpApiEndpoint from "./HttpApiEndpoint.ts"
|
|
@@ -98,7 +98,8 @@ export const groups = Effect.fnUntraced(function*<
|
|
|
98
98
|
handlers.set(endpointIdentifier, handler)
|
|
99
99
|
routes.push(HttpApiBuilder.handlerToRoute(api, group as any, handler, context))
|
|
100
100
|
}
|
|
101
|
-
|
|
101
|
+
const service: GroupService = { handlers, routes }
|
|
102
|
+
context = Context.add(context, group as any, service)
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
const layer: Layer.Layer<
|