@fgv/ts-extras 5.1.0-5 → 5.1.0-50
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/LICENSE +1 -1
- package/README.md +90 -0
- package/dist/index.browser.js +6 -2
- package/dist/index.browser.js.map +1 -0
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -0
- package/dist/packlets/ai-assist/chatRequestBuilders.js +282 -0
- package/dist/packlets/ai-assist/chatRequestBuilders.js.map +1 -0
- package/dist/packlets/ai-assist/{apiClient.js → completionClient.js} +165 -214
- package/dist/packlets/ai-assist/completionClient.js.map +1 -0
- package/dist/packlets/ai-assist/converters.js +47 -3
- package/dist/packlets/ai-assist/converters.js.map +1 -0
- package/dist/packlets/ai-assist/embeddingClient.js +345 -0
- package/dist/packlets/ai-assist/embeddingClient.js.map +1 -0
- package/dist/packlets/ai-assist/endpoint.js +107 -0
- package/dist/packlets/ai-assist/endpoint.js.map +1 -0
- package/dist/packlets/ai-assist/http.js +104 -0
- package/dist/packlets/ai-assist/http.js.map +1 -0
- package/dist/packlets/ai-assist/imageGenerationClient.js +454 -0
- package/dist/packlets/ai-assist/imageGenerationClient.js.map +1 -0
- package/dist/packlets/ai-assist/imageOptionsResolver.js +193 -0
- package/dist/packlets/ai-assist/imageOptionsResolver.js.map +1 -0
- package/dist/packlets/ai-assist/index.js +12 -4
- package/dist/packlets/ai-assist/index.js.map +1 -0
- package/dist/packlets/ai-assist/jsonCompletion.js +93 -0
- package/dist/packlets/ai-assist/jsonCompletion.js.map +1 -0
- package/dist/packlets/ai-assist/jsonResponse.js +423 -0
- package/dist/packlets/ai-assist/jsonResponse.js.map +1 -0
- package/dist/packlets/ai-assist/listModelsClient.js +294 -0
- package/dist/packlets/ai-assist/listModelsClient.js.map +1 -0
- package/dist/packlets/ai-assist/model.js +301 -9
- package/dist/packlets/ai-assist/model.js.map +1 -0
- package/dist/packlets/ai-assist/registry.js +376 -12
- package/dist/packlets/ai-assist/registry.js.map +1 -0
- package/dist/packlets/ai-assist/sseParser.js +123 -0
- package/dist/packlets/ai-assist/sseParser.js.map +1 -0
- package/dist/packlets/ai-assist/streamingAdapters/anthropic.js +376 -0
- package/dist/packlets/ai-assist/streamingAdapters/anthropic.js.map +1 -0
- package/dist/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js +687 -0
- package/dist/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js.map +1 -0
- package/dist/packlets/ai-assist/streamingAdapters/common.js +187 -0
- package/dist/packlets/ai-assist/streamingAdapters/common.js.map +1 -0
- package/dist/packlets/ai-assist/streamingAdapters/gemini.js +208 -0
- package/dist/packlets/ai-assist/streamingAdapters/gemini.js.map +1 -0
- package/dist/packlets/ai-assist/streamingAdapters/openaiChat.js +175 -0
- package/dist/packlets/ai-assist/streamingAdapters/openaiChat.js.map +1 -0
- package/dist/packlets/ai-assist/streamingAdapters/openaiResponses.js +390 -0
- package/dist/packlets/ai-assist/streamingAdapters/openaiResponses.js.map +1 -0
- package/dist/packlets/ai-assist/streamingAdapters/proxy.js +178 -0
- package/dist/packlets/ai-assist/streamingAdapters/proxy.js.map +1 -0
- package/dist/packlets/ai-assist/streamingClient.js +140 -0
- package/dist/packlets/ai-assist/streamingClient.js.map +1 -0
- package/dist/packlets/ai-assist/thinkingOptionsResolver.js +288 -0
- package/dist/packlets/ai-assist/thinkingOptionsResolver.js.map +1 -0
- package/dist/packlets/ai-assist/toolFormats.js +106 -10
- package/dist/packlets/ai-assist/toolFormats.js.map +1 -0
- package/dist/packlets/conversion/converters.js +35 -1
- package/dist/packlets/conversion/converters.js.map +1 -0
- package/dist/packlets/conversion/index.js.map +1 -0
- package/dist/packlets/crypto-utils/constants.js.map +1 -0
- package/dist/packlets/crypto-utils/converters.js +42 -4
- package/dist/packlets/crypto-utils/converters.js.map +1 -0
- package/dist/packlets/crypto-utils/directEncryptionProvider.js.map +1 -0
- package/dist/packlets/crypto-utils/encryptedFile.js +37 -0
- package/dist/packlets/crypto-utils/encryptedFile.js.map +1 -0
- package/dist/packlets/crypto-utils/hpkeProvider.js +355 -0
- package/dist/packlets/crypto-utils/hpkeProvider.js.map +1 -0
- package/dist/packlets/crypto-utils/index.browser.js +13 -2
- package/dist/packlets/crypto-utils/index.browser.js.map +1 -0
- package/dist/packlets/crypto-utils/index.js +9 -1
- package/dist/packlets/crypto-utils/index.js.map +1 -0
- package/dist/packlets/crypto-utils/keyPairAlgorithmParams.js +71 -0
- package/dist/packlets/crypto-utils/keyPairAlgorithmParams.js.map +1 -0
- package/dist/packlets/crypto-utils/keystore/converters.js +111 -16
- package/dist/packlets/crypto-utils/keystore/converters.js.map +1 -0
- package/dist/packlets/crypto-utils/keystore/encryptedFilePrivateKeyStorage.js +287 -0
- package/dist/packlets/crypto-utils/keystore/encryptedFilePrivateKeyStorage.js.map +1 -0
- package/dist/packlets/crypto-utils/keystore/index.browser.js +36 -0
- package/dist/packlets/crypto-utils/keystore/index.browser.js.map +1 -0
- package/dist/packlets/crypto-utils/keystore/index.js +3 -0
- package/dist/packlets/crypto-utils/keystore/index.js.map +1 -0
- package/dist/packlets/crypto-utils/keystore/keyStore.js +872 -119
- package/dist/packlets/crypto-utils/keystore/keyStore.js.map +1 -0
- package/dist/packlets/crypto-utils/keystore/model.js +35 -4
- package/dist/packlets/crypto-utils/keystore/model.js.map +1 -0
- package/dist/packlets/crypto-utils/keystore/privateKeyStorage.js +21 -0
- package/dist/packlets/crypto-utils/keystore/privateKeyStorage.js.map +1 -0
- package/dist/packlets/crypto-utils/model.js +32 -0
- package/dist/packlets/crypto-utils/model.js.map +1 -0
- package/dist/packlets/crypto-utils/nodeCryptoProvider.js +347 -1
- package/dist/packlets/crypto-utils/nodeCryptoProvider.js.map +1 -0
- package/dist/packlets/crypto-utils/seedDerivedKeyPair.js +120 -0
- package/dist/packlets/crypto-utils/seedDerivedKeyPair.js.map +1 -0
- package/dist/packlets/crypto-utils/spkiHelpers.js +284 -0
- package/dist/packlets/crypto-utils/spkiHelpers.js.map +1 -0
- package/dist/packlets/csv/csvFileHelpers.js +0 -14
- package/dist/packlets/csv/csvFileHelpers.js.map +1 -0
- package/dist/packlets/csv/csvHelpers.js +14 -0
- package/dist/packlets/csv/csvHelpers.js.map +1 -0
- package/dist/packlets/csv/index.browser.js +1 -3
- package/dist/packlets/csv/index.browser.js.map +1 -0
- package/dist/packlets/csv/index.js.map +1 -0
- package/dist/packlets/experimental/extendedArray.js.map +1 -0
- package/dist/packlets/experimental/formatter.js.map +1 -0
- package/dist/packlets/experimental/index.js.map +1 -0
- package/dist/packlets/experimental/rangeOf.js.map +1 -0
- package/dist/packlets/hash/index.browser.js.map +1 -0
- package/dist/packlets/hash/index.js.map +1 -0
- package/dist/packlets/hash/index.node.js.map +1 -0
- package/dist/packlets/hash/md5Normalizer.browser.js.map +1 -0
- package/dist/packlets/hash/md5Normalizer.js.map +1 -0
- package/dist/packlets/mustache/index.js.map +1 -0
- package/dist/packlets/mustache/interfaces.js.map +1 -0
- package/dist/packlets/mustache/mustacheTemplate.js +42 -4
- package/dist/packlets/mustache/mustacheTemplate.js.map +1 -0
- package/dist/packlets/record-jar/index.browser.js +1 -3
- package/dist/packlets/record-jar/index.browser.js.map +1 -0
- package/dist/packlets/record-jar/index.js.map +1 -0
- package/dist/packlets/record-jar/recordJarFileHelpers.js +0 -18
- package/dist/packlets/record-jar/recordJarFileHelpers.js.map +1 -0
- package/dist/packlets/record-jar/recordJarHelpers.js +18 -0
- package/dist/packlets/record-jar/recordJarHelpers.js.map +1 -0
- package/dist/packlets/safer-fetch/addressClassification.js +438 -0
- package/dist/packlets/safer-fetch/addressClassification.js.map +1 -0
- package/dist/packlets/safer-fetch/addressPolicy.js +119 -0
- package/dist/packlets/safer-fetch/addressPolicy.js.map +1 -0
- package/dist/packlets/safer-fetch/contentType.js +120 -0
- package/dist/packlets/safer-fetch/contentType.js.map +1 -0
- package/dist/packlets/safer-fetch/deadline.js +254 -0
- package/dist/packlets/safer-fetch/deadline.js.map +1 -0
- package/dist/packlets/safer-fetch/defaults.js +131 -0
- package/dist/packlets/safer-fetch/defaults.js.map +1 -0
- package/dist/packlets/safer-fetch/failureReason.js +21 -0
- package/dist/packlets/safer-fetch/failureReason.js.map +1 -0
- package/dist/packlets/safer-fetch/guards.js +148 -0
- package/dist/packlets/safer-fetch/guards.js.map +1 -0
- package/dist/packlets/safer-fetch/index.browser.js +58 -0
- package/dist/packlets/safer-fetch/index.browser.js.map +1 -0
- package/dist/packlets/safer-fetch/index.js +52 -0
- package/dist/packlets/safer-fetch/index.js.map +1 -0
- package/dist/packlets/safer-fetch/model.js +21 -0
- package/dist/packlets/safer-fetch/model.js.map +1 -0
- package/dist/packlets/safer-fetch/nodeAddressGuard.js +191 -0
- package/dist/packlets/safer-fetch/nodeAddressGuard.js.map +1 -0
- package/dist/packlets/safer-fetch/redirect.js +93 -0
- package/dist/packlets/safer-fetch/redirect.js.map +1 -0
- package/dist/packlets/safer-fetch/retry.js +188 -0
- package/dist/packlets/safer-fetch/retry.js.map +1 -0
- package/dist/packlets/safer-fetch/saferFetch.js +755 -0
- package/dist/packlets/safer-fetch/saferFetch.js.map +1 -0
- package/dist/packlets/safer-fetch/transport.js +50 -0
- package/dist/packlets/safer-fetch/transport.js.map +1 -0
- package/dist/packlets/yaml/converters.js.map +1 -0
- package/dist/packlets/yaml/index.js +1 -0
- package/dist/packlets/yaml/index.js.map +1 -0
- package/dist/packlets/yaml/serializers.js +48 -0
- package/dist/packlets/yaml/serializers.js.map +1 -0
- package/dist/packlets/zip-file-tree/index.js.map +1 -0
- package/dist/packlets/zip-file-tree/zipFileTreeAccessors.js +99 -9
- package/dist/packlets/zip-file-tree/zipFileTreeAccessors.js.map +1 -0
- package/dist/packlets/zip-file-tree/zipFileTreeWriter.js +16 -1
- package/dist/packlets/zip-file-tree/zipFileTreeWriter.js.map +1 -0
- package/dist/ts-extras.d.ts +6648 -553
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/index.browser.d.ts +5 -2
- package/lib/index.browser.d.ts.map +1 -0
- package/lib/index.browser.js +11 -3
- package/lib/index.browser.js.map +1 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +3 -1
- package/lib/index.js.map +1 -0
- package/lib/packlets/ai-assist/chatRequestBuilders.d.ts +149 -0
- package/lib/packlets/ai-assist/chatRequestBuilders.d.ts.map +1 -0
- package/lib/packlets/ai-assist/chatRequestBuilders.js +293 -0
- package/lib/packlets/ai-assist/chatRequestBuilders.js.map +1 -0
- package/lib/packlets/ai-assist/completionClient.d.ts +74 -0
- package/lib/packlets/ai-assist/completionClient.d.ts.map +1 -0
- package/lib/packlets/ai-assist/{apiClient.js → completionClient.js} +164 -213
- package/lib/packlets/ai-assist/completionClient.js.map +1 -0
- package/lib/packlets/ai-assist/converters.d.ts +15 -1
- package/lib/packlets/ai-assist/converters.d.ts.map +1 -0
- package/lib/packlets/ai-assist/converters.js +47 -3
- package/lib/packlets/ai-assist/converters.js.map +1 -0
- package/lib/packlets/ai-assist/embeddingClient.d.ts +69 -0
- package/lib/packlets/ai-assist/embeddingClient.d.ts.map +1 -0
- package/lib/packlets/ai-assist/embeddingClient.js +349 -0
- package/lib/packlets/ai-assist/embeddingClient.js.map +1 -0
- package/lib/packlets/ai-assist/endpoint.d.ts +49 -0
- package/lib/packlets/ai-assist/endpoint.d.ts.map +1 -0
- package/lib/packlets/ai-assist/endpoint.js +113 -0
- package/lib/packlets/ai-assist/endpoint.js.map +1 -0
- package/lib/packlets/ai-assist/http.d.ts +34 -0
- package/lib/packlets/ai-assist/http.d.ts.map +1 -0
- package/lib/packlets/ai-assist/http.js +109 -0
- package/lib/packlets/ai-assist/http.js.map +1 -0
- package/lib/packlets/ai-assist/imageGenerationClient.d.ts +46 -0
- package/lib/packlets/ai-assist/imageGenerationClient.d.ts.map +1 -0
- package/lib/packlets/ai-assist/imageGenerationClient.js +458 -0
- package/lib/packlets/ai-assist/imageGenerationClient.js.map +1 -0
- package/lib/packlets/ai-assist/imageOptionsResolver.d.ts +66 -0
- package/lib/packlets/ai-assist/imageOptionsResolver.d.ts.map +1 -0
- package/lib/packlets/ai-assist/imageOptionsResolver.js +197 -0
- package/lib/packlets/ai-assist/imageOptionsResolver.js.map +1 -0
- package/lib/packlets/ai-assist/index.d.ts +12 -4
- package/lib/packlets/ai-assist/index.d.ts.map +1 -0
- package/lib/packlets/ai-assist/index.js +47 -4
- package/lib/packlets/ai-assist/index.js.map +1 -0
- package/lib/packlets/ai-assist/jsonCompletion.d.ts +93 -0
- package/lib/packlets/ai-assist/jsonCompletion.d.ts.map +1 -0
- package/lib/packlets/ai-assist/jsonCompletion.js +97 -0
- package/lib/packlets/ai-assist/jsonCompletion.js.map +1 -0
- package/lib/packlets/ai-assist/jsonResponse.d.ts +194 -0
- package/lib/packlets/ai-assist/jsonResponse.d.ts.map +1 -0
- package/lib/packlets/ai-assist/jsonResponse.js +429 -0
- package/lib/packlets/ai-assist/jsonResponse.js.map +1 -0
- package/lib/packlets/ai-assist/listModelsClient.d.ts +46 -0
- package/lib/packlets/ai-assist/listModelsClient.d.ts.map +1 -0
- package/lib/packlets/ai-assist/listModelsClient.js +298 -0
- package/lib/packlets/ai-assist/listModelsClient.js.map +1 -0
- package/lib/packlets/ai-assist/model.d.ts +1346 -12
- package/lib/packlets/ai-assist/model.d.ts.map +1 -0
- package/lib/packlets/ai-assist/model.js +309 -10
- package/lib/packlets/ai-assist/model.js.map +1 -0
- package/lib/packlets/ai-assist/registry.d.ts +76 -1
- package/lib/packlets/ai-assist/registry.d.ts.map +1 -0
- package/lib/packlets/ai-assist/registry.js +381 -13
- package/lib/packlets/ai-assist/registry.js.map +1 -0
- package/lib/packlets/ai-assist/sseParser.d.ts +45 -0
- package/lib/packlets/ai-assist/sseParser.d.ts.map +1 -0
- package/lib/packlets/ai-assist/sseParser.js +128 -0
- package/lib/packlets/ai-assist/sseParser.js.map +1 -0
- package/lib/packlets/ai-assist/streamingAdapters/anthropic.d.ts +72 -0
- package/lib/packlets/ai-assist/streamingAdapters/anthropic.d.ts.map +1 -0
- package/lib/packlets/ai-assist/streamingAdapters/anthropic.js +379 -0
- package/lib/packlets/ai-assist/streamingAdapters/anthropic.js.map +1 -0
- package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.d.ts +269 -0
- package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.d.ts.map +1 -0
- package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js +694 -0
- package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js.map +1 -0
- package/lib/packlets/ai-assist/streamingAdapters/common.d.ts +163 -0
- package/lib/packlets/ai-assist/streamingAdapters/common.d.ts.map +1 -0
- package/lib/packlets/ai-assist/streamingAdapters/common.js +193 -0
- package/lib/packlets/ai-assist/streamingAdapters/common.js.map +1 -0
- package/lib/packlets/ai-assist/streamingAdapters/gemini.d.ts +43 -0
- package/lib/packlets/ai-assist/streamingAdapters/gemini.d.ts.map +1 -0
- package/lib/packlets/ai-assist/streamingAdapters/gemini.js +211 -0
- package/lib/packlets/ai-assist/streamingAdapters/gemini.js.map +1 -0
- package/lib/packlets/ai-assist/streamingAdapters/openaiChat.d.ts +19 -0
- package/lib/packlets/ai-assist/streamingAdapters/openaiChat.d.ts.map +1 -0
- package/lib/packlets/ai-assist/streamingAdapters/openaiChat.js +178 -0
- package/lib/packlets/ai-assist/streamingAdapters/openaiChat.js.map +1 -0
- package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.d.ts +33 -0
- package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.d.ts.map +1 -0
- package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.js +393 -0
- package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.js.map +1 -0
- package/lib/packlets/ai-assist/streamingAdapters/proxy.d.ts +34 -0
- package/lib/packlets/ai-assist/streamingAdapters/proxy.d.ts.map +1 -0
- package/lib/packlets/ai-assist/streamingAdapters/proxy.js +181 -0
- package/lib/packlets/ai-assist/streamingAdapters/proxy.js.map +1 -0
- package/lib/packlets/ai-assist/streamingClient.d.ts +50 -0
- package/lib/packlets/ai-assist/streamingClient.d.ts.map +1 -0
- package/lib/packlets/ai-assist/streamingClient.js +146 -0
- package/lib/packlets/ai-assist/streamingClient.js.map +1 -0
- package/lib/packlets/ai-assist/thinkingOptionsResolver.d.ts +87 -0
- package/lib/packlets/ai-assist/thinkingOptionsResolver.d.ts.map +1 -0
- package/lib/packlets/ai-assist/thinkingOptionsResolver.js +294 -0
- package/lib/packlets/ai-assist/thinkingOptionsResolver.js.map +1 -0
- package/lib/packlets/ai-assist/toolFormats.d.ts +40 -9
- package/lib/packlets/ai-assist/toolFormats.d.ts.map +1 -0
- package/lib/packlets/ai-assist/toolFormats.js +107 -10
- package/lib/packlets/ai-assist/toolFormats.js.map +1 -0
- package/lib/packlets/conversion/converters.d.ts +8 -1
- package/lib/packlets/conversion/converters.d.ts.map +1 -0
- package/lib/packlets/conversion/converters.js +36 -2
- package/lib/packlets/conversion/converters.js.map +1 -0
- package/lib/packlets/conversion/index.d.ts.map +1 -0
- package/lib/packlets/conversion/index.js.map +1 -0
- package/lib/packlets/crypto-utils/constants.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/constants.js.map +1 -0
- package/lib/packlets/crypto-utils/converters.d.ts +20 -1
- package/lib/packlets/crypto-utils/converters.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/converters.js +43 -5
- package/lib/packlets/crypto-utils/converters.js.map +1 -0
- package/lib/packlets/crypto-utils/directEncryptionProvider.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/directEncryptionProvider.js.map +1 -0
- package/lib/packlets/crypto-utils/encryptedFile.d.ts +25 -0
- package/lib/packlets/crypto-utils/encryptedFile.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/encryptedFile.js +38 -0
- package/lib/packlets/crypto-utils/encryptedFile.js.map +1 -0
- package/lib/packlets/crypto-utils/hpkeProvider.d.ts +150 -0
- package/lib/packlets/crypto-utils/hpkeProvider.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/hpkeProvider.js +359 -0
- package/lib/packlets/crypto-utils/hpkeProvider.js.map +1 -0
- package/lib/packlets/crypto-utils/index.browser.d.ts +5 -1
- package/lib/packlets/crypto-utils/index.browser.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/index.browser.js +28 -3
- package/lib/packlets/crypto-utils/index.browser.js.map +1 -0
- package/lib/packlets/crypto-utils/index.d.ts +5 -1
- package/lib/packlets/crypto-utils/index.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/index.js +24 -1
- package/lib/packlets/crypto-utils/index.js.map +1 -0
- package/lib/packlets/crypto-utils/keyPairAlgorithmParams.d.ts +54 -0
- package/lib/packlets/crypto-utils/keyPairAlgorithmParams.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/keyPairAlgorithmParams.js +74 -0
- package/lib/packlets/crypto-utils/keyPairAlgorithmParams.js.map +1 -0
- package/lib/packlets/crypto-utils/keystore/converters.d.ts +68 -6
- package/lib/packlets/crypto-utils/keystore/converters.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/keystore/converters.js +109 -14
- package/lib/packlets/crypto-utils/keystore/converters.js.map +1 -0
- package/lib/packlets/crypto-utils/keystore/encryptedFilePrivateKeyStorage.d.ts +148 -0
- package/lib/packlets/crypto-utils/keystore/encryptedFilePrivateKeyStorage.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/keystore/encryptedFilePrivateKeyStorage.js +324 -0
- package/lib/packlets/crypto-utils/keystore/encryptedFilePrivateKeyStorage.js.map +1 -0
- package/lib/packlets/crypto-utils/keystore/index.browser.d.ts +10 -0
- package/lib/packlets/crypto-utils/keystore/index.browser.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/keystore/index.browser.js +76 -0
- package/lib/packlets/crypto-utils/keystore/index.browser.js.map +1 -0
- package/lib/packlets/crypto-utils/keystore/index.d.ts +2 -0
- package/lib/packlets/crypto-utils/keystore/index.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/keystore/index.js +5 -1
- package/lib/packlets/crypto-utils/keystore/index.js.map +1 -0
- package/lib/packlets/crypto-utils/keystore/keyStore.d.ts +314 -13
- package/lib/packlets/crypto-utils/keystore/keyStore.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/keystore/keyStore.js +877 -124
- package/lib/packlets/crypto-utils/keystore/keyStore.js.map +1 -0
- package/lib/packlets/crypto-utils/keystore/model.d.ts +404 -21
- package/lib/packlets/crypto-utils/keystore/model.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/keystore/model.js +37 -5
- package/lib/packlets/crypto-utils/keystore/model.js.map +1 -0
- package/lib/packlets/crypto-utils/keystore/privateKeyStorage.d.ts +53 -0
- package/lib/packlets/crypto-utils/keystore/privateKeyStorage.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/keystore/privateKeyStorage.js +22 -0
- package/lib/packlets/crypto-utils/keystore/privateKeyStorage.js.map +1 -0
- package/lib/packlets/crypto-utils/model.d.ts +518 -10
- package/lib/packlets/crypto-utils/model.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/model.js +33 -1
- package/lib/packlets/crypto-utils/model.js.map +1 -0
- package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts +142 -2
- package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/nodeCryptoProvider.js +346 -0
- package/lib/packlets/crypto-utils/nodeCryptoProvider.js.map +1 -0
- package/lib/packlets/crypto-utils/seedDerivedKeyPair.d.ts +42 -0
- package/lib/packlets/crypto-utils/seedDerivedKeyPair.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/seedDerivedKeyPair.js +123 -0
- package/lib/packlets/crypto-utils/seedDerivedKeyPair.js.map +1 -0
- package/lib/packlets/crypto-utils/spkiHelpers.d.ts +151 -0
- package/lib/packlets/crypto-utils/spkiHelpers.d.ts.map +1 -0
- package/lib/packlets/crypto-utils/spkiHelpers.js +297 -0
- package/lib/packlets/crypto-utils/spkiHelpers.js.map +1 -0
- package/lib/packlets/csv/csvFileHelpers.d.ts +0 -10
- package/lib/packlets/csv/csvFileHelpers.d.ts.map +1 -0
- package/lib/packlets/csv/csvFileHelpers.js +0 -15
- package/lib/packlets/csv/csvFileHelpers.js.map +1 -0
- package/lib/packlets/csv/csvHelpers.d.ts +10 -0
- package/lib/packlets/csv/csvHelpers.d.ts.map +1 -0
- package/lib/packlets/csv/csvHelpers.js +15 -0
- package/lib/packlets/csv/csvHelpers.js.map +1 -0
- package/lib/packlets/csv/index.browser.d.ts +0 -1
- package/lib/packlets/csv/index.browser.d.ts.map +1 -0
- package/lib/packlets/csv/index.browser.js +1 -5
- package/lib/packlets/csv/index.browser.js.map +1 -0
- package/lib/packlets/csv/index.d.ts.map +1 -0
- package/lib/packlets/csv/index.js.map +1 -0
- package/lib/packlets/experimental/extendedArray.d.ts.map +1 -0
- package/lib/packlets/experimental/extendedArray.js.map +1 -0
- package/lib/packlets/experimental/formatter.d.ts.map +1 -0
- package/lib/packlets/experimental/formatter.js.map +1 -0
- package/lib/packlets/experimental/index.d.ts.map +1 -0
- package/lib/packlets/experimental/index.js.map +1 -0
- package/lib/packlets/experimental/rangeOf.d.ts.map +1 -0
- package/lib/packlets/experimental/rangeOf.js.map +1 -0
- package/lib/packlets/hash/index.browser.d.ts.map +1 -0
- package/lib/packlets/hash/index.browser.js.map +1 -0
- package/lib/packlets/hash/index.d.ts.map +1 -0
- package/lib/packlets/hash/index.js.map +1 -0
- package/lib/packlets/hash/index.node.d.ts.map +1 -0
- package/lib/packlets/hash/index.node.js.map +1 -0
- package/lib/packlets/hash/md5Normalizer.browser.d.ts.map +1 -0
- package/lib/packlets/hash/md5Normalizer.browser.js.map +1 -0
- package/lib/packlets/hash/md5Normalizer.d.ts.map +1 -0
- package/lib/packlets/hash/md5Normalizer.js.map +1 -0
- package/lib/packlets/mustache/index.d.ts +1 -1
- package/lib/packlets/mustache/index.d.ts.map +1 -0
- package/lib/packlets/mustache/index.js.map +1 -0
- package/lib/packlets/mustache/interfaces.d.ts +34 -0
- package/lib/packlets/mustache/interfaces.d.ts.map +1 -0
- package/lib/packlets/mustache/interfaces.js.map +1 -0
- package/lib/packlets/mustache/mustacheTemplate.d.ts +2 -0
- package/lib/packlets/mustache/mustacheTemplate.d.ts.map +1 -0
- package/lib/packlets/mustache/mustacheTemplate.js +42 -4
- package/lib/packlets/mustache/mustacheTemplate.js.map +1 -0
- package/lib/packlets/record-jar/index.browser.d.ts +0 -1
- package/lib/packlets/record-jar/index.browser.d.ts.map +1 -0
- package/lib/packlets/record-jar/index.browser.js +1 -5
- package/lib/packlets/record-jar/index.browser.js.map +1 -0
- package/lib/packlets/record-jar/index.d.ts.map +1 -0
- package/lib/packlets/record-jar/index.js.map +1 -0
- package/lib/packlets/record-jar/recordJarFileHelpers.d.ts +0 -11
- package/lib/packlets/record-jar/recordJarFileHelpers.d.ts.map +1 -0
- package/lib/packlets/record-jar/recordJarFileHelpers.js +0 -19
- package/lib/packlets/record-jar/recordJarFileHelpers.js.map +1 -0
- package/lib/packlets/record-jar/recordJarHelpers.d.ts +11 -0
- package/lib/packlets/record-jar/recordJarHelpers.d.ts.map +1 -0
- package/lib/packlets/record-jar/recordJarHelpers.js +19 -0
- package/lib/packlets/record-jar/recordJarHelpers.js.map +1 -0
- package/lib/packlets/safer-fetch/addressClassification.d.ts +144 -0
- package/lib/packlets/safer-fetch/addressClassification.d.ts.map +1 -0
- package/lib/packlets/safer-fetch/addressClassification.js +441 -0
- package/lib/packlets/safer-fetch/addressClassification.js.map +1 -0
- package/lib/packlets/safer-fetch/addressPolicy.d.ts +113 -0
- package/lib/packlets/safer-fetch/addressPolicy.d.ts.map +1 -0
- package/lib/packlets/safer-fetch/addressPolicy.js +123 -0
- package/lib/packlets/safer-fetch/addressPolicy.js.map +1 -0
- package/lib/packlets/safer-fetch/contentType.d.ts +51 -0
- package/lib/packlets/safer-fetch/contentType.d.ts.map +1 -0
- package/lib/packlets/safer-fetch/contentType.js +127 -0
- package/lib/packlets/safer-fetch/contentType.js.map +1 -0
- package/lib/packlets/safer-fetch/deadline.d.ts +138 -0
- package/lib/packlets/safer-fetch/deadline.d.ts.map +1 -0
- package/lib/packlets/safer-fetch/deadline.js +258 -0
- package/lib/packlets/safer-fetch/deadline.js.map +1 -0
- package/lib/packlets/safer-fetch/defaults.d.ts +108 -0
- package/lib/packlets/safer-fetch/defaults.d.ts.map +1 -0
- package/lib/packlets/safer-fetch/defaults.js +134 -0
- package/lib/packlets/safer-fetch/defaults.js.map +1 -0
- package/lib/packlets/safer-fetch/failureReason.d.ts +148 -0
- package/lib/packlets/safer-fetch/failureReason.d.ts.map +1 -0
- package/lib/packlets/safer-fetch/failureReason.js +22 -0
- package/lib/packlets/safer-fetch/failureReason.js.map +1 -0
- package/lib/packlets/safer-fetch/guards.d.ts +62 -0
- package/lib/packlets/safer-fetch/guards.d.ts.map +1 -0
- package/lib/packlets/safer-fetch/guards.js +153 -0
- package/lib/packlets/safer-fetch/guards.js.map +1 -0
- package/lib/packlets/safer-fetch/index.browser.d.ts +33 -0
- package/lib/packlets/safer-fetch/index.browser.d.ts.map +1 -0
- package/lib/packlets/safer-fetch/index.browser.js +82 -0
- package/lib/packlets/safer-fetch/index.browser.js.map +1 -0
- package/lib/packlets/safer-fetch/index.d.ts +27 -0
- package/lib/packlets/safer-fetch/index.d.ts.map +1 -0
- package/lib/packlets/safer-fetch/index.js +78 -0
- package/lib/packlets/safer-fetch/index.js.map +1 -0
- package/lib/packlets/safer-fetch/model.d.ts +373 -0
- package/lib/packlets/safer-fetch/model.d.ts.map +1 -0
- package/lib/packlets/safer-fetch/model.js +22 -0
- package/lib/packlets/safer-fetch/model.js.map +1 -0
- package/lib/packlets/safer-fetch/nodeAddressGuard.d.ts +129 -0
- package/lib/packlets/safer-fetch/nodeAddressGuard.d.ts.map +1 -0
- package/lib/packlets/safer-fetch/nodeAddressGuard.js +196 -0
- package/lib/packlets/safer-fetch/nodeAddressGuard.js.map +1 -0
- package/lib/packlets/safer-fetch/redirect.d.ts +62 -0
- package/lib/packlets/safer-fetch/redirect.d.ts.map +1 -0
- package/lib/packlets/safer-fetch/redirect.js +98 -0
- package/lib/packlets/safer-fetch/redirect.js.map +1 -0
- package/lib/packlets/safer-fetch/retry.d.ts +162 -0
- package/lib/packlets/safer-fetch/retry.d.ts.map +1 -0
- package/lib/packlets/safer-fetch/retry.js +197 -0
- package/lib/packlets/safer-fetch/retry.js.map +1 -0
- package/lib/packlets/safer-fetch/saferFetch.d.ts +108 -0
- package/lib/packlets/safer-fetch/saferFetch.d.ts.map +1 -0
- package/lib/packlets/safer-fetch/saferFetch.js +760 -0
- package/lib/packlets/safer-fetch/saferFetch.js.map +1 -0
- package/lib/packlets/safer-fetch/transport.d.ts +18 -0
- package/lib/packlets/safer-fetch/transport.d.ts.map +1 -0
- package/lib/packlets/safer-fetch/transport.js +53 -0
- package/lib/packlets/safer-fetch/transport.js.map +1 -0
- package/lib/packlets/yaml/converters.d.ts.map +1 -0
- package/lib/packlets/yaml/converters.js.map +1 -0
- package/lib/packlets/yaml/index.d.ts +1 -0
- package/lib/packlets/yaml/index.d.ts.map +1 -0
- package/lib/packlets/yaml/index.js +1 -0
- package/lib/packlets/yaml/index.js.map +1 -0
- package/lib/packlets/yaml/serializers.d.ts +45 -0
- package/lib/packlets/yaml/serializers.d.ts.map +1 -0
- package/lib/packlets/yaml/serializers.js +84 -0
- package/lib/packlets/yaml/serializers.js.map +1 -0
- package/lib/packlets/zip-file-tree/index.d.ts.map +1 -0
- package/lib/packlets/zip-file-tree/index.js.map +1 -0
- package/lib/packlets/zip-file-tree/zipFileTreeAccessors.d.ts +84 -8
- package/lib/packlets/zip-file-tree/zipFileTreeAccessors.d.ts.map +1 -0
- package/lib/packlets/zip-file-tree/zipFileTreeAccessors.js +99 -9
- package/lib/packlets/zip-file-tree/zipFileTreeAccessors.js.map +1 -0
- package/lib/packlets/zip-file-tree/zipFileTreeWriter.d.ts +26 -1
- package/lib/packlets/zip-file-tree/zipFileTreeWriter.d.ts.map +1 -0
- package/lib/packlets/zip-file-tree/zipFileTreeWriter.js +17 -1
- package/lib/packlets/zip-file-tree/zipFileTreeWriter.js.map +1 -0
- package/package.json +30 -15
- package/lib/packlets/ai-assist/apiClient.d.ts +0 -60
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saferFetch.js","sourceRoot":"","sources":["../../../src/packlets/safer-fetch/saferFetch.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport {\n captureAsyncResult,\n captureResult,\n failWithDetail,\n Logging,\n succeed,\n succeedWithDetail,\n type Converter,\n type DetailedFailure,\n type DetailedResult,\n type Result,\n type Validator\n} from '@fgv/ts-utils';\nimport { Converters as JsonBaseConverters, type JsonValue } from '@fgv/ts-json-base';\n\nimport { parseCharset, parseContentLength } from './contentType';\nimport { DeadlineWatch, type DeadlineStopCause } from './deadline';\nimport {\n DEFAULT_HEADERS_TIMEOUT_MS,\n DEFAULT_MAX_REDIRECTS,\n DEFAULT_MAX_RESPONSE_BYTES,\n DEFAULT_TIMEOUT_MS,\n REDIRECT_STATUSES,\n SUPPORTED_SCHEMES\n} from './defaults';\nimport type { FetchFailureReason } from './failureReason';\nimport { resolveGuards } from './guards';\nimport {\n computeRetryDelayMs,\n honorsRetryAfter,\n isRetryableFailure,\n isRetryableMethod,\n parseRetryAfterMs,\n resolveRetryPolicy,\n type IResolvedRetryPolicy\n} from './retry';\nimport type {\n IGuardVerdict,\n IRequestHop,\n IResolvedGuards,\n ISaferFetchOptions,\n ISaferFetchRequest,\n ISaferFetchResponse,\n ISaferFetchResponseHead,\n SaferFetchMethod,\n SaferFetchRedirectPolicy\n} from './model';\nimport { resolveLocation, rewriteForRedirect, sensitiveHeaderSet } from './redirect';\nimport { platformFetchTransport } from './transport';\n\n/** Every entry point's carrier: a value, or a machine-readable reason it failed. */\ntype Outcome<T> = DetailedResult<T, FetchFailureReason>;\n\n/**\n * The raw outcome of a call, before the body bytes are interpreted as bytes, text, or JSON.\n * @internal\n */\ninterface IRawOutcome {\n readonly bytes: Uint8Array;\n readonly head: ISaferFetchResponseHead;\n readonly urlChain: ReadonlyArray<string>;\n}\n\n/** Resolved, validated per-call settings. Every field concrete from here down. */\ninterface IResolvedCallOptions {\n readonly method: SaferFetchMethod;\n readonly headers: Record<string, string>;\n readonly body: string | Uint8Array | undefined;\n readonly timeoutMs: number;\n readonly headersTimeoutMs: number;\n readonly maxResponseBytes: number;\n readonly redirectPolicy: SaferFetchRedirectPolicy;\n readonly maxRedirects: number;\n /** Lowercased; the always-stripped three unioned with the caller's additions. */\n readonly sensitiveHeaders: ReadonlySet<string>;\n /** Never absent once resolved: an omitted `retry` option resolves to zero attempts. */\n readonly retry: IResolvedRetryPolicy;\n readonly logger: Logging.ILogger;\n}\n\n/**\n * Per-attempt out-channel for scheduling information the failure taxonomy deliberately does not\n * carry.\n *\n * @remarks\n * `Retry-After` is advice to this process about when to come back, not a fact about the response\n * — and it is chosen by a server this threat model treats as potentially hostile, so it does not\n * belong on a `FetchFailureReason` that callers are invited to log and map. Carrying it beside\n * the failure instead of on it keeps the taxonomy's surface unchanged.\n *\n * A fresh instance is created per attempt, so a stale header from the attempt before cannot\n * schedule the attempt after.\n */\ninterface IAttemptNotes {\n /** Raw `Retry-After` header of the response that failed, when one was sent. */\n retryAfter?: string;\n}\n\n/**\n * A hop the address guard has cleared: the URL that will actually be requested, and the address\n * the guard requires the connection to be pinned to, if any.\n */\ninterface IClearedHop {\n readonly url: URL;\n readonly pinnedAddress: string | undefined;\n}\n\n/**\n * A hop that has already been requested and redirected away from.\n *\n * @remarks\n * Narrows `IRequestHop.status` from optional to required. A completed hop always has one — it\n * is the redirect status that produced its successor — and typing it as present is what lets\n * loop detection name that status without inventing a fallback for a case that cannot occur.\n */\ninterface ICompletedHop extends IRequestHop {\n readonly status: number;\n}\n\n/**\n * What one attempt produced: either the response this call was after, or a redirect to follow.\n *\n * @remarks\n * A discriminated union rather than a sentinel because the redirect branch carries fields the\n * final branch does not have and vice versa — and because the alternative, letting `_receive`\n * decide whether to recurse, would put the hop loop inside the response-handling path where the\n * hop cap and the credential rule are much harder to see.\n */\ntype AttemptOutcome =\n | { readonly kind: 'final'; readonly bytes: Uint8Array; readonly head: ISaferFetchResponseHead }\n | { readonly kind: 'redirect'; readonly status: number; readonly location: string };\n\n/** One completed attempt, with the URL that was actually requested. */\ninterface IAttempt {\n /**\n * The URL the transport was given — the address guard's cleared, possibly normalized URL,\n * not necessarily the spelling the caller or a `Location` header used. This is what a relative\n * `Location` resolves against, and what lands in `urlChain`.\n */\n readonly url: URL;\n readonly connectedAddress: string | undefined;\n readonly outcome: AttemptOutcome;\n}\n\nconst METHODS_WITHOUT_BODY: ReadonlyArray<SaferFetchMethod> = ['GET', 'HEAD'];\n\nconst REDIRECT_POLICIES: ReadonlyArray<SaferFetchRedirectPolicy> = ['reject', 'validate-each-hop'];\n\nfunction _succeed<T>(value: T): Outcome<T> {\n return succeedWithDetail<T, FetchFailureReason>(value);\n}\n\nfunction _fail<T>(detail: FetchFailureReason, message: string): Outcome<T> {\n return failWithDetail<T, FetchFailureReason>(message, detail);\n}\n\n/** Re-types a failure for the next stage without re-deriving its message or detail. */\nfunction _propagate<TFrom, TTo>(from: DetailedFailure<TFrom, FetchFailureReason>): Outcome<TTo> {\n return failWithDetail<TTo, FetchFailureReason>(from.message, from.detail);\n}\n\nfunction _unknown<T>(message: string): Outcome<T> {\n return _fail<T>({ kind: 'unknown', detail: message }, message);\n}\n\n/** The wrapping that every escaped-exception path reports, defined once so the two agree exactly. */\nfunction _unexpected<T>(message: string): Outcome<T> {\n return _unknown<T>(`saferFetch: unexpected error: ${message}`);\n}\n\n/**\n * Restores the taxonomy's invariant that **every** failure leaving this module carries a\n * `FetchFailureReason`.\n *\n * @remarks\n * Only one thing can produce a detail-less failure: a bug inside this module that throws or\n * rejects somewhere a `thenOnSuccess` callback catches it. `AsyncDetailedResult` converts such a\n * throw to a `DetailedFailure` with `detail: undefined` — correctly, since a thrown error supplies\n * no reason and inventing one would be worse — but that is a *chaining* primitive's contract, not\n * this module's.\n *\n * Before the chaining pass those throws propagated as real rejections all the way to\n * {@link _execute}'s `captureAsyncResult` and were reported as `'unknown'`. Catching them earlier\n * must not change what the caller sees, so the same wrapping is reapplied here. Without this a\n * caller switching on `detail.kind` — the documented way to consume this API — would fault on\n * `undefined`.\n */\nfunction _withReason<T>(outcome: Outcome<T>): Outcome<T> {\n return outcome.isFailure() && outcome.detail === undefined ? _unexpected<T>(outcome.message) : outcome;\n}\n\nfunction _blocked<T>(seam: string, url: URL, hop: number, guard: string, detail: string): Outcome<T> {\n return _fail<T>(\n { kind: 'blocked-by-guard', url: url.toString(), hop, guard, detail },\n `${seam} guard \"${guard}\" rejected ${url.toString()} at hop ${hop}: ${detail}`\n );\n}\n\n/**\n * Awaits a guard or transport call, converting a thrown error or rejected promise into a\n * `Failure` so a misbehaving implementation cannot escape the taxonomy as an exception.\n */\nasync function _capture<T>(fn: () => Promise<Result<T>>): Promise<Result<T>> {\n return captureAsyncResult(fn).onSuccess((inner) => inner);\n}\n\n/**\n * Runs a guard or transport call against the deadlines and folds all three outcomes — stopped,\n * refused, cleared — into one `DetailedResult` the caller can chain from.\n *\n * @remarks\n * Exists so the request path reads as a chain rather than as five copies of the same\n * stopped-then-failed ladder. The taxonomy mapping stays per-site, because it genuinely differs\n * per site: an address guard's refusal is `'blocked-by-guard'`, a transport's is `'network'`,\n * and a content-type guard's is `'unsupported-content-type'`.\n *\n * **A stop is checked first and is never re-derived afterwards.** A stop resolves every\n * in-flight race the instant it fires, so reaching the failure branch means the work settled\n * *before* the call gave up — and relabelling that as a timeout because the deadline expired a\n * microsecond later would be the taxonomy lying about which came first.\n *\n * @param onAbandon - Released whenever the value will not be used — on a stop and on a refusal\n * alike. In practice this is the response body: leaving one unconsumed holds the connection\n * open for a call that has already failed.\n */\nasync function _raced<T>(\n watch: DeadlineWatch,\n work: () => Promise<Result<T>>,\n toFailure: (message: string) => Outcome<T>,\n onAbandon?: () => void\n): Promise<Outcome<T>> {\n const race = await watch.race(_capture(work));\n if (race.stopped) {\n onAbandon?.();\n return _stopped<T>(watch, race.cause);\n }\n if (race.value.isFailure()) {\n onAbandon?.();\n return toFailure(race.value.message);\n }\n return _succeed(race.value.value);\n}\n\nfunction _stopMessage(cause: DeadlineStopCause): string {\n return cause === 'caller-aborted' ? 'request aborted by caller.' : `request timed out (${cause}).`;\n}\n\nfunction _stopped<T>(watch: DeadlineWatch, cause: DeadlineStopCause): Outcome<T> {\n return _fail<T>(watch.toFailureReason(cause), _stopMessage(cause));\n}\n\n/**\n * Rejects any scheme this primitive will never request.\n *\n * `file:`, `data:`, `blob:`, `ftp:`, `gopher:` and `ws:` are refused here, in the core, because\n * none is a legitimate network fetch and each is a standard SSRF payload. Choosing between\n * `http:` and `https:`, and deciding which ports are acceptable, is the address guard's job —\n * which is why the core does not narrow further, and why `allowInsecureHttp` can exist there.\n */\nfunction _checkScheme(url: URL): Outcome<URL> {\n if (!SUPPORTED_SCHEMES.includes(url.protocol)) {\n const detail = `scheme \"${url.protocol}\" is not supported (expected ${SUPPORTED_SCHEMES.join(' or ')})`;\n return _fail<URL>({ kind: 'invalid-url', url: url.toString(), detail }, `invalid URL: ${detail}`);\n }\n return _succeed(url);\n}\n\nfunction _parseUrl(url: string | URL): Outcome<URL> {\n const text = String(url);\n const parsed = captureResult(() => new URL(text));\n if (parsed.isFailure()) {\n return _fail<URL>(\n { kind: 'invalid-url', url: text, detail: parsed.message },\n `invalid URL \"${text}\": ${parsed.message}`\n );\n }\n return _checkScheme(parsed.value);\n}\n\nfunction _lowercaseHeaders(headers: Readonly<Record<string, string>>): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [name, value] of Object.entries(headers)) {\n result[name.toLowerCase()] = value;\n }\n return result;\n}\n\nfunction _readHeaders(response: Response): Record<string, string> {\n const headers: Record<string, string> = {};\n response.headers.forEach((value: string, name: string) => {\n headers[name.toLowerCase()] = value;\n });\n return headers;\n}\n\n/** Releases a response body that will not be read, so the socket is not held open. */\nfunction _discardBody(response: Response): void {\n const body = response.body ?? undefined;\n if (body !== undefined) {\n // Best-effort and deliberately not awaited: the failure is already decided, and a cancel\n // that rejects (an already-errored stream) must not replace it.\n body.cancel().catch(() => undefined);\n }\n}\n\nasync function _cancelReader(reader: ReadableStreamDefaultReader<Uint8Array>): Promise<void> {\n // A cancel that rejects (an already-errored or already-released stream) must not mask the\n // failure that prompted it.\n await reader.cancel().catch(() => undefined);\n}\n\nfunction _resolveCallOptions(options: ISaferFetchOptions): Outcome<IResolvedCallOptions> {\n const method = options.method ?? 'GET';\n const body = options.body ?? undefined;\n if (body !== undefined && METHODS_WITHOUT_BODY.includes(method)) {\n return _unknown<IResolvedCallOptions>(`a ${method} request cannot carry a body.`);\n }\n\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const headersTimeoutMs = options.headersTimeoutMs ?? DEFAULT_HEADERS_TIMEOUT_MS;\n const maxResponseBytes = options.maxResponseBytes ?? DEFAULT_MAX_RESPONSE_BYTES;\n const limits: ReadonlyArray<readonly [string, number]> = [\n ['timeoutMs', timeoutMs],\n ['headersTimeoutMs', headersTimeoutMs],\n ['maxResponseBytes', maxResponseBytes]\n ];\n for (const [name, value] of limits) {\n if (!Number.isFinite(value) || value <= 0) {\n return _unknown<IResolvedCallOptions>(`${name} must be a positive finite number; got ${value}.`);\n }\n }\n\n // `String(...)` and a lookup rather than a literal comparison, so that a JavaScript caller\n // supplying a policy this release does not implement is rejected instead of silently getting a\n // different one. The lookup also narrows to the union with no cast.\n const requestedPolicy = String(options.redirectPolicy ?? 'reject');\n const redirectPolicy = REDIRECT_POLICIES.find((p) => p === requestedPolicy);\n if (redirectPolicy === undefined) {\n return _unknown<IResolvedCallOptions>(\n `redirectPolicy \"${requestedPolicy}\" is not supported; expected ${REDIRECT_POLICIES.join(' or ')}.`\n );\n }\n\n const maxRedirects = options.maxRedirects ?? DEFAULT_MAX_REDIRECTS;\n if (!Number.isInteger(maxRedirects) || maxRedirects < 0) {\n return _unknown<IResolvedCallOptions>(\n `maxRedirects must be a non-negative integer; got ${maxRedirects}.`\n );\n }\n\n // Same reasoning as `redirectPolicy` above, and the stakes are higher: these name the headers\n // that get stripped on a cross-origin hop. A JavaScript caller can pass anything, and a\n // non-string entry would throw out of an API contracted to only ever return a `Result`.\n // Coercing instead of rejecting would be worse than either — `String(123)` is a header name\n // that silently never matches, so a caller who fumbled the type would believe a credential was\n // being stripped while it was carried across origins. A non-array is rejected for the same\n // reason: spreading a bare string would enumerate it into single characters.\n const extraSensitive = options.sensitiveHeaders;\n if (extraSensitive !== undefined) {\n if (!Array.isArray(extraSensitive)) {\n return _unknown<IResolvedCallOptions>(\n `sensitiveHeaders must be an array of header names; got ${typeof extraSensitive}.`\n );\n }\n // `findIndex`, not `find`: an array containing `undefined` is itself invalid, and `find`\n // cannot distinguish that from \"no offender\".\n const badIndex = extraSensitive.findIndex((n) => typeof n !== 'string');\n if (badIndex >= 0) {\n return _unknown<IResolvedCallOptions>(\n `sensitiveHeaders[${badIndex}] must be a string header name; got ${typeof extraSensitive[badIndex]}.`\n );\n }\n }\n\n const retry = resolveRetryPolicy(options.retry);\n if (retry.isFailure()) {\n return _unknown<IResolvedCallOptions>(retry.message);\n }\n\n return _succeed({\n method,\n headers: _lowercaseHeaders(options.headers ?? {}),\n body,\n timeoutMs,\n headersTimeoutMs,\n maxResponseBytes,\n redirectPolicy,\n maxRedirects,\n sensitiveHeaders: sensitiveHeaderSet(options.sensitiveHeaders),\n retry: retry.value,\n logger: options.logger ?? new Logging.NoOpLogger()\n });\n}\n\n/**\n * Reads the body, counting decoded bytes as they arrive and failing the moment the cap is\n * exceeded.\n *\n * `Content-Length` is a fast-reject path only. It is absent on chunked responses, and it is a\n * value a hostile server chooses freely — a `Content-Length: 12` on a ten-gigabyte body costs\n * the attacker nothing. The cap must therefore hold with no help from it, which is what\n * counting during the read buys.\n *\n * The count is of *decoded* bytes, because the platform transparently decompresses\n * `Content-Encoding`. That is also the decompression-bomb defense: a 2 KB gzip that expands to\n * 10 GB clears the fast reject and then trips the cap after `limit` decoded bytes. It is why\n * `too-large.declared` reads as \"what the wire claimed\", never as \"how big it was\".\n */\nasync function _readCappedBody(\n response: Response,\n head: ISaferFetchResponseHead,\n limit: number,\n watch: DeadlineWatch\n): Promise<Outcome<Uint8Array>> {\n const declared = head.contentLength;\n if (declared !== undefined && declared > limit) {\n _discardBody(response);\n return _fail<Uint8Array>(\n { kind: 'too-large', bytesRead: 0, limit, declared },\n `response declares ${declared} bytes, over the ${limit}-byte cap.`\n );\n }\n\n const body = response.body ?? undefined;\n if (body === undefined) {\n return _succeed(new Uint8Array(0));\n }\n\n const reader = body.getReader();\n const chunks: Uint8Array[] = [];\n let total: number = 0;\n for (;;) {\n // The read must be captured, not raced raw. `reader.read()` rejects whenever the connection\n // drops mid-transfer — a server reset, a proxy killing an idle connection, a TLS teardown —\n // which is ordinary AC2 behaviour, not an exotic one. Racing the bare promise would let that\n // rejection escape as a throw out of an entry point documented to always return a Result,\n // which is precisely the guarantee this primitive sells.\n const race = await watch.race(_capture(() => reader.read().then(succeed)));\n if (race.stopped) {\n // Cancelling is what makes the deadline effective rather than decorative: without it the\n // transfer continues against a call that has already given up.\n await _cancelReader(reader);\n return _stopped<Uint8Array>(watch, race.cause);\n }\n if (race.value.isFailure()) {\n // No cancel: the stream has already errored, so there is nothing left to cancel. Reported\n // as `network` — the same kind a transport-level failure gets, because it is the same\n // class of event, observed a few frames later.\n return _fail<Uint8Array>(\n { kind: 'network', detail: race.value.message },\n `response body read failed: ${race.value.message}`\n );\n }\n if (race.value.value.done) {\n break;\n }\n const chunk = race.value.value.value;\n total += chunk.byteLength;\n if (total > limit) {\n // Returning without cancelling would leave the body unconsumed and the connection held,\n // turning the size-cap rejection into the exact resource exhaustion the cap exists to\n // prevent.\n await _cancelReader(reader);\n return _fail<Uint8Array>(\n { kind: 'too-large', bytesRead: total, limit, declared },\n `response exceeded the ${limit}-byte cap after ${total} bytes.`\n );\n }\n chunks.push(chunk);\n }\n\n const bytes = new Uint8Array(total);\n let offset: number = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return _succeed(bytes);\n}\nasync function _receive(\n response: Response,\n url: URL,\n chain: ReadonlyArray<IRequestHop>,\n guards: IResolvedGuards,\n resolved: IResolvedCallOptions,\n watch: DeadlineWatch,\n notes: IAttemptNotes\n): Promise<Outcome<AttemptOutcome>> {\n if (response.type === 'opaqueredirect') {\n _discardBody(response);\n return _fail<AttemptOutcome>(\n { kind: 'redirect-opaque' },\n 'the platform returned an opaque redirect, whose target cannot be inspected or guarded.'\n );\n }\n\n if (REDIRECT_STATUSES.includes(response.status)) {\n // The body of a redirect is never the body this call wanted, and leaving it unconsumed holds\n // the connection open for the whole rest of the chain.\n _discardBody(response);\n if (resolved.redirectPolicy === 'reject') {\n return _fail<AttemptOutcome>(\n { kind: 'redirect-rejected', url: url.toString(), status: response.status },\n `${url.toString()} redirected with status ${response.status}; redirects are rejected.`\n );\n }\n const location = response.headers.get('location') ?? undefined;\n if (location === undefined || location.trim().length === 0) {\n return _fail<AttemptOutcome>(\n { kind: 'redirect-rejected', url: url.toString(), status: response.status },\n `${url.toString()} redirected with status ${response.status} but sent no usable Location header.`\n );\n }\n return _succeed<AttemptOutcome>({ kind: 'redirect', status: response.status, location });\n }\n\n const headers = _readHeaders(response);\n // Annotated because a `Record<string, string>` lookup is typed as present even when the\n // header was never sent; these are read as optional everywhere downstream.\n const contentType: string | undefined = headers['content-type'];\n const contentLength: string | undefined = headers['content-length'];\n const head: ISaferFetchResponseHead = {\n status: response.status,\n statusText: response.statusText,\n headers,\n contentType,\n contentLength: parseContentLength(contentLength)\n };\n\n if (!response.ok) {\n _discardBody(response);\n // Recorded before the failure is built rather than carried on it: `Retry-After` is\n // scheduling advice for this process, not a fact about the response worth widening the\n // taxonomy — and the taxonomy is a surface callers may echo, which advice from an\n // attacker-controlled server should not join.\n notes.retryAfter = headers['retry-after'];\n return _fail<AttemptOutcome>(\n // `bodyPreview` is deliberately never populated: error bodies routinely echo request\n // content, including credentials.\n { kind: 'http-status', status: response.status, statusText: response.statusText },\n `${url.toString()} returned ${response.status} ${response.statusText}.`\n );\n }\n\n const hop = chain.length - 1;\n // Chained rather than stepped: `thenOnSuccess` now preserves `FetchFailureReason` across an\n // async step, so each stage's failure propagates with its detail intact and the two\n // `_propagate` re-types this sequence used to need are gone.\n return (\n await _raced(\n watch,\n () => guards.responseHeaders.check(head, chain),\n (message) => {\n // A content-type allowlist names itself by exposing `acceptedContentTypes`, and its\n // rejections carry a more useful payload than an opaque policy refusal would.\n const accepted = guards.responseHeaders.acceptedContentTypes ?? undefined;\n return accepted !== undefined\n ? _fail<true>(\n { kind: 'unsupported-content-type', contentType: head.contentType, accepted },\n `${url.toString()}: ${message}`\n )\n : _blocked<true>('response-headers', url, hop, guards.responseHeaders.name, message);\n },\n () => _discardBody(response)\n )\n )\n .thenOnSuccess(async () => _readCappedBody(response, head, resolved.maxResponseBytes, watch))\n .thenOnSuccess(async (bytes) =>\n (\n await _raced(\n watch,\n () => guards.responseBody.check(bytes, head),\n (message) => _blocked<true>('response-body', url, hop, guards.responseBody.name, message)\n )\n ).onSuccess(() => _succeed<AttemptOutcome>({ kind: 'final', bytes, head }))\n );\n}\n\n/**\n * Runs the address guard on the hop about to be requested and returns the URL it cleared.\n *\n * @remarks\n * Split out of {@link _connect} so that the guard's verdict is available to the caller *before*\n * anything is put on the wire. Redirect loop detection needs exactly that: it compares the hop\n * about to be requested against the hops already requested, and both sides have to be\n * guard-cleared URLs for the comparison to mean anything (see {@link _detectLoop}).\n *\n * It runs after the request guard, so a request guard that returned a replacement request\n * cannot route around it, and it runs on **every** hop rather than only the first: a `302` to\n * `http://169.254.169.254/` is exactly what a guard that only saw the caller's URL would miss.\n */\nasync function _clearAddress(\n chain: ReadonlyArray<IRequestHop>,\n guards: IResolvedGuards,\n watch: DeadlineWatch\n): Promise<Outcome<IClearedHop>> {\n const hop = chain[chain.length - 1];\n const hopIndex = chain.length - 1;\n return (\n await _raced(\n watch,\n () => guards.address.check(chain),\n (message) => _blocked<IGuardVerdict>('address', hop.url, hopIndex, guards.address.name, message)\n )\n ).onSuccess((verdict) =>\n // A guard may normalize the URL it cleared; the normalized URL is what gets requested. The\n // scheme is re-checked because normalization must never be able to widen it.\n _checkScheme(verdict.url).onSuccess((url) =>\n _succeed<IClearedHop>({ url, pinnedAddress: verdict.pinnedAddress ?? undefined })\n )\n );\n}\n\n/**\n * Rejects a hop that revisits a URL already requested on this walk.\n *\n * @remarks\n * `A → B → A → B` passes every per-hop check while consuming the whole redirect budget, and the\n * hop cap alone would let it — the same reason the address guard is handed the chain rather\n * than a counter.\n *\n * **Both sides of the comparison are guard-cleared URLs**, which is why this runs after\n * {@link _clearAddress} rather than on the raw `Location` target. A guard may normalize the URL\n * it clears — `IGuardVerdict.url` explicitly permits lowercasing a host, stripping a trailing\n * dot, punycoding an IDN — so comparing a cleared URL against an uncleared one lets a repeat\n * escape detection and run to `maxRedirects` instead. Comparing like with like is the whole\n * fix; special-casing particular normalizations here would be worse than leaving it, because\n * this layer does not own normalization and cannot anticipate what a custom guard does.\n *\n * `url` on the failure is the URL that **issued** the redirect, never the repeated target — the\n * contract `FetchFailureReason.redirect-rejected` documents. The target is named in the message.\n */\nfunction _detectLoop(cleared: URL, completed: ReadonlyArray<ICompletedHop>): Outcome<URL> {\n const issuer = completed[completed.length - 1] ?? undefined;\n // Hop 0 cannot repeat anything, so an empty chain is trivially clear — and there would be no\n // issuing hop to name if it could.\n if (issuer === undefined || !completed.some((hop) => hop.url.toString() === cleared.toString())) {\n return _succeed(cleared);\n }\n return _fail<URL>(\n { kind: 'redirect-rejected', url: issuer.url.toString(), status: issuer.status },\n `${issuer.url.toString()} redirected with status ${\n issuer.status\n } to ${cleared.toString()}, which is already in the chain.`\n );\n}\n\nasync function _connect(\n request: ISaferFetchRequest,\n cleared: IClearedHop,\n chain: ReadonlyArray<IRequestHop>,\n guards: IResolvedGuards,\n options: ISaferFetchOptions,\n resolved: IResolvedCallOptions,\n watch: DeadlineWatch,\n notes: IAttemptNotes\n): Promise<Outcome<IAttempt>> {\n const transport = options.transport ?? platformFetchTransport;\n\n const init: RequestInit = {\n method: request.method,\n headers: request.headers,\n // `'manual'` rather than `'follow'`: the platform must not follow anything on our behalf,\n // because a hop the guard never sees is a hop the guard never guarded.\n redirect: 'manual',\n signal: watch.signal\n };\n if (request.body !== undefined) {\n // A byte body is copied into a fresh buffer rather than handed over by reference: it keeps\n // the platform's non-shared `BufferSource` requirement satisfied without a cast, and it\n // means a caller mutating its array after the call cannot change what goes on the wire.\n init.body = typeof request.body === 'string' ? request.body : new Uint8Array(request.body);\n }\n\n return (\n await _raced(\n watch,\n () => transport.fetch(cleared.url, init, { pinnedAddress: cleared.pinnedAddress }),\n (message) =>\n _fail<Response>(\n { kind: 'network', detail: message },\n `transport \"${transport.name}\" failed: ${message}`\n )\n )\n )\n .thenOnSuccess(async (response) => {\n // Inside the continuation rather than before it, which is where it already ran: the\n // headers deadline is retired only once a response has actually arrived.\n watch.headersReceived();\n return _receive(response, cleared.url, chain, guards, resolved, watch, notes);\n })\n .onSuccess((outcome) =>\n // The pin is recorded only once the transport has accepted it. A transport that cannot\n // honor a pin is required to fail rather than connect by hostname, so a settled request\n // with a pin set is evidence the pin held — which is the only basis on which recording it\n // would be honest.\n _succeed({ url: cleared.url, connectedAddress: cleared.pinnedAddress, outcome })\n );\n}\n\n/**\n * Derives the next hop's request from a redirect, or explains why the chain stops here.\n *\n * @remarks\n * The hop cap is checked before the target is resolved: a chain that has already run out of\n * budget stops for that reason, whatever the `Location` header happens to contain.\n *\n * Loop detection is deliberately **not** here — it belongs after the address guard has cleared\n * the next hop, where both sides of the comparison are cleared URLs. See {@link _detectLoop}.\n */\nfunction _nextHop(\n from: URL,\n completed: ReadonlyArray<ICompletedHop>,\n redirect: { readonly status: number; readonly location: string },\n request: ISaferFetchRequest,\n resolved: IResolvedCallOptions\n): Outcome<ISaferFetchRequest> {\n const followed = completed.length;\n if (followed >= resolved.maxRedirects) {\n return _fail<ISaferFetchRequest>(\n { kind: 'too-many-redirects', hops: followed + 1, limit: resolved.maxRedirects },\n `redirect chain exceeded the limit of ${resolved.maxRedirects} hops.`\n );\n }\n\n // The plain-`Result`-to-`DetailedResult` conversion is done here rather than chained, for the\n // same reason `_parseUrl` and `_decodeText` do it: it is the boundary where a `Result` becomes\n // an `Outcome`, and naming the boundary is what lets everything downstream of it chain.\n const located = resolveLocation(redirect.location, from);\n if (located.isFailure()) {\n return _fail<ISaferFetchRequest>(\n { kind: 'invalid-url', url: redirect.location, detail: located.message },\n `invalid redirect target: ${located.message}`\n );\n }\n\n return _checkScheme(located.value).onSuccess((to) => {\n // Headers come from the request that was actually sent on this hop, never from the\n // caller's original set — that carry-forward is what makes credential stripping monotonic.\n const rewritten = rewriteForRedirect({\n from,\n to,\n status: redirect.status,\n method: request.method,\n headers: request.headers,\n body: request.body,\n sensitiveHeaders: resolved.sensitiveHeaders\n });\n return _succeed<ISaferFetchRequest>({\n url: to,\n method: rewritten.method,\n headers: rewritten.headers,\n ...(rewritten.body !== undefined ? { body: rewritten.body } : {})\n });\n });\n}\n\n/**\n * Walks one attempt: the caller's URL, then every redirect hop it leads to, each fully guarded.\n *\n * @remarks\n * **A retry calls this again from the top, with a request rebuilt from the caller's resolved\n * options.** Nothing is carried across attempts — not the guard's verdict, not the redirect\n * chain, not the headers a previous attempt's cross-origin hop had already stripped. That is\n * what makes a retry a full re-walk rather than a resume, and the reason is in\n * {@link SaferFetch.IRetryPolicy}: a cached verdict would turn retry into a DNS-rebinding\n * amplifier, and a resumed chain would revalidate hops the new attempt no longer follows.\n */\nasync function _walk(\n url: URL,\n guards: IResolvedGuards,\n options: ISaferFetchOptions,\n resolved: IResolvedCallOptions,\n watch: DeadlineWatch,\n notes: IAttemptNotes\n): Promise<Outcome<IRawOutcome>> {\n let request: ISaferFetchRequest = {\n url,\n method: resolved.method,\n headers: resolved.headers,\n ...(resolved.body !== undefined ? { body: resolved.body } : {})\n };\n /** Hops already requested and redirected away from, oldest first. */\n const completed: ICompletedHop[] = [];\n\n for (;;) {\n // Re-arms the per-attempt headers deadline. Without this, the first hop's\n // `headersReceived()` would retire it for the whole call and a later host that never\n // answers would be bounded only by the overall deadline.\n watch.attemptStarted();\n\n const guarded = await _raced(\n watch,\n () => guards.request.check(request, [...completed, { url: request.url }]),\n (message) =>\n _blocked<ISaferFetchRequest>('request', request.url, completed.length, guards.request.name, message)\n );\n if (guarded.isFailure()) {\n return _propagate<ISaferFetchRequest, IRawOutcome>(guarded);\n }\n\n const checked = guarded.value;\n const rechecked = _checkScheme(checked.url);\n if (rechecked.isFailure()) {\n return _propagate<URL, IRawOutcome>(rechecked);\n }\n\n // The address guard runs immediately before the connect and after the request guard, so it\n // is always the last word before anything reaches the wire.\n const cleared = await _clearAddress([...completed, { url: checked.url }], guards, watch);\n if (cleared.isFailure()) {\n return _propagate<IClearedHop, IRawOutcome>(cleared);\n }\n\n const unrepeated = _detectLoop(cleared.value.url, completed);\n if (unrepeated.isFailure()) {\n resolved.logger.detail(`saferFetch: ${cleared.value.url.toString()} failed: ${unrepeated.message}`);\n return _propagate<URL, IRawOutcome>(unrepeated);\n }\n\n // Downstream guards see the chain as it was actually requested, so the URL a response guard\n // reads is the URL the address guard cleared — not the pre-normalization spelling.\n const requested: ReadonlyArray<IRequestHop> = [...completed, { url: cleared.value.url }];\n const attempted = await _connect(\n checked,\n cleared.value,\n requested,\n guards,\n options,\n resolved,\n watch,\n notes\n );\n if (attempted.isFailure()) {\n resolved.logger.detail(`saferFetch: ${cleared.value.url.toString()} failed: ${attempted.message}`);\n return _propagate<IAttempt, IRawOutcome>(attempted);\n }\n const attempt = attempted.value;\n\n if (attempt.outcome.kind === 'final') {\n return _succeed({\n bytes: attempt.outcome.bytes,\n head: attempt.outcome.head,\n urlChain: [...completed.map((hop) => hop.url.toString()), attempt.url.toString()]\n });\n }\n\n const next = _nextHop(attempt.url, completed, attempt.outcome, checked, resolved);\n if (next.isFailure()) {\n resolved.logger.detail(`saferFetch: ${attempt.url.toString()} failed: ${next.message}`);\n return _propagate<ISaferFetchRequest, IRawOutcome>(next);\n }\n\n completed.push({\n url: attempt.url,\n status: attempt.outcome.status,\n ...(attempt.connectedAddress !== undefined ? { connectedAddress: attempt.connectedAddress } : {})\n });\n request = next.value;\n }\n}\n\n/**\n * Decides how long to wait before retrying a failed walk, or that it must not be retried.\n *\n * @remarks\n * Every rule that can refuse a retry is applied here, in one place, so \"would this have been\n * retried?\" is answerable by reading one function: the attempt budget, the retryable-failure\n * set, the idempotency rule, the `Retry-After` clamp, and the overall deadline as ceiling.\n *\n * **The deadline is the last word.** When the remaining budget is shorter than the computed\n * delay, the call fails with the attempt's own failure rather than sleeping past the deadline\n * the caller set — a `timeout` reported at `timeoutMs` is what the caller asked for, and one\n * reported at `timeoutMs + backoff` is a primitive that does not keep its own promises.\n */\nfunction _retryDelayMs(\n reason: FetchFailureReason | undefined,\n attempt: number,\n resolved: IResolvedCallOptions,\n notes: IAttemptNotes,\n watch: DeadlineWatch\n): number | undefined {\n const policy = resolved.retry;\n if (attempt >= policy.attempts) {\n return undefined;\n }\n if (!isRetryableFailure(reason) || !isRetryableMethod(resolved.method, policy)) {\n return undefined;\n }\n const retryAfterMs = honorsRetryAfter(reason, policy)\n ? parseRetryAfterMs(notes.retryAfter, Date.now())\n : undefined;\n const delay = computeRetryDelayMs({\n attempt,\n policy,\n ...(retryAfterMs !== undefined ? { retryAfterMs } : {}),\n random: Math.random\n });\n return delay <= watch.remainingMs ? delay : undefined;\n}\n\n/**\n * Runs one attempt and, if the policy says so, the next one after it.\n *\n * @remarks\n * Recursive rather than a loop, because **a retry is a fresh start rather than another turn of\n * something already in progress**: every attempt is a full {@link _walk} from hop 0, and nothing\n * survives the boundary — not the guard's verdict, not the redirect chain, not the headers a\n * cross-origin hop stripped, not the previous response's `Retry-After`. Expressing that as a\n * self-call keeps the \"nothing carries over\" property visible in the shape of the code rather\n * than resting on a reader noticing which variables are declared inside the loop body.\n *\n * Depth is bounded by `retry.attempts` and each level is `await`ed, so the frames unwind rather\n * than nest.\n *\n * @param attempt - 0-based index of the attempt about to run; `0` is the caller's first request.\n */\nasync function _runAttempt(\n url: URL,\n guards: IResolvedGuards,\n options: ISaferFetchOptions,\n resolved: IResolvedCallOptions,\n watch: DeadlineWatch,\n attempt: number\n): Promise<Outcome<IRawOutcome>> {\n // Fresh per attempt: notes describe the attempt that just failed, and carrying a previous\n // attempt's `Retry-After` into a later decision would schedule against a response that is no\n // longer the reason we are retrying.\n const notes: IAttemptNotes = {};\n const walked = await _walk(url, guards, options, resolved, watch, notes);\n // `!isFailure()` rather than `isSuccess()`: only the former narrows to the failure branch\n // below, where `detail` is known to be present.\n if (!walked.isFailure()) {\n return walked;\n }\n\n const delay = _retryDelayMs(walked.detail, attempt, resolved, notes, watch);\n if (delay === undefined) {\n return walked;\n }\n // Clears an attempt-scoped stop — a headers timeout ends the attempt, not the call — so the\n // backoff below is not answered instantly by the previous attempt's own deadline. A terminal\n // stop deliberately survives, and ends the call at the first race below.\n watch.attemptEnded();\n resolved.logger.detail(\n `saferFetch: ${url.toString()} failed (${walked.message}); retrying in ` +\n `${Math.round(delay)}ms — attempt ${attempt + 2} of ${resolved.retry.attempts + 1}.`\n );\n\n // Delayed on the same watch the request races against, so a caller who aborts during a backoff\n // is answered then rather than after the sleep.\n const slept = await watch.delay(delay);\n return slept.stopped\n ? _stopped<IRawOutcome>(watch, slept.cause)\n : _runAttempt(url, guards, options, resolved, watch, attempt + 1);\n}\n\nasync function _execute(url: string | URL, options: ISaferFetchOptions): Promise<Outcome<IRawOutcome>> {\n const resolvedOptions = _resolveCallOptions(options);\n if (resolvedOptions.isFailure()) {\n return _propagate<IResolvedCallOptions, IRawOutcome>(resolvedOptions);\n }\n const resolved = resolvedOptions.value;\n\n const resolvedGuards = resolveGuards(options);\n if (resolvedGuards.isFailure()) {\n return _unknown<IRawOutcome>(resolvedGuards.message);\n }\n const guards = resolvedGuards.value;\n\n const parsed = _parseUrl(url);\n if (parsed.isFailure()) {\n return _propagate<URL, IRawOutcome>(parsed);\n }\n\n const watch = new DeadlineWatch(resolved.timeoutMs, resolved.headersTimeoutMs, options.signal);\n // `captureAsyncResult` rather than `try`/`finally`, for the same reason `_capture` wraps every\n // guard and transport call: an entry point documented to always return a `Result` has to keep\n // that promise even when a collaborator breaks its own. Nothing inside is *supposed* to throw\n // — guards, transports and the body read are each captured already — but the caller's\n // `logger` is collaborator code this primitive does not wrap, and a thrown diagnostic must not\n // become the caller's problem. The watch is disposed on both paths because the capture has\n // already converted the throw into a value.\n const ran = await captureAsyncResult(async () =>\n _runAttempt(parsed.value, guards, options, resolved, watch, 0)\n );\n watch.dispose();\n return ran.isFailure()\n ? // `'unknown'` is the taxonomy's honest slot for \"something violated its contract\", rather\n // than a guess at a more specific kind.\n _unexpected<IRawOutcome>(ran.message)\n : // Same wrapping for a throw a `thenOnSuccess` callback caught before it could reach the\n // capture above — see {@link _withReason}. This is the single boundary where an `Outcome`\n // becomes the caller's result, so it is the one place the invariant has to hold.\n _withReason(ran.value);\n}\n\nfunction _toResponse<T>(value: T, raw: IRawOutcome): ISaferFetchResponse<T> {\n return {\n value,\n status: raw.head.status,\n headers: raw.head.headers,\n urlChain: raw.urlChain,\n bytesRead: raw.bytes.byteLength\n };\n}\n\n/**\n * Applies the caller's parser to the decoded body.\n *\n * @remarks\n * Exists for the same reason as {@link _decodeText}: it is the boundary where a plain\n * `Result` from a `Converter` becomes a `DetailedResult` carrying a `FetchFailureReason`.\n * Isolating that conversion in a named helper is what lets the entry points stay chained.\n */\nfunction _parseJson<T>(text: string, parser: Converter<T | JsonValue>): Outcome<T | JsonValue> {\n const parsed = parser.convert(text);\n if (parsed.isFailure()) {\n return _fail<T | JsonValue>(\n { kind: 'parse', detail: parsed.message },\n `failed to parse response as JSON: ${parsed.message}`\n );\n }\n return _succeed(parsed.value);\n}\n\nfunction _decodeText(raw: IRawOutcome): Outcome<string> {\n const charset = parseCharset(raw.head.contentType) ?? 'utf-8';\n // `fatal: true` so an unknown charset, or a byte sequence invalid in the declared one,\n // surfaces as a decode failure rather than as silent mojibake some caller treats as data.\n const decoded = captureResult(() => new TextDecoder(charset, { fatal: true }).decode(raw.bytes));\n if (decoded.isFailure()) {\n return _fail<string>(\n { kind: 'decode', detail: decoded.message },\n `failed to decode response as \"${charset}\": ${decoded.message}`\n );\n }\n return _succeed(decoded.value);\n}\n\n/**\n * Fetches a URL and returns the raw response bytes, subject to the scheme check, the address\n * guard, the request and response guards, the deadlines, and the response size cap.\n *\n * @remarks\n * **What this does not protect against.** It is not a sandbox: a caller who wants to reach\n * `127.0.0.1` can call `globalThis.fetch` directly, so this guards untrusted *data*, never\n * untrusted *code in the same process*. It does no certificate pinning and adds nothing\n * against a network-position attacker — TLS is that control. It does not resist DNS rebinding:\n * an address guard validates a resolved address and the transport then re-resolves, so a\n * hostile resolver can answer the two lookups differently. And it inspects nothing in the\n * response body. If your deployment has an egress proxy or firewall, that control is strictly\n * stronger than this one; this is defense in depth for deployments that do not.\n *\n * **The failure detail is an internal-network scanning oracle.** Log it; do not echo it, or\n * any string derived from it, to an untrusted caller. The detail is structured precisely so\n * that mapping it to a coarse public code is trivial.\n *\n * **Redirects are rejected unless you ask for them.** `redirectPolicy: 'validate-each-hop'`\n * follows them, runs the address guard on every hop before any connection, and drops credential\n * headers the first time the chain leaves an origin — and never restores them, so an\n * `A` → `B` → `A` chain does not hand the token back to `A`.\n *\n * @param url - The URL to fetch. Only `http:` and `https:` are ever requested; every other\n * scheme fails as `'invalid-url'`.\n * @param options - Call options. `addressGuard` is required and has no default — use\n * `blockPrivateNetworks()` on Node, or `allowAnyAddress()` to name the absence of the\n * guarantee at the call site. `maxResponseBytes` defaults to 5 MiB and is meant to be tuned\n * per call: real documents clear that, and raising it for the calls that need it is the\n * intended use, not a workaround.\n * @public\n */\nexport async function saferFetchBytes(\n url: string | URL,\n options: ISaferFetchOptions\n): Promise<DetailedResult<ISaferFetchResponse<Uint8Array>, FetchFailureReason>> {\n return (await _execute(url, options)).onSuccess((raw) => _succeed(_toResponse(raw.bytes, raw)));\n}\n\n/**\n * Fetches a URL and decodes the response body as text.\n *\n * @remarks\n * The charset comes from the `Content-Type` parameter and defaults to UTF-8. Decoding is\n * strict: an unknown charset, or a byte sequence that is not valid in the declared one, fails\n * as `'decode'` rather than silently producing mojibake that some caller downstream treats as\n * data.\n *\n * See {@link SaferFetch.saferFetchBytes} for what this primitive does **not** protect against,\n * and for the warning about echoing failure detail to untrusted callers.\n *\n * @param url - The URL to fetch.\n * @param options - Call options. `addressGuard` is required. `maxResponseBytes` defaults to\n * 5 MiB and is meant to be tuned per call.\n * @public\n */\nexport async function saferFetchText(\n url: string | URL,\n options: ISaferFetchOptions\n): Promise<DetailedResult<ISaferFetchResponse<string>, FetchFailureReason>> {\n // Nested rather than flat: `_toResponse` needs both the decoded text and the raw outcome it\n // came from, and nesting is what keeps `raw` in scope for it.\n return (await _execute(url, options)).onSuccess((raw) =>\n _decodeText(raw).onSuccess((text) => _succeed(_toResponse(text, raw)))\n );\n}\n\n/**\n * Options for the validating form of {@link SaferFetch.saferFetchJson}.\n *\n * @remarks\n * `converter` is **required** here, and `T` is inferred from it. There is deliberately no way\n * to assert a `T` without supplying the converter that evidences it at runtime: a caller-named\n * type with nothing checking it is a claim the primitive cannot keep. Omit the whole options\n * type and the value comes back as `JsonValue`, which is what the wire actually guarantees.\n * @public\n */\nexport interface ISaferFetchJsonOptions<T> extends ISaferFetchOptions {\n /** Applied to the parsed JSON, taking the caller from wire to validated `T` in one step. */\n readonly converter: Converter<T> | Validator<T>;\n}\n\n/**\n * Fetches a URL and parses the response body as JSON, yielding the raw `JsonValue` for the\n * caller to validate.\n *\n * @remarks\n * **This does not gate on `Content-Type` by itself.** A server returning an HTML error page\n * with a `200` will be decoded and parsed, and fail as `'parse'` — twenty frames from where it\n * actually went wrong. Pass `responseHeadersGuard: allowContentTypes(['application/json'])`\n * to reject on the header instead: it costs a header comparison rather than a body transfer,\n * and the failure names the type. Content-type gating is a guard rather than an option so that\n * there is exactly one mechanism for it.\n *\n * See {@link SaferFetch.saferFetchBytes} for what this primitive does **not** protect against,\n * and for the warning about echoing failure detail to untrusted callers.\n *\n * @param url - The URL to fetch.\n * @param options - Call options. `addressGuard` is required. `maxResponseBytes` defaults to\n * 5 MiB and is meant to be tuned per call.\n * @public\n */\nexport async function saferFetchJson(\n url: string | URL,\n options: ISaferFetchOptions\n): Promise<DetailedResult<ISaferFetchResponse<JsonValue>, FetchFailureReason>>;\n/**\n * Fetches a URL, parses the response body as JSON, and runs it through the supplied converter\n * or validator so the caller reaches a validated `T` in one step.\n *\n * @remarks\n * `T` is inferred from `converter` and is never caller-asserted, so the returned type is\n * evidenced at runtime rather than claimed.\n *\n * See {@link SaferFetch.saferFetchBytes} for what this primitive does **not** protect against,\n * and for the warning about echoing failure detail to untrusted callers.\n *\n * @param url - The URL to fetch.\n * @param options - Call options plus the required `converter`. `addressGuard` is required.\n * `maxResponseBytes` defaults to 5 MiB and is meant to be tuned per call.\n * @public\n */\nexport async function saferFetchJson<T>(\n url: string | URL,\n options: ISaferFetchJsonOptions<T>\n): Promise<DetailedResult<ISaferFetchResponse<T>, FetchFailureReason>>;\nexport async function saferFetchJson<T>(\n url: string | URL,\n options: ISaferFetchOptions | ISaferFetchJsonOptions<T>\n): Promise<DetailedResult<ISaferFetchResponse<T | JsonValue>, FetchFailureReason>> {\n const converter = (options as Partial<ISaferFetchJsonOptions<T>>).converter ?? undefined;\n const parser: Converter<T | JsonValue> =\n converter !== undefined\n ? JsonBaseConverters.stringifiedJson<T>(converter)\n : JsonBaseConverters.stringifiedJson();\n\n // Nested for the same reason as `saferFetchText`: the response needs the raw outcome as well\n // as the parsed value, and nesting is what keeps `raw` in scope.\n return (await _execute(url, options)).onSuccess((raw) =>\n _decodeText(raw).onSuccess((text) =>\n _parseJson(text, parser).onSuccess((parsed) => _succeed(_toResponse(parsed, raw)))\n )\n );\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IFetchTransport } from './model';
|
|
2
|
+
/**
|
|
3
|
+
* The {@link SaferFetch.IFetchTransport | transport} that wraps `globalThis.fetch`.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* **Fails loudly when asked to honor a `pinnedAddress`.** `globalThis.fetch` connects by
|
|
7
|
+
* hostname and re-resolves DNS itself, so it cannot honor a pin. Ignoring the hint instead
|
|
8
|
+
* would mean that a deployment which wired an address-pinning guard but forgot the matching
|
|
9
|
+
* pinning transport gets exactly the DNS-rebinding exposure it believed it had closed, and
|
|
10
|
+
* gets it silently. A primitive that advertises a guarantee it does not have is worse than no
|
|
11
|
+
* primitive — and that applies to future versions of itself.
|
|
12
|
+
*
|
|
13
|
+
* No guard in this release populates `pinnedAddress`, so the interlock is dormant. It is here
|
|
14
|
+
* so that populating it later is an additive change that cannot be made unsafely.
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
export declare const platformFetchTransport: IFetchTransport;
|
|
18
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../src/packlets/safer-fetch/transport.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,eAAe,EAAwB,MAAM,SAAS,CAAC;AAErE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,sBAAsB,EAAE,eAepC,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) 2026 Erik Fortune
|
|
3
|
+
//
|
|
4
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
// in the Software without restriction, including without limitation the rights
|
|
7
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
// furnished to do so, subject to the following conditions:
|
|
10
|
+
//
|
|
11
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
// copies or substantial portions of the Software.
|
|
13
|
+
//
|
|
14
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
// SOFTWARE.
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.platformFetchTransport = void 0;
|
|
23
|
+
const ts_utils_1 = require("@fgv/ts-utils");
|
|
24
|
+
/**
|
|
25
|
+
* The {@link SaferFetch.IFetchTransport | transport} that wraps `globalThis.fetch`.
|
|
26
|
+
*
|
|
27
|
+
* @remarks
|
|
28
|
+
* **Fails loudly when asked to honor a `pinnedAddress`.** `globalThis.fetch` connects by
|
|
29
|
+
* hostname and re-resolves DNS itself, so it cannot honor a pin. Ignoring the hint instead
|
|
30
|
+
* would mean that a deployment which wired an address-pinning guard but forgot the matching
|
|
31
|
+
* pinning transport gets exactly the DNS-rebinding exposure it believed it had closed, and
|
|
32
|
+
* gets it silently. A primitive that advertises a guarantee it does not have is worse than no
|
|
33
|
+
* primitive — and that applies to future versions of itself.
|
|
34
|
+
*
|
|
35
|
+
* No guard in this release populates `pinnedAddress`, so the interlock is dormant. It is here
|
|
36
|
+
* so that populating it later is an additive change that cannot be made unsafely.
|
|
37
|
+
* @public
|
|
38
|
+
*/
|
|
39
|
+
exports.platformFetchTransport = {
|
|
40
|
+
name: 'platformFetchTransport',
|
|
41
|
+
fetch: async (url, init, hints) => {
|
|
42
|
+
var _a;
|
|
43
|
+
// `?? undefined` rather than `!== undefined`: a `null` from a JavaScript caller or an
|
|
44
|
+
// `unknown` escape hatch means "no pin", and must not be mistaken for one.
|
|
45
|
+
const pinnedAddress = (_a = hints.pinnedAddress) !== null && _a !== void 0 ? _a : undefined;
|
|
46
|
+
if (pinnedAddress !== undefined) {
|
|
47
|
+
return (0, ts_utils_1.fail)(`platformFetchTransport cannot honor pinnedAddress ${pinnedAddress}: it connects by ` +
|
|
48
|
+
'hostname. Use a pinning transport, or a guard that does not pin.');
|
|
49
|
+
}
|
|
50
|
+
return (0, ts_utils_1.captureAsyncResult)(async () => globalThis.fetch(url.toString(), init));
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../src/packlets/safer-fetch/transport.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;AAEZ,4CAAiE;AAIjE;;;;;;;;;;;;;;GAcG;AACU,QAAA,sBAAsB,GAAoB;IACrD,IAAI,EAAE,wBAAwB;IAE9B,KAAK,EAAE,KAAK,EAAE,GAAQ,EAAE,IAAiB,EAAE,KAA2B,EAA6B,EAAE;;QACnG,sFAAsF;QACtF,2EAA2E;QAC3E,MAAM,aAAa,GAAG,MAAA,KAAK,CAAC,aAAa,mCAAI,SAAS,CAAC;QACvD,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,IAAA,eAAI,EACT,qDAAqD,aAAa,mBAAmB;gBACnF,kEAAkE,CACrE,CAAC;QACJ,CAAC;QACD,OAAO,IAAA,6BAAkB,EAAC,KAAK,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;IAChF,CAAC;CACF,CAAC","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport { captureAsyncResult, fail, Result } from '@fgv/ts-utils';\n\nimport type { IFetchTransport, IFetchTransportHints } from './model';\n\n/**\n * The {@link SaferFetch.IFetchTransport | transport} that wraps `globalThis.fetch`.\n *\n * @remarks\n * **Fails loudly when asked to honor a `pinnedAddress`.** `globalThis.fetch` connects by\n * hostname and re-resolves DNS itself, so it cannot honor a pin. Ignoring the hint instead\n * would mean that a deployment which wired an address-pinning guard but forgot the matching\n * pinning transport gets exactly the DNS-rebinding exposure it believed it had closed, and\n * gets it silently. A primitive that advertises a guarantee it does not have is worse than no\n * primitive — and that applies to future versions of itself.\n *\n * No guard in this release populates `pinnedAddress`, so the interlock is dormant. It is here\n * so that populating it later is an additive change that cannot be made unsafely.\n * @public\n */\nexport const platformFetchTransport: IFetchTransport = {\n name: 'platformFetchTransport',\n\n fetch: async (url: URL, init: RequestInit, hints: IFetchTransportHints): Promise<Result<Response>> => {\n // `?? undefined` rather than `!== undefined`: a `null` from a JavaScript caller or an\n // `unknown` escape hatch means \"no pin\", and must not be mistaken for one.\n const pinnedAddress = hints.pinnedAddress ?? undefined;\n if (pinnedAddress !== undefined) {\n return fail(\n `platformFetchTransport cannot honor pinnedAddress ${pinnedAddress}: it connects by ` +\n 'hostname. Use a pinning transport, or a guard that does not pin.'\n );\n }\n return captureAsyncResult(async () => globalThis.fetch(url.toString(), init));\n }\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"converters.d.ts","sourceRoot":"","sources":["../../../src/packlets/yaml/converters.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAc,SAAS,EAA+B,MAAM,eAAe,CAAC;AAGnF;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAkBtE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"converters.js","sourceRoot":"","sources":["../../../src/packlets/yaml/converters.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWH,sCAkBC;AA3BD,4CAAmF;AACnF,8CAAgC;AAEhC;;;;;GAKG;AACH,SAAgB,aAAa,CAAI,SAAuB;IACtD,OAAO,IAAI,qBAAU,CAAC,aAAa,CAAI,CAAC,IAAa,EAAa,EAAE;QAClE,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,OAAO,IAAA,eAAI,EAAC,wBAAwB,CAAC,CAAC;QACxC,CAAC;QAED,MAAM,WAAW,GAAG,IAAA,wBAAa,EAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACzD,IAAI,WAAW,CAAC,SAAS,EAAE,EAAE,CAAC;YAC5B,OAAO,IAAA,eAAI,EAAC,yBAAyB,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC;QACjC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAClD,OAAO,IAAA,eAAI,EAAC,sDAAsD,CAAC,CAAC;QACtE,CAAC;QAED,OAAO,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["/*\n * Copyright (c) 2024 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Conversion, Converter, Result, captureResult, fail } from '@fgv/ts-utils';\nimport * as yaml from 'js-yaml';\n\n/**\n * Creates a converter that parses YAML string content and then applies the supplied converter.\n * @param converter - Converter to apply to the parsed YAML\n * @returns Converter that parses YAML then validates\n * @public\n */\nexport function yamlConverter<T>(converter: Converter<T>): Converter<T> {\n return new Conversion.BaseConverter<T>((from: unknown): Result<T> => {\n if (typeof from !== 'string') {\n return fail('Input must be a string');\n }\n\n const parseResult = captureResult(() => yaml.load(from));\n if (parseResult.isFailure()) {\n return fail(`Failed to parse YAML: ${parseResult.message}`);\n }\n\n const parsed = parseResult.value;\n if (typeof parsed !== 'object' || parsed === null) {\n return fail('Failed to parse YAML: YAML content must be an object');\n }\n\n return converter.convert(parsed);\n });\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/packlets/yaml/index.ts"],"names":[],"mappings":"AAsBA,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC"}
|
|
@@ -36,4 +36,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
36
36
|
};
|
|
37
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
38
|
__exportStar(require("./converters"), exports);
|
|
39
|
+
__exportStar(require("./serializers"), exports);
|
|
39
40
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/packlets/yaml/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;;;;;;;;;;;;;;AAEH,+CAA6B;AAC7B,gDAA8B","sourcesContent":["/*\n * Copyright (c) 2024 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nexport * from './converters';\nexport * from './serializers';\n"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Result } from '@fgv/ts-utils';
|
|
2
|
+
/**
|
|
3
|
+
* Options for YAML serialization, mirroring commonly-used `js-yaml` `DumpOptions`.
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export interface IYamlSerializeOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Indentation width in spaces (default: 2).
|
|
9
|
+
*/
|
|
10
|
+
readonly indent?: number;
|
|
11
|
+
/**
|
|
12
|
+
* Nesting level at which to switch from block to flow style.
|
|
13
|
+
* -1 means block style everywhere (default: -1).
|
|
14
|
+
*/
|
|
15
|
+
readonly flowLevel?: number;
|
|
16
|
+
/**
|
|
17
|
+
* If true, sort keys when dumping (default: false).
|
|
18
|
+
*/
|
|
19
|
+
readonly sortKeys?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Maximum line width (default: 80).
|
|
22
|
+
*/
|
|
23
|
+
readonly lineWidth?: number;
|
|
24
|
+
/**
|
|
25
|
+
* If true, don't convert duplicate objects into references (default: false).
|
|
26
|
+
*/
|
|
27
|
+
readonly noRefs?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* If true, don't add an indentation level to array elements (default: false).
|
|
30
|
+
*/
|
|
31
|
+
readonly noArrayIndent?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* If true, all non-key strings will be quoted (default: false).
|
|
34
|
+
*/
|
|
35
|
+
readonly forceQuotes?: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Serializes a value to a YAML string.
|
|
39
|
+
* @param value - The value to serialize (must be an object or array)
|
|
40
|
+
* @param options - Optional serialization options
|
|
41
|
+
* @returns `Success` with YAML string, or `Failure` with error
|
|
42
|
+
* @public
|
|
43
|
+
*/
|
|
44
|
+
export declare function yamlStringify(value: unknown, options?: IYamlSerializeOptions): Result<string>;
|
|
45
|
+
//# sourceMappingURL=serializers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serializers.d.ts","sourceRoot":"","sources":["../../../src/packlets/yaml/serializers.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,MAAM,EAAuB,MAAM,eAAe,CAAC;AAG5D;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAE1B;;OAEG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IAEjC;;OAEG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAAC,MAAM,CAAC,CAmB7F"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2024 Erik Fortune
|
|
4
|
+
*
|
|
5
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
* in the Software without restriction, including without limitation the rights
|
|
8
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
* furnished to do so, subject to the following conditions:
|
|
11
|
+
*
|
|
12
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
* copies or substantial portions of the Software.
|
|
14
|
+
*
|
|
15
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
* SOFTWARE.
|
|
22
|
+
*/
|
|
23
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
26
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
27
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
28
|
+
}
|
|
29
|
+
Object.defineProperty(o, k2, desc);
|
|
30
|
+
}) : (function(o, m, k, k2) {
|
|
31
|
+
if (k2 === undefined) k2 = k;
|
|
32
|
+
o[k2] = m[k];
|
|
33
|
+
}));
|
|
34
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
35
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
36
|
+
}) : function(o, v) {
|
|
37
|
+
o["default"] = v;
|
|
38
|
+
});
|
|
39
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
40
|
+
var ownKeys = function(o) {
|
|
41
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
42
|
+
var ar = [];
|
|
43
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
44
|
+
return ar;
|
|
45
|
+
};
|
|
46
|
+
return ownKeys(o);
|
|
47
|
+
};
|
|
48
|
+
return function (mod) {
|
|
49
|
+
if (mod && mod.__esModule) return mod;
|
|
50
|
+
var result = {};
|
|
51
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
52
|
+
__setModuleDefault(result, mod);
|
|
53
|
+
return result;
|
|
54
|
+
};
|
|
55
|
+
})();
|
|
56
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
57
|
+
exports.yamlStringify = yamlStringify;
|
|
58
|
+
const ts_utils_1 = require("@fgv/ts-utils");
|
|
59
|
+
const yaml = __importStar(require("js-yaml"));
|
|
60
|
+
/**
|
|
61
|
+
* Serializes a value to a YAML string.
|
|
62
|
+
* @param value - The value to serialize (must be an object or array)
|
|
63
|
+
* @param options - Optional serialization options
|
|
64
|
+
* @returns `Success` with YAML string, or `Failure` with error
|
|
65
|
+
* @public
|
|
66
|
+
*/
|
|
67
|
+
function yamlStringify(value, options) {
|
|
68
|
+
if (value === null || value === undefined) {
|
|
69
|
+
return (0, ts_utils_1.fail)('Cannot serialize null or undefined to YAML');
|
|
70
|
+
}
|
|
71
|
+
if (typeof value !== 'object') {
|
|
72
|
+
return (0, ts_utils_1.fail)('YAML serialization requires an object or array');
|
|
73
|
+
}
|
|
74
|
+
return (0, ts_utils_1.captureResult)(() => yaml.dump(value, {
|
|
75
|
+
indent: options === null || options === void 0 ? void 0 : options.indent,
|
|
76
|
+
flowLevel: options === null || options === void 0 ? void 0 : options.flowLevel,
|
|
77
|
+
sortKeys: options === null || options === void 0 ? void 0 : options.sortKeys,
|
|
78
|
+
lineWidth: options === null || options === void 0 ? void 0 : options.lineWidth,
|
|
79
|
+
noRefs: options === null || options === void 0 ? void 0 : options.noRefs,
|
|
80
|
+
noArrayIndent: options === null || options === void 0 ? void 0 : options.noArrayIndent,
|
|
81
|
+
forceQuotes: options === null || options === void 0 ? void 0 : options.forceQuotes
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=serializers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serializers.js","sourceRoot":"","sources":["../../../src/packlets/yaml/serializers.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDH,sCAmBC;AAvED,4CAA4D;AAC5D,8CAAgC;AA4ChC;;;;;;GAMG;AACH,SAAgB,aAAa,CAAC,KAAc,EAAE,OAA+B;IAC3E,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,IAAA,eAAI,EAAC,4CAA4C,CAAC,CAAC;IAC5D,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,IAAA,eAAI,EAAC,gDAAgD,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,IAAA,wBAAa,EAAC,GAAG,EAAE,CACxB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;QACf,MAAM,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM;QACvB,SAAS,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS;QAC7B,QAAQ,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,QAAQ;QAC3B,SAAS,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS;QAC7B,MAAM,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM;QACvB,aAAa,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,aAAa;QACrC,WAAW,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW;KAClC,CAAC,CACH,CAAC;AACJ,CAAC","sourcesContent":["/*\n * Copyright (c) 2024 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Result, captureResult, fail } from '@fgv/ts-utils';\nimport * as yaml from 'js-yaml';\n\n/**\n * Options for YAML serialization, mirroring commonly-used `js-yaml` `DumpOptions`.\n * @public\n */\nexport interface IYamlSerializeOptions {\n /**\n * Indentation width in spaces (default: 2).\n */\n readonly indent?: number;\n\n /**\n * Nesting level at which to switch from block to flow style.\n * -1 means block style everywhere (default: -1).\n */\n readonly flowLevel?: number;\n\n /**\n * If true, sort keys when dumping (default: false).\n */\n readonly sortKeys?: boolean;\n\n /**\n * Maximum line width (default: 80).\n */\n readonly lineWidth?: number;\n\n /**\n * If true, don't convert duplicate objects into references (default: false).\n */\n readonly noRefs?: boolean;\n\n /**\n * If true, don't add an indentation level to array elements (default: false).\n */\n readonly noArrayIndent?: boolean;\n\n /**\n * If true, all non-key strings will be quoted (default: false).\n */\n readonly forceQuotes?: boolean;\n}\n\n/**\n * Serializes a value to a YAML string.\n * @param value - The value to serialize (must be an object or array)\n * @param options - Optional serialization options\n * @returns `Success` with YAML string, or `Failure` with error\n * @public\n */\nexport function yamlStringify(value: unknown, options?: IYamlSerializeOptions): Result<string> {\n if (value === null || value === undefined) {\n return fail('Cannot serialize null or undefined to YAML');\n }\n if (typeof value !== 'object') {\n return fail('YAML serialization requires an object or array');\n }\n\n return captureResult(() =>\n yaml.dump(value, {\n indent: options?.indent,\n flowLevel: options?.flowLevel,\n sortKeys: options?.sortKeys,\n lineWidth: options?.lineWidth,\n noRefs: options?.noRefs,\n noArrayIndent: options?.noArrayIndent,\n forceQuotes: options?.forceQuotes\n })\n );\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/packlets/zip-file-tree/index.ts"],"names":[],"mappings":"AAsBA;;;;;;;;GAQG;AAEH,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC7F,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/packlets/zip-file-tree/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;;;;;;;;;;;;;;;AAEH;;;;;;;;GAQG;AAEH,+DAA6F;AAApF,4HAAA,oBAAoB,OAAA;AAAE,mHAAA,WAAW,OAAA;AAAE,wHAAA,gBAAgB,OAAA;AAC5D,sDAAoC","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n/**\n * ZIP-based FileTree implementation for ts-extras.\n *\n * This packlet provides a FileTree accessor implementation that can read from ZIP archives,\n * making it useful for browser environments where files need to be bundled and transferred\n * as a single archive.\n *\n * @packageDocumentation\n */\n\nexport { ZipFileTreeAccessors, ZipFileItem, ZipDirectoryItem } from './zipFileTreeAccessors';\nexport * from './zipFileTreeWriter';\n"]}
|
|
@@ -4,9 +4,15 @@ import { FileTree, JsonValue } from '@fgv/ts-json-base';
|
|
|
4
4
|
* Implementation of `FileTree.IFileTreeFileItem` for files in a ZIP archive.
|
|
5
5
|
* ZIP files are read-only, so this item does not support mutation.
|
|
6
6
|
* Use {@link FileTree.isMutableFileItem | isMutableFileItem} to check before attempting mutations.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* ZIP entries are byte-native, so this item also implements the read half of the
|
|
10
|
+
* optional binary capability (`FileTree.IBinaryFileTreeFileItem`) — use
|
|
11
|
+
* `FileTree.isBinaryFileItem` to narrow and `getRawBytes()` to read the entry's
|
|
12
|
+
* undecoded bytes.
|
|
7
13
|
* @public
|
|
8
14
|
*/
|
|
9
|
-
export declare class ZipFileItem<TCT extends string = string> implements FileTree.
|
|
15
|
+
export declare class ZipFileItem<TCT extends string = string> implements FileTree.IBinaryFileTreeFileItem<TCT>, FileTree.IStrictTextFileTreeFileItem<TCT> {
|
|
10
16
|
/**
|
|
11
17
|
* Indicates that this `FileTree.FileTreeItem` is a file.
|
|
12
18
|
*/
|
|
@@ -32,9 +38,18 @@ export declare class ZipFileItem<TCT extends string = string> implements FileTre
|
|
|
32
38
|
*/
|
|
33
39
|
get contentType(): TCT | undefined;
|
|
34
40
|
/**
|
|
35
|
-
* The pre-loaded
|
|
41
|
+
* The pre-loaded raw bytes of the ZIP entry.
|
|
36
42
|
*/
|
|
37
|
-
private readonly
|
|
43
|
+
private readonly _bytes;
|
|
44
|
+
/**
|
|
45
|
+
* Text form of the entry, decoded lazily from the raw bytes on first text read.
|
|
46
|
+
*/
|
|
47
|
+
private _contents;
|
|
48
|
+
/**
|
|
49
|
+
* Whether `_bytes` is what the archive carried, rather than a re-encode of text
|
|
50
|
+
* supplied to the constructor. Only the former can answer "was this valid UTF-8?".
|
|
51
|
+
*/
|
|
52
|
+
private readonly _bytesAreOriginal;
|
|
38
53
|
/**
|
|
39
54
|
* The ZIP file tree accessors that created this item.
|
|
40
55
|
*/
|
|
@@ -50,10 +65,12 @@ export declare class ZipFileItem<TCT extends string = string> implements FileTre
|
|
|
50
65
|
/**
|
|
51
66
|
* Constructor for ZipFileItem.
|
|
52
67
|
* @param zipFilePath - The path of the file within the ZIP.
|
|
53
|
-
* @param contents - The pre-loaded contents of the
|
|
68
|
+
* @param contents - The pre-loaded contents of the entry, either as raw bytes or as
|
|
69
|
+
* already-decoded text. Text is encoded as UTF-8 for the byte accessor and is also
|
|
70
|
+
* retained verbatim, so supplying text never round-trips through a decode.
|
|
54
71
|
* @param accessors - The ZIP file tree accessors.
|
|
55
72
|
*/
|
|
56
|
-
constructor(zipFilePath: string, contents: string, accessors: ZipFileTreeAccessors<TCT>);
|
|
73
|
+
constructor(zipFilePath: string, contents: string | Uint8Array, accessors: ZipFileTreeAccessors<TCT>);
|
|
57
74
|
/**
|
|
58
75
|
* Sets the content type of the file.
|
|
59
76
|
* @param contentType - The content type of the file.
|
|
@@ -66,8 +83,33 @@ export declare class ZipFileItem<TCT extends string = string> implements FileTre
|
|
|
66
83
|
getContents<T>(converter: Validator<T> | Converter<T>): Result<T>;
|
|
67
84
|
/**
|
|
68
85
|
* Gets the raw contents of the file as a string.
|
|
86
|
+
*
|
|
87
|
+
* @remarks
|
|
88
|
+
* The entry's bytes are decoded as UTF-8 with the lenient WHATWG default, so
|
|
89
|
+
* malformed input is silently replaced with U+FFFD. Use `getRawBytes()` for the
|
|
90
|
+
* undecoded bytes — and `new TextDecoder('utf-8', { fatal: true }).decode(bytes)`
|
|
91
|
+
* for a decode that fails loudly instead.
|
|
69
92
|
*/
|
|
70
93
|
getRawContents(): Result<string>;
|
|
94
|
+
/**
|
|
95
|
+
* Gets the raw bytes of the ZIP entry, with no text decoding applied.
|
|
96
|
+
*
|
|
97
|
+
* @remarks
|
|
98
|
+
* The returned array is the item's internal buffer and must not be modified.
|
|
99
|
+
*/
|
|
100
|
+
getRawBytes(): Result<Uint8Array>;
|
|
101
|
+
/**
|
|
102
|
+
* Gets the file's contents, decoding UTF-8 strictly.
|
|
103
|
+
*
|
|
104
|
+
* @remarks
|
|
105
|
+
* Decidable for an entry read out of the archive, which is byte-native: this
|
|
106
|
+
* item holds exactly the bytes the archive carried. An item constructed from
|
|
107
|
+
* already-decoded text fails instead — its bytes are a re-encode, so they are
|
|
108
|
+
* well-formed UTF-8 by construction and a success would say nothing.
|
|
109
|
+
* @returns `Success` with the decoded text; `Failure` if the entry's bytes are
|
|
110
|
+
* not valid UTF-8, or if this item never held the original bytes.
|
|
111
|
+
*/
|
|
112
|
+
getTextStrict(): Result<string>;
|
|
71
113
|
}
|
|
72
114
|
/**
|
|
73
115
|
* Implementation of `IFileTreeDirectoryItem` for directories in a ZIP archive.
|
|
@@ -105,9 +147,15 @@ export declare class ZipDirectoryItem<TCT extends string = string> implements Fi
|
|
|
105
147
|
* Read-only file tree accessors for ZIP archives.
|
|
106
148
|
* ZIP archives are read-only by design — use {@link FileTree.isMutableAccessors | isMutableAccessors}
|
|
107
149
|
* to check before attempting mutations.
|
|
150
|
+
*
|
|
151
|
+
* @remarks
|
|
152
|
+
* ZIP entries are byte-native, so these accessors also implement the read half of the
|
|
153
|
+
* optional binary capability (`FileTree.IBinaryFileTreeAccessors`) — use
|
|
154
|
+
* `FileTree.isBinaryAccessors` to narrow and `getFileBytes()` to read an entry's
|
|
155
|
+
* undecoded bytes.
|
|
108
156
|
* @public
|
|
109
157
|
*/
|
|
110
|
-
export declare class ZipFileTreeAccessors<TCT extends string = string> implements FileTree.
|
|
158
|
+
export declare class ZipFileTreeAccessors<TCT extends string = string> implements FileTree.IBinaryFileTreeAccessors<TCT>, FileTree.IStrictTextFileTreeAccessors<TCT> {
|
|
111
159
|
/**
|
|
112
160
|
* The unzipped file data.
|
|
113
161
|
*/
|
|
@@ -132,8 +180,8 @@ export declare class ZipFileTreeAccessors<TCT extends string = string> implement
|
|
|
132
180
|
private constructor();
|
|
133
181
|
/**
|
|
134
182
|
* Default function to infer the content type of a file.
|
|
135
|
-
* @param
|
|
136
|
-
* @param
|
|
183
|
+
* @param __filePath - The path of the file.
|
|
184
|
+
* @param __provided - Optional supplied content type.
|
|
137
185
|
* @returns `Success` with the content type of the file if successful, or
|
|
138
186
|
* `Failure` with an error message otherwise.
|
|
139
187
|
* @remarks This default implementation always returns `Success` with `undefined`.
|
|
@@ -201,8 +249,36 @@ export declare class ZipFileTreeAccessors<TCT extends string = string> implement
|
|
|
201
249
|
getItem(path: string): Result<FileTree.FileTreeItem<TCT>>;
|
|
202
250
|
/**
|
|
203
251
|
* Gets the contents of a file in the file tree.
|
|
252
|
+
*
|
|
253
|
+
* @remarks
|
|
254
|
+
* The entry's bytes are decoded as UTF-8 with the lenient WHATWG default. Use
|
|
255
|
+
* `getFileBytes()` for the undecoded bytes.
|
|
204
256
|
*/
|
|
205
257
|
getFileContents(path: string): Result<string>;
|
|
258
|
+
/**
|
|
259
|
+
* Gets the raw bytes of a ZIP entry, with no text decoding applied.
|
|
260
|
+
*
|
|
261
|
+
* @remarks
|
|
262
|
+
* The returned array is the archive's internal buffer and must not be modified.
|
|
263
|
+
*/
|
|
264
|
+
getFileBytes(path: string): Result<Uint8Array>;
|
|
265
|
+
/**
|
|
266
|
+
* Gets the contents of a file in the file tree, decoding UTF-8 strictly.
|
|
267
|
+
*
|
|
268
|
+
* @remarks
|
|
269
|
+
* Always decidable here: ZIP entries are byte-native, so this store holds
|
|
270
|
+
* exactly the bytes the archive carried.
|
|
271
|
+
* @param path - Absolute path of the entry.
|
|
272
|
+
* @returns `Success` with the decoded text; `Failure` if the entry's bytes are
|
|
273
|
+
* not valid UTF-8.
|
|
274
|
+
*/
|
|
275
|
+
getFileTextStrict(path: string): Result<string>;
|
|
276
|
+
/**
|
|
277
|
+
* Resolves a path to the ZIP file item it names.
|
|
278
|
+
* @param path - Path of the entry to look up.
|
|
279
|
+
* @returns `Success` with the item, or `Failure` if it is missing or is a directory.
|
|
280
|
+
*/
|
|
281
|
+
private _getFileItem;
|
|
206
282
|
/**
|
|
207
283
|
* Gets the content type of a file in the file tree.
|
|
208
284
|
*/
|