effect 4.0.7 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/BigDecimal.d.ts.map +1 -1
- package/dist/BigDecimal.js +3 -0
- package/dist/BigDecimal.js.map +1 -1
- package/dist/Channel.d.ts +12 -6
- package/dist/Channel.d.ts.map +1 -1
- package/dist/Channel.js +9 -3
- package/dist/Channel.js.map +1 -1
- package/dist/Config.d.ts +7 -1
- package/dist/Config.d.ts.map +1 -1
- package/dist/Config.js.map +1 -1
- package/dist/Context.d.ts +18 -1
- package/dist/Context.d.ts.map +1 -1
- package/dist/Context.js +27 -8
- package/dist/Context.js.map +1 -1
- package/dist/Cron.d.ts +81 -11
- package/dist/Cron.d.ts.map +1 -1
- package/dist/Cron.js +101 -26
- package/dist/Cron.js.map +1 -1
- package/dist/Duration.d.ts +78 -0
- package/dist/Duration.d.ts.map +1 -1
- package/dist/Duration.js +123 -0
- package/dist/Duration.js.map +1 -1
- package/dist/Effect.d.ts +164 -7
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +11 -1
- package/dist/Effect.js.map +1 -1
- package/dist/FileSystem.d.ts +59 -4
- package/dist/FileSystem.d.ts.map +1 -1
- package/dist/FileSystem.js +9 -2
- package/dist/FileSystem.js.map +1 -1
- package/dist/Glob.d.ts +165 -0
- package/dist/Glob.d.ts.map +1 -0
- package/dist/Glob.js +127 -0
- package/dist/Glob.js.map +1 -0
- package/dist/Match.d.ts +86 -0
- package/dist/Match.d.ts.map +1 -1
- package/dist/Match.js +72 -0
- package/dist/Match.js.map +1 -1
- package/dist/Pool.d.ts +51 -0
- package/dist/Pool.d.ts.map +1 -1
- package/dist/Pool.js +59 -9
- package/dist/Pool.js.map +1 -1
- package/dist/Random.d.ts.map +1 -1
- package/dist/Random.js +3 -3
- package/dist/Random.js.map +1 -1
- package/dist/RcMap.d.ts.map +1 -1
- package/dist/RcMap.js +8 -2
- package/dist/RcMap.js.map +1 -1
- package/dist/Schedule.d.ts +18 -1
- package/dist/Schedule.d.ts.map +1 -1
- package/dist/Schedule.js +7 -2
- package/dist/Schedule.js.map +1 -1
- package/dist/Schema.d.ts +666 -41
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +650 -0
- package/dist/Schema.js.map +1 -1
- package/dist/SchemaGetter.d.ts +6 -1
- package/dist/SchemaGetter.d.ts.map +1 -1
- package/dist/SchemaGetter.js +22 -11
- package/dist/SchemaGetter.js.map +1 -1
- package/dist/SchemaRepresentation.d.ts +14 -0
- package/dist/SchemaRepresentation.d.ts.map +1 -1
- package/dist/SchemaRepresentation.js +16 -0
- package/dist/SchemaRepresentation.js.map +1 -1
- package/dist/SchemaTransformation.d.ts +8 -3
- package/dist/SchemaTransformation.d.ts.map +1 -1
- package/dist/SchemaTransformation.js +6 -3
- package/dist/SchemaTransformation.js.map +1 -1
- package/dist/ScopedCache.d.ts.map +1 -1
- package/dist/ScopedCache.js +5 -7
- package/dist/ScopedCache.js.map +1 -1
- package/dist/Semaphore.d.ts +130 -0
- package/dist/Semaphore.d.ts.map +1 -1
- package/dist/Semaphore.js +40 -0
- package/dist/Semaphore.js.map +1 -1
- package/dist/Stream.d.ts +13 -4
- package/dist/Stream.d.ts.map +1 -1
- package/dist/Stream.js +9 -0
- package/dist/Stream.js.map +1 -1
- package/dist/Terminal.d.ts +18 -1
- package/dist/Terminal.d.ts.map +1 -1
- package/dist/Terminal.js +1 -1
- package/dist/Terminal.js.map +1 -1
- package/dist/ai/AiError.d.ts +43 -116
- package/dist/ai/AiError.d.ts.map +1 -1
- package/dist/ai/AiError.js +53 -72
- package/dist/ai/AiError.js.map +1 -1
- package/dist/ai/Decision.d.ts +196 -15
- package/dist/ai/Decision.d.ts.map +1 -1
- package/dist/ai/Decision.js +130 -0
- package/dist/ai/Decision.js.map +1 -1
- package/dist/ai/DecisionModel.d.ts +54 -13
- package/dist/ai/DecisionModel.d.ts.map +1 -1
- package/dist/ai/DecisionModel.js +123 -12
- package/dist/ai/DecisionModel.js.map +1 -1
- package/dist/ai/McpServer.d.ts +630 -29
- package/dist/ai/McpServer.d.ts.map +1 -1
- package/dist/ai/McpServer.js +562 -116
- package/dist/ai/McpServer.js.map +1 -1
- package/dist/ai/McpTest.d.ts +130 -0
- package/dist/ai/McpTest.d.ts.map +1 -0
- package/dist/ai/McpTest.js +237 -0
- package/dist/ai/McpTest.js.map +1 -0
- package/dist/ai/Response.d.ts +1 -25
- package/dist/ai/Response.d.ts.map +1 -1
- package/dist/ai/Response.js +1 -10
- package/dist/ai/Response.js.map +1 -1
- package/dist/ai/Tool.d.ts +19 -1
- package/dist/ai/Tool.d.ts.map +1 -1
- package/dist/ai/Tool.js.map +1 -1
- package/dist/ai/index.d.ts +5 -0
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +5 -0
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/internal/mcpCore.js +17 -12
- package/dist/ai/internal/mcpCore.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2024_11_05.js +4 -5
- package/dist/ai/internal/mcpProtocol/v2024_11_05.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_03_26.js +4 -5
- package/dist/ai/internal/mcpProtocol/v2025_03_26.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_06_18.js +4 -5
- package/dist/ai/internal/mcpProtocol/v2025_06_18.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2025_11_25.js +4 -5
- package/dist/ai/internal/mcpProtocol/v2025_11_25.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2026_07_28.js +18 -10
- package/dist/ai/internal/mcpProtocol/v2026_07_28.js.map +1 -1
- package/dist/ai/internal/mcpProtocol.js +13 -0
- package/dist/ai/internal/mcpProtocol.js.map +1 -1
- package/dist/ai/internal/mcpRuntime.js +5 -3
- package/dist/ai/internal/mcpRuntime.js.map +1 -1
- package/dist/ai/internal/mcpStatefulRuntime.js +6 -1
- package/dist/ai/internal/mcpStatefulRuntime.js.map +1 -1
- package/dist/cli/Argument.d.ts +6 -0
- package/dist/cli/Argument.d.ts.map +1 -1
- package/dist/cli/Argument.js +2 -0
- package/dist/cli/Argument.js.map +1 -1
- package/dist/cli/CliOutput.d.ts +65 -1
- package/dist/cli/CliOutput.d.ts.map +1 -1
- package/dist/cli/CliOutput.js +94 -37
- package/dist/cli/CliOutput.js.map +1 -1
- package/dist/cli/Command.d.ts +23 -0
- package/dist/cli/Command.d.ts.map +1 -1
- package/dist/cli/Command.js +8 -0
- package/dist/cli/Command.js.map +1 -1
- package/dist/cli/Flag.d.ts +107 -0
- package/dist/cli/Flag.d.ts.map +1 -1
- package/dist/cli/Flag.js +37 -0
- package/dist/cli/Flag.js.map +1 -1
- package/dist/cli/HelpDoc.d.ts +15 -1
- package/dist/cli/HelpDoc.d.ts.map +1 -1
- package/dist/cli/Param.d.ts +6 -0
- package/dist/cli/Param.d.ts.map +1 -1
- package/dist/cli/Param.js +2 -0
- package/dist/cli/Param.js.map +1 -1
- package/dist/cli/Primitive.d.ts +14 -0
- package/dist/cli/Primitive.d.ts.map +1 -1
- package/dist/cli/Primitive.js +15 -1
- package/dist/cli/Primitive.js.map +1 -1
- package/dist/cli/Prompt.d.ts +1 -0
- package/dist/cli/Prompt.d.ts.map +1 -1
- package/dist/cli/Prompt.js +1 -0
- package/dist/cli/Prompt.js.map +1 -1
- package/dist/cli/internal/help.d.ts.map +1 -1
- package/dist/cli/internal/help.js +17 -10
- package/dist/cli/internal/help.js.map +1 -1
- package/dist/cluster/Sharding.d.ts.map +1 -1
- package/dist/cluster/Sharding.js +90 -28
- package/dist/cluster/Sharding.js.map +1 -1
- package/dist/cluster/ShardingConfig.d.ts +72 -6
- package/dist/cluster/ShardingConfig.d.ts.map +1 -1
- package/dist/cluster/ShardingConfig.js +4 -0
- package/dist/cluster/ShardingConfig.js.map +1 -1
- package/dist/cluster/SingleRunner.d.ts +3 -3
- package/dist/cluster/SingleRunner.d.ts.map +1 -1
- package/dist/cluster/SingleRunner.js +1 -1
- package/dist/cluster/SqlMessageStorage.d.ts +37 -6
- package/dist/cluster/SqlMessageStorage.d.ts.map +1 -1
- package/dist/cluster/SqlMessageStorage.js +34 -7
- package/dist/cluster/SqlMessageStorage.js.map +1 -1
- package/dist/cluster/SqlRunnerStorage.d.ts.map +1 -1
- package/dist/cluster/SqlRunnerStorage.js +23 -8
- package/dist/cluster/SqlRunnerStorage.js.map +1 -1
- package/dist/crypto/Aead.d.ts +322 -0
- package/dist/crypto/Aead.d.ts.map +1 -0
- package/dist/crypto/Aead.js +331 -0
- package/dist/crypto/Aead.js.map +1 -0
- package/dist/crypto/Cipher.d.ts +235 -0
- package/dist/crypto/Cipher.d.ts.map +1 -0
- package/dist/crypto/Cipher.js +233 -0
- package/dist/crypto/Cipher.js.map +1 -0
- package/dist/crypto/CryptoError.d.ts +212 -0
- package/dist/crypto/CryptoError.d.ts.map +1 -0
- package/dist/crypto/CryptoError.js +202 -0
- package/dist/crypto/CryptoError.js.map +1 -0
- package/dist/crypto/Digest.d.ts +143 -0
- package/dist/crypto/Digest.d.ts.map +1 -0
- package/dist/crypto/Digest.js +146 -0
- package/dist/crypto/Digest.js.map +1 -0
- package/dist/crypto/Kdf.d.ts +220 -0
- package/dist/crypto/Kdf.d.ts.map +1 -0
- package/dist/crypto/Kdf.js +212 -0
- package/dist/crypto/Kdf.js.map +1 -0
- package/dist/crypto/KeyAgreement.d.ts +323 -0
- package/dist/crypto/KeyAgreement.d.ts.map +1 -0
- package/dist/crypto/KeyAgreement.js +303 -0
- package/dist/crypto/KeyAgreement.js.map +1 -0
- package/dist/crypto/KeyFormat.d.ts +309 -0
- package/dist/crypto/KeyFormat.d.ts.map +1 -0
- package/dist/crypto/KeyFormat.js +556 -0
- package/dist/crypto/KeyFormat.js.map +1 -0
- package/dist/crypto/KeyWrap.d.ts +389 -0
- package/dist/crypto/KeyWrap.d.ts.map +1 -0
- package/dist/crypto/KeyWrap.js +381 -0
- package/dist/crypto/KeyWrap.js.map +1 -0
- package/dist/crypto/Mac.d.ts +277 -0
- package/dist/crypto/Mac.d.ts.map +1 -0
- package/dist/crypto/Mac.js +288 -0
- package/dist/crypto/Mac.js.map +1 -0
- package/dist/crypto/SecureRandom.d.ts +340 -0
- package/dist/crypto/SecureRandom.d.ts.map +1 -0
- package/dist/crypto/SecureRandom.js +257 -0
- package/dist/crypto/SecureRandom.js.map +1 -0
- package/dist/crypto/Signature.d.ts +448 -0
- package/dist/crypto/Signature.d.ts.map +1 -0
- package/dist/crypto/Signature.js +484 -0
- package/dist/crypto/Signature.js.map +1 -0
- package/dist/crypto/WebCrypto.d.ts +61 -0
- package/dist/crypto/WebCrypto.d.ts.map +1 -0
- package/dist/crypto/WebCrypto.js +63 -0
- package/dist/crypto/WebCrypto.js.map +1 -0
- package/dist/crypto/index.d.ts +65 -0
- package/dist/crypto/index.d.ts.map +1 -0
- package/dist/crypto/index.js +66 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/crypto/internal/asymmetric.d.ts +2 -0
- package/dist/crypto/internal/asymmetric.d.ts.map +1 -0
- package/dist/crypto/internal/asymmetric.js +210 -0
- package/dist/crypto/internal/asymmetric.js.map +1 -0
- package/dist/crypto/internal/chacha.d.ts +46 -0
- package/dist/crypto/internal/chacha.d.ts.map +1 -0
- package/dist/crypto/internal/chacha.js +885 -0
- package/dist/crypto/internal/chacha.js.map +1 -0
- package/dist/crypto/internal/der.d.ts +6 -0
- package/dist/crypto/internal/der.d.ts.map +1 -0
- package/dist/crypto/internal/der.js +86 -0
- package/dist/crypto/internal/der.js.map +1 -0
- package/dist/crypto/internal/digest.d.ts +2 -0
- package/dist/crypto/internal/digest.d.ts.map +1 -0
- package/dist/crypto/internal/digest.js +15 -0
- package/dist/crypto/internal/digest.js.map +1 -0
- package/dist/crypto/internal/key.d.ts +2 -0
- package/dist/crypto/internal/key.d.ts.map +1 -0
- package/dist/crypto/internal/key.js +170 -0
- package/dist/crypto/internal/key.js.map +1 -0
- package/dist/crypto/internal/md5.d.ts +39 -0
- package/dist/crypto/internal/md5.d.ts.map +1 -0
- package/dist/crypto/internal/md5.js +179 -0
- package/dist/crypto/internal/md5.js.map +1 -0
- package/dist/crypto/internal/webCrypto.d.ts +2 -0
- package/dist/crypto/internal/webCrypto.d.ts.map +1 -0
- package/dist/crypto/internal/webCrypto.js +111 -0
- package/dist/crypto/internal/webCrypto.js.map +1 -0
- package/dist/encoding/Base64Url.d.ts.map +1 -1
- package/dist/encoding/Base64Url.js +3 -2
- package/dist/encoding/Base64Url.js.map +1 -1
- package/dist/encoding/Csv.d.ts +608 -0
- package/dist/encoding/Csv.d.ts.map +1 -0
- package/dist/encoding/Csv.js +718 -0
- package/dist/encoding/Csv.js.map +1 -0
- package/dist/encoding/Hex.d.ts +3 -2
- package/dist/encoding/Hex.d.ts.map +1 -1
- package/dist/encoding/Hex.js +3 -2
- package/dist/encoding/Hex.js.map +1 -1
- package/dist/encoding/SchemaBinary.d.ts.map +1 -1
- package/dist/encoding/SchemaBinary.js +42 -4
- package/dist/encoding/SchemaBinary.js.map +1 -1
- package/dist/encoding/Toml.d.ts +17 -3
- package/dist/encoding/Toml.d.ts.map +1 -1
- package/dist/encoding/Toml.js +104 -16
- package/dist/encoding/Toml.js.map +1 -1
- package/dist/encoding/Yaml.d.ts +8 -1
- package/dist/encoding/Yaml.d.ts.map +1 -1
- package/dist/encoding/Yaml.js +54 -18
- package/dist/encoding/Yaml.js.map +1 -1
- package/dist/encoding/index.d.ts +5 -0
- package/dist/encoding/index.d.ts.map +1 -1
- package/dist/encoding/index.js +5 -0
- package/dist/encoding/index.js.map +1 -1
- package/dist/eventlog/EventJournal.d.ts.map +1 -1
- package/dist/eventlog/EventJournal.js +6 -3
- package/dist/eventlog/EventJournal.js.map +1 -1
- package/dist/eventlog/EventLog.d.ts +119 -4
- package/dist/eventlog/EventLog.d.ts.map +1 -1
- package/dist/eventlog/EventLog.js +200 -12
- package/dist/eventlog/EventLog.js.map +1 -1
- package/dist/eventlog/EventLogEncryption.d.ts +41 -4
- package/dist/eventlog/EventLogEncryption.d.ts.map +1 -1
- package/dist/eventlog/EventLogEncryption.js +83 -64
- package/dist/eventlog/EventLogEncryption.js.map +1 -1
- package/dist/eventlog/EventLogMessage.d.ts +279 -0
- package/dist/eventlog/EventLogMessage.d.ts.map +1 -1
- package/dist/eventlog/EventLogMessage.js +217 -1
- package/dist/eventlog/EventLogMessage.js.map +1 -1
- package/dist/eventlog/EventLogRemote.d.ts +200 -28
- package/dist/eventlog/EventLogRemote.d.ts.map +1 -1
- package/dist/eventlog/EventLogRemote.js +186 -16
- package/dist/eventlog/EventLogRemote.js.map +1 -1
- package/dist/eventlog/EventLogServer.d.ts +3 -0
- package/dist/eventlog/EventLogServer.d.ts.map +1 -1
- package/dist/eventlog/EventLogServer.js +18 -10
- package/dist/eventlog/EventLogServer.js.map +1 -1
- package/dist/eventlog/EventLogServerEncrypted.d.ts +326 -5
- package/dist/eventlog/EventLogServerEncrypted.d.ts.map +1 -1
- package/dist/eventlog/EventLogServerEncrypted.js +769 -14
- package/dist/eventlog/EventLogServerEncrypted.js.map +1 -1
- package/dist/eventlog/EventLogSessionAuth.d.ts +5 -3
- package/dist/eventlog/EventLogSessionAuth.d.ts.map +1 -1
- package/dist/eventlog/EventLogSessionAuth.js +41 -64
- package/dist/eventlog/EventLogSessionAuth.js.map +1 -1
- package/dist/eventlog/EventRow.d.ts +4 -0
- package/dist/eventlog/EventRow.d.ts.map +1 -1
- package/dist/eventlog/EventRow.js +12 -2
- package/dist/eventlog/EventRow.js.map +1 -1
- package/dist/eventlog/SqlEventJournal.js +2 -2
- package/dist/eventlog/SqlEventJournal.js.map +1 -1
- package/dist/eventlog/SqlEventLogServerEncrypted.d.ts +21 -5
- package/dist/eventlog/SqlEventLogServerEncrypted.d.ts.map +1 -1
- package/dist/eventlog/SqlEventLogServerEncrypted.js +1048 -113
- package/dist/eventlog/SqlEventLogServerEncrypted.js.map +1 -1
- package/dist/eventlog/SqlEventLogServerUnencrypted.js +2 -2
- package/dist/eventlog/SqlEventLogServerUnencrypted.js.map +1 -1
- package/dist/eventlog/internal/batches.d.ts +12 -0
- package/dist/eventlog/internal/batches.d.ts.map +1 -0
- package/dist/eventlog/internal/batches.js +26 -0
- package/dist/eventlog/internal/batches.js.map +1 -0
- package/dist/eventlog/internal/compaction.d.ts +38 -0
- package/dist/eventlog/internal/compaction.d.ts.map +1 -0
- package/dist/eventlog/internal/compaction.js +33 -0
- package/dist/eventlog/internal/compaction.js.map +1 -0
- package/dist/eventlog/internal/identityRootSecretDerivation.js +66 -67
- package/dist/eventlog/internal/identityRootSecretDerivation.js.map +1 -1
- package/dist/eventlog/internal/remoteCompaction.d.ts +31 -0
- package/dist/eventlog/internal/remoteCompaction.d.ts.map +1 -0
- package/dist/eventlog/internal/remoteCompaction.js +76 -0
- package/dist/eventlog/internal/remoteCompaction.js.map +1 -0
- package/dist/http/Cookies.d.ts +172 -0
- package/dist/http/Cookies.d.ts.map +1 -1
- package/dist/http/Cookies.js +143 -1
- package/dist/http/Cookies.js.map +1 -1
- package/dist/http/FetchHttpClient.d.ts +26 -2
- package/dist/http/FetchHttpClient.d.ts.map +1 -1
- package/dist/http/FetchHttpClient.js +78 -15
- package/dist/http/FetchHttpClient.js.map +1 -1
- package/dist/http/HttpClient.d.ts +79 -8
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/http/HttpClient.js +65 -5
- package/dist/http/HttpClient.js.map +1 -1
- package/dist/http/HttpClientRequest.d.ts +9 -5
- package/dist/http/HttpClientRequest.d.ts.map +1 -1
- package/dist/http/HttpClientRequest.js +2 -3
- package/dist/http/HttpClientRequest.js.map +1 -1
- package/dist/http/HttpClientResponse.d.ts.map +1 -1
- package/dist/http/HttpClientResponse.js +3 -2
- package/dist/http/HttpClientResponse.js.map +1 -1
- package/dist/http/HttpMethod.d.ts +7 -1
- package/dist/http/HttpMethod.d.ts.map +1 -1
- package/dist/http/HttpMethod.js +3 -8
- package/dist/http/HttpMethod.js.map +1 -1
- package/dist/http/HttpServerRequest.d.ts +5 -2
- package/dist/http/HttpServerRequest.d.ts.map +1 -1
- package/dist/http/HttpServerRequest.js +6 -17
- package/dist/http/HttpServerRequest.js.map +1 -1
- package/dist/http/HttpServerResponse.d.ts.map +1 -1
- package/dist/http/HttpServerResponse.js +3 -2
- package/dist/http/HttpServerResponse.js.map +1 -1
- package/dist/http/HttpTraceContext.d.ts +2 -1
- package/dist/http/HttpTraceContext.d.ts.map +1 -1
- package/dist/http/HttpTraceContext.js +7 -5
- package/dist/http/HttpTraceContext.js.map +1 -1
- package/dist/http/ProblemDetails.d.ts +96 -0
- package/dist/http/ProblemDetails.d.ts.map +1 -0
- package/dist/http/ProblemDetails.js +98 -0
- package/dist/http/ProblemDetails.js.map +1 -0
- package/dist/http/index.d.ts +5 -0
- package/dist/http/index.d.ts.map +1 -1
- package/dist/http/index.js +5 -0
- package/dist/http/index.js.map +1 -1
- package/dist/http/internal/decompression.js +3 -2
- package/dist/http/internal/decompression.js.map +1 -1
- package/dist/http/internal/urlParams.js +8 -0
- package/dist/http/internal/urlParams.js.map +1 -1
- package/dist/http-api/HttpApiBuilder.js +19 -5
- package/dist/http-api/HttpApiBuilder.js.map +1 -1
- package/dist/http-api/HttpApiClient.d.ts +63 -0
- package/dist/http-api/HttpApiClient.d.ts.map +1 -1
- package/dist/http-api/HttpApiClient.js +51 -0
- package/dist/http-api/HttpApiClient.js.map +1 -1
- package/dist/http-api/HttpApiEndpoint.d.ts.map +1 -1
- package/dist/http-api/HttpApiEndpoint.js +14 -5
- package/dist/http-api/HttpApiEndpoint.js.map +1 -1
- package/dist/http-api/HttpApiError.d.ts +185 -13
- package/dist/http-api/HttpApiError.d.ts.map +1 -1
- package/dist/http-api/HttpApiError.js +128 -0
- package/dist/http-api/HttpApiError.js.map +1 -1
- package/dist/http-api/HttpApiMiddleware.d.ts +64 -17
- package/dist/http-api/HttpApiMiddleware.d.ts.map +1 -1
- package/dist/http-api/HttpApiMiddleware.js +85 -1
- package/dist/http-api/HttpApiMiddleware.js.map +1 -1
- package/dist/http-api/HttpApiSchema.d.ts +76 -14
- package/dist/http-api/HttpApiSchema.d.ts.map +1 -1
- package/dist/http-api/HttpApiSchema.js +53 -0
- package/dist/http-api/HttpApiSchema.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/internal/effect.js +25 -14
- package/dist/internal/effect.js.map +1 -1
- package/dist/internal/glob.d.ts +2 -0
- package/dist/internal/glob.d.ts.map +1 -0
- package/dist/internal/glob.js +630 -0
- package/dist/internal/glob.js.map +1 -0
- package/dist/internal/matcher.js +10 -0
- package/dist/internal/matcher.js.map +1 -1
- package/dist/internal/persistence.js +9 -0
- package/dist/internal/persistence.js.map +1 -1
- package/dist/internal/rcRef.js +4 -1
- package/dist/internal/rcRef.js.map +1 -1
- package/dist/internal/schema/toCodeDocument.js +6 -3
- package/dist/internal/schema/toCodeDocument.js.map +1 -1
- package/dist/internal/trie.js +42 -13
- package/dist/internal/trie.js.map +1 -1
- package/dist/internal/ulid.js +41 -0
- package/dist/internal/ulid.js.map +1 -1
- package/dist/internal/uuid.js +52 -8
- package/dist/internal/uuid.js.map +1 -1
- package/dist/internal/version.js +1 -1
- package/dist/observability/Otlp.d.ts +15 -4
- package/dist/observability/Otlp.d.ts.map +1 -1
- package/dist/observability/Otlp.js +10 -0
- package/dist/observability/Otlp.js.map +1 -1
- package/dist/observability/OtlpResource.d.ts +7 -0
- package/dist/observability/OtlpResource.d.ts.map +1 -1
- package/dist/observability/OtlpResource.js +11 -1
- package/dist/observability/OtlpResource.js.map +1 -1
- package/dist/persistence/KeyValueStore.d.ts +47 -2
- package/dist/persistence/KeyValueStore.d.ts.map +1 -1
- package/dist/persistence/KeyValueStore.js +129 -18
- package/dist/persistence/KeyValueStore.js.map +1 -1
- package/dist/persistence/PersistedQueue.d.ts +9 -0
- package/dist/persistence/PersistedQueue.d.ts.map +1 -1
- package/dist/persistence/PersistedQueue.js +94 -52
- package/dist/persistence/PersistedQueue.js.map +1 -1
- package/dist/persistence/Persistence.d.ts +10 -4
- package/dist/persistence/Persistence.d.ts.map +1 -1
- package/dist/persistence/Persistence.js +18 -11
- package/dist/persistence/Persistence.js.map +1 -1
- package/dist/process/ChildProcess.d.ts +207 -67
- package/dist/process/ChildProcess.d.ts.map +1 -1
- package/dist/process/ChildProcess.js +56 -158
- package/dist/process/ChildProcess.js.map +1 -1
- package/dist/process/ChildProcessSpawner.d.ts +5 -0
- package/dist/process/ChildProcessSpawner.d.ts.map +1 -1
- package/dist/process/ChildProcessSpawner.js.map +1 -1
- package/dist/process/CommandLine.d.ts +294 -0
- package/dist/process/CommandLine.d.ts.map +1 -0
- package/dist/process/CommandLine.js +481 -0
- package/dist/process/CommandLine.js.map +1 -0
- package/dist/process/index.d.ts +5 -0
- package/dist/process/index.d.ts.map +1 -1
- package/dist/process/index.js +5 -0
- package/dist/process/index.js.map +1 -1
- package/dist/reactivity/Atom.d.ts +2 -1
- package/dist/reactivity/Atom.d.ts.map +1 -1
- package/dist/reactivity/Atom.js +3 -4
- package/dist/reactivity/Atom.js.map +1 -1
- package/dist/reactivity/AtomRegistry.js.map +1 -1
- package/dist/rpc/RpcClient.d.ts +16 -1
- package/dist/rpc/RpcClient.d.ts.map +1 -1
- package/dist/rpc/RpcClient.js +50 -16
- package/dist/rpc/RpcClient.js.map +1 -1
- package/dist/rpc/RpcMessage.d.ts +10 -1
- package/dist/rpc/RpcMessage.d.ts.map +1 -1
- package/dist/rpc/RpcMessage.js +1 -0
- package/dist/rpc/RpcMessage.js.map +1 -1
- package/dist/rpc/RpcSerialization.d.ts.map +1 -1
- package/dist/rpc/RpcSerialization.js +6 -0
- package/dist/rpc/RpcSerialization.js.map +1 -1
- package/dist/rpc/RpcServer.d.ts +31 -0
- package/dist/rpc/RpcServer.d.ts.map +1 -1
- package/dist/rpc/RpcServer.js +139 -66
- package/dist/rpc/RpcServer.js.map +1 -1
- package/dist/schema/Model.d.ts +14 -0
- package/dist/schema/Model.d.ts.map +1 -1
- package/dist/schema/Model.js +18 -3
- package/dist/schema/Model.js.map +1 -1
- package/dist/sql/Migrator.d.ts +0 -19
- package/dist/sql/Migrator.d.ts.map +1 -1
- package/dist/sql/Migrator.js +3 -48
- package/dist/sql/Migrator.js.map +1 -1
- package/dist/sql/MigratorFileSystem.d.ts +21 -0
- package/dist/sql/MigratorFileSystem.d.ts.map +1 -0
- package/dist/sql/MigratorFileSystem.js +57 -0
- package/dist/sql/MigratorFileSystem.js.map +1 -0
- package/dist/sql/SqlClient.d.ts.map +1 -1
- package/dist/sql/SqlClient.js +5 -9
- package/dist/sql/SqlClient.js.map +1 -1
- package/dist/sql/Statement.d.ts +20 -6
- package/dist/sql/Statement.d.ts.map +1 -1
- package/dist/sql/Statement.js +0 -13
- package/dist/sql/Statement.js.map +1 -1
- package/dist/sql/index.js +1 -1
- package/dist/testing/index.d.ts +0 -5
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +0 -5
- package/dist/testing/index.js.map +1 -1
- package/dist/workflow/internal/crypto.js +9 -8
- package/dist/workflow/internal/crypto.js.map +1 -1
- package/package.json +3 -1
- package/src/BigDecimal.ts +3 -0
- package/src/Channel.ts +17 -11
- package/src/Config.ts +7 -1
- package/src/Context.ts +34 -10
- package/src/Cron.ts +178 -29
- package/src/Duration.ts +140 -0
- package/src/Effect.ts +914 -85
- package/src/FileSystem.ts +65 -4
- package/src/Glob.ts +205 -0
- package/src/Match.ts +127 -0
- package/src/Pool.ts +73 -15
- package/src/Random.ts +3 -3
- package/src/RcMap.ts +5 -1
- package/src/Schedule.ts +26 -3
- package/src/Schema.ts +1189 -62
- package/src/SchemaGetter.ts +27 -11
- package/src/SchemaRepresentation.ts +19 -0
- package/src/SchemaTransformation.ts +8 -3
- package/src/ScopedCache.ts +5 -9
- package/src/Semaphore.ts +141 -0
- package/src/Stream.ts +15 -6
- package/src/Terminal.ts +19 -1
- package/src/ai/AiError.ts +56 -80
- package/src/ai/Decision.ts +257 -6
- package/src/ai/DecisionModel.ts +171 -28
- package/src/ai/McpServer.ts +1269 -286
- package/src/ai/McpTest.ts +380 -0
- package/src/ai/Response.ts +2 -22
- package/src/ai/Tool.ts +27 -8
- package/src/ai/index.ts +6 -0
- package/src/ai/internal/mcpCore.ts +78 -44
- package/src/ai/internal/mcpProtocol/v2024_11_05.ts +4 -7
- package/src/ai/internal/mcpProtocol/v2025_03_26.ts +4 -7
- package/src/ai/internal/mcpProtocol/v2025_06_18.ts +4 -7
- package/src/ai/internal/mcpProtocol/v2025_11_25.ts +4 -7
- package/src/ai/internal/mcpProtocol/v2026_07_28.ts +15 -10
- package/src/ai/internal/mcpProtocol.ts +29 -0
- package/src/ai/internal/mcpRuntime.ts +9 -5
- package/src/ai/internal/mcpStatefulRuntime.ts +14 -2
- package/src/cli/Argument.ts +6 -0
- package/src/cli/CliOutput.ts +117 -49
- package/src/cli/Command.ts +23 -0
- package/src/cli/Flag.ts +107 -0
- package/src/cli/HelpDoc.ts +18 -1
- package/src/cli/Param.ts +6 -0
- package/src/cli/Primitive.ts +16 -1
- package/src/cli/Prompt.ts +1 -0
- package/src/cli/internal/help.ts +21 -9
- package/src/cluster/Sharding.ts +93 -26
- package/src/cluster/ShardingConfig.ts +41 -3
- package/src/cluster/SingleRunner.ts +3 -3
- package/src/cluster/SqlMessageStorage.ts +49 -17
- package/src/cluster/SqlRunnerStorage.ts +37 -27
- package/src/crypto/Aead.ts +517 -0
- package/src/crypto/Cipher.ts +326 -0
- package/src/crypto/CryptoError.ts +242 -0
- package/src/crypto/Digest.ts +167 -0
- package/src/crypto/Kdf.ts +315 -0
- package/src/crypto/KeyAgreement.ts +489 -0
- package/src/crypto/KeyFormat.ts +712 -0
- package/src/crypto/KeyWrap.ts +639 -0
- package/src/crypto/Mac.ts +386 -0
- package/src/crypto/SecureRandom.ts +459 -0
- package/src/crypto/Signature.ts +673 -0
- package/src/crypto/WebCrypto.ts +64 -0
- package/src/crypto/index.ts +78 -0
- package/src/crypto/internal/asymmetric.ts +329 -0
- package/src/crypto/internal/chacha.ts +1088 -0
- package/src/crypto/internal/der.ts +110 -0
- package/src/crypto/internal/digest.ts +16 -0
- package/src/crypto/internal/key.ts +235 -0
- package/src/crypto/internal/md5.ts +170 -0
- package/src/crypto/internal/webCrypto.ts +150 -0
- package/src/encoding/Base64Url.ts +5 -2
- package/src/encoding/Csv.ts +1298 -0
- package/src/encoding/Hex.ts +3 -2
- package/src/encoding/SchemaBinary.ts +40 -4
- package/src/encoding/Toml.ts +85 -20
- package/src/encoding/Yaml.ts +61 -18
- package/src/encoding/index.ts +6 -0
- package/src/eventlog/EventJournal.ts +4 -3
- package/src/eventlog/EventLog.ts +340 -15
- package/src/eventlog/EventLogEncryption.ts +118 -110
- package/src/eventlog/EventLogMessage.ts +273 -1
- package/src/eventlog/EventLogRemote.ts +367 -23
- package/src/eventlog/EventLogServer.ts +23 -8
- package/src/eventlog/EventLogServerEncrypted.ts +1130 -67
- package/src/eventlog/EventLogSessionAuth.ts +56 -70
- package/src/eventlog/EventRow.ts +12 -3
- package/src/eventlog/SqlEventJournal.ts +2 -2
- package/src/eventlog/SqlEventLogServerEncrypted.ts +1244 -136
- package/src/eventlog/SqlEventLogServerUnencrypted.ts +2 -2
- package/src/eventlog/internal/batches.ts +30 -0
- package/src/eventlog/internal/compaction.ts +64 -0
- package/src/eventlog/internal/identityRootSecretDerivation.ts +93 -123
- package/src/eventlog/internal/remoteCompaction.ts +92 -0
- package/src/http/Cookies.ts +281 -1
- package/src/http/FetchHttpClient.ts +88 -16
- package/src/http/HttpClient.ts +89 -22
- package/src/http/HttpClientRequest.ts +12 -9
- package/src/http/HttpClientResponse.ts +3 -2
- package/src/http/HttpMethod.ts +10 -2
- package/src/http/HttpServerRequest.ts +15 -30
- package/src/http/HttpServerResponse.ts +3 -2
- package/src/http/HttpTraceContext.ts +7 -4
- package/src/http/ProblemDetails.ts +149 -0
- package/src/http/index.ts +6 -0
- package/src/http/internal/decompression.ts +4 -4
- package/src/http/internal/urlParams.ts +8 -0
- package/src/http-api/HttpApiBuilder.ts +24 -12
- package/src/http-api/HttpApiClient.ts +67 -1
- package/src/http-api/HttpApiEndpoint.ts +14 -5
- package/src/http-api/HttpApiError.ts +250 -0
- package/src/http-api/HttpApiMiddleware.ts +95 -1
- package/src/http-api/HttpApiSchema.ts +105 -14
- package/src/index.ts +6 -6
- package/src/internal/effect.ts +34 -18
- package/src/internal/glob.ts +736 -0
- package/src/internal/matcher.ts +17 -0
- package/src/internal/persistence.ts +11 -0
- package/src/internal/rcRef.ts +4 -1
- package/src/internal/schema/toCodeDocument.ts +7 -3
- package/src/internal/trie.ts +43 -14
- package/src/internal/ulid.ts +44 -0
- package/src/internal/uuid.ts +57 -16
- package/src/internal/version.ts +1 -1
- package/src/observability/Otlp.ts +21 -4
- package/src/observability/OtlpResource.ts +9 -1
- package/src/persistence/KeyValueStore.ts +219 -22
- package/src/persistence/PersistedQueue.ts +128 -59
- package/src/persistence/Persistence.ts +20 -13
- package/src/process/ChildProcess.ts +255 -260
- package/src/process/ChildProcessSpawner.ts +5 -0
- package/src/process/CommandLine.ts +630 -0
- package/src/process/index.ts +6 -0
- package/src/reactivity/Atom.ts +5 -5
- package/src/reactivity/AtomRegistry.ts +1 -1
- package/src/rpc/RpcClient.ts +62 -26
- package/src/rpc/RpcMessage.ts +10 -1
- package/src/rpc/RpcSerialization.ts +3 -0
- package/src/rpc/RpcServer.ts +176 -78
- package/src/schema/Model.ts +26 -3
- package/src/sql/Migrator.ts +4 -63
- package/src/sql/MigratorFileSystem.ts +71 -0
- package/src/sql/SqlClient.ts +2 -16
- package/src/sql/Statement.ts +8 -7
- package/src/sql/index.ts +1 -1
- package/src/testing/index.ts +0 -6
- package/src/workflow/internal/crypto.ts +15 -11
- package/dist/Crypto.d.ts +0 -244
- package/dist/Crypto.d.ts.map +0 -1
- package/dist/Crypto.js +0 -139
- package/dist/Crypto.js.map +0 -1
- package/dist/testing/TestCrypto.d.ts +0 -73
- package/dist/testing/TestCrypto.d.ts.map +0 -1
- package/dist/testing/TestCrypto.js +0 -87
- package/dist/testing/TestCrypto.js.map +0 -1
- package/src/Crypto.ts +0 -347
- package/src/testing/TestCrypto.ts +0 -94
|
@@ -0,0 +1,718 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encodes and decodes CSV streams, with optional schema transformations.
|
|
3
|
+
*
|
|
4
|
+
* **Details**
|
|
5
|
+
*
|
|
6
|
+
* Follows RFC 4180 with a configurable delimiter. Cells are strings, and
|
|
7
|
+
* whitespace and empty cells are kept as they are. Quoted fields can contain
|
|
8
|
+
* delimiters, line breaks and doubled quotes. Decoders accept LF, CRLF and CR
|
|
9
|
+
* line endings and strip a leading BOM. Schema adapters convert cells to and
|
|
10
|
+
* from typed values.
|
|
11
|
+
*
|
|
12
|
+
* @stability unstable
|
|
13
|
+
* @since 4.1.0
|
|
14
|
+
*/
|
|
15
|
+
import * as Arr from "../Array.js";
|
|
16
|
+
import * as Cause from "../Cause.js";
|
|
17
|
+
import * as Channel from "../Channel.js";
|
|
18
|
+
import * as Data from "../Data.js";
|
|
19
|
+
import * as Effect from "../Effect.js";
|
|
20
|
+
import * as Predicate from "../Predicate.js";
|
|
21
|
+
import * as Pull from "../Pull.js";
|
|
22
|
+
import * as Schema from "../Schema.js";
|
|
23
|
+
import * as SchemaAST from "../SchemaAST.js";
|
|
24
|
+
import * as SchemaIssue from "../SchemaIssue.js";
|
|
25
|
+
const CsvErrorTypeId = "~effect/encoding/Csv/CsvError";
|
|
26
|
+
/**
|
|
27
|
+
* A CSV decoding failure.
|
|
28
|
+
*
|
|
29
|
+
* **Details**
|
|
30
|
+
*
|
|
31
|
+
* `record` is one-based and counts the header row and blank lines. `line` is
|
|
32
|
+
* the one-based physical line where the record starts. `column` is the
|
|
33
|
+
* one-based cell index of a syntax error, and `undefined` otherwise.
|
|
34
|
+
*
|
|
35
|
+
* @stability unstable
|
|
36
|
+
* @category errors
|
|
37
|
+
* @since 4.1.0
|
|
38
|
+
*/
|
|
39
|
+
export class CsvError extends /*#__PURE__*/Data.TaggedError("CsvError") {
|
|
40
|
+
/**
|
|
41
|
+
* Identifies CSV errors across module instances.
|
|
42
|
+
*
|
|
43
|
+
* @stability unstable
|
|
44
|
+
* @since 4.1.0
|
|
45
|
+
*/
|
|
46
|
+
[CsvErrorTypeId] = CsvErrorTypeId;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Checks whether a value is a `CsvError`.
|
|
50
|
+
*
|
|
51
|
+
* @stability unstable
|
|
52
|
+
* @category guards
|
|
53
|
+
* @since 4.1.0
|
|
54
|
+
*/
|
|
55
|
+
export const isCsvError = u => Predicate.hasProperty(u, CsvErrorTypeId);
|
|
56
|
+
const defaultMaxRecordSize = 1024 * 1024;
|
|
57
|
+
const checkDelimiter = delimiter => {
|
|
58
|
+
if (delimiter.length !== 1 || delimiter === "\"" || delimiter === "\r" || delimiter === "\n") {
|
|
59
|
+
throw new Error(`Csv: delimiter must be one character other than a quote or line break, got ${delimiter}`);
|
|
60
|
+
}
|
|
61
|
+
return delimiter;
|
|
62
|
+
};
|
|
63
|
+
const QUOTE = 34;
|
|
64
|
+
const CR = 13;
|
|
65
|
+
const LF = 10;
|
|
66
|
+
// Parser states. QUOTE_IN_QUOTED follows a quote inside a quoted field, which
|
|
67
|
+
// either closes the field or starts an escaped quote.
|
|
68
|
+
const FIELD_START = 0;
|
|
69
|
+
const UNQUOTED = 1;
|
|
70
|
+
const QUOTED = 2;
|
|
71
|
+
const QUOTE_IN_QUOTED = 3;
|
|
72
|
+
class Parser {
|
|
73
|
+
delimiter;
|
|
74
|
+
maxRecordSize;
|
|
75
|
+
ignoreEmptyLines;
|
|
76
|
+
state = FIELD_START;
|
|
77
|
+
// The partial field, carried across chunks.
|
|
78
|
+
field = "";
|
|
79
|
+
cells = [];
|
|
80
|
+
// The size of the current record before the current chunk.
|
|
81
|
+
size = 0;
|
|
82
|
+
record = 1;
|
|
83
|
+
line = 1;
|
|
84
|
+
recordLine = 1;
|
|
85
|
+
started = false;
|
|
86
|
+
// A CR ended the previous record, so a leading LF completes a CRLF.
|
|
87
|
+
skipLF = false;
|
|
88
|
+
// Quoted content ended with a CR, so a leading LF does not start a new line.
|
|
89
|
+
quotedCR = false;
|
|
90
|
+
constructor(delimiter, maxRecordSize, ignoreEmptyLines) {
|
|
91
|
+
this.delimiter = delimiter.charCodeAt(0);
|
|
92
|
+
this.maxRecordSize = maxRecordSize;
|
|
93
|
+
this.ignoreEmptyLines = ignoreEmptyLines;
|
|
94
|
+
}
|
|
95
|
+
fail(kind, message) {
|
|
96
|
+
return new CsvError({
|
|
97
|
+
kind,
|
|
98
|
+
message,
|
|
99
|
+
record: this.record,
|
|
100
|
+
line: this.recordLine,
|
|
101
|
+
column: kind === "Syntax" ? this.cells.length + 1 : undefined
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
checkSize(size) {
|
|
105
|
+
if (size > this.maxRecordSize) {
|
|
106
|
+
throw this.fail("RecordSize", `CSV record exceeds maxRecordSize of ${this.maxRecordSize}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// A record that is already too large reports its size, not the syntax error.
|
|
110
|
+
failSyntax(size, message) {
|
|
111
|
+
this.checkSize(size);
|
|
112
|
+
return this.fail("Syntax", message);
|
|
113
|
+
}
|
|
114
|
+
endRecord(size, out) {
|
|
115
|
+
this.checkSize(size);
|
|
116
|
+
if (size > 0 || !this.ignoreEmptyLines) {
|
|
117
|
+
out.push({
|
|
118
|
+
cells: this.cells,
|
|
119
|
+
record: this.record,
|
|
120
|
+
line: this.recordLine
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
this.cells = [];
|
|
124
|
+
this.size = 0;
|
|
125
|
+
this.record++;
|
|
126
|
+
}
|
|
127
|
+
countLines(text, start, end) {
|
|
128
|
+
for (let i = start; i < end; i++) {
|
|
129
|
+
const c = text.charCodeAt(i);
|
|
130
|
+
if (c === CR) this.line++;else if (c === LF && !(i === start ? this.quotedCR : text.charCodeAt(i - 1) === CR)) this.line++;
|
|
131
|
+
}
|
|
132
|
+
if (end > start) this.quotedCR = text.charCodeAt(end - 1) === CR;
|
|
133
|
+
}
|
|
134
|
+
feed(text, out) {
|
|
135
|
+
const length = text.length;
|
|
136
|
+
const delimiter = this.delimiter;
|
|
137
|
+
let i = 0;
|
|
138
|
+
if (length > 0 && !this.started) {
|
|
139
|
+
this.started = true;
|
|
140
|
+
if (text.charCodeAt(0) === 0xFEFF) i = 1;
|
|
141
|
+
}
|
|
142
|
+
// The current record starts at `start` in this chunk, so its size at `i`
|
|
143
|
+
// is `this.size + i - start`.
|
|
144
|
+
let start = i;
|
|
145
|
+
let state = this.state;
|
|
146
|
+
let field = this.field;
|
|
147
|
+
while (i < length) {
|
|
148
|
+
if (state === FIELD_START) {
|
|
149
|
+
if (this.skipLF) {
|
|
150
|
+
this.skipLF = false;
|
|
151
|
+
if (text.charCodeAt(i) === LF) {
|
|
152
|
+
start = ++i;
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (text.charCodeAt(i) === QUOTE) {
|
|
157
|
+
state = QUOTED;
|
|
158
|
+
this.quotedCR = false;
|
|
159
|
+
i++;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
state = UNQUOTED;
|
|
163
|
+
}
|
|
164
|
+
if (state === UNQUOTED) {
|
|
165
|
+
let j = i;
|
|
166
|
+
let c = 0;
|
|
167
|
+
while (j < length) {
|
|
168
|
+
c = text.charCodeAt(j);
|
|
169
|
+
if (c === delimiter || c === CR || c === LF || c === QUOTE) break;
|
|
170
|
+
j++;
|
|
171
|
+
}
|
|
172
|
+
if (j > i) field = field === "" ? text.slice(i, j) : field + text.slice(i, j);
|
|
173
|
+
if (j === length) {
|
|
174
|
+
i = j;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
if (c === QUOTE) {
|
|
178
|
+
throw this.failSyntax(this.size + j - start, "Unexpected quote in an unquoted field");
|
|
179
|
+
}
|
|
180
|
+
this.cells.push(field);
|
|
181
|
+
field = "";
|
|
182
|
+
state = FIELD_START;
|
|
183
|
+
i = j + 1;
|
|
184
|
+
if (c !== delimiter) {
|
|
185
|
+
this.endRecord(this.size + j - start, out);
|
|
186
|
+
this.line++;
|
|
187
|
+
this.recordLine = this.line;
|
|
188
|
+
this.skipLF = c === CR;
|
|
189
|
+
start = i;
|
|
190
|
+
}
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (state === QUOTED) {
|
|
194
|
+
const end = text.indexOf("\"", i);
|
|
195
|
+
const j = end === -1 ? length : end;
|
|
196
|
+
if (j > i) {
|
|
197
|
+
field += text.slice(i, j);
|
|
198
|
+
this.countLines(text, i, j);
|
|
199
|
+
}
|
|
200
|
+
if (end === -1) {
|
|
201
|
+
i = j;
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
state = QUOTE_IN_QUOTED;
|
|
205
|
+
i = j + 1;
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
// QUOTE_IN_QUOTED
|
|
209
|
+
const c = text.charCodeAt(i);
|
|
210
|
+
if (c === QUOTE) {
|
|
211
|
+
field += "\"";
|
|
212
|
+
state = QUOTED;
|
|
213
|
+
this.quotedCR = false;
|
|
214
|
+
i++;
|
|
215
|
+
} else if (c === delimiter || c === CR || c === LF) {
|
|
216
|
+
this.cells.push(field);
|
|
217
|
+
field = "";
|
|
218
|
+
state = FIELD_START;
|
|
219
|
+
i++;
|
|
220
|
+
if (c !== delimiter) {
|
|
221
|
+
this.endRecord(this.size + i - 1 - start, out);
|
|
222
|
+
this.line++;
|
|
223
|
+
this.recordLine = this.line;
|
|
224
|
+
this.skipLF = c === CR;
|
|
225
|
+
start = i;
|
|
226
|
+
}
|
|
227
|
+
} else {
|
|
228
|
+
throw this.failSyntax(this.size + i - start, "Expected a delimiter or line break after a closing quote");
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
this.state = state;
|
|
232
|
+
this.field = field;
|
|
233
|
+
this.size += length - start;
|
|
234
|
+
this.checkSize(this.size);
|
|
235
|
+
}
|
|
236
|
+
end(out) {
|
|
237
|
+
if (this.state === QUOTED) throw this.fail("Syntax", "Unterminated quoted field");
|
|
238
|
+
if (this.size > 0 || this.cells.length > 0) {
|
|
239
|
+
this.cells.push(this.field);
|
|
240
|
+
this.field = "";
|
|
241
|
+
this.state = FIELD_START;
|
|
242
|
+
this.endRecord(this.size, out);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const decodeRecords = options => {
|
|
247
|
+
const delimiter = checkDelimiter(options?.delimiter ?? ",");
|
|
248
|
+
const maxRecordSize = options?.maxRecordSize ?? defaultMaxRecordSize;
|
|
249
|
+
if (!(maxRecordSize > 0)) {
|
|
250
|
+
throw new Error(`Csv: maxRecordSize must be positive, got ${maxRecordSize}`);
|
|
251
|
+
}
|
|
252
|
+
const ignoreEmptyLines = options?.ignoreEmptyLines === true;
|
|
253
|
+
const useHeaders = options?.headers === true;
|
|
254
|
+
return Channel.fromTransform((upstream, _scope) => Effect.sync(() => {
|
|
255
|
+
const parser = new Parser(delimiter, maxRecordSize, ignoreEmptyLines);
|
|
256
|
+
let headers;
|
|
257
|
+
// Plain assignment is faster than `Object.fromEntries`, but a `__proto__`
|
|
258
|
+
// header would set the prototype instead of a property.
|
|
259
|
+
let assignable = false;
|
|
260
|
+
let done;
|
|
261
|
+
const toRecord = row => {
|
|
262
|
+
if (!useHeaders) return {
|
|
263
|
+
value: row.cells,
|
|
264
|
+
record: row.record
|
|
265
|
+
};
|
|
266
|
+
if (row.cells.length !== headers.length) {
|
|
267
|
+
throw new CsvError({
|
|
268
|
+
kind: "Header",
|
|
269
|
+
message: `Expected ${headers.length} cells, got ${row.cells.length}`,
|
|
270
|
+
record: row.record,
|
|
271
|
+
line: row.line,
|
|
272
|
+
column: undefined
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
if (!assignable) {
|
|
276
|
+
return {
|
|
277
|
+
value: Object.fromEntries(headers.map((name, i) => [name, row.cells[i]])),
|
|
278
|
+
record: row.record
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
const value = {};
|
|
282
|
+
for (let i = 0; i < headers.length; i++) value[headers[i]] = row.cells[i];
|
|
283
|
+
return {
|
|
284
|
+
value,
|
|
285
|
+
record: row.record
|
|
286
|
+
};
|
|
287
|
+
};
|
|
288
|
+
const emit = run => {
|
|
289
|
+
const rows = [];
|
|
290
|
+
const out = [];
|
|
291
|
+
try {
|
|
292
|
+
run(rows);
|
|
293
|
+
for (const row of rows) {
|
|
294
|
+
if (useHeaders && headers === undefined) {
|
|
295
|
+
if (new Set(row.cells).size !== row.cells.length) {
|
|
296
|
+
throw new CsvError({
|
|
297
|
+
kind: "Header",
|
|
298
|
+
message: "Duplicate header name",
|
|
299
|
+
record: row.record,
|
|
300
|
+
line: row.line,
|
|
301
|
+
column: undefined
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
headers = row.cells;
|
|
305
|
+
assignable = !headers.includes("__proto__");
|
|
306
|
+
} else {
|
|
307
|
+
out.push(toRecord(row));
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
} catch (error) {
|
|
311
|
+
if (isCsvError(error)) return Effect.fail(error);
|
|
312
|
+
throw error;
|
|
313
|
+
}
|
|
314
|
+
return Arr.isArrayNonEmpty(out) ? Effect.succeed(out) : pull;
|
|
315
|
+
};
|
|
316
|
+
const pull = Effect.suspend(() => {
|
|
317
|
+
if (done !== undefined) return done;
|
|
318
|
+
return Pull.matchEffect(upstream, {
|
|
319
|
+
onSuccess: texts => emit(out => {
|
|
320
|
+
for (const text of texts) parser.feed(text, out);
|
|
321
|
+
}),
|
|
322
|
+
onFailure: Effect.failCause,
|
|
323
|
+
onDone: value => {
|
|
324
|
+
done = Cause.done(value);
|
|
325
|
+
return emit(out => parser.end(out));
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
return pull;
|
|
330
|
+
}));
|
|
331
|
+
};
|
|
332
|
+
/**
|
|
333
|
+
* Creates a channel that parses text chunks into CSV records.
|
|
334
|
+
*
|
|
335
|
+
* **Details**
|
|
336
|
+
*
|
|
337
|
+
* Records are arrays of cells, or objects keyed by the first record when
|
|
338
|
+
* `headers` is `true`. Parser state is created per channel run.
|
|
339
|
+
*
|
|
340
|
+
* **Example** (Parsing header records)
|
|
341
|
+
*
|
|
342
|
+
* ```ts import.meta.vitest
|
|
343
|
+
* import { Effect, Stream } from "effect"
|
|
344
|
+
* import { Csv } from "effect/encoding"
|
|
345
|
+
*
|
|
346
|
+
* const records = Stream.make("name,city\nAlice,\"San\nFrancisco\"\n").pipe(
|
|
347
|
+
* Stream.pipeThroughChannel(Csv.decodeString({ headers: true })),
|
|
348
|
+
* Stream.runCollect
|
|
349
|
+
* )
|
|
350
|
+
* await Effect.runPromise(records) // => [{ name: "Alice", city: "San\nFrancisco" }]
|
|
351
|
+
* ```
|
|
352
|
+
*
|
|
353
|
+
* @see decode
|
|
354
|
+
* @see decodeSchemaString
|
|
355
|
+
* @stability unstable
|
|
356
|
+
* @category decoding
|
|
357
|
+
* @since 4.1.0
|
|
358
|
+
*/
|
|
359
|
+
export const decodeString = options => Channel.map(decodeRecords(options), Arr.map(record => record.value));
|
|
360
|
+
/**
|
|
361
|
+
* Creates a channel that parses UTF-8 byte chunks into CSV records.
|
|
362
|
+
*
|
|
363
|
+
* @see decodeString
|
|
364
|
+
* @stability unstable
|
|
365
|
+
* @category decoding
|
|
366
|
+
* @since 4.1.0
|
|
367
|
+
*/
|
|
368
|
+
export const decode = options => Channel.pipeTo(Channel.decodeText("utf-8", {
|
|
369
|
+
ignoreBOM: true
|
|
370
|
+
}), decodeString(options));
|
|
371
|
+
// Rewrites the chunk index at the head of each top-level issue path to the
|
|
372
|
+
// record number, keeping the rest of the issue unchanged.
|
|
373
|
+
const rebaseIssue = (error, record) => {
|
|
374
|
+
const issue = error.issue;
|
|
375
|
+
if (issue._tag !== "Composite") return error;
|
|
376
|
+
return new Schema.SchemaError(new SchemaIssue.Composite(issue.ast, Arr.map(issue.issues, issue => issue._tag === "Pointer" && typeof issue.path[0] === "number" ? new SchemaIssue.Pointer([record(issue.path[0]), ...issue.path.slice(1)], issue.issue) : issue), issue.input, {
|
|
377
|
+
reportInput: "input" in issue
|
|
378
|
+
}));
|
|
379
|
+
};
|
|
380
|
+
// Derived codecs are new ASTs, and schema parsers are cached per AST, so they
|
|
381
|
+
// are memoized to avoid recompiling parsers for every channel.
|
|
382
|
+
const stringTreeCodecs = /*#__PURE__*/new WeakMap();
|
|
383
|
+
const arrayCodecs = /*#__PURE__*/new WeakMap();
|
|
384
|
+
// The schema used for CSV cells. `toCodecStringTree` keeps the decoded type and
|
|
385
|
+
// services and only changes the encoded side, which is treated as unknown here.
|
|
386
|
+
const toCodec = (schema, disableCodecs) => {
|
|
387
|
+
if (disableCodecs === true) return schema;
|
|
388
|
+
let codec = stringTreeCodecs.get(schema);
|
|
389
|
+
if (codec === undefined) {
|
|
390
|
+
codec = Schema.toCodecStringTree(schema);
|
|
391
|
+
stringTreeCodecs.set(schema, codec);
|
|
392
|
+
}
|
|
393
|
+
return codec;
|
|
394
|
+
};
|
|
395
|
+
const toArrayCodec = codec => {
|
|
396
|
+
let array = arrayCodecs.get(codec);
|
|
397
|
+
if (array === undefined) {
|
|
398
|
+
array = Schema.NonEmptyArray(codec);
|
|
399
|
+
arrayCodecs.set(codec, array);
|
|
400
|
+
}
|
|
401
|
+
return array;
|
|
402
|
+
};
|
|
403
|
+
const isStringLeaf = ast => {
|
|
404
|
+
switch (ast._tag) {
|
|
405
|
+
case "String":
|
|
406
|
+
case "TemplateLiteral":
|
|
407
|
+
return true;
|
|
408
|
+
case "Literal":
|
|
409
|
+
return typeof ast.literal === "string";
|
|
410
|
+
case "Enum":
|
|
411
|
+
return ast.enums.every(([, value]) => typeof value === "string");
|
|
412
|
+
case "Union":
|
|
413
|
+
return ast.types.every(type => type._tag === "Undefined" || isStringLeaf(type));
|
|
414
|
+
default:
|
|
415
|
+
return false;
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
const resolveSuspend = ast => SchemaAST.isSuspend(ast) ? resolveSuspend(ast.thunk()) : ast;
|
|
419
|
+
// Throws unless every selected cell of an encoded struct or tuple is a string.
|
|
420
|
+
const checkCells = (ast, columns) => {
|
|
421
|
+
ast = resolveSuspend(ast);
|
|
422
|
+
const check = (name, type) => {
|
|
423
|
+
if (!isStringLeaf(type)) {
|
|
424
|
+
throw new Error(`Csv: ${name} encodes to ${type._tag}, not a string. ` + "Encode it as a single cell with a transformation, such as SchemaGetter.split for arrays");
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
if (SchemaAST.isObjects(ast)) {
|
|
428
|
+
for (const ps of ast.propertySignatures) {
|
|
429
|
+
if (typeof ps.name === "string" && (columns === undefined || columns.includes(ps.name))) {
|
|
430
|
+
check(`column ${JSON.stringify(ps.name)}`, ps.type);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
for (const is of ast.indexSignatures) check("index signature", is.type);
|
|
434
|
+
} else if (SchemaAST.isArrays(ast)) {
|
|
435
|
+
ast.elements.forEach((type, i) => check(`column ${i + 1}`, type));
|
|
436
|
+
for (const type of ast.rest) check("rest element", type);
|
|
437
|
+
} else if (SchemaAST.isUnion(ast)) {
|
|
438
|
+
for (const type of ast.types) checkCells(type, columns);
|
|
439
|
+
} else {
|
|
440
|
+
throw new Error(`Csv: cannot verify string cells for ${ast._tag}. ` + "Encode it as a flat struct or tuple with a transformation");
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
/**
|
|
444
|
+
* Creates a channel that parses CSV text and decodes each record with a schema.
|
|
445
|
+
*
|
|
446
|
+
* **Details**
|
|
447
|
+
*
|
|
448
|
+
* With `headers: true` the schema receives objects keyed by header name;
|
|
449
|
+
* otherwise it receives arrays of cells. Columns that do not encode to a string,
|
|
450
|
+
* such as arrays or nested structs, throw when the channel is created. Each
|
|
451
|
+
* chunk is decoded in one pass. Schema failures are `SchemaError`s whose issue
|
|
452
|
+
* paths start with the record number.
|
|
453
|
+
*
|
|
454
|
+
* **Example** (Decoding renamed headers)
|
|
455
|
+
*
|
|
456
|
+
* ```ts import.meta.vitest
|
|
457
|
+
* import { Effect, Schema, Stream } from "effect"
|
|
458
|
+
* import { Csv } from "effect/encoding"
|
|
459
|
+
*
|
|
460
|
+
* const Person = Schema.Struct({
|
|
461
|
+
* name: Schema.String,
|
|
462
|
+
* age: Schema.Number
|
|
463
|
+
* }).pipe(Schema.encodeKeys({ name: "Full Name", age: "Age (years)" }))
|
|
464
|
+
*
|
|
465
|
+
* const people = Stream.make("Full Name,Age (years)\nAlice,32").pipe(
|
|
466
|
+
* Stream.pipeThroughChannel(Csv.decodeSchemaString(Person)({ headers: true })),
|
|
467
|
+
* Stream.runCollect
|
|
468
|
+
* )
|
|
469
|
+
* await Effect.runPromise(people) // => [{ name: "Alice", age: 32 }]
|
|
470
|
+
* ```
|
|
471
|
+
*
|
|
472
|
+
* **Example** (Transforming positional records into objects)
|
|
473
|
+
*
|
|
474
|
+
* ```ts import.meta.vitest
|
|
475
|
+
* import { Effect, Schema, SchemaGetter, Stream } from "effect"
|
|
476
|
+
* import { Csv } from "effect/encoding"
|
|
477
|
+
*
|
|
478
|
+
* const Person = Schema.Tuple([Schema.String, Schema.Number]).pipe(
|
|
479
|
+
* Schema.decodeTo(Schema.Struct({ name: Schema.String, age: Schema.Number }), {
|
|
480
|
+
* decode: SchemaGetter.transform(([name, age]) => ({ name, age })),
|
|
481
|
+
* encode: SchemaGetter.transform(({ name, age }) => [name, age] as const)
|
|
482
|
+
* })
|
|
483
|
+
* )
|
|
484
|
+
*
|
|
485
|
+
* const people = Stream.make("Alice,32").pipe(
|
|
486
|
+
* Stream.pipeThroughChannel(Csv.decodeSchemaString(Person)()),
|
|
487
|
+
* Stream.runCollect
|
|
488
|
+
* )
|
|
489
|
+
* await Effect.runPromise(people) // => [{ name: "Alice", age: 32 }]
|
|
490
|
+
* ```
|
|
491
|
+
*
|
|
492
|
+
* @see decodeSchema
|
|
493
|
+
* @see encodeSchemaString
|
|
494
|
+
* @stability unstable
|
|
495
|
+
* @category decoding
|
|
496
|
+
* @since 4.1.0
|
|
497
|
+
*/
|
|
498
|
+
export const decodeSchemaString = schema => (options, parseOptions) => {
|
|
499
|
+
const codec = toCodec(schema, options?.disableCodecs);
|
|
500
|
+
const ast = resolveSuspend(SchemaAST.toEncoded(codec.ast));
|
|
501
|
+
checkCells(ast, undefined);
|
|
502
|
+
// CSV cannot tell an empty cell from a missing one, so empty cells of
|
|
503
|
+
// optional properties are decoded as missing keys.
|
|
504
|
+
const optional = options?.disableCodecs !== true && options?.headers === true && SchemaAST.isObjects(ast) ? ast.propertySignatures.flatMap(ps => typeof ps.name === "string" && SchemaAST.isOptional(ps.type) ? [ps.name] : []) : [];
|
|
505
|
+
const input = record => {
|
|
506
|
+
if (optional.length === 0) return record.value;
|
|
507
|
+
// Header records are created per row, so they can be updated in place.
|
|
508
|
+
const value = record.value;
|
|
509
|
+
for (const key of optional) {
|
|
510
|
+
if (value[key] === "") delete value[key];
|
|
511
|
+
}
|
|
512
|
+
return value;
|
|
513
|
+
};
|
|
514
|
+
const decode = Schema.decodeUnknownEffect(toArrayCodec(codec), parseOptions);
|
|
515
|
+
return Channel.mapEffect(decodeRecords(options), records => Effect.mapError(decode(Arr.map(records, input)), error => rebaseIssue(error, index => records[index].record)));
|
|
516
|
+
};
|
|
517
|
+
/**
|
|
518
|
+
* Creates a channel that parses UTF-8 CSV and decodes each record with a schema.
|
|
519
|
+
*
|
|
520
|
+
* @see decodeSchemaString
|
|
521
|
+
* @stability unstable
|
|
522
|
+
* @category decoding
|
|
523
|
+
* @since 4.1.0
|
|
524
|
+
*/
|
|
525
|
+
export const decodeSchema = schema => (options, parseOptions) => Channel.pipeTo(Channel.decodeText("utf-8", {
|
|
526
|
+
ignoreBOM: true
|
|
527
|
+
}), decodeSchemaString(schema)(options, parseOptions));
|
|
528
|
+
const textEncoder = /*#__PURE__*/new TextEncoder();
|
|
529
|
+
const makeWriter = options => {
|
|
530
|
+
const delimiter = checkDelimiter(options?.delimiter ?? ",");
|
|
531
|
+
const newline = options?.newline ?? "\r\n";
|
|
532
|
+
if (newline !== "\n" && newline !== "\r\n") {
|
|
533
|
+
throw new Error(`Csv: newline must be "\\n" or "\\r\\n", got ${JSON.stringify(newline)}`);
|
|
534
|
+
}
|
|
535
|
+
const columns = options?.columns;
|
|
536
|
+
if (options?.headers === true && columns === undefined) {
|
|
537
|
+
throw new Error("Csv: headers requires columns");
|
|
538
|
+
}
|
|
539
|
+
// Characters that require a cell to be quoted.
|
|
540
|
+
const special = new RegExp(`[${delimiter.replace(/[\\\]^-]/g, "\\$&")}"\\r\\n]`);
|
|
541
|
+
const cell = value => {
|
|
542
|
+
if (value === undefined) return "";
|
|
543
|
+
if (typeof value !== "string") throw new TypeError(`Csv: expected a string cell, got ${typeof value}`);
|
|
544
|
+
// A leading BOM is quoted so that decoders do not strip it.
|
|
545
|
+
return special.test(value) || value.charCodeAt(0) === 0xFEFF ? "\"" + value.replaceAll("\"", "\"\"") + "\"" : value;
|
|
546
|
+
};
|
|
547
|
+
const write = cells => {
|
|
548
|
+
// A single empty cell is quoted so that it is not read back as an empty line.
|
|
549
|
+
if (cells.length === 1 && (cells[0] === "" || cells[0] === undefined)) return "\"\"" + newline;
|
|
550
|
+
let line = cell(cells[0]);
|
|
551
|
+
for (let i = 1; i < cells.length; i++) line += delimiter + cell(cells[i]);
|
|
552
|
+
return line + newline;
|
|
553
|
+
};
|
|
554
|
+
const header = options?.headers === true ? write(columns) : undefined;
|
|
555
|
+
const writeRecord = value => {
|
|
556
|
+
if (Array.isArray(value)) return write(value);
|
|
557
|
+
if (columns === undefined) throw new TypeError("Csv: encoding object records requires columns");
|
|
558
|
+
const record = value;
|
|
559
|
+
return write(columns.map(key => Object.hasOwn(record, key) ? record[key] : undefined));
|
|
560
|
+
};
|
|
561
|
+
return {
|
|
562
|
+
header,
|
|
563
|
+
writeRecord
|
|
564
|
+
};
|
|
565
|
+
};
|
|
566
|
+
const encodeRecords = options => {
|
|
567
|
+
const {
|
|
568
|
+
header,
|
|
569
|
+
writeRecord
|
|
570
|
+
} = makeWriter(options);
|
|
571
|
+
return Channel.fromTransform((upstream, _scope) => Effect.sync(() => {
|
|
572
|
+
let pending = header;
|
|
573
|
+
const pull = Effect.suspend(() => {
|
|
574
|
+
if (pending !== undefined) {
|
|
575
|
+
const text = pending;
|
|
576
|
+
pending = undefined;
|
|
577
|
+
return Effect.succeed(Arr.of(text));
|
|
578
|
+
}
|
|
579
|
+
return Effect.flatMap(upstream, records => Effect.sync(() => Arr.map(records, writeRecord)));
|
|
580
|
+
});
|
|
581
|
+
return pull;
|
|
582
|
+
}));
|
|
583
|
+
};
|
|
584
|
+
/**
|
|
585
|
+
* Creates a channel that writes CSV records as text, one string per record.
|
|
586
|
+
*
|
|
587
|
+
* **Details**
|
|
588
|
+
*
|
|
589
|
+
* Without `columns`, records are arrays of cells. With `columns`, records are
|
|
590
|
+
* objects encoded by those keys. A non-string cell is a defect.
|
|
591
|
+
*
|
|
592
|
+
* **Example** (Writing header records)
|
|
593
|
+
*
|
|
594
|
+
* ```ts import.meta.vitest
|
|
595
|
+
* import { Effect, Stream } from "effect"
|
|
596
|
+
* import { Csv } from "effect/encoding"
|
|
597
|
+
*
|
|
598
|
+
* const csv = Stream.make({ name: "Smith, Charlie", city: "London" }).pipe(
|
|
599
|
+
* Stream.pipeThroughChannel(Csv.encodeString({ columns: ["name", "city"], headers: true })),
|
|
600
|
+
* Stream.runCollect,
|
|
601
|
+
* Effect.map((parts) => parts.join(""))
|
|
602
|
+
* )
|
|
603
|
+
* await Effect.runPromise(csv) // => 'name,city\r\n"Smith, Charlie",London\r\n'
|
|
604
|
+
* ```
|
|
605
|
+
*
|
|
606
|
+
* @see encode
|
|
607
|
+
* @see encodeSchemaString
|
|
608
|
+
* @stability unstable
|
|
609
|
+
* @category encoding
|
|
610
|
+
* @since 4.1.0
|
|
611
|
+
*/
|
|
612
|
+
export const encodeString = options => encodeRecords(options);
|
|
613
|
+
/**
|
|
614
|
+
* Creates a channel that writes CSV records as UTF-8 bytes, one byte array per
|
|
615
|
+
* input chunk.
|
|
616
|
+
*
|
|
617
|
+
* @see encodeString
|
|
618
|
+
* @stability unstable
|
|
619
|
+
* @category encoding
|
|
620
|
+
* @since 4.1.0
|
|
621
|
+
*/
|
|
622
|
+
export const encode = options => Channel.map(encodeRecords(options), texts => Arr.of(textEncoder.encode(texts.join(""))));
|
|
623
|
+
// Struct schemas encode by their encoded keys in declaration order. Tuple and
|
|
624
|
+
// array schemas encode by position. Other schemas, including records with
|
|
625
|
+
// index signatures, need explicit columns.
|
|
626
|
+
const schemaColumns = (ast, options) => {
|
|
627
|
+
if (options?.columns !== undefined) {
|
|
628
|
+
checkCells(ast, options.columns);
|
|
629
|
+
return options.columns;
|
|
630
|
+
}
|
|
631
|
+
if (SchemaAST.isObjects(ast) && ast.indexSignatures.length === 0) {
|
|
632
|
+
const columns = ast.propertySignatures.flatMap(ps => typeof ps.name === "string" ? [ps.name] : []);
|
|
633
|
+
checkCells(ast, columns);
|
|
634
|
+
return columns;
|
|
635
|
+
}
|
|
636
|
+
if (SchemaAST.isArrays(ast)) {
|
|
637
|
+
if (options?.headers === true) throw new Error("Csv: headers for tuple or array schemas require columns");
|
|
638
|
+
checkCells(ast, undefined);
|
|
639
|
+
return undefined;
|
|
640
|
+
}
|
|
641
|
+
throw new Error(`Csv: columns are required to encode ${ast._tag} schemas`);
|
|
642
|
+
};
|
|
643
|
+
const encodeSchemaRecords = (schema, options) => {
|
|
644
|
+
const codec = toCodec(schema, options?.disableCodecs);
|
|
645
|
+
const columns = schemaColumns(SchemaAST.toEncoded(codec.ast), options);
|
|
646
|
+
const writer = encodeRecords({
|
|
647
|
+
...options,
|
|
648
|
+
columns
|
|
649
|
+
});
|
|
650
|
+
const encode = Schema.encodeEffect(toArrayCodec(codec));
|
|
651
|
+
const firstRecord = options?.headers === true ? 2 : 1;
|
|
652
|
+
const values = Channel.fromTransform((upstream, _scope) => Effect.sync(() => {
|
|
653
|
+
let record = firstRecord;
|
|
654
|
+
return Effect.flatMap(upstream, chunk => {
|
|
655
|
+
const first = record;
|
|
656
|
+
record += chunk.length;
|
|
657
|
+
return Effect.mapError(encode(chunk), error => rebaseIssue(error, index => first + index));
|
|
658
|
+
});
|
|
659
|
+
}));
|
|
660
|
+
return Channel.pipeTo(values, writer);
|
|
661
|
+
};
|
|
662
|
+
/**
|
|
663
|
+
* Creates a channel that encodes values with a schema and writes them as CSV
|
|
664
|
+
* text, one string per record.
|
|
665
|
+
*
|
|
666
|
+
* **Details**
|
|
667
|
+
*
|
|
668
|
+
* Columns default to the encoded keys of a struct schema, including keys
|
|
669
|
+
* renamed with `Schema.encodeKeys`. Missing or `undefined` values become empty
|
|
670
|
+
* cells. Schema failures are `SchemaError`s whose issue paths start with the
|
|
671
|
+
* output record number, counting the header row.
|
|
672
|
+
*
|
|
673
|
+
* **Example** (Encoding renamed headers)
|
|
674
|
+
*
|
|
675
|
+
* ```ts import.meta.vitest
|
|
676
|
+
* import { Effect, Schema, Stream } from "effect"
|
|
677
|
+
* import { Csv } from "effect/encoding"
|
|
678
|
+
*
|
|
679
|
+
* const Person = Schema.Struct({
|
|
680
|
+
* name: Schema.String,
|
|
681
|
+
* age: Schema.Number,
|
|
682
|
+
* joined: Schema.Date
|
|
683
|
+
* }).pipe(Schema.encodeKeys({ name: "Full Name", age: "Age (years)" }))
|
|
684
|
+
*
|
|
685
|
+
* const csv = await Effect.runPromise(
|
|
686
|
+
* Stream.make({ name: "Alice", age: 32, joined: new Date(0) }).pipe(
|
|
687
|
+
* Stream.pipeThroughChannel(Csv.encodeSchemaString(Person)({ headers: true, newline: "\n" })),
|
|
688
|
+
* Stream.runCollect,
|
|
689
|
+
* Effect.map((parts) => parts.join(""))
|
|
690
|
+
* )
|
|
691
|
+
* )
|
|
692
|
+
* csv.split("\n") // => ["Full Name,Age (years),joined", "Alice,32,1970-01-01T00:00:00.000Z", ""]
|
|
693
|
+
* ```
|
|
694
|
+
*
|
|
695
|
+
* @see decodeSchemaString
|
|
696
|
+
* @see encodeSchema
|
|
697
|
+
* @stability unstable
|
|
698
|
+
* @category encoding
|
|
699
|
+
* @since 4.1.0
|
|
700
|
+
*/
|
|
701
|
+
export const encodeSchemaString = schema => options => encodeSchemaRecords(schema, options);
|
|
702
|
+
/**
|
|
703
|
+
* Creates a channel that encodes values with a schema and writes them as UTF-8
|
|
704
|
+
* CSV bytes.
|
|
705
|
+
*
|
|
706
|
+
* **Gotchas**
|
|
707
|
+
*
|
|
708
|
+
* When the bytes stream an HTTP response body, for example through
|
|
709
|
+
* `HttpApiSchema.StreamUint8Array`, an encoding failure ends the body; it
|
|
710
|
+
* cannot change a status that was already sent.
|
|
711
|
+
*
|
|
712
|
+
* @see encodeSchemaString
|
|
713
|
+
* @stability unstable
|
|
714
|
+
* @category encoding
|
|
715
|
+
* @since 4.1.0
|
|
716
|
+
*/
|
|
717
|
+
export const encodeSchema = schema => options => Channel.map(encodeSchemaRecords(schema, options), texts => Arr.of(textEncoder.encode(texts.join(""))));
|
|
718
|
+
//# sourceMappingURL=Csv.js.map
|