@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":"recordJarHelpers.js","sourceRoot":"","sources":["../../../src/packlets/record-jar/recordJarHelpers.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2022 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, fail, isKeyOf, succeed } from '@fgv/ts-utils';\nimport { FileTree } from '@fgv/ts-json-base';\n\ninterface IRecordBody {\n body: string;\n isContinuation: boolean;\n}\n\n/**\n * Represents a single record in a JAR file\n * @public\n */\nexport type JarRecord = Record<string, string | string[]>;\n\n/**\n * @public\n */\nexport type JarFieldPicker<T extends JarRecord = JarRecord> = (record: T) => (keyof T)[];\n\n/**\n * Options for a JAR record parser.\n * @public\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport interface JarRecordParserOptions {\n readonly arrayFields?: string[] | JarFieldPicker;\n readonly fixedContinuationSize?: number;\n}\n\nclass RecordParser {\n public readonly records: JarRecord[] = [];\n public readonly options: JarRecordParserOptions;\n\n protected _fields: JarRecord = {};\n protected _name: string | undefined = undefined;\n protected _body: IRecordBody | undefined = undefined;\n\n private constructor(options?: JarRecordParserOptions) {\n this.options = options ?? {};\n }\n\n public static parse(lines: string[], options?: JarRecordParserOptions): Result<JarRecord[]> {\n return new RecordParser(options)._parse(lines);\n }\n\n protected static _parseRecordBody(body: string): Result<IRecordBody> {\n const isContinuation = body.endsWith('\\\\');\n if (isContinuation) {\n body = body.slice(0, body.length - 1);\n }\n if (this._hasEscapes(body)) {\n const result = this._replaceEscapes(body);\n if (result.isFailure()) {\n return fail(result.message);\n }\n body = result.value;\n }\n return succeed({ body, isContinuation });\n }\n\n protected static _hasEscapes(from: string): boolean {\n return from.includes('\\\\') || from.includes('&');\n }\n\n protected static _replaceEscapes(body: string): Result<string> {\n const invalid: string[] = [];\n const escaped = body.replace(/(\\\\.)|(&#x[a-fA-F0-9]{2,6};)/g, (match) => {\n switch (match) {\n case '\\\\\\\\':\n return '\\\\';\n case '\\\\&':\n return '&';\n case '\\\\r':\n return '\\r';\n case '\\\\n':\n return '\\n';\n case '\\\\t':\n return '\\t';\n }\n if (match.startsWith('&')) {\n const hexCode = `0x${match.slice(3, match.length - 1)}`;\n const charCode = Number.parseInt(hexCode, 16);\n return String.fromCharCode(charCode);\n }\n invalid.push(match);\n return '\\\\';\n });\n if (invalid.length > 0) {\n return fail(`unrecognized escape \"${invalid.join(', ')}\" in record-jar body`);\n }\n return succeed(escaped);\n }\n\n protected static _applyOptions(record: JarRecord, options: JarRecordParserOptions): JarRecord {\n if (options.arrayFields) {\n record = { ...record }; // don't edit incoming values\n const arrayFields = Array.isArray(options.arrayFields)\n ? options.arrayFields\n : options.arrayFields(record);\n\n for (const field of arrayFields) {\n if (isKeyOf(field, record) && typeof record[field] === 'string') {\n const current = record[field] as string;\n record[field] = [current];\n }\n }\n }\n return record;\n }\n\n protected _parse(lines: string[]): Result<JarRecord[]> {\n for (let n = 0; n < lines.length; n++) {\n const line = lines[n];\n if (line.startsWith('%%') && !this._body?.isContinuation) {\n const result = this._writePendingRecord();\n if (result.isFailure()) {\n return fail(`${n}: ${result.message}`);\n }\n } else if (/^\\s*$/.test(line)) {\n // ignore blank lines but cancel continuation\n if (this._body) {\n this._body.isContinuation = false;\n }\n continue;\n } else if (this._body?.isContinuation || /^\\s+/.test(line)) {\n // explicit continuation on previous line or implicit starts with whitespace\n if (this._body === undefined) {\n return fail(`${n}: continuation (\"${line}\") without prior value.`);\n }\n const result = this._parseContinuation(line);\n if (result.isFailure()) {\n return fail(`${n}: ${result.message}`);\n }\n this._body = result.value;\n } else {\n const result = this._parseField(line);\n if (result.isFailure()) {\n return fail(`${n}: ${result.message}`);\n }\n }\n }\n\n const result = this._writePendingRecord();\n if (result.isFailure()) {\n return fail(`${lines.length}: ${result.message}`);\n }\n return succeed(this.records);\n }\n\n protected _parseField(line: string): Result<boolean> {\n const separatorIndex = line.indexOf(':');\n if (separatorIndex < 1) {\n return fail(`malformed line (\"${line}\") in record-jar.`);\n }\n const parts = [line.slice(0, separatorIndex), line.slice(separatorIndex + 1)];\n\n return this._writePendingField().onSuccess(() => {\n this._name = parts[0].trimEnd();\n return RecordParser._parseRecordBody(parts[1].trim()).onSuccess((body) => {\n this._body = body;\n return succeed(true);\n });\n });\n }\n\n protected _parseContinuation(line: string): Result<IRecordBody> {\n let trimmed = line.trim();\n if (!this._body!.isContinuation) {\n /* c8 ignore next - functional code tested but coverage intermittently missed */\n const fixedSize = this.options?.fixedContinuationSize ?? 0;\n if (fixedSize > 0) {\n if (trimmed.length < line.length - fixedSize) {\n // oops, took too much\n trimmed = line.slice(fixedSize);\n }\n }\n }\n return RecordParser._parseRecordBody(trimmed).onSuccess((newBody) => {\n return succeed({\n body: `${this._body!.body}${newBody.body}`,\n isContinuation: newBody.isContinuation\n });\n });\n }\n\n protected _havePendingRecord(): boolean {\n return Object.keys(this._fields).length > 0;\n }\n\n protected _writePendingRecord(): Result<JarRecord | undefined> {\n return this._writePendingField().onSuccess(() => {\n let record = this._havePendingRecord() ? this._fields : undefined;\n if (record !== undefined) {\n record = RecordParser._applyOptions(record, this.options);\n this.records.push(record);\n this._fields = {};\n }\n return succeed(undefined);\n });\n }\n\n protected _writePendingField(): Result<boolean> {\n if (this._name !== undefined) {\n if (this._body!.body.length < 1) {\n return fail('empty body value not allowed');\n }\n if (!isKeyOf(this._name, this._fields)) {\n this._fields[this._name] = this._body!.body;\n } else if (typeof this._fields[this._name] === 'string') {\n const current = this._fields[this._name] as string;\n this._fields[this._name] = [current, this._body!.body];\n } else {\n const current = this._fields[this._name] as string[];\n current.push(this._body!.body);\n }\n this._name = undefined;\n this._body = undefined;\n }\n return succeed(true);\n }\n}\n\n/**\n * Reads a record-jar from an array of strings, each of which represents one\n * line in the source file.\n * @param lines - the array of strings to be parsed\n * @param options - Optional parser configuration\n * @returns a corresponding array of `Record<string, string>`\n * @public\n */\nexport function parseRecordJarLines(lines: string[], options?: JarRecordParserOptions): Result<JarRecord[]> {\n return RecordParser.parse(lines, options);\n}\n\n/**\n * Reads a record-jar file from a FileTree.\n * @param fileTree - The FileTree to read from.\n * @param filePath - Path of the file within the tree.\n * @param options - Optional parser configuration\n * @returns The contents of the file as an array of `Record<string, string>`\n * @see https://datatracker.ietf.org/doc/html/draft-phillips-record-jar-01\n * @public\n */\nexport function readRecordJarFromTree(\n fileTree: FileTree.FileTree,\n filePath: string,\n options?: JarRecordParserOptions\n): Result<JarRecord[]> {\n return fileTree\n .getFile(filePath)\n .onSuccess((file) => file.getRawContents())\n .onSuccess((contents) => {\n const lines = contents.split(/\\r?\\n/);\n return parseRecordJarLines(lines, options);\n });\n}\n"]}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { type Result } from '@fgv/ts-utils';
|
|
2
|
+
/**
|
|
3
|
+
* The address family of a parsed IP address literal.
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export type AddressFamily = 'ipv4' | 'ipv6';
|
|
7
|
+
/**
|
|
8
|
+
* The security-relevant classification of an IP address.
|
|
9
|
+
*
|
|
10
|
+
* `'public'` is the only classification that describes an address which is
|
|
11
|
+
* globally routable on the public internet; every other value names a
|
|
12
|
+
* special-purpose range that a server-side fetch reaching untrusted input
|
|
13
|
+
* should not be able to reach by default.
|
|
14
|
+
*
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
export type AddressClassification =
|
|
18
|
+
/** Globally routable unicast — the only classification a default guard permits. */
|
|
19
|
+
'public'
|
|
20
|
+
/** `0.0.0.0/8` and `::` — "this host on this network"; routes to localhost on Linux. */
|
|
21
|
+
| 'unspecified'
|
|
22
|
+
/** `127.0.0.0/8` and `::1`. */
|
|
23
|
+
| 'loopback'
|
|
24
|
+
/**
|
|
25
|
+
* `169.254.0.0/16` and `fe80::/10`. The IPv4 range contains the cloud
|
|
26
|
+
* instance-metadata endpoint (`169.254.169.254`) and is the single
|
|
27
|
+
* highest-value SSRF target.
|
|
28
|
+
*/
|
|
29
|
+
| 'link-local'
|
|
30
|
+
/** RFC 1918 — `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`. */
|
|
31
|
+
| 'private'
|
|
32
|
+
/** RFC 4193 IPv6 unique-local — `fc00::/7`. */
|
|
33
|
+
| 'unique-local'
|
|
34
|
+
/** RFC 6598 carrier-grade NAT — `100.64.0.0/10`. Frequently carrier or container internal. */
|
|
35
|
+
| 'carrier-grade-nat'
|
|
36
|
+
/** RFC 2544 benchmarking — `198.18.0.0/15`. */
|
|
37
|
+
| 'benchmarking'
|
|
38
|
+
/** Documentation ranges — `192.0.2.0/24`, `198.51.100.0/24`, `203.0.113.0/24`, `2001:db8::/32`. */
|
|
39
|
+
| 'documentation'
|
|
40
|
+
/** IETF protocol assignments — `192.0.0.0/24` and `2001::/23`. */
|
|
41
|
+
| 'protocol-assignment'
|
|
42
|
+
/** `224.0.0.0/4` and `ff00::/8`. */
|
|
43
|
+
| 'multicast'
|
|
44
|
+
/** `255.255.255.255/32`. */
|
|
45
|
+
| 'broadcast'
|
|
46
|
+
/** Every other special-purpose or future-use range (e.g. `240.0.0.0/4`, `fec0::/10`). */
|
|
47
|
+
| 'reserved';
|
|
48
|
+
/**
|
|
49
|
+
* The way an IPv6 address carried the IPv4 address whose classification was used.
|
|
50
|
+
*
|
|
51
|
+
* Each of these is a documented SSRF bypass: an address such as
|
|
52
|
+
* `::ffff:169.254.169.254` is an IPv6 address by family, but the address the
|
|
53
|
+
* connection actually reaches is the embedded IPv4 one, so the embedded
|
|
54
|
+
* address is what must be classified.
|
|
55
|
+
*
|
|
56
|
+
* @public
|
|
57
|
+
*/
|
|
58
|
+
export type Ipv4EmbeddingKind =
|
|
59
|
+
/** `::ffff:0:0/96` — the IPv4-mapped IPv6 form. */
|
|
60
|
+
'ipv4-mapped'
|
|
61
|
+
/** `::/96` — the deprecated (RFC 4291) IPv4-compatible form. */
|
|
62
|
+
| 'ipv4-compatible'
|
|
63
|
+
/** `64:ff9b::/96` — the RFC 6052 well-known NAT64 prefix. */
|
|
64
|
+
| 'nat64'
|
|
65
|
+
/** `2002::/16` — the RFC 3056 6to4 form, whose IPv4 lives in bits 16..47. */
|
|
66
|
+
| '6to4';
|
|
67
|
+
/**
|
|
68
|
+
* The IPv4 address an IPv6 address embedded, and the way it embedded it.
|
|
69
|
+
* @public
|
|
70
|
+
*/
|
|
71
|
+
export interface IEmbeddedIpv4 {
|
|
72
|
+
/** The encoding that carried the IPv4 address. */
|
|
73
|
+
readonly kind: Ipv4EmbeddingKind;
|
|
74
|
+
/** The dotted-quad form of the embedded IPv4 address. */
|
|
75
|
+
readonly address: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The result of classifying a single IP address literal.
|
|
79
|
+
* @public
|
|
80
|
+
*/
|
|
81
|
+
export interface IClassifiedAddress {
|
|
82
|
+
/** The address exactly as supplied to {@link classifyAddress}. */
|
|
83
|
+
readonly address: string;
|
|
84
|
+
/**
|
|
85
|
+
* A canonical textual form of the address: dotted-quad for IPv4, and
|
|
86
|
+
* lowercase RFC 5952 hex-group form (with `::` run compression) for IPv6.
|
|
87
|
+
* Note that IPv6 addresses embedding an IPv4 address canonicalize to their
|
|
88
|
+
* hex-group form (`::ffff:a9fe:a9fe`), not to the dotted-quad mixed form;
|
|
89
|
+
* `embeddedIpv4` carries the readable IPv4 value.
|
|
90
|
+
*/
|
|
91
|
+
readonly canonical: string;
|
|
92
|
+
/** The address family of the literal as supplied — never the embedded family. */
|
|
93
|
+
readonly family: AddressFamily;
|
|
94
|
+
/**
|
|
95
|
+
* The classification used for policy decisions. For an IPv6 address that
|
|
96
|
+
* embeds an IPv4 address, this is the classification of the *embedded* IPv4
|
|
97
|
+
* address.
|
|
98
|
+
*/
|
|
99
|
+
readonly classification: AddressClassification;
|
|
100
|
+
/**
|
|
101
|
+
* Present exactly when `classification` was derived from an IPv4 address
|
|
102
|
+
* embedded in this IPv6 address, and absent otherwise.
|
|
103
|
+
*/
|
|
104
|
+
readonly embeddedIpv4?: IEmbeddedIpv4;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Classifies a single IP address literal.
|
|
108
|
+
*
|
|
109
|
+
* The function is pure, synchronous, and deterministic — it performs no name
|
|
110
|
+
* resolution and no I/O. Input that is not an IP address literal (a DNS
|
|
111
|
+
* hostname, for instance) fails; callers that accept hostnames should treat a
|
|
112
|
+
* failure here as "not a literal" and resolve the name, then classify each
|
|
113
|
+
* resolved address.
|
|
114
|
+
*
|
|
115
|
+
* Accepted forms:
|
|
116
|
+
*
|
|
117
|
+
* - dotted-quad IPv4 (`169.254.169.254`)
|
|
118
|
+
* - the shortened and non-decimal IPv4 forms the WHATWG URL parser accepts
|
|
119
|
+
* (`127.1`, `2130706433`, `0177.0.0.1`, `0x7f.1`)
|
|
120
|
+
* - IPv6, with or without `::` compression, optionally bracketed as a URL
|
|
121
|
+
* `hostname` is (`[::1]`) and optionally carrying a zone id (`fe80::1%eth0`)
|
|
122
|
+
* - IPv6 forms that embed an IPv4 address — IPv4-mapped, IPv4-compatible,
|
|
123
|
+
* NAT64 and 6to4 — which are classified by their embedded IPv4 address
|
|
124
|
+
*
|
|
125
|
+
* A trailing dot is accepted on an IPv4 literal (`127.0.0.1.`), matching URL
|
|
126
|
+
* hostname normalization.
|
|
127
|
+
*
|
|
128
|
+
* **Classify a URL's `hostname`, never the raw URL text.** This function does
|
|
129
|
+
* not apply IDNA/Unicode normalization, and that step is not cosmetic: the
|
|
130
|
+
* platform's URL parser reads `http://127.0.0.1/`, `http://127。0。0。1/` and
|
|
131
|
+
* even `http://⑫7.0.0.1/` as the host `127.0.0.1`, because IDNA normalizes
|
|
132
|
+
* fullwidth digits, the ideographic full stop and circled numbers to their
|
|
133
|
+
* ASCII equivalents. Handed one of those strings directly this function fails —
|
|
134
|
+
* which is fail-closed, but only because the caller is then expected to treat
|
|
135
|
+
* "not a literal" as "resolve it as a name". Reading `new URL(...).hostname`
|
|
136
|
+
* gets the normalization for free and is the only supported use.
|
|
137
|
+
*
|
|
138
|
+
* @param address - the address literal to classify.
|
|
139
|
+
* @returns `Success` with the {@link IClassifiedAddress | classification},
|
|
140
|
+
* or `Failure` if the supplied text is not a well-formed IP address literal.
|
|
141
|
+
* @public
|
|
142
|
+
*/
|
|
143
|
+
export declare function classifyAddress(address: string): Result<IClassifiedAddress>;
|
|
144
|
+
//# sourceMappingURL=addressClassification.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"addressClassification.d.ts","sourceRoot":"","sources":["../../../src/packlets/safer-fetch/addressClassification.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAE,KAAK,MAAM,EAAiB,MAAM,eAAe,CAAC;AAE3D;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5C;;;;;;;;;GASG;AACH,MAAM,MAAM,qBAAqB;AAC/B,mFAAmF;AACjF,QAAQ;AACV,wFAAwF;GACtF,aAAa;AACf,+BAA+B;GAC7B,UAAU;AACZ;;;;GAIG;GACD,YAAY;AACd,kEAAkE;GAChE,SAAS;AACX,+CAA+C;GAC7C,cAAc;AAChB,8FAA8F;GAC5F,mBAAmB;AACrB,+CAA+C;GAC7C,cAAc;AAChB,mGAAmG;GACjG,eAAe;AACjB,kEAAkE;GAChE,qBAAqB;AACvB,oCAAoC;GAClC,WAAW;AACb,4BAA4B;GAC1B,WAAW;AACb,yFAAyF;GACvF,UAAU,CAAC;AAEf;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB;AAC3B,mDAAmD;AACjD,aAAa;AACf,gEAAgE;GAC9D,iBAAiB;AACnB,6DAA6D;GAC3D,OAAO;AACT,6EAA6E;GAC3E,MAAM,CAAC;AAEX;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,kDAAkD;IAClD,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,yDAAyD;IACzD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,iFAAiF;IACjF,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,cAAc,EAAE,qBAAqB,CAAC;IAC/C;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC;CACvC;AAsZD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,kBAAkB,CAAC,CA0B3E"}
|
|
@@ -0,0 +1,441 @@
|
|
|
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 = classifyAddress;
|
|
23
|
+
// Address classification is prefix arithmetic: every range test is a mask and a
|
|
24
|
+
// compare, and every IPv6 group/byte conversion is a shift. Spelling those as
|
|
25
|
+
// arithmetic instead would be strictly harder to audit against the RFCs, which
|
|
26
|
+
// is the opposite of what this file needs. The repo already takes per-site
|
|
27
|
+
// disables for the same reason in `crypto-utils/keystore` and `ts-random`.
|
|
28
|
+
/* eslint-disable no-bitwise */
|
|
29
|
+
const ts_utils_1 = require("@fgv/ts-utils");
|
|
30
|
+
/**
|
|
31
|
+
* IPv4 special-purpose ranges, most specific first. The broadcast address is
|
|
32
|
+
* listed ahead of `240.0.0.0/4` because it falls inside it.
|
|
33
|
+
*/
|
|
34
|
+
const IPV4_RANGES = [
|
|
35
|
+
{ network: 0xffffffff, prefixLength: 32, classification: 'broadcast' },
|
|
36
|
+
{ network: 0x00000000, prefixLength: 8, classification: 'unspecified' },
|
|
37
|
+
{ network: 0x0a000000, prefixLength: 8, classification: 'private' },
|
|
38
|
+
{ network: 0x64400000, prefixLength: 10, classification: 'carrier-grade-nat' },
|
|
39
|
+
{ network: 0x7f000000, prefixLength: 8, classification: 'loopback' },
|
|
40
|
+
{ network: 0xa9fe0000, prefixLength: 16, classification: 'link-local' },
|
|
41
|
+
{ network: 0xac100000, prefixLength: 12, classification: 'private' },
|
|
42
|
+
{ network: 0xc0000000, prefixLength: 24, classification: 'protocol-assignment' },
|
|
43
|
+
{ network: 0xc0000200, prefixLength: 24, classification: 'documentation' },
|
|
44
|
+
{ network: 0xc0586300, prefixLength: 24, classification: 'reserved' },
|
|
45
|
+
{ network: 0xc0a80000, prefixLength: 16, classification: 'private' },
|
|
46
|
+
{ network: 0xc6120000, prefixLength: 15, classification: 'benchmarking' },
|
|
47
|
+
{ network: 0xc6336400, prefixLength: 24, classification: 'documentation' },
|
|
48
|
+
{ network: 0xcb007100, prefixLength: 24, classification: 'documentation' },
|
|
49
|
+
{ network: 0xe0000000, prefixLength: 4, classification: 'multicast' },
|
|
50
|
+
{ network: 0xf0000000, prefixLength: 4, classification: 'reserved' }
|
|
51
|
+
];
|
|
52
|
+
/**
|
|
53
|
+
* IPv6 special-purpose ranges, most specific first. Ranges whose addresses
|
|
54
|
+
* embed an IPv4 address are handled separately, before this table is consulted,
|
|
55
|
+
* and anything outside global unicast (`2000::/3`) that matches nothing here is
|
|
56
|
+
* classified `'reserved'` — so this table only needs to name the ranges that
|
|
57
|
+
* deserve a more specific classification than that fallback gives them.
|
|
58
|
+
*/
|
|
59
|
+
const IPV6_RANGES = [
|
|
60
|
+
{ prefix: [0x20, 0x01, 0x0d, 0xb8], prefixLength: 32, classification: 'documentation' },
|
|
61
|
+
{ prefix: [0x20, 0x01, 0x00], prefixLength: 23, classification: 'protocol-assignment' },
|
|
62
|
+
{ prefix: [0x3f, 0xff, 0x00], prefixLength: 20, classification: 'documentation' },
|
|
63
|
+
{ prefix: [0xfc], prefixLength: 7, classification: 'unique-local' },
|
|
64
|
+
{ prefix: [0xfe, 0x80], prefixLength: 10, classification: 'link-local' },
|
|
65
|
+
{ prefix: [0xff], prefixLength: 8, classification: 'multicast' }
|
|
66
|
+
];
|
|
67
|
+
/** The first three bits of a global unicast IPv6 address (`2000::/3`). */
|
|
68
|
+
const IPV6_GLOBAL_UNICAST_MASK = 0xe0;
|
|
69
|
+
const IPV6_GLOBAL_UNICAST_VALUE = 0x20;
|
|
70
|
+
/**
|
|
71
|
+
* Parses one component of an IPv4 literal using `inet_aton` conventions: a
|
|
72
|
+
* `0x`/`0X` prefix selects hexadecimal, an otherwise-leading `0` selects octal,
|
|
73
|
+
* and anything else is decimal.
|
|
74
|
+
*
|
|
75
|
+
* This is deliberately permissive about *radix* because the WHATWG URL parser
|
|
76
|
+
* is: `http://0177.0.0.1/` and `http://2130706433/` are both `127.0.0.1`, and a
|
|
77
|
+
* classifier that only understands dotted decimal is bypassed by either.
|
|
78
|
+
*/
|
|
79
|
+
function parseIpv4Component(text) {
|
|
80
|
+
if (text.length === 0) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
let radix = 10;
|
|
84
|
+
let digits = text;
|
|
85
|
+
if (text.length > 1 && (text[1] === 'x' || text[1] === 'X') && text[0] === '0') {
|
|
86
|
+
radix = 16;
|
|
87
|
+
digits = text.slice(2);
|
|
88
|
+
}
|
|
89
|
+
else if (text.length > 1 && text[0] === '0') {
|
|
90
|
+
radix = 8;
|
|
91
|
+
digits = text.slice(1);
|
|
92
|
+
}
|
|
93
|
+
// The WHATWG IPv4 number parser returns 0 when stripping the radix prefix
|
|
94
|
+
// leaves nothing behind, so a bare `0x` is zero: `127.0x.1` is `127.0.0.1`.
|
|
95
|
+
// Rejecting it here would leave a live encoding bypass.
|
|
96
|
+
if (digits.length === 0) {
|
|
97
|
+
return 0;
|
|
98
|
+
}
|
|
99
|
+
const allowed = radix === 16 ? /^[0-9a-fA-F]+$/ : radix === 8 ? /^[0-7]+$/ : /^[0-9]+$/;
|
|
100
|
+
if (!allowed.test(digits)) {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
const value = Number.parseInt(digits, radix);
|
|
104
|
+
return Number.isSafeInteger(value) ? value : undefined;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Parses an IPv4 literal in any of the forms the platform URL parser accepts
|
|
108
|
+
* (`a.b.c.d`, `a.b.c`, `a.b`, `a`), returning the address as an unsigned 32-bit
|
|
109
|
+
* value. The final component absorbs all remaining bytes, so `127.1` is
|
|
110
|
+
* `127.0.0.1` and `2130706433` is also `127.0.0.1`.
|
|
111
|
+
*/
|
|
112
|
+
function parseIpv4(text) {
|
|
113
|
+
const parts = text.split('.');
|
|
114
|
+
if (parts.length > 4) {
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
const values = [];
|
|
118
|
+
for (const part of parts) {
|
|
119
|
+
const value = parseIpv4Component(part);
|
|
120
|
+
if (value === undefined) {
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
values.push(value);
|
|
124
|
+
}
|
|
125
|
+
const leading = values.length - 1;
|
|
126
|
+
for (let i = 0; i < leading; i++) {
|
|
127
|
+
if (values[i] > 0xff) {
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (values[leading] > Math.pow(256, 4 - leading) - 1) {
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
let address = values[leading];
|
|
135
|
+
for (let i = 0; i < leading; i++) {
|
|
136
|
+
address += values[i] * Math.pow(256, 3 - i);
|
|
137
|
+
}
|
|
138
|
+
return address >>> 0;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Parses a strict dotted-quad IPv4 literal — exactly four decimal components,
|
|
142
|
+
* each `0..255`, with no octal or hexadecimal forms. This is the grammar RFC
|
|
143
|
+
* 4291 permits for the IPv4 tail of an IPv6 literal, and it is deliberately
|
|
144
|
+
* stricter than {@link parseIpv4}: an unparseable literal fails closed.
|
|
145
|
+
*/
|
|
146
|
+
function parseStrictDottedQuad(text) {
|
|
147
|
+
const parts = text.split('.');
|
|
148
|
+
if (parts.length !== 4) {
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
let address = 0;
|
|
152
|
+
for (const part of parts) {
|
|
153
|
+
if (!/^(0|[1-9][0-9]{0,2})$/.test(part)) {
|
|
154
|
+
return undefined;
|
|
155
|
+
}
|
|
156
|
+
const value = Number.parseInt(part, 10);
|
|
157
|
+
if (value > 0xff) {
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
160
|
+
address = address * 256 + value;
|
|
161
|
+
}
|
|
162
|
+
return address >>> 0;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Parses a colon-separated run of IPv6 groups, allowing a trailing embedded
|
|
166
|
+
* dotted-quad IPv4 literal which expands to the final two groups.
|
|
167
|
+
*
|
|
168
|
+
* @param allowEmbeddedIpv4 - whether this run may end in a dotted-quad IPv4
|
|
169
|
+
* literal. Only the run that ends the whole address may, so the run *before* a
|
|
170
|
+
* `::` never does: `1.2.3.4::` is malformed, not `102:304::`.
|
|
171
|
+
*/
|
|
172
|
+
function parseIpv6Groups(text, allowEmbeddedIpv4) {
|
|
173
|
+
if (text.length === 0) {
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
const parts = text.split(':');
|
|
177
|
+
const groups = [];
|
|
178
|
+
for (let i = 0; i < parts.length; i++) {
|
|
179
|
+
const part = parts[i];
|
|
180
|
+
if (part.indexOf('.') >= 0) {
|
|
181
|
+
if (!allowEmbeddedIpv4 || i !== parts.length - 1) {
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
const embedded = parseStrictDottedQuad(part);
|
|
185
|
+
if (embedded === undefined) {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
groups.push((embedded >>> 16) & 0xffff, embedded & 0xffff);
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (!/^[0-9a-fA-F]{1,4}$/.test(part)) {
|
|
192
|
+
return undefined;
|
|
193
|
+
}
|
|
194
|
+
groups.push(Number.parseInt(part, 16));
|
|
195
|
+
}
|
|
196
|
+
return groups;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Parses an IPv6 literal into its 16 constituent bytes.
|
|
200
|
+
*/
|
|
201
|
+
function parseIpv6(text) {
|
|
202
|
+
const doubleColon = text.indexOf('::');
|
|
203
|
+
let groups;
|
|
204
|
+
if (doubleColon >= 0) {
|
|
205
|
+
if (text.indexOf('::', doubleColon + 1) >= 0) {
|
|
206
|
+
return undefined;
|
|
207
|
+
}
|
|
208
|
+
const head = parseIpv6Groups(text.slice(0, doubleColon), false);
|
|
209
|
+
const tail = parseIpv6Groups(text.slice(doubleColon + 2), true);
|
|
210
|
+
if (head === undefined || tail === undefined) {
|
|
211
|
+
return undefined;
|
|
212
|
+
}
|
|
213
|
+
const elided = 8 - head.length - tail.length;
|
|
214
|
+
if (elided < 1) {
|
|
215
|
+
return undefined;
|
|
216
|
+
}
|
|
217
|
+
groups = head.concat(new Array(elided).fill(0), tail);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
groups = parseIpv6Groups(text, true);
|
|
221
|
+
if (groups === undefined || groups.length !== 8) {
|
|
222
|
+
return undefined;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
const bytes = new Uint8Array(16);
|
|
226
|
+
for (let i = 0; i < 8; i++) {
|
|
227
|
+
bytes[i * 2] = (groups[i] >>> 8) & 0xff;
|
|
228
|
+
bytes[i * 2 + 1] = groups[i] & 0xff;
|
|
229
|
+
}
|
|
230
|
+
return bytes;
|
|
231
|
+
}
|
|
232
|
+
function ipv4ToString(address) {
|
|
233
|
+
return [(address >>> 24) & 0xff, (address >>> 16) & 0xff, (address >>> 8) & 0xff, address & 0xff].join('.');
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Renders the RFC 5952 canonical text form of an IPv6 address: lowercase, no
|
|
237
|
+
* leading zeros in a group, and the leftmost longest run of two or more
|
|
238
|
+
* all-zero groups replaced by `::`.
|
|
239
|
+
*/
|
|
240
|
+
function ipv6ToString(bytes) {
|
|
241
|
+
const groups = [];
|
|
242
|
+
for (let i = 0; i < 8; i++) {
|
|
243
|
+
groups.push((bytes[i * 2] << 8) | bytes[i * 2 + 1]);
|
|
244
|
+
}
|
|
245
|
+
let bestStart = -1;
|
|
246
|
+
let bestLength = 0;
|
|
247
|
+
let runStart = -1;
|
|
248
|
+
let runLength = 0;
|
|
249
|
+
for (let i = 0; i < 8; i++) {
|
|
250
|
+
if (groups[i] === 0) {
|
|
251
|
+
if (runStart < 0) {
|
|
252
|
+
runStart = i;
|
|
253
|
+
runLength = 0;
|
|
254
|
+
}
|
|
255
|
+
runLength++;
|
|
256
|
+
if (runLength > bestLength) {
|
|
257
|
+
bestStart = runStart;
|
|
258
|
+
bestLength = runLength;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
runStart = -1;
|
|
263
|
+
runLength = 0;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
const rendered = groups.map((g) => g.toString(16));
|
|
267
|
+
if (bestLength < 2) {
|
|
268
|
+
return rendered.join(':');
|
|
269
|
+
}
|
|
270
|
+
const head = rendered.slice(0, bestStart).join(':');
|
|
271
|
+
const tail = rendered.slice(bestStart + bestLength).join(':');
|
|
272
|
+
return `${head}::${tail}`;
|
|
273
|
+
}
|
|
274
|
+
function classifyIpv4Value(address) {
|
|
275
|
+
for (const range of IPV4_RANGES) {
|
|
276
|
+
const mask = (0xffffffff << (32 - range.prefixLength)) >>> 0;
|
|
277
|
+
if ((address & mask) >>> 0 === range.network) {
|
|
278
|
+
return range.classification;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return 'public';
|
|
282
|
+
}
|
|
283
|
+
function matchesIpv6Range(bytes, range) {
|
|
284
|
+
const fullBytes = range.prefixLength >>> 3;
|
|
285
|
+
for (let i = 0; i < fullBytes; i++) {
|
|
286
|
+
if (bytes[i] !== range.prefix[i]) {
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
const remainingBits = range.prefixLength & 7;
|
|
291
|
+
if (remainingBits === 0) {
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
const mask = (0xff << (8 - remainingBits)) & 0xff;
|
|
295
|
+
return (bytes[fullBytes] & mask) === (range.prefix[fullBytes] & mask);
|
|
296
|
+
}
|
|
297
|
+
function allZero(bytes, start, end) {
|
|
298
|
+
for (let i = start; i < end; i++) {
|
|
299
|
+
if (bytes[i] !== 0) {
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return true;
|
|
304
|
+
}
|
|
305
|
+
function readIpv4At(bytes, offset) {
|
|
306
|
+
return (((bytes[offset] << 24) | (bytes[offset + 1] << 16) | (bytes[offset + 2] << 8) | bytes[offset + 3]) >>> 0);
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Detects the IPv4 address embedded in an IPv6 address, if any. `::` and `::1`
|
|
310
|
+
* are excluded before the IPv4-compatible check so that the unspecified and
|
|
311
|
+
* loopback addresses keep their own classifications.
|
|
312
|
+
*/
|
|
313
|
+
function detectIpv6Embedding(bytes) {
|
|
314
|
+
if (allZero(bytes, 0, 10) && bytes[10] === 0xff && bytes[11] === 0xff) {
|
|
315
|
+
return { kind: 'ipv4-mapped', value: readIpv4At(bytes, 12) };
|
|
316
|
+
}
|
|
317
|
+
if (bytes[0] === 0x00 &&
|
|
318
|
+
bytes[1] === 0x64 &&
|
|
319
|
+
bytes[2] === 0xff &&
|
|
320
|
+
bytes[3] === 0x9b &&
|
|
321
|
+
allZero(bytes, 4, 12)) {
|
|
322
|
+
return { kind: 'nat64', value: readIpv4At(bytes, 12) };
|
|
323
|
+
}
|
|
324
|
+
if (bytes[0] === 0x20 && bytes[1] === 0x02) {
|
|
325
|
+
return { kind: '6to4', value: readIpv4At(bytes, 2) };
|
|
326
|
+
}
|
|
327
|
+
if (allZero(bytes, 0, 12)) {
|
|
328
|
+
return { kind: 'ipv4-compatible', value: readIpv4At(bytes, 12) };
|
|
329
|
+
}
|
|
330
|
+
return undefined;
|
|
331
|
+
}
|
|
332
|
+
function classifyIpv6Bytes(bytes) {
|
|
333
|
+
const canonical = ipv6ToString(bytes);
|
|
334
|
+
if (allZero(bytes, 0, 16)) {
|
|
335
|
+
return { address: canonical, canonical, family: 'ipv6', classification: 'unspecified' };
|
|
336
|
+
}
|
|
337
|
+
if (allZero(bytes, 0, 15) && bytes[15] === 0x01) {
|
|
338
|
+
return { address: canonical, canonical, family: 'ipv6', classification: 'loopback' };
|
|
339
|
+
}
|
|
340
|
+
const embedding = detectIpv6Embedding(bytes);
|
|
341
|
+
if (embedding !== undefined) {
|
|
342
|
+
return {
|
|
343
|
+
address: canonical,
|
|
344
|
+
canonical,
|
|
345
|
+
family: 'ipv6',
|
|
346
|
+
classification: classifyIpv4Value(embedding.value),
|
|
347
|
+
embeddedIpv4: { kind: embedding.kind, address: ipv4ToString(embedding.value) }
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
for (const range of IPV6_RANGES) {
|
|
351
|
+
if (matchesIpv6Range(bytes, range)) {
|
|
352
|
+
return { address: canonical, canonical, family: 'ipv6', classification: range.classification };
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
// Only `2000::/3` is assigned as global unicast. Everything else that reached
|
|
356
|
+
// this point is unassigned or reserved for future use, so it is never public.
|
|
357
|
+
const classification = (bytes[0] & IPV6_GLOBAL_UNICAST_MASK) === IPV6_GLOBAL_UNICAST_VALUE ? 'public' : 'reserved';
|
|
358
|
+
return { address: canonical, canonical, family: 'ipv6', classification };
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Normalizes the textual forms an address can arrive in before parsing:
|
|
362
|
+
* surrounding whitespace and the square brackets a URL `hostname` carries for
|
|
363
|
+
* an IPv6 literal. A zone identifier is *not* stripped here — it is stripped on
|
|
364
|
+
* the IPv6 path only, because `8.8.8.8%something` is not an address with a zone
|
|
365
|
+
* and must fail rather than be read as `8.8.8.8`.
|
|
366
|
+
*/
|
|
367
|
+
function normalizeAddressText(address) {
|
|
368
|
+
const text = address.trim();
|
|
369
|
+
if (text.length > 1 && text[0] === '[' && text[text.length - 1] === ']') {
|
|
370
|
+
return text.slice(1, -1);
|
|
371
|
+
}
|
|
372
|
+
return text;
|
|
373
|
+
}
|
|
374
|
+
/** Strips an IPv6 zone identifier (`fe80::1%eth0`). */
|
|
375
|
+
function stripIpv6Zone(text) {
|
|
376
|
+
const zone = text.indexOf('%');
|
|
377
|
+
return zone >= 0 ? text.slice(0, zone) : text;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Classifies a single IP address literal.
|
|
381
|
+
*
|
|
382
|
+
* The function is pure, synchronous, and deterministic — it performs no name
|
|
383
|
+
* resolution and no I/O. Input that is not an IP address literal (a DNS
|
|
384
|
+
* hostname, for instance) fails; callers that accept hostnames should treat a
|
|
385
|
+
* failure here as "not a literal" and resolve the name, then classify each
|
|
386
|
+
* resolved address.
|
|
387
|
+
*
|
|
388
|
+
* Accepted forms:
|
|
389
|
+
*
|
|
390
|
+
* - dotted-quad IPv4 (`169.254.169.254`)
|
|
391
|
+
* - the shortened and non-decimal IPv4 forms the WHATWG URL parser accepts
|
|
392
|
+
* (`127.1`, `2130706433`, `0177.0.0.1`, `0x7f.1`)
|
|
393
|
+
* - IPv6, with or without `::` compression, optionally bracketed as a URL
|
|
394
|
+
* `hostname` is (`[::1]`) and optionally carrying a zone id (`fe80::1%eth0`)
|
|
395
|
+
* - IPv6 forms that embed an IPv4 address — IPv4-mapped, IPv4-compatible,
|
|
396
|
+
* NAT64 and 6to4 — which are classified by their embedded IPv4 address
|
|
397
|
+
*
|
|
398
|
+
* A trailing dot is accepted on an IPv4 literal (`127.0.0.1.`), matching URL
|
|
399
|
+
* hostname normalization.
|
|
400
|
+
*
|
|
401
|
+
* **Classify a URL's `hostname`, never the raw URL text.** This function does
|
|
402
|
+
* not apply IDNA/Unicode normalization, and that step is not cosmetic: the
|
|
403
|
+
* platform's URL parser reads `http://127.0.0.1/`, `http://127。0。0。1/` and
|
|
404
|
+
* even `http://⑫7.0.0.1/` as the host `127.0.0.1`, because IDNA normalizes
|
|
405
|
+
* fullwidth digits, the ideographic full stop and circled numbers to their
|
|
406
|
+
* ASCII equivalents. Handed one of those strings directly this function fails —
|
|
407
|
+
* which is fail-closed, but only because the caller is then expected to treat
|
|
408
|
+
* "not a literal" as "resolve it as a name". Reading `new URL(...).hostname`
|
|
409
|
+
* gets the normalization for free and is the only supported use.
|
|
410
|
+
*
|
|
411
|
+
* @param address - the address literal to classify.
|
|
412
|
+
* @returns `Success` with the {@link IClassifiedAddress | classification},
|
|
413
|
+
* or `Failure` if the supplied text is not a well-formed IP address literal.
|
|
414
|
+
* @public
|
|
415
|
+
*/
|
|
416
|
+
function classifyAddress(address) {
|
|
417
|
+
const text = normalizeAddressText(address);
|
|
418
|
+
if (text.length === 0) {
|
|
419
|
+
return (0, ts_utils_1.fail)(`"${address}": not a valid IP address literal (empty)`);
|
|
420
|
+
}
|
|
421
|
+
if (text.indexOf(':') >= 0) {
|
|
422
|
+
const bytes = parseIpv6(stripIpv6Zone(text));
|
|
423
|
+
if (bytes === undefined) {
|
|
424
|
+
return (0, ts_utils_1.fail)(`"${address}": not a valid IPv6 address literal`);
|
|
425
|
+
}
|
|
426
|
+
return (0, ts_utils_1.succeed)(Object.assign(Object.assign({}, classifyIpv6Bytes(bytes)), { address }));
|
|
427
|
+
}
|
|
428
|
+
const v4Text = text.length > 1 && text[text.length - 1] === '.' ? text.slice(0, -1) : text;
|
|
429
|
+
const value = parseIpv4(v4Text);
|
|
430
|
+
if (value === undefined) {
|
|
431
|
+
return (0, ts_utils_1.fail)(`"${address}": not a valid IP address literal`);
|
|
432
|
+
}
|
|
433
|
+
const canonical = ipv4ToString(value);
|
|
434
|
+
return (0, ts_utils_1.succeed)({
|
|
435
|
+
address,
|
|
436
|
+
canonical,
|
|
437
|
+
family: 'ipv4',
|
|
438
|
+
classification: classifyIpv4Value(value)
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
//# sourceMappingURL=addressClassification.js.map
|