@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,82 @@
|
|
|
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.classifyAddress = exports.blockPrivateNetworksPolicy = exports.allowAnyAddressPolicy = exports.saferFetchText = exports.saferFetchJson = exports.saferFetchBytes = exports.platformFetchTransport = exports.allowContentTypes = exports.allowAnyAddress = exports.SUPPORTED_SCHEMES = exports.RETRYABLE_HTTP_STATUSES = exports.RETRY_AFTER_STATUSES = exports.REDIRECT_STATUSES = exports.IDEMPOTENT_METHODS = exports.DEFAULT_TIMEOUT_MS = exports.DEFAULT_RETRY_MAX_DELAY_MS = exports.DEFAULT_RETRY_BASE_DELAY_MS = exports.DEFAULT_MAX_RESPONSE_BYTES = exports.DEFAULT_MAX_REDIRECTS = exports.DEFAULT_HEADERS_TIMEOUT_MS = exports.ALWAYS_STRIPPED_HEADERS = void 0;
|
|
23
|
+
/**
|
|
24
|
+
* An HTTP fetch primitive with an explicit threat model (browser version).
|
|
25
|
+
*
|
|
26
|
+
* This barrel deliberately omits `blockPrivateNetworks` and the resolver seam beneath it: that
|
|
27
|
+
* module imports `node:dns/promises`, and exporting it here would pull a Node builtin into a
|
|
28
|
+
* browser bundle.
|
|
29
|
+
*
|
|
30
|
+
* The address-classification layer — `classifyAddress`, and the pure synchronous policies
|
|
31
|
+
* `allowAnyAddressPolicy` / `blockPrivateNetworksPolicy` — **is** exported here: it is pure
|
|
32
|
+
* arithmetic over parsed octets, it works identically in a browser, and it is useful for a
|
|
33
|
+
* URL-zero check. It is not a substitute for the guard, and cannot be: it classifies an address
|
|
34
|
+
* a caller already holds, while what the browser lacks is any way to learn the address a
|
|
35
|
+
* hostname resolves to.
|
|
36
|
+
*
|
|
37
|
+
* Note: the resolved-address (private-IP) guard and per-hop redirect revalidation are NOT
|
|
38
|
+
* available in a browser, and not for want of implementation. There is no browser API that
|
|
39
|
+
* returns a hostname's A/AAAA records, nothing in `fetch` or `Response` exposes the peer
|
|
40
|
+
* address, and `redirect: 'manual'` yields an opaque response whose `Location` is not
|
|
41
|
+
* readable — a `'validate-each-hop'` call there fails as `'redirect-opaque'` rather than
|
|
42
|
+
* quietly following anything. `allowAnyAddress()` is the honest choice, and its name says so.
|
|
43
|
+
*
|
|
44
|
+
* @packageDocumentation
|
|
45
|
+
*/
|
|
46
|
+
var defaults_1 = require("./defaults");
|
|
47
|
+
Object.defineProperty(exports, "ALWAYS_STRIPPED_HEADERS", { enumerable: true, get: function () { return defaults_1.ALWAYS_STRIPPED_HEADERS; } });
|
|
48
|
+
Object.defineProperty(exports, "DEFAULT_HEADERS_TIMEOUT_MS", { enumerable: true, get: function () { return defaults_1.DEFAULT_HEADERS_TIMEOUT_MS; } });
|
|
49
|
+
Object.defineProperty(exports, "DEFAULT_MAX_REDIRECTS", { enumerable: true, get: function () { return defaults_1.DEFAULT_MAX_REDIRECTS; } });
|
|
50
|
+
Object.defineProperty(exports, "DEFAULT_MAX_RESPONSE_BYTES", { enumerable: true, get: function () { return defaults_1.DEFAULT_MAX_RESPONSE_BYTES; } });
|
|
51
|
+
Object.defineProperty(exports, "DEFAULT_RETRY_BASE_DELAY_MS", { enumerable: true, get: function () { return defaults_1.DEFAULT_RETRY_BASE_DELAY_MS; } });
|
|
52
|
+
Object.defineProperty(exports, "DEFAULT_RETRY_MAX_DELAY_MS", { enumerable: true, get: function () { return defaults_1.DEFAULT_RETRY_MAX_DELAY_MS; } });
|
|
53
|
+
Object.defineProperty(exports, "DEFAULT_TIMEOUT_MS", { enumerable: true, get: function () { return defaults_1.DEFAULT_TIMEOUT_MS; } });
|
|
54
|
+
Object.defineProperty(exports, "IDEMPOTENT_METHODS", { enumerable: true, get: function () { return defaults_1.IDEMPOTENT_METHODS; } });
|
|
55
|
+
Object.defineProperty(exports, "REDIRECT_STATUSES", { enumerable: true, get: function () { return defaults_1.REDIRECT_STATUSES; } });
|
|
56
|
+
Object.defineProperty(exports, "RETRY_AFTER_STATUSES", { enumerable: true, get: function () { return defaults_1.RETRY_AFTER_STATUSES; } });
|
|
57
|
+
Object.defineProperty(exports, "RETRYABLE_HTTP_STATUSES", { enumerable: true, get: function () { return defaults_1.RETRYABLE_HTTP_STATUSES; } });
|
|
58
|
+
Object.defineProperty(exports, "SUPPORTED_SCHEMES", { enumerable: true, get: function () { return defaults_1.SUPPORTED_SCHEMES; } });
|
|
59
|
+
var guards_1 = require("./guards");
|
|
60
|
+
Object.defineProperty(exports, "allowAnyAddress", { enumerable: true, get: function () { return guards_1.allowAnyAddress; } });
|
|
61
|
+
Object.defineProperty(exports, "allowContentTypes", { enumerable: true, get: function () { return guards_1.allowContentTypes; } });
|
|
62
|
+
var transport_1 = require("./transport");
|
|
63
|
+
Object.defineProperty(exports, "platformFetchTransport", { enumerable: true, get: function () { return transport_1.platformFetchTransport; } });
|
|
64
|
+
var saferFetch_1 = require("./saferFetch");
|
|
65
|
+
Object.defineProperty(exports, "saferFetchBytes", { enumerable: true, get: function () { return saferFetch_1.saferFetchBytes; } });
|
|
66
|
+
Object.defineProperty(exports, "saferFetchJson", { enumerable: true, get: function () { return saferFetch_1.saferFetchJson; } });
|
|
67
|
+
Object.defineProperty(exports, "saferFetchText", { enumerable: true, get: function () { return saferFetch_1.saferFetchText; } });
|
|
68
|
+
// Runtime-agnostic and exported from both barrels: the address *classification* layer is pure
|
|
69
|
+
// arithmetic over parsed octets with no I/O, so it works in a browser exactly as it does on
|
|
70
|
+
// Node. It is useful there for a URL-zero check — a caller can refuse an IP-literal URL that
|
|
71
|
+
// classifies as private before ever calling `fetch`.
|
|
72
|
+
//
|
|
73
|
+
// **It cannot substitute for the resolved-address guard.** It classifies an address you already
|
|
74
|
+
// have; the guarantee the browser lacks is *obtaining* the address a hostname resolves to, which
|
|
75
|
+
// no browser API provides. `https://internal.example.com/` resolving to `10.0.0.5` is invisible
|
|
76
|
+
// to every function exported here.
|
|
77
|
+
var addressPolicy_1 = require("./addressPolicy");
|
|
78
|
+
Object.defineProperty(exports, "allowAnyAddressPolicy", { enumerable: true, get: function () { return addressPolicy_1.allowAnyAddressPolicy; } });
|
|
79
|
+
Object.defineProperty(exports, "blockPrivateNetworksPolicy", { enumerable: true, get: function () { return addressPolicy_1.blockPrivateNetworksPolicy; } });
|
|
80
|
+
var addressClassification_1 = require("./addressClassification");
|
|
81
|
+
Object.defineProperty(exports, "classifyAddress", { enumerable: true, get: function () { return addressClassification_1.classifyAddress; } });
|
|
82
|
+
//# sourceMappingURL=index.browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.browser.js","sourceRoot":"","sources":["../../../src/packlets/safer-fetch/index.browser.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;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,uCAaoB;AAZlB,mHAAA,uBAAuB,OAAA;AACvB,sHAAA,0BAA0B,OAAA;AAC1B,iHAAA,qBAAqB,OAAA;AACrB,sHAAA,0BAA0B,OAAA;AAC1B,uHAAA,2BAA2B,OAAA;AAC3B,sHAAA,0BAA0B,OAAA;AAC1B,8GAAA,kBAAkB,OAAA;AAClB,8GAAA,kBAAkB,OAAA;AAClB,6GAAA,iBAAiB,OAAA;AACjB,gHAAA,oBAAoB,OAAA;AACpB,mHAAA,uBAAuB,OAAA;AACvB,6GAAA,iBAAiB,OAAA;AAwBnB,mCAA8D;AAArD,yGAAA,eAAe,OAAA;AAAE,2GAAA,iBAAiB,OAAA;AAE3C,yCAAqD;AAA5C,mHAAA,sBAAsB,OAAA;AAE/B,2CAA4G;AAAnG,6GAAA,eAAe,OAAA;AAAE,4GAAA,cAAc,OAAA;AAAE,4GAAA,cAAc,OAAA;AAExD,8FAA8F;AAC9F,4FAA4F;AAC5F,6FAA6F;AAC7F,qDAAqD;AACrD,EAAE;AACF,gGAAgG;AAChG,iGAAiG;AACjG,gGAAgG;AAChG,mCAAmC;AACnC,iDAMyB;AALvB,sHAAA,qBAAqB,OAAA;AACrB,2HAAA,0BAA0B,OAAA;AAM5B,iEAOiC;AAN/B,wHAAA,eAAe,OAAA","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\n/**\n * An HTTP fetch primitive with an explicit threat model (browser version).\n *\n * This barrel deliberately omits `blockPrivateNetworks` and the resolver seam beneath it: that\n * module imports `node:dns/promises`, and exporting it here would pull a Node builtin into a\n * browser bundle.\n *\n * The address-classification layer — `classifyAddress`, and the pure synchronous policies\n * `allowAnyAddressPolicy` / `blockPrivateNetworksPolicy` — **is** exported here: it is pure\n * arithmetic over parsed octets, it works identically in a browser, and it is useful for a\n * URL-zero check. It is not a substitute for the guard, and cannot be: it classifies an address\n * a caller already holds, while what the browser lacks is any way to learn the address a\n * hostname resolves to.\n *\n * Note: the resolved-address (private-IP) guard and per-hop redirect revalidation are NOT\n * available in a browser, and not for want of implementation. There is no browser API that\n * returns a hostname's A/AAAA records, nothing in `fetch` or `Response` exposes the peer\n * address, and `redirect: 'manual'` yields an opaque response whose `Location` is not\n * readable — a `'validate-each-hop'` call there fails as `'redirect-opaque'` rather than\n * quietly following anything. `allowAnyAddress()` is the honest choice, and its name says so.\n *\n * @packageDocumentation\n */\n\nexport {\n ALWAYS_STRIPPED_HEADERS,\n DEFAULT_HEADERS_TIMEOUT_MS,\n DEFAULT_MAX_REDIRECTS,\n DEFAULT_MAX_RESPONSE_BYTES,\n DEFAULT_RETRY_BASE_DELAY_MS,\n DEFAULT_RETRY_MAX_DELAY_MS,\n DEFAULT_TIMEOUT_MS,\n IDEMPOTENT_METHODS,\n REDIRECT_STATUSES,\n RETRY_AFTER_STATUSES,\n RETRYABLE_HTTP_STATUSES,\n SUPPORTED_SCHEMES\n} from './defaults';\n\nexport type { FetchFailureReason, FetchTimeoutPhase } from './failureReason';\nexport type { IRetryPolicy } from './retry';\n\nexport type {\n IAddressGuard,\n IFetchTransport,\n IFetchTransportHints,\n IGuardVerdict,\n IRequestGuard,\n IRequestHop,\n IResolvedGuards,\n IResponseBodyGuard,\n IResponseHeadersGuard,\n ISaferFetchOptions,\n ISaferFetchRequest,\n ISaferFetchResponse,\n ISaferFetchResponseHead,\n SaferFetchMethod,\n SaferFetchRedirectPolicy\n} from './model';\n\nexport { allowAnyAddress, allowContentTypes } from './guards';\n\nexport { platformFetchTransport } from './transport';\n\nexport { saferFetchBytes, saferFetchJson, saferFetchText, type ISaferFetchJsonOptions } from './saferFetch';\n\n// Runtime-agnostic and exported from both barrels: the address *classification* layer is pure\n// arithmetic over parsed octets with no I/O, so it works in a browser exactly as it does on\n// Node. It is useful there for a URL-zero check — a caller can refuse an IP-literal URL that\n// classifies as private before ever calling `fetch`.\n//\n// **It cannot substitute for the resolved-address guard.** It classifies an address you already\n// have; the guarantee the browser lacks is *obtaining* the address a hostname resolves to, which\n// no browser API provides. `https://internal.example.com/` resolving to `10.0.0.5` is invisible\n// to every function exported here.\nexport {\n allowAnyAddressPolicy,\n blockPrivateNetworksPolicy,\n type IAddressCheckVerdict,\n type IAddressPolicy,\n type IBlockPrivateNetworksOptions\n} from './addressPolicy';\n\nexport {\n classifyAddress,\n type AddressClassification,\n type AddressFamily,\n type IClassifiedAddress,\n type IEmbeddedIpv4,\n type Ipv4EmbeddingKind\n} from './addressClassification';\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A safer `fetch` primitive with an explicit threat model.
|
|
3
|
+
*
|
|
4
|
+
* This is deliberately **not** a thin, unopinionated boundary over an upstream library. There
|
|
5
|
+
* is no upstream to wrap — `fetch` is a platform global — and the opinion *is* the product:
|
|
6
|
+
* the deadlines, the scheme refusal, the streaming size cap, the redirect posture, and the
|
|
7
|
+
* required address guard are the deliverable. A caller who strips the opinion out has `fetch`,
|
|
8
|
+
* which is where they started.
|
|
9
|
+
*
|
|
10
|
+
* The guiding constraint: *a primitive that advertises a guarantee it does not have is worse
|
|
11
|
+
* than five lines at a call site, because it transfers responsibility without transferring
|
|
12
|
+
* protection.* Every entry point's documentation names what it does **not** protect against
|
|
13
|
+
* next to what it does.
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
export { ALWAYS_STRIPPED_HEADERS, DEFAULT_HEADERS_TIMEOUT_MS, DEFAULT_MAX_REDIRECTS, DEFAULT_MAX_RESPONSE_BYTES, DEFAULT_RETRY_BASE_DELAY_MS, DEFAULT_RETRY_MAX_DELAY_MS, DEFAULT_TIMEOUT_MS, IDEMPOTENT_METHODS, REDIRECT_STATUSES, RETRY_AFTER_STATUSES, RETRYABLE_HTTP_STATUSES, SUPPORTED_SCHEMES } from './defaults';
|
|
18
|
+
export type { FetchFailureReason, FetchTimeoutPhase } from './failureReason';
|
|
19
|
+
export type { IRetryPolicy } from './retry';
|
|
20
|
+
export type { IAddressGuard, IFetchTransport, IFetchTransportHints, IGuardVerdict, IRequestGuard, IRequestHop, IResolvedGuards, IResponseBodyGuard, IResponseHeadersGuard, ISaferFetchOptions, ISaferFetchRequest, ISaferFetchResponse, ISaferFetchResponseHead, SaferFetchMethod, SaferFetchRedirectPolicy } from './model';
|
|
21
|
+
export { allowAnyAddress, allowContentTypes } from './guards';
|
|
22
|
+
export { platformFetchTransport } from './transport';
|
|
23
|
+
export { saferFetchBytes, saferFetchJson, saferFetchText, type ISaferFetchJsonOptions } from './saferFetch';
|
|
24
|
+
export { allowAnyAddressPolicy, blockPrivateNetworksPolicy, type IAddressCheckVerdict, type IAddressPolicy, type IBlockPrivateNetworksOptions } from './addressPolicy';
|
|
25
|
+
export { blockPrivateNetworks, nodeHostResolver, type HostResolver, type IBlockPrivateNetworksGuardOptions } from './nodeAddressGuard';
|
|
26
|
+
export { classifyAddress, type AddressClassification, type AddressFamily, type IClassifiedAddress, type IEmbeddedIpv4, type Ipv4EmbeddingKind } from './addressClassification';
|
|
27
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/packlets/safer-fetch/index.ts"],"names":[],"mappings":"AAoBA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,qBAAqB,EACrB,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,EAC1B,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC7E,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,YAAY,EACV,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,aAAa,EACb,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,gBAAgB,EAChB,wBAAwB,EACzB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,KAAK,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAQ5G,OAAO,EACL,qBAAqB,EACrB,0BAA0B,EAC1B,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,4BAA4B,EAClC,MAAM,iBAAiB,CAAC;AAKzB,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,KAAK,YAAY,EACjB,KAAK,iCAAiC,EACvC,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,eAAe,EACf,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACvB,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
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.classifyAddress = exports.nodeHostResolver = exports.blockPrivateNetworks = exports.blockPrivateNetworksPolicy = exports.allowAnyAddressPolicy = exports.saferFetchText = exports.saferFetchJson = exports.saferFetchBytes = exports.platformFetchTransport = exports.allowContentTypes = exports.allowAnyAddress = exports.SUPPORTED_SCHEMES = exports.RETRYABLE_HTTP_STATUSES = exports.RETRY_AFTER_STATUSES = exports.REDIRECT_STATUSES = exports.IDEMPOTENT_METHODS = exports.DEFAULT_TIMEOUT_MS = exports.DEFAULT_RETRY_MAX_DELAY_MS = exports.DEFAULT_RETRY_BASE_DELAY_MS = exports.DEFAULT_MAX_RESPONSE_BYTES = exports.DEFAULT_MAX_REDIRECTS = exports.DEFAULT_HEADERS_TIMEOUT_MS = exports.ALWAYS_STRIPPED_HEADERS = void 0;
|
|
23
|
+
/**
|
|
24
|
+
* A safer `fetch` primitive with an explicit threat model.
|
|
25
|
+
*
|
|
26
|
+
* This is deliberately **not** a thin, unopinionated boundary over an upstream library. There
|
|
27
|
+
* is no upstream to wrap — `fetch` is a platform global — and the opinion *is* the product:
|
|
28
|
+
* the deadlines, the scheme refusal, the streaming size cap, the redirect posture, and the
|
|
29
|
+
* required address guard are the deliverable. A caller who strips the opinion out has `fetch`,
|
|
30
|
+
* which is where they started.
|
|
31
|
+
*
|
|
32
|
+
* The guiding constraint: *a primitive that advertises a guarantee it does not have is worse
|
|
33
|
+
* than five lines at a call site, because it transfers responsibility without transferring
|
|
34
|
+
* protection.* Every entry point's documentation names what it does **not** protect against
|
|
35
|
+
* next to what it does.
|
|
36
|
+
*
|
|
37
|
+
* @packageDocumentation
|
|
38
|
+
*/
|
|
39
|
+
var defaults_1 = require("./defaults");
|
|
40
|
+
Object.defineProperty(exports, "ALWAYS_STRIPPED_HEADERS", { enumerable: true, get: function () { return defaults_1.ALWAYS_STRIPPED_HEADERS; } });
|
|
41
|
+
Object.defineProperty(exports, "DEFAULT_HEADERS_TIMEOUT_MS", { enumerable: true, get: function () { return defaults_1.DEFAULT_HEADERS_TIMEOUT_MS; } });
|
|
42
|
+
Object.defineProperty(exports, "DEFAULT_MAX_REDIRECTS", { enumerable: true, get: function () { return defaults_1.DEFAULT_MAX_REDIRECTS; } });
|
|
43
|
+
Object.defineProperty(exports, "DEFAULT_MAX_RESPONSE_BYTES", { enumerable: true, get: function () { return defaults_1.DEFAULT_MAX_RESPONSE_BYTES; } });
|
|
44
|
+
Object.defineProperty(exports, "DEFAULT_RETRY_BASE_DELAY_MS", { enumerable: true, get: function () { return defaults_1.DEFAULT_RETRY_BASE_DELAY_MS; } });
|
|
45
|
+
Object.defineProperty(exports, "DEFAULT_RETRY_MAX_DELAY_MS", { enumerable: true, get: function () { return defaults_1.DEFAULT_RETRY_MAX_DELAY_MS; } });
|
|
46
|
+
Object.defineProperty(exports, "DEFAULT_TIMEOUT_MS", { enumerable: true, get: function () { return defaults_1.DEFAULT_TIMEOUT_MS; } });
|
|
47
|
+
Object.defineProperty(exports, "IDEMPOTENT_METHODS", { enumerable: true, get: function () { return defaults_1.IDEMPOTENT_METHODS; } });
|
|
48
|
+
Object.defineProperty(exports, "REDIRECT_STATUSES", { enumerable: true, get: function () { return defaults_1.REDIRECT_STATUSES; } });
|
|
49
|
+
Object.defineProperty(exports, "RETRY_AFTER_STATUSES", { enumerable: true, get: function () { return defaults_1.RETRY_AFTER_STATUSES; } });
|
|
50
|
+
Object.defineProperty(exports, "RETRYABLE_HTTP_STATUSES", { enumerable: true, get: function () { return defaults_1.RETRYABLE_HTTP_STATUSES; } });
|
|
51
|
+
Object.defineProperty(exports, "SUPPORTED_SCHEMES", { enumerable: true, get: function () { return defaults_1.SUPPORTED_SCHEMES; } });
|
|
52
|
+
var guards_1 = require("./guards");
|
|
53
|
+
Object.defineProperty(exports, "allowAnyAddress", { enumerable: true, get: function () { return guards_1.allowAnyAddress; } });
|
|
54
|
+
Object.defineProperty(exports, "allowContentTypes", { enumerable: true, get: function () { return guards_1.allowContentTypes; } });
|
|
55
|
+
var transport_1 = require("./transport");
|
|
56
|
+
Object.defineProperty(exports, "platformFetchTransport", { enumerable: true, get: function () { return transport_1.platformFetchTransport; } });
|
|
57
|
+
var saferFetch_1 = require("./saferFetch");
|
|
58
|
+
Object.defineProperty(exports, "saferFetchBytes", { enumerable: true, get: function () { return saferFetch_1.saferFetchBytes; } });
|
|
59
|
+
Object.defineProperty(exports, "saferFetchJson", { enumerable: true, get: function () { return saferFetch_1.saferFetchJson; } });
|
|
60
|
+
Object.defineProperty(exports, "saferFetchText", { enumerable: true, get: function () { return saferFetch_1.saferFetchText; } });
|
|
61
|
+
// Two layers, one naming rule: an **unsuffixed** factory returns the asynchronous,
|
|
62
|
+
// hop-chain-aware, name-resolving `IAddressGuard` that an entry point's `addressGuard` option
|
|
63
|
+
// takes (`allowAnyAddress`, `blockPrivateNetworks`), while a **`Policy`-suffixed** factory
|
|
64
|
+
// returns the pure, synchronous `IAddressPolicy` over an already-resolved address list that such
|
|
65
|
+
// a guard delegates to (`allowAnyAddressPolicy`, `blockPrivateNetworksPolicy`). The unsuffixed
|
|
66
|
+
// names are the ones callers reach for, which is why they are the ones that fit the call site.
|
|
67
|
+
var addressPolicy_1 = require("./addressPolicy");
|
|
68
|
+
Object.defineProperty(exports, "allowAnyAddressPolicy", { enumerable: true, get: function () { return addressPolicy_1.allowAnyAddressPolicy; } });
|
|
69
|
+
Object.defineProperty(exports, "blockPrivateNetworksPolicy", { enumerable: true, get: function () { return addressPolicy_1.blockPrivateNetworksPolicy; } });
|
|
70
|
+
// Node only — it resolves names, and no browser API returns a hostname's A/AAAA records. This
|
|
71
|
+
// is the one module in the packlet that performs I/O, and the reason this barrel and the browser
|
|
72
|
+
// barrel differ at all.
|
|
73
|
+
var nodeAddressGuard_1 = require("./nodeAddressGuard");
|
|
74
|
+
Object.defineProperty(exports, "blockPrivateNetworks", { enumerable: true, get: function () { return nodeAddressGuard_1.blockPrivateNetworks; } });
|
|
75
|
+
Object.defineProperty(exports, "nodeHostResolver", { enumerable: true, get: function () { return nodeAddressGuard_1.nodeHostResolver; } });
|
|
76
|
+
var addressClassification_1 = require("./addressClassification");
|
|
77
|
+
Object.defineProperty(exports, "classifyAddress", { enumerable: true, get: function () { return addressClassification_1.classifyAddress; } });
|
|
78
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/packlets/safer-fetch/index.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;;;;;;;;;;;;;;;GAeG;AAEH,uCAaoB;AAZlB,mHAAA,uBAAuB,OAAA;AACvB,sHAAA,0BAA0B,OAAA;AAC1B,iHAAA,qBAAqB,OAAA;AACrB,sHAAA,0BAA0B,OAAA;AAC1B,uHAAA,2BAA2B,OAAA;AAC3B,sHAAA,0BAA0B,OAAA;AAC1B,8GAAA,kBAAkB,OAAA;AAClB,8GAAA,kBAAkB,OAAA;AAClB,6GAAA,iBAAiB,OAAA;AACjB,gHAAA,oBAAoB,OAAA;AACpB,mHAAA,uBAAuB,OAAA;AACvB,6GAAA,iBAAiB,OAAA;AAwBnB,mCAA8D;AAArD,yGAAA,eAAe,OAAA;AAAE,2GAAA,iBAAiB,OAAA;AAE3C,yCAAqD;AAA5C,mHAAA,sBAAsB,OAAA;AAE/B,2CAA4G;AAAnG,6GAAA,eAAe,OAAA;AAAE,4GAAA,cAAc,OAAA;AAAE,4GAAA,cAAc,OAAA;AAExD,mFAAmF;AACnF,8FAA8F;AAC9F,2FAA2F;AAC3F,iGAAiG;AACjG,+FAA+F;AAC/F,+FAA+F;AAC/F,iDAMyB;AALvB,sHAAA,qBAAqB,OAAA;AACrB,2HAAA,0BAA0B,OAAA;AAM5B,8FAA8F;AAC9F,iGAAiG;AACjG,wBAAwB;AACxB,uDAK4B;AAJ1B,wHAAA,oBAAoB,OAAA;AACpB,oHAAA,gBAAgB,OAAA;AAKlB,iEAOiC;AAN/B,wHAAA,eAAe,OAAA","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\n/**\n * A safer `fetch` primitive with an explicit threat model.\n *\n * This is deliberately **not** a thin, unopinionated boundary over an upstream library. There\n * is no upstream to wrap — `fetch` is a platform global — and the opinion *is* the product:\n * the deadlines, the scheme refusal, the streaming size cap, the redirect posture, and the\n * required address guard are the deliverable. A caller who strips the opinion out has `fetch`,\n * which is where they started.\n *\n * The guiding constraint: *a primitive that advertises a guarantee it does not have is worse\n * than five lines at a call site, because it transfers responsibility without transferring\n * protection.* Every entry point's documentation names what it does **not** protect against\n * next to what it does.\n *\n * @packageDocumentation\n */\n\nexport {\n ALWAYS_STRIPPED_HEADERS,\n DEFAULT_HEADERS_TIMEOUT_MS,\n DEFAULT_MAX_REDIRECTS,\n DEFAULT_MAX_RESPONSE_BYTES,\n DEFAULT_RETRY_BASE_DELAY_MS,\n DEFAULT_RETRY_MAX_DELAY_MS,\n DEFAULT_TIMEOUT_MS,\n IDEMPOTENT_METHODS,\n REDIRECT_STATUSES,\n RETRY_AFTER_STATUSES,\n RETRYABLE_HTTP_STATUSES,\n SUPPORTED_SCHEMES\n} from './defaults';\n\nexport type { FetchFailureReason, FetchTimeoutPhase } from './failureReason';\nexport type { IRetryPolicy } from './retry';\n\nexport type {\n IAddressGuard,\n IFetchTransport,\n IFetchTransportHints,\n IGuardVerdict,\n IRequestGuard,\n IRequestHop,\n IResolvedGuards,\n IResponseBodyGuard,\n IResponseHeadersGuard,\n ISaferFetchOptions,\n ISaferFetchRequest,\n ISaferFetchResponse,\n ISaferFetchResponseHead,\n SaferFetchMethod,\n SaferFetchRedirectPolicy\n} from './model';\n\nexport { allowAnyAddress, allowContentTypes } from './guards';\n\nexport { platformFetchTransport } from './transport';\n\nexport { saferFetchBytes, saferFetchJson, saferFetchText, type ISaferFetchJsonOptions } from './saferFetch';\n\n// Two layers, one naming rule: an **unsuffixed** factory returns the asynchronous,\n// hop-chain-aware, name-resolving `IAddressGuard` that an entry point's `addressGuard` option\n// takes (`allowAnyAddress`, `blockPrivateNetworks`), while a **`Policy`-suffixed** factory\n// returns the pure, synchronous `IAddressPolicy` over an already-resolved address list that such\n// a guard delegates to (`allowAnyAddressPolicy`, `blockPrivateNetworksPolicy`). The unsuffixed\n// names are the ones callers reach for, which is why they are the ones that fit the call site.\nexport {\n allowAnyAddressPolicy,\n blockPrivateNetworksPolicy,\n type IAddressCheckVerdict,\n type IAddressPolicy,\n type IBlockPrivateNetworksOptions\n} from './addressPolicy';\n\n// Node only — it resolves names, and no browser API returns a hostname's A/AAAA records. This\n// is the one module in the packlet that performs I/O, and the reason this barrel and the browser\n// barrel differ at all.\nexport {\n blockPrivateNetworks,\n nodeHostResolver,\n type HostResolver,\n type IBlockPrivateNetworksGuardOptions\n} from './nodeAddressGuard';\n\nexport {\n classifyAddress,\n type AddressClassification,\n type AddressFamily,\n type IClassifiedAddress,\n type IEmbeddedIpv4,\n type Ipv4EmbeddingKind\n} from './addressClassification';\n"]}
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
import type { Logging, Result } from '@fgv/ts-utils';
|
|
2
|
+
import type { IRetryPolicy } from './retry';
|
|
3
|
+
/**
|
|
4
|
+
* HTTP methods a safer-fetch call may use.
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export type SaferFetchMethod = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
8
|
+
/**
|
|
9
|
+
* How redirects are handled.
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* `'reject'` fails on any redirect status. It is the default, and the only mode with an
|
|
13
|
+
* equivalent guarantee on every runtime — a browser cannot inspect a redirect hop at all, so a
|
|
14
|
+
* per-hop revalidating mode is not implementable there.
|
|
15
|
+
*
|
|
16
|
+
* The *guarantee* is equivalent on both runtimes; the failure **reason** is not. Every call uses
|
|
17
|
+
* `redirect: 'manual'`, so on Node a rejected redirect surfaces as `'redirect-rejected'` carrying
|
|
18
|
+
* the status, while in a browser the response is opaque — `type` is `'opaqueredirect'` and
|
|
19
|
+
* `status` is `0`, so there is no status to report — and the same redirect surfaces as
|
|
20
|
+
* `'redirect-opaque'`. Callers that branch on the reason under `'reject'` must handle both.
|
|
21
|
+
*
|
|
22
|
+
* `'validate-each-hop'` follows redirects with `redirect: 'manual'` and runs the **full address
|
|
23
|
+
* guard on every hop before any connection is made**, resolving `Location` against the hop that
|
|
24
|
+
* sent it. Redirect handling and the address check are one mechanism, not two: a guard that
|
|
25
|
+
* validated only the caller's URL is defeated by a single `302` to `http://169.254.169.254/`.
|
|
26
|
+
* Following hops also makes this primitive responsible for credential stripping — see
|
|
27
|
+
* `ISaferFetchOptions.sensitiveHeaders`.
|
|
28
|
+
*
|
|
29
|
+
* **`'validate-each-hop'` is accepted by the browser barrel but cannot succeed there, and fails
|
|
30
|
+
* loudly rather than degrading.** The type is shared because one core serves both runtimes; the
|
|
31
|
+
* runtime is not. A browser's `redirect: 'manual'` yields an opaque response — `type` is
|
|
32
|
+
* `'opaqueredirect'`, `status` is `0`, and `Location` is not readable — so the first redirect
|
|
33
|
+
* fails as `'redirect-opaque'`. That is the honest outcome: the hop information does not exist
|
|
34
|
+
* on the browser side of the API, so there is nothing to guard and nothing to follow. Use
|
|
35
|
+
* `'reject'` there, or handle `'redirect-opaque'`.
|
|
36
|
+
*
|
|
37
|
+
* A mode that defers to the platform's own redirect following is deliberately absent on Node:
|
|
38
|
+
* it would put hops on the wire that the guard never saw.
|
|
39
|
+
* @public
|
|
40
|
+
*/
|
|
41
|
+
export type SaferFetchRedirectPolicy = 'reject' | 'validate-each-hop';
|
|
42
|
+
/**
|
|
43
|
+
* One hop in a redirect chain. Entry 0 is the caller's original request.
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
export interface IRequestHop {
|
|
47
|
+
/** The URL under consideration for this hop. */
|
|
48
|
+
readonly url: URL;
|
|
49
|
+
/** The redirect status that produced the NEXT hop; absent on the current one. */
|
|
50
|
+
readonly status?: number;
|
|
51
|
+
/**
|
|
52
|
+
* The address actually connected to on this hop, when address pinning was in effect.
|
|
53
|
+
*
|
|
54
|
+
* @remarks
|
|
55
|
+
* Populated from the address guard's {@link SaferFetch.IGuardVerdict.pinnedAddress} once the
|
|
56
|
+
* transport has accepted it — which is sound because a transport that cannot honor a pin is
|
|
57
|
+
* required to fail rather than connect by hostname, so a completed request with a pin set is
|
|
58
|
+
* evidence the pin held. **Undefined throughout this release**, since no shipped guard pins
|
|
59
|
+
* and {@link SaferFetch.platformFetchTransport} cannot honor one; the field is where the
|
|
60
|
+
* rebinding defense's per-hop evidence will live.
|
|
61
|
+
*/
|
|
62
|
+
readonly connectedAddress?: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* An address guard's decision about a hop.
|
|
66
|
+
* @public
|
|
67
|
+
*/
|
|
68
|
+
export interface IGuardVerdict {
|
|
69
|
+
/**
|
|
70
|
+
* The URL cleared for request. Guards may **normalize** it — lowercase the host, strip a
|
|
71
|
+
* trailing dot, punycode an IDN — and the normalized URL is what gets requested. Guards
|
|
72
|
+
* must not **retarget** it to a different destination.
|
|
73
|
+
*
|
|
74
|
+
* @remarks
|
|
75
|
+
* That contract is documented rather than enforced: origin-equality enforcement would
|
|
76
|
+
* reject exactly the normalizations the guard is supposed to perform. Guards are trusted
|
|
77
|
+
* first-party code; a malicious in-process caller is out of this primitive's threat model.
|
|
78
|
+
* The one check that is enforced is the scheme — a verdict URL whose scheme is not
|
|
79
|
+
* `http:` or `https:` is rejected.
|
|
80
|
+
*/
|
|
81
|
+
readonly url: URL;
|
|
82
|
+
/**
|
|
83
|
+
* The address the guard validated and to which the connection SHOULD be pinned.
|
|
84
|
+
*
|
|
85
|
+
* @remarks
|
|
86
|
+
* **Always `undefined` in this release** — reserved for the pinned-connect work that
|
|
87
|
+
* closes the DNS-rebinding hole. A transport that receives a defined value it cannot
|
|
88
|
+
* honor MUST fail rather than connect by hostname; {@link SaferFetch.platformFetchTransport}
|
|
89
|
+
* does exactly that. Ignoring the hint would give a deployment that wired a pinning guard
|
|
90
|
+
* but forgot the matching transport precisely the rebinding exposure it believed it had
|
|
91
|
+
* closed, silently.
|
|
92
|
+
*/
|
|
93
|
+
readonly pinnedAddress?: string;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Decides whether a connection may be made. Invoked once per redirect hop, never only on
|
|
97
|
+
* the initial URL.
|
|
98
|
+
*
|
|
99
|
+
* @remarks
|
|
100
|
+
* This is the SSRF boundary and the one guard whose failure is catastrophic, which is why
|
|
101
|
+
* it is a separate seam from the request and response policy guards: "did the address check
|
|
102
|
+
* run, and run correctly?" should be answerable by reading one small implementation.
|
|
103
|
+
*
|
|
104
|
+
* The seam is **asynchronous and hop-chain-aware so that it can wrap a pure classifier**: a
|
|
105
|
+
* real guard resolves `url.hostname` to an address list and then delegates the judgement to a
|
|
106
|
+
* synchronous, address-list-in policy. That split keeps the part with the adversarial test
|
|
107
|
+
* matrix — the address classification itself — free of transports, DNS, and hop bookkeeping,
|
|
108
|
+
* and keeps exactly one implementation of it. A guard is the resolving, chain-aware half; it
|
|
109
|
+
* should not re-derive what the classifier already decides.
|
|
110
|
+
*
|
|
111
|
+
* Classify `url.hostname`, never raw URL text: the WHATWG parser has already normalized
|
|
112
|
+
* `127.0x.1` to `127.0.0.1` and `::ffff:169.254.169.254` to `::ffff:a9fe:a9fe`, and text
|
|
113
|
+
* matching misses both.
|
|
114
|
+
* @public
|
|
115
|
+
*/
|
|
116
|
+
export interface IAddressGuard {
|
|
117
|
+
/** Stable identifier, surfaced in `'blocked-by-guard'` failures. */
|
|
118
|
+
readonly name: string;
|
|
119
|
+
/**
|
|
120
|
+
* @param chain - Every hop so far, oldest first. The URL under consideration is the last
|
|
121
|
+
* entry; `chain.length === 1` is the initial request. There is deliberately no separate
|
|
122
|
+
* "is this a redirect" flag — hop 0 is not a special case, and a guard that compares only
|
|
123
|
+
* against the immediately previous hop cannot see an `A → B → A` laundering hop.
|
|
124
|
+
*/
|
|
125
|
+
check(chain: ReadonlyArray<IRequestHop>): Promise<Result<IGuardVerdict>>;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* The request a safer-fetch call is about to issue.
|
|
129
|
+
* @public
|
|
130
|
+
*/
|
|
131
|
+
export interface ISaferFetchRequest {
|
|
132
|
+
readonly url: URL;
|
|
133
|
+
readonly method: SaferFetchMethod;
|
|
134
|
+
/** Header names are lowercased. */
|
|
135
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
136
|
+
readonly body?: string | Uint8Array;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Response status and headers, available before any body bytes are read.
|
|
140
|
+
* @public
|
|
141
|
+
*/
|
|
142
|
+
export interface ISaferFetchResponseHead {
|
|
143
|
+
readonly status: number;
|
|
144
|
+
readonly statusText: string;
|
|
145
|
+
/** Header names are lowercased. */
|
|
146
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
147
|
+
/** Raw `content-type` header value, including any parameters. */
|
|
148
|
+
readonly contentType?: string;
|
|
149
|
+
/** Parsed `content-length`, present only when the header was sent and is a valid count. */
|
|
150
|
+
readonly contentLength?: number;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Policy guard over the outbound request.
|
|
154
|
+
*
|
|
155
|
+
* @remarks
|
|
156
|
+
* **Reject-only.** Silently rewriting a caller's headers or body inside a fetch primitive
|
|
157
|
+
* means the caller no longer knows what was sent. To alter the request, return an explicit
|
|
158
|
+
* replacement the caller could have observed.
|
|
159
|
+
*
|
|
160
|
+
* Runs **before** the address guard, so an address guard is always the last word before the
|
|
161
|
+
* connect: a replacement request that changed the URL is still address-checked.
|
|
162
|
+
* @public
|
|
163
|
+
*/
|
|
164
|
+
export interface IRequestGuard {
|
|
165
|
+
readonly name: string;
|
|
166
|
+
check(request: ISaferFetchRequest, chain: ReadonlyArray<IRequestHop>): Promise<Result<ISaferFetchRequest>>;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Policy guard over the response head.
|
|
170
|
+
*
|
|
171
|
+
* @remarks
|
|
172
|
+
* Runs before any body bytes are read, so a rejection costs a header comparison instead of a
|
|
173
|
+
* partial body transfer. This is the right layer for content-type gating — see
|
|
174
|
+
* {@link SaferFetch.allowContentTypes}.
|
|
175
|
+
* @public
|
|
176
|
+
*/
|
|
177
|
+
export interface IResponseHeadersGuard {
|
|
178
|
+
readonly name: string;
|
|
179
|
+
/**
|
|
180
|
+
* The media types this guard accepts, when it is a content-type allowlist.
|
|
181
|
+
*
|
|
182
|
+
* @remarks
|
|
183
|
+
* Present so that a rejection can be reported as `'unsupported-content-type'` carrying the
|
|
184
|
+
* accepted list, rather than as an opaque policy rejection the caller has to parse a message
|
|
185
|
+
* to understand. A guard that is not a content-type allowlist omits it and its rejections are
|
|
186
|
+
* reported as `'blocked-by-guard'`.
|
|
187
|
+
*/
|
|
188
|
+
readonly acceptedContentTypes?: ReadonlyArray<string>;
|
|
189
|
+
check(head: ISaferFetchResponseHead, chain: ReadonlyArray<IRequestHop>): Promise<Result<true>>;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Policy guard over the buffered response body.
|
|
193
|
+
*
|
|
194
|
+
* @remarks
|
|
195
|
+
* Runs on the buffered body, after the size cap has been enforced — so it can never be handed
|
|
196
|
+
* an unbounded stream.
|
|
197
|
+
* @public
|
|
198
|
+
*/
|
|
199
|
+
export interface IResponseBodyGuard {
|
|
200
|
+
readonly name: string;
|
|
201
|
+
check(body: Uint8Array, head: ISaferFetchResponseHead): Promise<Result<true>>;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Out-of-band information a transport may need that `RequestInit` cannot express.
|
|
205
|
+
* @public
|
|
206
|
+
*/
|
|
207
|
+
export interface IFetchTransportHints {
|
|
208
|
+
/**
|
|
209
|
+
* The address the address guard validated, to which this connection must be pinned.
|
|
210
|
+
* A transport that cannot pin MUST fail rather than connect by hostname.
|
|
211
|
+
*/
|
|
212
|
+
readonly pinnedAddress?: string;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Performs the actual request.
|
|
216
|
+
*
|
|
217
|
+
* @remarks
|
|
218
|
+
* Injectable for two reasons. It is the seam through which a pinned-connect implementation
|
|
219
|
+
* drops in without any caller-visible signature change — which is what keeps closing the
|
|
220
|
+
* DNS-rebinding hole additive rather than breaking. And it is the test seam: redirect chains,
|
|
221
|
+
* lying `Content-Length` headers, compression-bomb shapes, and trickling bodies are all
|
|
222
|
+
* unit-testable through a scripted transport, with no live server anywhere in the suite.
|
|
223
|
+
* @public
|
|
224
|
+
*/
|
|
225
|
+
export interface IFetchTransport {
|
|
226
|
+
readonly name: string;
|
|
227
|
+
fetch(url: URL, init: RequestInit, hints: IFetchTransportHints): Promise<Result<Response>>;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Options common to every safer-fetch entry point.
|
|
231
|
+
* @public
|
|
232
|
+
*/
|
|
233
|
+
export interface ISaferFetchOptions {
|
|
234
|
+
/**
|
|
235
|
+
* **Required, with no default.** A passthrough default here would be exactly the failure
|
|
236
|
+
* this primitive exists to avoid — advertising a guarantee it does not have. Requiring it
|
|
237
|
+
* makes omission a *compile* error rather than a runtime surprise or a lint rule, and makes
|
|
238
|
+
* every call site's posture greppable in one search with no ambient default to overlook.
|
|
239
|
+
*
|
|
240
|
+
* Use a named factory. `allowAnyAddress()` is the explicit, deliberately uncomfortable
|
|
241
|
+
* opt-out, and is the only correct choice in a browser, where neither DNS resolution nor
|
|
242
|
+
* redirect interposition exists.
|
|
243
|
+
*/
|
|
244
|
+
readonly addressGuard: IAddressGuard;
|
|
245
|
+
/**
|
|
246
|
+
* Policy guard over the outbound request. Optional here and non-optional once resolved —
|
|
247
|
+
* it defaults to silent passthrough, applied once at the boundary, so no downstream code
|
|
248
|
+
* path branches on a guard's absence.
|
|
249
|
+
*/
|
|
250
|
+
readonly requestGuard?: IRequestGuard;
|
|
251
|
+
/**
|
|
252
|
+
* Policy guard over the response head. Defaults to silent passthrough. Content-type gating
|
|
253
|
+
* lives here — see {@link SaferFetch.allowContentTypes}; it is deliberately not a separate
|
|
254
|
+
* option, which would be a second mechanism for one job.
|
|
255
|
+
*/
|
|
256
|
+
readonly responseHeadersGuard?: IResponseHeadersGuard;
|
|
257
|
+
/** Policy guard over the buffered body. Defaults to silent passthrough. */
|
|
258
|
+
readonly responseBodyGuard?: IResponseBodyGuard;
|
|
259
|
+
/** Defaults to `'GET'`. */
|
|
260
|
+
readonly method?: SaferFetchMethod;
|
|
261
|
+
/** Request headers. Names are lowercased before the request guard sees them. */
|
|
262
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
263
|
+
/** Request body. Not permitted with `'GET'` or `'HEAD'`. */
|
|
264
|
+
readonly body?: string | Uint8Array;
|
|
265
|
+
/**
|
|
266
|
+
* Overall deadline in milliseconds, covering the connect, the response headers, and the
|
|
267
|
+
* body read. Default {@link SaferFetch.DEFAULT_TIMEOUT_MS}. This is the deadline that stops
|
|
268
|
+
* a response dribbling one byte every 25 seconds, which passes every per-read check.
|
|
269
|
+
*/
|
|
270
|
+
readonly timeoutMs?: number;
|
|
271
|
+
/**
|
|
272
|
+
* Deadline to first response headers, in milliseconds. Default
|
|
273
|
+
* {@link SaferFetch.DEFAULT_HEADERS_TIMEOUT_MS}. Distinguishes "the host is not answering"
|
|
274
|
+
* from "the host is answering slowly", which the failure taxonomy then reports as
|
|
275
|
+
* `timeout.phase`.
|
|
276
|
+
*
|
|
277
|
+
* @remarks
|
|
278
|
+
* Measured from the start of the attempt, which includes guard evaluation — an address guard
|
|
279
|
+
* that resolves DNS spends this budget too. That is deliberate: the deadline bounds the time
|
|
280
|
+
* a caller waits for a usable response, not the time one layer of the implementation spends.
|
|
281
|
+
*/
|
|
282
|
+
readonly headersTimeoutMs?: number;
|
|
283
|
+
/**
|
|
284
|
+
* Cap on decoded response bytes. Default {@link SaferFetch.DEFAULT_MAX_RESPONSE_BYTES}
|
|
285
|
+
* (5 MiB).
|
|
286
|
+
*
|
|
287
|
+
* @remarks
|
|
288
|
+
* **This knob is meant to be reached for.** 5 MiB is roughly an order of magnitude above a
|
|
289
|
+
* realistic JSON API response and is generous for text, but real documents clear it — raise
|
|
290
|
+
* it per call for the calls that need it rather than treating the default as a ceiling. The
|
|
291
|
+
* cap is enforced by counting decoded bytes during the read, so raising it raises the
|
|
292
|
+
* buffer the process may be asked to hold; size it against the heap you are willing to
|
|
293
|
+
* spend, not against the largest document you can imagine.
|
|
294
|
+
*/
|
|
295
|
+
readonly maxResponseBytes?: number;
|
|
296
|
+
/**
|
|
297
|
+
* How redirects are handled. Defaults to `'reject'`.
|
|
298
|
+
*
|
|
299
|
+
* @remarks
|
|
300
|
+
* The conservative default is deliberate, and is the same polarity as `addressGuard` having no
|
|
301
|
+
* default: one core serves both runtimes, `'reject'` is the only mode whose guarantee is
|
|
302
|
+
* identical on each, and following a redirect chain into hosts the caller never named is a
|
|
303
|
+
* posture worth spelling at the call site. Callers ingesting real-world URLs want
|
|
304
|
+
* `'validate-each-hop'`.
|
|
305
|
+
*/
|
|
306
|
+
readonly redirectPolicy?: SaferFetchRedirectPolicy;
|
|
307
|
+
/**
|
|
308
|
+
* Cap on redirect hops followed under `'validate-each-hop'`. Default
|
|
309
|
+
* {@link SaferFetch.DEFAULT_MAX_REDIRECTS} (5). Must be a non-negative integer; `0` refuses
|
|
310
|
+
* to follow any redirect.
|
|
311
|
+
*/
|
|
312
|
+
readonly maxRedirects?: number;
|
|
313
|
+
/**
|
|
314
|
+
* Additional header names to drop on a cross-origin redirect hop, on top of the always-dropped
|
|
315
|
+
* `authorization`, `cookie` and `proxy-authorization`
|
|
316
|
+
* ({@link SaferFetch.ALWAYS_STRIPPED_HEADERS}).
|
|
317
|
+
*
|
|
318
|
+
* @remarks
|
|
319
|
+
* Matching is case-insensitive. Use this for bearer-equivalent headers a deployment invented —
|
|
320
|
+
* `x-api-key`, `x-auth-token`, a signed-request header. Stripping is **monotonic**: once a hop
|
|
321
|
+
* has left an origin the headers are gone for the rest of the chain, so an `A` → `B` → `A`
|
|
322
|
+
* chain does not hand the credential back to `A` after `B` has watched it leave.
|
|
323
|
+
*/
|
|
324
|
+
readonly sensitiveHeaders?: ReadonlyArray<string>;
|
|
325
|
+
/**
|
|
326
|
+
* Opt-in retry. **Off by default** — a primitive that silently retries changes the semantics
|
|
327
|
+
* of every call site and amplifies load against a service that is already struggling.
|
|
328
|
+
*
|
|
329
|
+
* @remarks
|
|
330
|
+
* Retries consume `timeoutMs` and never reset it, so enabling retry does not extend the
|
|
331
|
+
* deadline; and every attempt re-runs the address guard from hop 0 as a full re-walk, never a
|
|
332
|
+
* resume and never a cached verdict. Both rules are load-bearing rather than incidental — see
|
|
333
|
+
* {@link SaferFetch.IRetryPolicy}, which states why.
|
|
334
|
+
*/
|
|
335
|
+
readonly retry?: IRetryPolicy;
|
|
336
|
+
/** Defaults to {@link SaferFetch.platformFetchTransport}. */
|
|
337
|
+
readonly transport?: IFetchTransport;
|
|
338
|
+
/** Caller's cancellation signal. Reported as `'aborted'`, never as `'timeout'`. */
|
|
339
|
+
readonly signal?: AbortSignal;
|
|
340
|
+
/** Diagnostics sink. Defaults to a no-op logger. */
|
|
341
|
+
readonly logger?: Logging.ILogger;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* The guards a call will actually use. Every field is concrete: defaults are applied once, at
|
|
345
|
+
* the boundary, and nothing downstream branches on a guard's absence.
|
|
346
|
+
* @public
|
|
347
|
+
*/
|
|
348
|
+
export interface IResolvedGuards {
|
|
349
|
+
/** Caller-supplied; there is no default. */
|
|
350
|
+
readonly address: IAddressGuard;
|
|
351
|
+
readonly request: IRequestGuard;
|
|
352
|
+
readonly responseHeaders: IResponseHeadersGuard;
|
|
353
|
+
readonly responseBody: IResponseBodyGuard;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* A successful safer-fetch response.
|
|
357
|
+
* @public
|
|
358
|
+
*/
|
|
359
|
+
export interface ISaferFetchResponse<T> {
|
|
360
|
+
readonly value: T;
|
|
361
|
+
readonly status: number;
|
|
362
|
+
/** Header names are lowercased. */
|
|
363
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
364
|
+
/**
|
|
365
|
+
* Every URL actually requested, in order, as cleared by the address guard. `[0]` is the
|
|
366
|
+
* caller's; later entries are redirect hops. A caller that allowlisted `api.example.com`
|
|
367
|
+
* and was redirected to `cdn.example.com` usually wants to know.
|
|
368
|
+
*/
|
|
369
|
+
readonly urlChain: ReadonlyArray<string>;
|
|
370
|
+
/** Decoded bytes read from the response body. */
|
|
371
|
+
readonly bytesRead: number;
|
|
372
|
+
}
|
|
373
|
+
//# sourceMappingURL=model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/packlets/safer-fetch/model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
//# sourceMappingURL=model.js.map
|