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,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The few DER operations `KeyFormat` needs to turn PKCS#1 and SEC1 private
|
|
3
|
+
* keys into PKCS#8, and to find the public point of an EC private key.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/** @internal */
|
|
7
|
+
export interface Element {
|
|
8
|
+
readonly tag: number
|
|
9
|
+
/** The offset of the tag. */
|
|
10
|
+
readonly offset: number
|
|
11
|
+
/** The offset of the contents. */
|
|
12
|
+
readonly start: number
|
|
13
|
+
/** The offset after the contents. */
|
|
14
|
+
readonly end: number
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Reads the element at `offset`, returning `undefined` when it does not fit
|
|
19
|
+
* in `end` or its length is not in definite form of at most 3 bytes.
|
|
20
|
+
*
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
export const read = (bytes: Uint8Array, offset: number, end = bytes.length): Element | undefined => {
|
|
24
|
+
if (offset + 2 > end) return undefined
|
|
25
|
+
const tag = bytes[offset]
|
|
26
|
+
const first = bytes[offset + 1]
|
|
27
|
+
let start = offset + 2
|
|
28
|
+
let length = first
|
|
29
|
+
if (first >= 0x80) {
|
|
30
|
+
const size = first & 0x7f
|
|
31
|
+
if (size === 0 || size > 3 || start + size > end) return undefined
|
|
32
|
+
length = 0
|
|
33
|
+
for (let i = 0; i < size; i++) length = length * 256 + bytes[start++]
|
|
34
|
+
}
|
|
35
|
+
return start + length > end ? undefined : { tag, offset, start, end: start + length }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Reads a whole input as one element, with nothing after it.
|
|
40
|
+
*
|
|
41
|
+
* @internal
|
|
42
|
+
*/
|
|
43
|
+
export const readOnly = (bytes: Uint8Array, tag: number): Element | undefined => {
|
|
44
|
+
const element = read(bytes, 0)
|
|
45
|
+
return element !== undefined && element.tag === tag && element.end === bytes.length ? element : undefined
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Reads the elements inside a constructed element, returning `undefined`
|
|
50
|
+
* when they do not fill it exactly.
|
|
51
|
+
*
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
export const children = (bytes: Uint8Array, parent: Element): ReadonlyArray<Element> | undefined => {
|
|
55
|
+
const out: Array<Element> = []
|
|
56
|
+
let offset = parent.start
|
|
57
|
+
while (offset < parent.end) {
|
|
58
|
+
const element = read(bytes, offset, parent.end)
|
|
59
|
+
if (element === undefined) return undefined
|
|
60
|
+
out.push(element)
|
|
61
|
+
offset = element.end
|
|
62
|
+
}
|
|
63
|
+
return out
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** @internal */
|
|
67
|
+
export const slice = (bytes: Uint8Array, element: Element): Uint8Array => bytes.subarray(element.offset, element.end)
|
|
68
|
+
|
|
69
|
+
const length = (n: number): Array<number> =>
|
|
70
|
+
n < 0x80
|
|
71
|
+
? [n]
|
|
72
|
+
: n < 0x100
|
|
73
|
+
? [0x81, n]
|
|
74
|
+
: n < 0x10000
|
|
75
|
+
? [0x82, n >> 8, n & 0xff]
|
|
76
|
+
: [0x83, n >> 16, (n >> 8) & 0xff, n & 0xff]
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Encodes an element from its tag and contents.
|
|
80
|
+
*
|
|
81
|
+
* @internal
|
|
82
|
+
*/
|
|
83
|
+
export const encode = (tag: number, ...contents: ReadonlyArray<Uint8Array>): Uint8Array => {
|
|
84
|
+
const size = contents.reduce((sum, part) => sum + part.length, 0)
|
|
85
|
+
const header = [tag, ...length(size)]
|
|
86
|
+
const out = new Uint8Array(header.length + size)
|
|
87
|
+
out.set(header)
|
|
88
|
+
let offset = header.length
|
|
89
|
+
for (const part of contents) {
|
|
90
|
+
out.set(part, offset)
|
|
91
|
+
offset += part.length
|
|
92
|
+
}
|
|
93
|
+
return out
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** @internal */
|
|
97
|
+
export const sequence = 0x30
|
|
98
|
+
|
|
99
|
+
/** @internal */
|
|
100
|
+
export const octetString = 0x04
|
|
101
|
+
|
|
102
|
+
/** @internal */
|
|
103
|
+
export const integer = 0x02
|
|
104
|
+
|
|
105
|
+
/** @internal */
|
|
106
|
+
export const objectIdentifier = 0x06
|
|
107
|
+
|
|
108
|
+
/** @internal */
|
|
109
|
+
export const equals = (a: Uint8Array, b: Uint8Array): boolean =>
|
|
110
|
+
a.length === b.length && a.every((byte, i) => byte === b[i])
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as Effect from "../../Effect.ts"
|
|
2
|
+
import type { Algorithm } from "../Digest.ts"
|
|
3
|
+
import * as internal from "./webCrypto.ts"
|
|
4
|
+
|
|
5
|
+
/** @internal */
|
|
6
|
+
export const webCryptoDigest = (crypto: Crypto, algorithm: Algorithm, data: Uint8Array): Effect.Effect<Uint8Array> => {
|
|
7
|
+
const implementation = algorithm.implementation
|
|
8
|
+
if (implementation !== undefined) {
|
|
9
|
+
return Effect.sync(() => implementation(data))
|
|
10
|
+
}
|
|
11
|
+
return Effect.suspend(() => {
|
|
12
|
+
const subtle = crypto?.subtle
|
|
13
|
+
if (subtle === undefined) return Effect.die(internal.subtleUnavailable())
|
|
14
|
+
return Effect.promise(async () => new Uint8Array(await subtle.digest(algorithm.name, data as BufferSource)))
|
|
15
|
+
})
|
|
16
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import * as Effect from "../../Effect.ts"
|
|
2
|
+
import * as Equal from "../../Equal.ts"
|
|
3
|
+
import { format } from "../../Formatter.ts"
|
|
4
|
+
import { NodeInspectSymbol } from "../../Inspectable.ts"
|
|
5
|
+
import * as Predicate from "../../Predicate.ts"
|
|
6
|
+
import type * as CryptoError from "../CryptoError.ts"
|
|
7
|
+
import * as internal from "./webCrypto.ts"
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* What a key holds: bytes, which every layer accepts, or a `CryptoKey` from a
|
|
11
|
+
* `*FromCryptoKey` constructor.
|
|
12
|
+
*
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export type Material =
|
|
16
|
+
| { readonly _tag: "Bytes"; readonly bytes: Uint8Array }
|
|
17
|
+
| { readonly _tag: "CryptoKey"; readonly cryptoKey: CryptoKey }
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The property holding a key's material. Only this package reads it: platform
|
|
21
|
+
* layers pass primitives to a family's `layerWebCryptoWith` instead, and
|
|
22
|
+
* third-party layers use the family's public `toBytes`.
|
|
23
|
+
*
|
|
24
|
+
* This is not a secrecy mechanism. Being non-enumerable keeps the material out
|
|
25
|
+
* of `JSON.stringify` and `inspect`, but anyone holding a key can reach it
|
|
26
|
+
* through `Object.getOwnPropertySymbols`.
|
|
27
|
+
*
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
export const MaterialId: unique symbol = Symbol("~effect/crypto/Key/material") as never
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Copies bytes into a plain `Uint8Array` with its own buffer. A subclass's
|
|
34
|
+
* `slice` may not copy: a Node.js `Buffer`'s returns a view of the same memory.
|
|
35
|
+
*
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
export const copyBytes = (bytes: Uint8Array): Uint8Array => new Uint8Array(bytes)
|
|
39
|
+
|
|
40
|
+
/** @internal */
|
|
41
|
+
export const material = (key: object): Material => (key as { readonly [MaterialId]: Material })[MaterialId]
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Builds a key prototype that displays only its algorithm.
|
|
45
|
+
*
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
48
|
+
export const redactedProto = (typeId: string, label: string): object => ({
|
|
49
|
+
[typeId]: typeId,
|
|
50
|
+
toJSON(this: { readonly algorithm: { readonly name: string } }) {
|
|
51
|
+
return { _id: label, algorithm: this.algorithm.name }
|
|
52
|
+
},
|
|
53
|
+
toString(this: { toJSON(): unknown }) {
|
|
54
|
+
return format(this.toJSON())
|
|
55
|
+
},
|
|
56
|
+
[NodeInspectSymbol](this: { toJSON(): unknown }) {
|
|
57
|
+
return this.toJSON()
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Builds a key. Keys compare by reference: comparing key bytes is not constant
|
|
63
|
+
* time, and structural equality would let secret keys act as `HashMap` keys.
|
|
64
|
+
*/
|
|
65
|
+
const make = <K>(proto: object, algorithm: unknown, material: Material): K =>
|
|
66
|
+
Equal.byReferenceUnsafe(Object.create(proto, {
|
|
67
|
+
algorithm: { value: algorithm, enumerable: true },
|
|
68
|
+
[MaterialId]: { value: material }
|
|
69
|
+
}))
|
|
70
|
+
|
|
71
|
+
/** @internal */
|
|
72
|
+
export const makeBytes = <K>(proto: object, algorithm: unknown, bytes: Uint8Array): K =>
|
|
73
|
+
make(proto, algorithm, { _tag: "Bytes", bytes })
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Checks the length of a symmetric key against its algorithm.
|
|
77
|
+
*
|
|
78
|
+
* @internal
|
|
79
|
+
*/
|
|
80
|
+
export const checkKeyLength =
|
|
81
|
+
(algorithm: { readonly name: string; readonly keyLength: number }) => (bytes: Uint8Array): string | undefined =>
|
|
82
|
+
bytes.length === algorithm.keyLength
|
|
83
|
+
? undefined
|
|
84
|
+
: `Expected a ${algorithm.keyLength}-byte key for ${algorithm.name}, not ${bytes.length} bytes`
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Copies raw key bytes into a byte-backed key, rejecting other values and
|
|
88
|
+
* bytes that fail `check`.
|
|
89
|
+
*
|
|
90
|
+
* @internal
|
|
91
|
+
*/
|
|
92
|
+
export const fromBytes = <K>(
|
|
93
|
+
module: string,
|
|
94
|
+
method: string,
|
|
95
|
+
proto: object,
|
|
96
|
+
algorithm: unknown,
|
|
97
|
+
bytes: Uint8Array,
|
|
98
|
+
check: (bytes: Uint8Array) => string | undefined
|
|
99
|
+
): Effect.Effect<K, CryptoError.CryptoError> =>
|
|
100
|
+
Effect.suspend(() => {
|
|
101
|
+
if (!(bytes instanceof Uint8Array)) return internal.invalidKey(module, method, "Expected the key as a Uint8Array")
|
|
102
|
+
const problem = check(bytes)
|
|
103
|
+
return problem === undefined
|
|
104
|
+
? Effect.succeed(makeBytes<K>(proto, algorithm, copyBytes(bytes)))
|
|
105
|
+
: internal.invalidKey(module, method, problem)
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* What a `CryptoKey` must match to back a typed key.
|
|
110
|
+
*
|
|
111
|
+
* `usagePolicy: "all"` requires every expected usage. `"any"` is for RSA-OAEP,
|
|
112
|
+
* where the layer chooses an available usage for the key's role.
|
|
113
|
+
*
|
|
114
|
+
* @internal
|
|
115
|
+
*/
|
|
116
|
+
export interface ExpectedCryptoKey {
|
|
117
|
+
readonly type: KeyType
|
|
118
|
+
readonly name: string
|
|
119
|
+
readonly usages: ReadonlyArray<KeyUsage>
|
|
120
|
+
readonly usagePolicy: "all" | "any"
|
|
121
|
+
readonly check?: ((algorithm: KeyAlgorithm) => string | undefined) | undefined
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Checks that an AES `CryptoKey` has the algorithm's length.
|
|
126
|
+
*
|
|
127
|
+
* @internal
|
|
128
|
+
*/
|
|
129
|
+
export const checkAesLength = (name: string, keyLength: number) => (algorithm: KeyAlgorithm): string | undefined => {
|
|
130
|
+
const length = (algorithm as AesKeyAlgorithm).length
|
|
131
|
+
return length === keyLength * 8 ? undefined : `Expected a ${keyLength * 8}-bit ${name} key, not ${length} bits`
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const checkCryptoKey = (cryptoKey: CryptoKey, expected: ExpectedCryptoKey): string | undefined => {
|
|
135
|
+
if (
|
|
136
|
+
!Predicate.hasProperty(cryptoKey, "type") || !Predicate.hasProperty(cryptoKey, "algorithm") ||
|
|
137
|
+
!Predicate.hasProperty(cryptoKey, "usages") || !Array.isArray(cryptoKey.usages)
|
|
138
|
+
) {
|
|
139
|
+
return "Expected a CryptoKey"
|
|
140
|
+
}
|
|
141
|
+
if (cryptoKey.algorithm.name !== expected.name) {
|
|
142
|
+
return `Expected a ${expected.name} key, not ${cryptoKey.algorithm.name}`
|
|
143
|
+
}
|
|
144
|
+
if (cryptoKey.type !== expected.type) return `Expected a ${expected.type} key, not ${cryptoKey.type}`
|
|
145
|
+
const problem = expected.check?.(cryptoKey.algorithm)
|
|
146
|
+
if (problem !== undefined) return problem
|
|
147
|
+
const usages: ReadonlyArray<string> = cryptoKey.usages
|
|
148
|
+
if (expected.usagePolicy === "all") {
|
|
149
|
+
if (!expected.usages.every((usage) => usages.includes(usage))) {
|
|
150
|
+
return `Expected a key with the usages ${expected.usages.join(" and ")}, not ${usages.join(", ") || "none"}`
|
|
151
|
+
}
|
|
152
|
+
} else if (!expected.usages.some((usage) => usages.includes(usage))) {
|
|
153
|
+
return `Expected a key with one of the usages ${expected.usages.join(", ")}`
|
|
154
|
+
}
|
|
155
|
+
return undefined
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* The algorithm of a key imported from `cryptoKey`. An RSA algorithm's
|
|
160
|
+
* `modulusLength` is only read by key generation, so the key reports the real
|
|
161
|
+
* size of `cryptoKey` instead.
|
|
162
|
+
*
|
|
163
|
+
* @internal
|
|
164
|
+
*/
|
|
165
|
+
export const importedAlgorithm = (algorithm: unknown, cryptoKey: CryptoKey): unknown => {
|
|
166
|
+
const modulusLength = (cryptoKey.algorithm as Partial<RsaKeyAlgorithm>).modulusLength
|
|
167
|
+
return Predicate.hasProperty(algorithm, "modulusLength") && modulusLength !== undefined &&
|
|
168
|
+
algorithm.modulusLength !== modulusLength
|
|
169
|
+
? { ...algorithm, modulusLength }
|
|
170
|
+
: algorithm
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Synchronously validates and wraps a `CryptoKey`.
|
|
175
|
+
*
|
|
176
|
+
* @internal
|
|
177
|
+
*/
|
|
178
|
+
export const fromCryptoKey = <K>(
|
|
179
|
+
module: string,
|
|
180
|
+
method: string,
|
|
181
|
+
proto: object,
|
|
182
|
+
algorithm: unknown,
|
|
183
|
+
cryptoKey: CryptoKey,
|
|
184
|
+
expected: ExpectedCryptoKey
|
|
185
|
+
): Effect.Effect<K, CryptoError.CryptoError> =>
|
|
186
|
+
Effect.suspend(() => {
|
|
187
|
+
const problem = checkCryptoKey(cryptoKey, expected)
|
|
188
|
+
return problem === undefined
|
|
189
|
+
? Effect.succeed(make<K>(proto, importedAlgorithm(algorithm, cryptoKey), { _tag: "CryptoKey", cryptoKey }))
|
|
190
|
+
: internal.invalidKey(module, method, problem)
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
/** @internal */
|
|
194
|
+
export const exportRaw = async (subtle: SubtleCrypto, cryptoKey: CryptoKey): Promise<Uint8Array> =>
|
|
195
|
+
new Uint8Array(await subtle.exportKey("raw", cryptoKey))
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Exports a key's stored representation as fresh bytes. `CryptoKey`-backed
|
|
199
|
+
* keys are exported on the `WebCrypto` reference with `exportKey`.
|
|
200
|
+
*
|
|
201
|
+
* @internal
|
|
202
|
+
*/
|
|
203
|
+
export const toBytes = (
|
|
204
|
+
module: string,
|
|
205
|
+
key: { readonly algorithm: { readonly name: string } },
|
|
206
|
+
exportKey: (subtle: SubtleCrypto, cryptoKey: CryptoKey) => Promise<Uint8Array>
|
|
207
|
+
): Effect.Effect<Uint8Array, CryptoError.CryptoError> =>
|
|
208
|
+
Effect.suspend(() => {
|
|
209
|
+
const stored = material(key)
|
|
210
|
+
if (stored._tag === "Bytes") return Effect.succeed(copyBytes(stored.bytes))
|
|
211
|
+
if (!stored.cryptoKey.extractable) return internal.notExtractable(module, "toBytes")
|
|
212
|
+
return internal.runWithReference(module, "toBytes", key.algorithm.name, (subtle) =>
|
|
213
|
+
exportKey(subtle, stored.cryptoKey))
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* A per-layer cache of the `CryptoKey`s imported from byte-backed keys.
|
|
218
|
+
*
|
|
219
|
+
* @internal
|
|
220
|
+
*/
|
|
221
|
+
export const makeCache = (
|
|
222
|
+
importKey: (subtle: SubtleCrypto, bytes: Uint8Array, algorithm: any) => Promise<CryptoKey>
|
|
223
|
+
) => {
|
|
224
|
+
const cache = new WeakMap<object, CryptoKey>()
|
|
225
|
+
return async (subtle: SubtleCrypto, key: { readonly algorithm: unknown }): Promise<CryptoKey> => {
|
|
226
|
+
const stored = material(key)
|
|
227
|
+
if (stored._tag === "CryptoKey") return stored.cryptoKey
|
|
228
|
+
let cryptoKey = cache.get(key)
|
|
229
|
+
if (cryptoKey === undefined) {
|
|
230
|
+
cryptoKey = await importKey(subtle, stored.bytes, key.algorithm)
|
|
231
|
+
cache.set(key, cryptoKey)
|
|
232
|
+
}
|
|
233
|
+
return cryptoKey
|
|
234
|
+
}
|
|
235
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MD5 (RFC 1321), vendored from `@noble/hashes`.
|
|
3
|
+
*
|
|
4
|
+
* Upstream: https://github.com/paulmillr/noble-hashes
|
|
5
|
+
* Version: 2.4.0, commit 663c2aeeffc308ac0cded59bd32f7c212adacfc2
|
|
6
|
+
* Files: `src/legacy.ts` (`_MD5`), `src/_md.ts` (`HashMD`, `Chi`), and the
|
|
7
|
+
* helpers it uses from `src/utils.ts` and `src/_u64.ts`.
|
|
8
|
+
*
|
|
9
|
+
* Changes from upstream: merged into one file, removed the `Hash` interface,
|
|
10
|
+
* cloning, input assertions, and `destroy` bookkeeping, and exposed only a
|
|
11
|
+
* one-shot `md5(data)` function. The compression function and padding are
|
|
12
|
+
* unchanged.
|
|
13
|
+
*
|
|
14
|
+
* The MIT License (MIT)
|
|
15
|
+
*
|
|
16
|
+
* Copyright (c) 2022 Paul Miller (https://paulmillr.com)
|
|
17
|
+
*
|
|
18
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
19
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
20
|
+
* in the Software without restriction, including without limitation the rights
|
|
21
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
22
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
23
|
+
* furnished to do so, subject to the following conditions:
|
|
24
|
+
*
|
|
25
|
+
* The above copyright notice and this permission notice shall be included in
|
|
26
|
+
* all copies or substantial portions of the Software.
|
|
27
|
+
*
|
|
28
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
29
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
30
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
31
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
32
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
33
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
34
|
+
* THE SOFTWARE.
|
|
35
|
+
*
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
// utils.ts
|
|
40
|
+
const createView = (arr: Uint8Array): DataView => new DataView(arr.buffer, arr.byteOffset, arr.byteLength)
|
|
41
|
+
const rotl = (word: number, shift: number): number => (word << shift) | ((word >>> (32 - shift)) >>> 0)
|
|
42
|
+
|
|
43
|
+
// _u64.ts
|
|
44
|
+
const setU64FromNum = (view: DataView, byteOffset: number, n: number, isLE: boolean): void => {
|
|
45
|
+
const h = (n / 2 ** 32) | 0
|
|
46
|
+
const l = n >>> 0
|
|
47
|
+
view.setUint32(byteOffset, isLE ? l : h, isLE)
|
|
48
|
+
view.setUint32(byteOffset + 4, isLE ? h : l, isLE)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// _md.ts
|
|
52
|
+
const Chi = (a: number, b: number, c: number): number => (a & b) ^ (~a & c)
|
|
53
|
+
|
|
54
|
+
// legacy.ts
|
|
55
|
+
const p32 = Math.pow(2, 32)
|
|
56
|
+
const K = Array.from({ length: 64 }, (_, i) => Math.floor(p32 * Math.abs(Math.sin(i + 1))))
|
|
57
|
+
const MD5_IV = Uint32Array.from([0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476])
|
|
58
|
+
const MD5_W = new Uint32Array(16)
|
|
59
|
+
const MD5_SHIFTS = (() => {
|
|
60
|
+
const S = [
|
|
61
|
+
[7, 12, 17, 22],
|
|
62
|
+
[5, 9, 14, 20],
|
|
63
|
+
[4, 11, 16, 23],
|
|
64
|
+
[6, 10, 15, 21]
|
|
65
|
+
]
|
|
66
|
+
return Uint8Array.from({ length: 64 }, (_, i) => S[Math.floor(i / 16)][i % 4])
|
|
67
|
+
})()
|
|
68
|
+
|
|
69
|
+
const blockLen = 64
|
|
70
|
+
const outputLen = 16
|
|
71
|
+
const padOffset = 8
|
|
72
|
+
const isLE = true
|
|
73
|
+
|
|
74
|
+
class MD5 {
|
|
75
|
+
private A = MD5_IV[0] | 0
|
|
76
|
+
private B = MD5_IV[1] | 0
|
|
77
|
+
private C = MD5_IV[2] | 0
|
|
78
|
+
private D = MD5_IV[3] | 0
|
|
79
|
+
|
|
80
|
+
private buffer = new Uint8Array(blockLen)
|
|
81
|
+
private view = createView(this.buffer)
|
|
82
|
+
private length = 0
|
|
83
|
+
private pos = 0
|
|
84
|
+
|
|
85
|
+
private get(): [number, number, number, number] {
|
|
86
|
+
const { A, B, C, D } = this
|
|
87
|
+
return [A, B, C, D]
|
|
88
|
+
}
|
|
89
|
+
private set(A: number, B: number, C: number, D: number): void {
|
|
90
|
+
this.A = A | 0
|
|
91
|
+
this.B = B | 0
|
|
92
|
+
this.C = C | 0
|
|
93
|
+
this.D = D | 0
|
|
94
|
+
}
|
|
95
|
+
private process(view: DataView, offset: number): void {
|
|
96
|
+
for (let i = 0; i < 16; i++, offset += 4) MD5_W[i] = view.getUint32(offset, true)
|
|
97
|
+
let { A, B, C, D } = this
|
|
98
|
+
for (let i = 0; i < 64; i++) {
|
|
99
|
+
let F, g
|
|
100
|
+
if (i < 16) {
|
|
101
|
+
F = Chi(B, C, D)
|
|
102
|
+
g = i
|
|
103
|
+
} else if (i < 32) {
|
|
104
|
+
// RFC 1321 round 2 uses G(B,C,D) = (B & D) | (C & ~D), which is `Chi(D, B, C)`.
|
|
105
|
+
F = Chi(D, B, C)
|
|
106
|
+
g = (5 * i + 1) % 16
|
|
107
|
+
} else if (i < 48) {
|
|
108
|
+
F = B ^ C ^ D
|
|
109
|
+
g = (3 * i + 5) % 16
|
|
110
|
+
} else {
|
|
111
|
+
F = C ^ (B | ~D)
|
|
112
|
+
g = (7 * i) % 16
|
|
113
|
+
}
|
|
114
|
+
F = F + A + K[i] + MD5_W[g]
|
|
115
|
+
A = D
|
|
116
|
+
D = C
|
|
117
|
+
C = B
|
|
118
|
+
B = B + rotl(F, MD5_SHIFTS[i])
|
|
119
|
+
}
|
|
120
|
+
A = (A + this.A) | 0
|
|
121
|
+
B = (B + this.B) | 0
|
|
122
|
+
C = (C + this.C) | 0
|
|
123
|
+
D = (D + this.D) | 0
|
|
124
|
+
this.set(A, B, C, D)
|
|
125
|
+
}
|
|
126
|
+
update(data: Uint8Array): this {
|
|
127
|
+
const { view, buffer } = this
|
|
128
|
+
const len = data.length
|
|
129
|
+
for (let pos = 0; pos < len;) {
|
|
130
|
+
const take = Math.min(blockLen - this.pos, len - pos)
|
|
131
|
+
if (take === blockLen) {
|
|
132
|
+
const dataView = createView(data)
|
|
133
|
+
for (; blockLen <= len - pos; pos += blockLen) this.process(dataView, pos)
|
|
134
|
+
continue
|
|
135
|
+
}
|
|
136
|
+
buffer.set(data.subarray(pos, pos + take), this.pos)
|
|
137
|
+
this.pos += take
|
|
138
|
+
pos += take
|
|
139
|
+
if (this.pos === blockLen) {
|
|
140
|
+
this.process(view, 0)
|
|
141
|
+
this.pos = 0
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
this.length += data.length
|
|
145
|
+
return this
|
|
146
|
+
}
|
|
147
|
+
digest(): Uint8Array {
|
|
148
|
+
const { buffer, view } = this
|
|
149
|
+
let { pos } = this
|
|
150
|
+
buffer[pos++] = 0b10000000
|
|
151
|
+
buffer.fill(0, pos)
|
|
152
|
+
if (padOffset > blockLen - pos) {
|
|
153
|
+
this.process(view, 0)
|
|
154
|
+
buffer.fill(0)
|
|
155
|
+
}
|
|
156
|
+
setU64FromNum(view, blockLen - 8, this.length * 8, isLE)
|
|
157
|
+
this.process(view, 0)
|
|
158
|
+
MD5_W.fill(0)
|
|
159
|
+
const out = new Uint8Array(outputLen)
|
|
160
|
+
const oview = createView(out)
|
|
161
|
+
const state = this.get()
|
|
162
|
+
for (let i = 0; i < outputLen / 4; i++) oview.setUint32(4 * i, state[i], isLE)
|
|
163
|
+
this.set(0, 0, 0, 0)
|
|
164
|
+
buffer.fill(0)
|
|
165
|
+
return out
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** @internal */
|
|
170
|
+
export const md5 = (data: Uint8Array): Uint8Array => new MD5().update(data).digest()
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import * as Effect from "../../Effect.ts"
|
|
2
|
+
import * as Predicate from "../../Predicate.ts"
|
|
3
|
+
import * as CryptoError from "../CryptoError.ts"
|
|
4
|
+
import { WebCrypto } from "../WebCrypto.ts"
|
|
5
|
+
|
|
6
|
+
/** @internal */
|
|
7
|
+
export const subtleUnavailable = (): Error =>
|
|
8
|
+
new Error("crypto.subtle is unavailable; browsers expose it only in secure contexts")
|
|
9
|
+
|
|
10
|
+
/** @internal */
|
|
11
|
+
export const fail = (
|
|
12
|
+
module: string,
|
|
13
|
+
method: string,
|
|
14
|
+
reason: CryptoError.CryptoErrorReason
|
|
15
|
+
): Effect.Effect<never, CryptoError.CryptoError> => Effect.fail(new CryptoError.CryptoError({ module, method, reason }))
|
|
16
|
+
|
|
17
|
+
/** @internal */
|
|
18
|
+
export const invalidKey = (module: string, method: string, description: string) =>
|
|
19
|
+
fail(module, method, new CryptoError.InvalidKey({ description }))
|
|
20
|
+
|
|
21
|
+
/** @internal */
|
|
22
|
+
export const notExtractable = (module: string, method: string) =>
|
|
23
|
+
fail(module, method, new CryptoError.NotExtractable({ description: "The CryptoKey is not extractable" }))
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Moves an error raised by another module's function onto `module.method`.
|
|
27
|
+
*
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
export const rehome = (module: string, method: string) => (error: CryptoError.CryptoError) =>
|
|
31
|
+
fail(module, method, error.reason)
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Thrown inside {@link run} to fail with a typed reason instead of a defect,
|
|
35
|
+
* for checks that need the imported `CryptoKey`.
|
|
36
|
+
*
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
export class Failure {
|
|
40
|
+
readonly reason: CryptoError.CryptoErrorReason
|
|
41
|
+
constructor(reason: CryptoError.CryptoErrorReason) {
|
|
42
|
+
this.reason = reason
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** @internal */
|
|
47
|
+
export const isOperationError = (cause: unknown): boolean =>
|
|
48
|
+
Predicate.hasProperty(cause, "name") && cause.name === "OperationError"
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Maps an exception thrown by `crypto.subtle` in `module.layerWebCrypto` to a
|
|
52
|
+
* `CryptoError`.
|
|
53
|
+
*
|
|
54
|
+
* A {@link Failure} carries its own reason. `DataError` and
|
|
55
|
+
* `InvalidAccessError` are `InvalidKey`, and `NotSupportedError` is
|
|
56
|
+
* `Unsupported`, naming the algorithm and the layer. An `OperationError`
|
|
57
|
+
* becomes the reason from `onOperationError`, such as `DecryptionFailed` for a
|
|
58
|
+
* decryption. Any other exception is rethrown, which `Effect.tryPromise` turns
|
|
59
|
+
* into a defect.
|
|
60
|
+
*
|
|
61
|
+
* @internal
|
|
62
|
+
*/
|
|
63
|
+
export const webCryptoError = (
|
|
64
|
+
module: string,
|
|
65
|
+
method: string,
|
|
66
|
+
algorithm: string,
|
|
67
|
+
cause: unknown,
|
|
68
|
+
onOperationError?: () => CryptoError.CryptoErrorReason
|
|
69
|
+
): CryptoError.CryptoError =>
|
|
70
|
+
toCryptoError(module, method, `${module}.layerWebCrypto`, algorithm, cause, onOperationError)
|
|
71
|
+
|
|
72
|
+
const toCryptoError = (
|
|
73
|
+
module: string,
|
|
74
|
+
method: string,
|
|
75
|
+
provider: string,
|
|
76
|
+
algorithm: string,
|
|
77
|
+
cause: unknown,
|
|
78
|
+
onOperationError?: () => CryptoError.CryptoErrorReason
|
|
79
|
+
): CryptoError.CryptoError => {
|
|
80
|
+
const reason = reasonFor(method, provider, algorithm, cause, onOperationError)
|
|
81
|
+
if (reason === undefined) throw cause
|
|
82
|
+
return new CryptoError.CryptoError({ module, method, reason })
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const reasonFor = (
|
|
86
|
+
method: string,
|
|
87
|
+
provider: string,
|
|
88
|
+
algorithm: string,
|
|
89
|
+
cause: unknown,
|
|
90
|
+
onOperationError: (() => CryptoError.CryptoErrorReason) | undefined
|
|
91
|
+
): CryptoError.CryptoErrorReason | undefined => {
|
|
92
|
+
if (cause instanceof Failure) return cause.reason
|
|
93
|
+
switch (Predicate.hasProperty(cause, "name") ? cause.name : undefined) {
|
|
94
|
+
case "DataError":
|
|
95
|
+
return new CryptoError.InvalidKey({ description: "Invalid key data", cause })
|
|
96
|
+
case "InvalidAccessError":
|
|
97
|
+
return new CryptoError.InvalidKey({ description: `The key cannot be used for ${method}`, cause })
|
|
98
|
+
case "NotSupportedError":
|
|
99
|
+
return new CryptoError.Unsupported({ description: `${provider} does not provide ${algorithm}`, cause })
|
|
100
|
+
case "OperationError":
|
|
101
|
+
return onOperationError?.()
|
|
102
|
+
default:
|
|
103
|
+
return undefined
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Runs `f` on the `subtle` of a `Crypto` object in `module.layerWebCrypto`,
|
|
109
|
+
* dying when it is missing, as in an insecure browser context. Exceptions go
|
|
110
|
+
* through `onError`, which defaults to {@link webCryptoError}.
|
|
111
|
+
*
|
|
112
|
+
* @internal
|
|
113
|
+
*/
|
|
114
|
+
export const run = <A>(
|
|
115
|
+
module: string,
|
|
116
|
+
method: string,
|
|
117
|
+
algorithm: string,
|
|
118
|
+
crypto: Crypto | undefined,
|
|
119
|
+
f: (subtle: SubtleCrypto) => Promise<A>,
|
|
120
|
+
onError: (cause: unknown) => CryptoError.CryptoError = (cause) => webCryptoError(module, method, algorithm, cause)
|
|
121
|
+
): Effect.Effect<A, CryptoError.CryptoError> =>
|
|
122
|
+
Effect.suspend(() => {
|
|
123
|
+
const subtle = crypto?.subtle
|
|
124
|
+
if (subtle === undefined) return Effect.die(subtleUnavailable())
|
|
125
|
+
return Effect.tryPromise({ try: () => f(subtle), catch: onError })
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* {@link run} on the `WebCrypto` reference, for the top-level functions that
|
|
130
|
+
* have no layer to read it from. `crypto.subtle` is named as the provider
|
|
131
|
+
* that declined an algorithm.
|
|
132
|
+
*
|
|
133
|
+
* @internal
|
|
134
|
+
*/
|
|
135
|
+
export const runWithReference = <A>(
|
|
136
|
+
module: string,
|
|
137
|
+
method: string,
|
|
138
|
+
algorithm: string,
|
|
139
|
+
f: (subtle: SubtleCrypto) => Promise<A>
|
|
140
|
+
): Effect.Effect<A, CryptoError.CryptoError> =>
|
|
141
|
+
WebCrypto.use((crypto) =>
|
|
142
|
+
run(
|
|
143
|
+
module,
|
|
144
|
+
method,
|
|
145
|
+
algorithm,
|
|
146
|
+
crypto,
|
|
147
|
+
f,
|
|
148
|
+
(cause) => toCryptoError(module, method, "crypto.subtle", algorithm, cause)
|
|
149
|
+
)
|
|
150
|
+
)
|
|
@@ -102,13 +102,16 @@ export const encodePadded: (input: Uint8Array | string) => string = (input) =>
|
|
|
102
102
|
export const decode = (str: string): Result.Result<Uint8Array, EncodingError> => {
|
|
103
103
|
const stripped = str.replace(/[\n\r]/g, "")
|
|
104
104
|
const length = stripped.length
|
|
105
|
-
|
|
105
|
+
const padded = stripped.endsWith("=")
|
|
106
|
+
if (padded ? length % 4 !== 0 : length % 4 === 1) {
|
|
106
107
|
return Result.fail(
|
|
107
108
|
new EncodingError({
|
|
108
109
|
module: "Base64Url",
|
|
109
110
|
kind: "Decode",
|
|
110
111
|
input: stripped,
|
|
111
|
-
message:
|
|
112
|
+
message: padded
|
|
113
|
+
? `Padded length should be a multiple of 4, but is ${length}`
|
|
114
|
+
: `Unpadded length should not be 1 more than a multiple of 4, but is ${length}`
|
|
112
115
|
})
|
|
113
116
|
)
|
|
114
117
|
}
|