@metamask/snap-networks-utils 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +63 -1
- package/README.md +4 -10
- package/dist/index.cjs +102 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +51 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +32 -1
- package/dist/index.mjs.map +1 -1
- package/dist/providers/assets/AssetsProvider.cjs +36 -18
- package/dist/providers/assets/AssetsProvider.cjs.map +1 -1
- package/dist/providers/assets/AssetsProvider.d.cts +30 -2
- package/dist/providers/assets/AssetsProvider.d.cts.map +1 -1
- package/dist/providers/assets/AssetsProvider.d.mts +30 -2
- package/dist/providers/assets/AssetsProvider.d.mts.map +1 -1
- package/dist/providers/assets/AssetsProvider.mjs +36 -18
- package/dist/providers/assets/AssetsProvider.mjs.map +1 -1
- package/dist/providers/remote-feature-flags/RemoteFeatureFlagsProvider.cjs +4 -17
- package/dist/providers/remote-feature-flags/RemoteFeatureFlagsProvider.cjs.map +1 -1
- package/dist/providers/remote-feature-flags/RemoteFeatureFlagsProvider.mjs +4 -17
- package/dist/providers/remote-feature-flags/RemoteFeatureFlagsProvider.mjs.map +1 -1
- package/dist/services/analytics/AnalyticsService.cjs +225 -0
- package/dist/services/analytics/AnalyticsService.cjs.map +1 -0
- package/dist/services/analytics/AnalyticsService.d.cts +175 -0
- package/dist/services/analytics/AnalyticsService.d.cts.map +1 -0
- package/dist/services/analytics/AnalyticsService.d.mts +175 -0
- package/dist/services/analytics/AnalyticsService.d.mts.map +1 -0
- package/dist/services/analytics/AnalyticsService.mjs +221 -0
- package/dist/services/analytics/AnalyticsService.mjs.map +1 -0
- package/dist/ui/ActionHeader/ActionHeader.cjs +23 -0
- package/dist/ui/ActionHeader/ActionHeader.cjs.map +1 -0
- package/dist/ui/ActionHeader/ActionHeader.d.cts +27 -0
- package/dist/ui/ActionHeader/ActionHeader.d.cts.map +1 -0
- package/dist/ui/ActionHeader/ActionHeader.d.mts +27 -0
- package/dist/ui/ActionHeader/ActionHeader.d.mts.map +1 -0
- package/dist/ui/ActionHeader/ActionHeader.mjs +19 -0
- package/dist/ui/ActionHeader/ActionHeader.mjs.map +1 -0
- package/dist/ui/Asset/Asset.cjs +68 -0
- package/dist/ui/Asset/Asset.cjs.map +1 -0
- package/dist/ui/Asset/Asset.d.cts +83 -0
- package/dist/ui/Asset/Asset.d.cts.map +1 -0
- package/dist/ui/Asset/Asset.d.mts +83 -0
- package/dist/ui/Asset/Asset.d.mts.map +1 -0
- package/dist/ui/Asset/Asset.mjs +60 -0
- package/dist/ui/Asset/Asset.mjs.map +1 -0
- package/dist/ui/Asset/question-mark.svg +3 -0
- package/dist/ui/EstimatedChanges/EstimatedChanges.cjs +57 -0
- package/dist/ui/EstimatedChanges/EstimatedChanges.cjs.map +1 -0
- package/dist/ui/EstimatedChanges/EstimatedChanges.d.cts +50 -0
- package/dist/ui/EstimatedChanges/EstimatedChanges.d.cts.map +1 -0
- package/dist/ui/EstimatedChanges/EstimatedChanges.d.mts +50 -0
- package/dist/ui/EstimatedChanges/EstimatedChanges.d.mts.map +1 -0
- package/dist/ui/EstimatedChanges/EstimatedChanges.mjs +53 -0
- package/dist/ui/EstimatedChanges/EstimatedChanges.mjs.map +1 -0
- package/dist/ui/TransactionAlert/TransactionAlert.cjs +72 -0
- package/dist/ui/TransactionAlert/TransactionAlert.cjs.map +1 -0
- package/dist/ui/TransactionAlert/TransactionAlert.d.cts +58 -0
- package/dist/ui/TransactionAlert/TransactionAlert.d.cts.map +1 -0
- package/dist/ui/TransactionAlert/TransactionAlert.d.mts +58 -0
- package/dist/ui/TransactionAlert/TransactionAlert.d.mts.map +1 -0
- package/dist/ui/TransactionAlert/TransactionAlert.mjs +68 -0
- package/dist/ui/TransactionAlert/TransactionAlert.mjs.map +1 -0
- package/dist/utils/async/async.cjs +95 -0
- package/dist/utils/async/async.cjs.map +1 -0
- package/dist/utils/async/async.d.cts +51 -0
- package/dist/utils/async/async.d.cts.map +1 -0
- package/dist/utils/async/async.d.mts +51 -0
- package/dist/utils/async/async.d.mts.map +1 -0
- package/dist/utils/async/async.mjs +88 -0
- package/dist/utils/async/async.mjs.map +1 -0
- package/dist/utils/buildUrl/buildUrl.cjs +54 -0
- package/dist/utils/buildUrl/buildUrl.cjs.map +1 -0
- package/dist/utils/buildUrl/buildUrl.d.cts +15 -0
- package/dist/utils/buildUrl/buildUrl.d.cts.map +1 -0
- package/dist/utils/buildUrl/buildUrl.d.mts +15 -0
- package/dist/utils/buildUrl/buildUrl.d.mts.map +1 -0
- package/dist/utils/buildUrl/buildUrl.mjs +51 -0
- package/dist/utils/buildUrl/buildUrl.mjs.map +1 -0
- package/dist/utils/cache/InMemoryCache.cjs +134 -0
- package/dist/utils/cache/InMemoryCache.cjs.map +1 -0
- package/dist/utils/cache/InMemoryCache.d.cts +29 -0
- package/dist/utils/cache/InMemoryCache.d.cts.map +1 -0
- package/dist/utils/cache/InMemoryCache.d.mts +29 -0
- package/dist/utils/cache/InMemoryCache.d.mts.map +1 -0
- package/dist/utils/cache/InMemoryCache.mjs +130 -0
- package/dist/utils/cache/InMemoryCache.mjs.map +1 -0
- package/dist/utils/cache/StateCache.cjs +193 -0
- package/dist/utils/cache/StateCache.cjs.map +1 -0
- package/dist/utils/cache/StateCache.d.cts +96 -0
- package/dist/utils/cache/StateCache.d.cts.map +1 -0
- package/dist/utils/cache/StateCache.d.mts +96 -0
- package/dist/utils/cache/StateCache.d.mts.map +1 -0
- package/dist/utils/cache/StateCache.mjs +189 -0
- package/dist/utils/cache/StateCache.mjs.map +1 -0
- package/dist/utils/cache/types.cjs +3 -0
- package/dist/utils/cache/types.cjs.map +1 -0
- package/dist/utils/cache/types.d.cts +99 -0
- package/dist/utils/cache/types.d.cts.map +1 -0
- package/dist/utils/cache/types.d.mts +99 -0
- package/dist/utils/cache/types.d.mts.map +1 -0
- package/dist/utils/cache/types.mjs +2 -0
- package/dist/utils/cache/types.mjs.map +1 -0
- package/dist/utils/cache/useCache.cjs +82 -0
- package/dist/utils/cache/useCache.cjs.map +1 -0
- package/dist/utils/cache/useCache.d.cts +57 -0
- package/dist/utils/cache/useCache.d.cts.map +1 -0
- package/dist/utils/cache/useCache.d.mts +57 -0
- package/dist/utils/cache/useCache.d.mts.map +1 -0
- package/dist/utils/cache/useCache.mjs +78 -0
- package/dist/utils/cache/useCache.mjs.map +1 -0
- package/dist/utils/cache/useCacheUntil.cjs +80 -0
- package/dist/utils/cache/useCacheUntil.cjs.map +1 -0
- package/dist/utils/cache/useCacheUntil.d.cts +54 -0
- package/dist/utils/cache/useCacheUntil.d.cts.map +1 -0
- package/dist/utils/cache/useCacheUntil.d.mts +54 -0
- package/dist/utils/cache/useCacheUntil.d.mts.map +1 -0
- package/dist/utils/cache/useCacheUntil.mjs +76 -0
- package/dist/utils/cache/useCacheUntil.mjs.map +1 -0
- package/dist/utils/config/BaseConfigProvider.cjs +62 -0
- package/dist/utils/config/BaseConfigProvider.cjs.map +1 -0
- package/dist/utils/config/BaseConfigProvider.d.cts +54 -0
- package/dist/utils/config/BaseConfigProvider.d.cts.map +1 -0
- package/dist/utils/config/BaseConfigProvider.d.mts +54 -0
- package/dist/utils/config/BaseConfigProvider.d.mts.map +1 -0
- package/dist/utils/config/BaseConfigProvider.mjs +58 -0
- package/dist/utils/config/BaseConfigProvider.mjs.map +1 -0
- package/dist/utils/config/envStructs.cjs +69 -0
- package/dist/utils/config/envStructs.cjs.map +1 -0
- package/dist/utils/config/envStructs.d.cts +57 -0
- package/dist/utils/config/envStructs.d.cts.map +1 -0
- package/dist/utils/config/envStructs.d.mts +57 -0
- package/dist/utils/config/envStructs.d.mts.map +1 -0
- package/dist/utils/config/envStructs.mjs +61 -0
- package/dist/utils/config/envStructs.mjs.map +1 -0
- package/dist/utils/config/environmentStruct.cjs +19 -0
- package/dist/utils/config/environmentStruct.cjs.map +1 -0
- package/dist/utils/config/environmentStruct.d.cts +20 -0
- package/dist/utils/config/environmentStruct.d.cts.map +1 -0
- package/dist/utils/config/environmentStruct.d.mts +20 -0
- package/dist/utils/config/environmentStruct.d.mts.map +1 -0
- package/dist/utils/config/environmentStruct.mjs +16 -0
- package/dist/utils/config/environmentStruct.mjs.map +1 -0
- package/dist/utils/config/logLevelStruct.cjs +14 -0
- package/dist/utils/config/logLevelStruct.cjs.map +1 -0
- package/dist/utils/config/logLevelStruct.d.cts +17 -0
- package/dist/utils/config/logLevelStruct.d.cts.map +1 -0
- package/dist/utils/config/logLevelStruct.d.mts +17 -0
- package/dist/utils/config/logLevelStruct.d.mts.map +1 -0
- package/dist/utils/config/logLevelStruct.mjs +11 -0
- package/dist/utils/config/logLevelStruct.mjs.map +1 -0
- package/dist/utils/config/parseEnv.cjs +30 -0
- package/dist/utils/config/parseEnv.cjs.map +1 -0
- package/dist/utils/config/parseEnv.d.cts +19 -0
- package/dist/utils/config/parseEnv.d.cts.map +1 -0
- package/dist/utils/config/parseEnv.d.mts +19 -0
- package/dist/utils/config/parseEnv.d.mts.map +1 -0
- package/dist/utils/config/parseEnv.mjs +26 -0
- package/dist/utils/config/parseEnv.mjs.map +1 -0
- package/dist/utils/dedupe/InFlightCoalescer.cjs +28 -0
- package/dist/utils/dedupe/InFlightCoalescer.cjs.map +1 -0
- package/dist/utils/dedupe/InFlightCoalescer.d.cts +12 -0
- package/dist/utils/dedupe/InFlightCoalescer.d.cts.map +1 -0
- package/dist/utils/dedupe/InFlightCoalescer.d.mts +12 -0
- package/dist/utils/dedupe/InFlightCoalescer.d.mts.map +1 -0
- package/dist/utils/dedupe/InFlightCoalescer.mjs +24 -0
- package/dist/utils/dedupe/InFlightCoalescer.mjs.map +1 -0
- package/dist/utils/errors/errors.cjs +44 -0
- package/dist/utils/errors/errors.cjs.map +1 -0
- package/dist/utils/errors/errors.d.cts +37 -0
- package/dist/utils/errors/errors.d.cts.map +1 -0
- package/dist/utils/errors/errors.d.mts +37 -0
- package/dist/utils/errors/errors.d.mts.map +1 -0
- package/dist/utils/errors/errors.mjs +40 -0
- package/dist/utils/errors/errors.mjs.map +1 -0
- package/dist/utils/errors/index.cjs +18 -0
- package/dist/utils/errors/index.cjs.map +1 -0
- package/dist/utils/errors/index.d.cts +10 -0
- package/dist/utils/errors/index.d.cts.map +1 -0
- package/dist/utils/errors/index.d.mts +10 -0
- package/dist/utils/errors/index.d.mts.map +1 -0
- package/dist/utils/errors/index.mjs +6 -0
- package/dist/utils/errors/index.mjs.map +1 -0
- package/dist/utils/errors/snapRpcError.cjs +33 -0
- package/dist/utils/errors/snapRpcError.cjs.map +1 -0
- package/dist/utils/errors/snapRpcError.d.cts +11 -0
- package/dist/utils/errors/snapRpcError.d.cts.map +1 -0
- package/dist/utils/errors/snapRpcError.d.mts +11 -0
- package/dist/utils/errors/snapRpcError.d.mts.map +1 -0
- package/dist/utils/errors/snapRpcError.mjs +30 -0
- package/dist/utils/errors/snapRpcError.mjs.map +1 -0
- package/dist/utils/errors/stringifyReason.cjs +36 -0
- package/dist/utils/errors/stringifyReason.cjs.map +1 -0
- package/dist/utils/errors/stringifyReason.d.cts +15 -0
- package/dist/utils/errors/stringifyReason.d.cts.map +1 -0
- package/dist/utils/errors/stringifyReason.d.mts +15 -0
- package/dist/utils/errors/stringifyReason.d.mts.map +1 -0
- package/dist/utils/errors/stringifyReason.mjs +33 -0
- package/dist/utils/errors/stringifyReason.mjs.map +1 -0
- package/dist/utils/errors/syncError.cjs +98 -0
- package/dist/utils/errors/syncError.cjs.map +1 -0
- package/dist/utils/errors/syncError.d.cts +60 -0
- package/dist/utils/errors/syncError.d.cts.map +1 -0
- package/dist/utils/errors/syncError.d.mts +60 -0
- package/dist/utils/errors/syncError.d.mts.map +1 -0
- package/dist/utils/errors/syncError.mjs +92 -0
- package/dist/utils/errors/syncError.mjs.map +1 -0
- package/dist/utils/errors/trackError.cjs +76 -0
- package/dist/utils/errors/trackError.cjs.map +1 -0
- package/dist/utils/errors/trackError.d.cts +64 -0
- package/dist/utils/errors/trackError.d.cts.map +1 -0
- package/dist/utils/errors/trackError.d.mts +64 -0
- package/dist/utils/errors/trackError.d.mts.map +1 -0
- package/dist/utils/errors/trackError.mjs +72 -0
- package/dist/utils/errors/trackError.mjs.map +1 -0
- package/dist/utils/handlers/wrapSnapHandlers.cjs +57 -0
- package/dist/utils/handlers/wrapSnapHandlers.cjs.map +1 -0
- package/dist/utils/handlers/wrapSnapHandlers.d.cts +74 -0
- package/dist/utils/handlers/wrapSnapHandlers.d.cts.map +1 -0
- package/dist/utils/handlers/wrapSnapHandlers.d.mts +74 -0
- package/dist/utils/handlers/wrapSnapHandlers.d.mts.map +1 -0
- package/dist/utils/handlers/wrapSnapHandlers.mjs +53 -0
- package/dist/utils/handlers/wrapSnapHandlers.mjs.map +1 -0
- package/dist/utils/keyringAccount/keyringAccount.cjs +25 -0
- package/dist/utils/keyringAccount/keyringAccount.cjs.map +1 -0
- package/dist/utils/keyringAccount/keyringAccount.d.cts +29 -0
- package/dist/utils/keyringAccount/keyringAccount.d.cts.map +1 -0
- package/dist/utils/keyringAccount/keyringAccount.d.mts +29 -0
- package/dist/utils/keyringAccount/keyringAccount.d.mts.map +1 -0
- package/dist/utils/keyringAccount/keyringAccount.mjs +22 -0
- package/dist/utils/keyringAccount/keyringAccount.mjs.map +1 -0
- package/dist/utils/logger/Logger.cjs +140 -0
- package/dist/utils/logger/Logger.cjs.map +1 -0
- package/dist/utils/logger/Logger.d.cts +118 -0
- package/dist/utils/logger/Logger.d.cts.map +1 -0
- package/dist/utils/logger/Logger.d.mts +118 -0
- package/dist/utils/logger/Logger.d.mts.map +1 -0
- package/dist/utils/logger/Logger.mjs +136 -0
- package/dist/utils/logger/Logger.mjs.map +1 -0
- package/dist/utils/logger/__mocks__/Logger.cjs +26 -0
- package/dist/utils/logger/__mocks__/Logger.cjs.map +1 -0
- package/dist/utils/logger/__mocks__/Logger.d.cts +3 -0
- package/dist/utils/logger/__mocks__/Logger.d.cts.map +1 -0
- package/dist/utils/logger/__mocks__/Logger.d.mts +3 -0
- package/dist/utils/logger/__mocks__/Logger.d.mts.map +1 -0
- package/dist/utils/logger/__mocks__/Logger.mjs +23 -0
- package/dist/utils/logger/__mocks__/Logger.mjs.map +1 -0
- package/dist/utils/originPermissions/createOriginPermissions.cjs +30 -0
- package/dist/utils/originPermissions/createOriginPermissions.cjs.map +1 -0
- package/dist/utils/originPermissions/createOriginPermissions.d.cts +24 -0
- package/dist/utils/originPermissions/createOriginPermissions.d.cts.map +1 -0
- package/dist/utils/originPermissions/createOriginPermissions.d.mts +24 -0
- package/dist/utils/originPermissions/createOriginPermissions.d.mts.map +1 -0
- package/dist/utils/originPermissions/createOriginPermissions.mjs +26 -0
- package/dist/utils/originPermissions/createOriginPermissions.mjs.map +1 -0
- package/dist/utils/originPermissions/validateOrigin.cjs +23 -0
- package/dist/utils/originPermissions/validateOrigin.cjs.map +1 -0
- package/dist/utils/originPermissions/validateOrigin.d.cts +10 -0
- package/dist/utils/originPermissions/validateOrigin.d.cts.map +1 -0
- package/dist/utils/originPermissions/validateOrigin.d.mts +10 -0
- package/dist/utils/originPermissions/validateOrigin.d.mts.map +1 -0
- package/dist/utils/originPermissions/validateOrigin.mjs +19 -0
- package/dist/utils/originPermissions/validateOrigin.mjs.map +1 -0
- package/dist/utils/proofOfOwnership/proofOfOwnership.cjs +89 -0
- package/dist/utils/proofOfOwnership/proofOfOwnership.cjs.map +1 -0
- package/dist/utils/proofOfOwnership/proofOfOwnership.d.cts +143 -0
- package/dist/utils/proofOfOwnership/proofOfOwnership.d.cts.map +1 -0
- package/dist/utils/proofOfOwnership/proofOfOwnership.d.mts +143 -0
- package/dist/utils/proofOfOwnership/proofOfOwnership.d.mts.map +1 -0
- package/dist/utils/proofOfOwnership/proofOfOwnership.mjs +85 -0
- package/dist/utils/proofOfOwnership/proofOfOwnership.mjs.map +1 -0
- package/dist/utils/safeMerge/safeMerge.cjs +26 -0
- package/dist/utils/safeMerge/safeMerge.cjs.map +1 -0
- package/dist/utils/safeMerge/safeMerge.d.cts +17 -0
- package/dist/utils/safeMerge/safeMerge.d.cts.map +1 -0
- package/dist/utils/safeMerge/safeMerge.d.mts +17 -0
- package/dist/utils/safeMerge/safeMerge.d.mts.map +1 -0
- package/dist/utils/safeMerge/safeMerge.mjs +22 -0
- package/dist/utils/safeMerge/safeMerge.mjs.map +1 -0
- package/dist/utils/sanitize/sanitize.cjs +42 -0
- package/dist/utils/sanitize/sanitize.cjs.map +1 -0
- package/dist/utils/sanitize/sanitize.d.cts +15 -0
- package/dist/utils/sanitize/sanitize.d.cts.map +1 -0
- package/dist/utils/sanitize/sanitize.d.mts +15 -0
- package/dist/utils/sanitize/sanitize.d.mts.map +1 -0
- package/dist/utils/sanitize/sanitize.mjs +38 -0
- package/dist/utils/sanitize/sanitize.mjs.map +1 -0
- package/dist/utils/serialization/serialization.cjs +73 -0
- package/dist/utils/serialization/serialization.cjs.map +1 -0
- package/dist/utils/serialization/serialization.d.cts +19 -0
- package/dist/utils/serialization/serialization.d.cts.map +1 -0
- package/dist/utils/serialization/serialization.d.mts +19 -0
- package/dist/utils/serialization/serialization.d.mts.map +1 -0
- package/dist/utils/serialization/serialization.mjs +69 -0
- package/dist/utils/serialization/serialization.mjs.map +1 -0
- package/dist/utils/serialization/types.cjs +3 -0
- package/dist/utils/serialization/types.cjs.map +1 -0
- package/dist/utils/serialization/types.d.cts +8 -0
- package/dist/utils/serialization/types.d.cts.map +1 -0
- package/dist/utils/serialization/types.d.mts +8 -0
- package/dist/utils/serialization/types.d.mts.map +1 -0
- package/dist/utils/serialization/types.mjs +2 -0
- package/dist/utils/serialization/types.mjs.map +1 -0
- package/dist/utils/state/IStateManager.cjs +3 -0
- package/dist/utils/state/IStateManager.cjs.map +1 -0
- package/dist/utils/state/IStateManager.d.cts +69 -0
- package/dist/utils/state/IStateManager.d.cts.map +1 -0
- package/dist/utils/state/IStateManager.d.mts +69 -0
- package/dist/utils/state/IStateManager.d.mts.map +1 -0
- package/dist/utils/state/IStateManager.mjs +2 -0
- package/dist/utils/state/IStateManager.mjs.map +1 -0
- package/dist/utils/state/InMemoryState.cjs +41 -0
- package/dist/utils/state/InMemoryState.cjs.map +1 -0
- package/dist/utils/state/InMemoryState.d.cts +18 -0
- package/dist/utils/state/InMemoryState.d.cts.map +1 -0
- package/dist/utils/state/InMemoryState.d.mts +18 -0
- package/dist/utils/state/InMemoryState.d.mts.map +1 -0
- package/dist/utils/state/InMemoryState.mjs +38 -0
- package/dist/utils/state/InMemoryState.mjs.map +1 -0
- package/dist/utils/state/State.cjs +159 -0
- package/dist/utils/state/State.cjs.map +1 -0
- package/dist/utils/state/State.d.cts +25 -0
- package/dist/utils/state/State.d.cts.map +1 -0
- package/dist/utils/state/State.d.mts +25 -0
- package/dist/utils/state/State.d.mts.map +1 -0
- package/dist/utils/state/State.mjs +156 -0
- package/dist/utils/state/State.mjs.map +1 -0
- package/dist/utils/transactionType/transactionType.cjs +32 -0
- package/dist/utils/transactionType/transactionType.cjs.map +1 -0
- package/dist/utils/transactionType/transactionType.d.cts +17 -0
- package/dist/utils/transactionType/transactionType.d.cts.map +1 -0
- package/dist/utils/transactionType/transactionType.d.mts +17 -0
- package/dist/utils/transactionType/transactionType.d.mts.map +1 -0
- package/dist/utils/transactionType/transactionType.mjs +28 -0
- package/dist/utils/transactionType/transactionType.mjs.map +1 -0
- package/dist/utils/urlStruct/urlStruct.cjs +96 -0
- package/dist/utils/urlStruct/urlStruct.cjs.map +1 -0
- package/dist/utils/urlStruct/urlStruct.d.cts +25 -0
- package/dist/utils/urlStruct/urlStruct.d.cts.map +1 -0
- package/dist/utils/urlStruct/urlStruct.d.mts +25 -0
- package/dist/utils/urlStruct/urlStruct.d.mts.map +1 -0
- package/dist/utils/urlStruct/urlStruct.mjs +93 -0
- package/dist/utils/urlStruct/urlStruct.mjs.map +1 -0
- package/dist/utils/uuidStruct/uuidStruct.cjs +12 -0
- package/dist/utils/uuidStruct/uuidStruct.cjs.map +1 -0
- package/dist/utils/uuidStruct/uuidStruct.d.cts +8 -0
- package/dist/utils/uuidStruct/uuidStruct.d.cts.map +1 -0
- package/dist/utils/uuidStruct/uuidStruct.d.mts +8 -0
- package/dist/utils/uuidStruct/uuidStruct.d.mts.map +1 -0
- package/dist/utils/uuidStruct/uuidStruct.mjs +9 -0
- package/dist/utils/uuidStruct/uuidStruct.mjs.map +1 -0
- package/package.json +33 -13
- package/dist/logger.cjs +0 -57
- package/dist/logger.cjs.map +0 -1
- package/dist/logger.d.cts +0 -30
- package/dist/logger.d.cts.map +0 -1
- package/dist/logger.d.mts +0 -30
- package/dist/logger.d.mts.map +0 -1
- package/dist/logger.mjs +0 -53
- package/dist/logger.mjs.map +0 -1
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splits items into chunks of a given size.
|
|
3
|
+
*
|
|
4
|
+
* @param items - Input items; order is preserved in the returned chunks.
|
|
5
|
+
* @param chunkSize - Size of each chunk (must be ≥ 1).
|
|
6
|
+
* @returns An array of chunks, each containing `chunkSize` items.
|
|
7
|
+
*/
|
|
8
|
+
export function chunks(items, chunkSize) {
|
|
9
|
+
if (chunkSize < 1) {
|
|
10
|
+
throw new RangeError('chunkSize must be at least 1');
|
|
11
|
+
}
|
|
12
|
+
const itemsChunks = [];
|
|
13
|
+
for (let index = 0; index < items.length; index += chunkSize) {
|
|
14
|
+
itemsChunks.push(items.slice(index, index + chunkSize));
|
|
15
|
+
}
|
|
16
|
+
return itemsChunks;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Runs async work on items in fixed-size waves, using {@link Promise.all} per wave.
|
|
20
|
+
* The next wave starts only after the current wave completes; any rejection fails the whole call.
|
|
21
|
+
*
|
|
22
|
+
* @param items - Input items; order is preserved in the returned results.
|
|
23
|
+
* @param batchSize - Maximum concurrent mapper invocations per wave (must be ≥ 1).
|
|
24
|
+
* @param mapper - Async function for each item; receives the global index in `items`.
|
|
25
|
+
* @returns One result per item, in the same order as `items`.
|
|
26
|
+
*/
|
|
27
|
+
export async function batchesAll(items, batchSize, mapper) {
|
|
28
|
+
if (batchSize < 1) {
|
|
29
|
+
throw new RangeError('batchSize must be at least 1');
|
|
30
|
+
}
|
|
31
|
+
const results = [];
|
|
32
|
+
for (let index = 0; index < items.length; index += batchSize) {
|
|
33
|
+
const batch = items.slice(index, index + batchSize);
|
|
34
|
+
const batchResults = await Promise.all(batch.map(async (item, batchOffset) => mapper(item, index + batchOffset)));
|
|
35
|
+
results.push(...batchResults);
|
|
36
|
+
}
|
|
37
|
+
return results;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Runs async work on items in fixed-size waves, using {@link Promise.allSettled} per wave.
|
|
41
|
+
* The next wave starts only after the current one settles, limiting concurrency to `batchSize`.
|
|
42
|
+
*
|
|
43
|
+
* @param items - Input items; order is preserved in the returned results.
|
|
44
|
+
* @param batchSize - Maximum concurrent mapper invocations per wave (must be ≥ 1).
|
|
45
|
+
* @param mapper - Async function for each item; receives the global index in `items`.
|
|
46
|
+
* @returns One settled result per item, in the same order as `items`.
|
|
47
|
+
*/
|
|
48
|
+
export async function batchesAllSettled(items, batchSize, mapper) {
|
|
49
|
+
if (batchSize < 1) {
|
|
50
|
+
throw new RangeError('batchSize must be at least 1');
|
|
51
|
+
}
|
|
52
|
+
const results = [];
|
|
53
|
+
for (let index = 0; index < items.length; index += batchSize) {
|
|
54
|
+
const batch = items.slice(index, index + batchSize);
|
|
55
|
+
const settled = await Promise.allSettled(batch.map(async (item, batchOffset) => mapper(item, index + batchOffset)));
|
|
56
|
+
results.push(...settled);
|
|
57
|
+
}
|
|
58
|
+
return results;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Splits `items` into consecutive chunks of `chunkSize`, then runs {@link batchesAllSettled} on those chunks.
|
|
62
|
+
* Each mapper call receives one chunk; settled results are in chunk order (same order as {@link chunks}).
|
|
63
|
+
*
|
|
64
|
+
* @param items - Flat input items.
|
|
65
|
+
* @param chunkSize - Items per chunk (must be ≥ 1).
|
|
66
|
+
* @param batchSize - Max concurrent chunk mappers per wave (must be ≥ 1).
|
|
67
|
+
* @param mapper - Async work for a single chunk; second argument is the chunk index (0-based).
|
|
68
|
+
* @returns One settled result per chunk.
|
|
69
|
+
*/
|
|
70
|
+
export async function batchesAllSettledWithChunks(items, chunkSize, batchSize, mapper) {
|
|
71
|
+
const itemChunks = chunks(items, chunkSize);
|
|
72
|
+
return batchesAllSettled(itemChunks, batchSize, async (chunk, chunkIndex) => mapper(chunk, chunkIndex));
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Splits `items` into consecutive chunks of `chunkSize`, then runs {@link batchesAll} on those chunks.
|
|
76
|
+
* Each mapper call receives one chunk; results are in chunk order (same order as {@link chunks}).
|
|
77
|
+
*
|
|
78
|
+
* @param items - Flat input items.
|
|
79
|
+
* @param chunkSize - Items per chunk (must be ≥ 1).
|
|
80
|
+
* @param batchSize - Max concurrent chunk mappers per wave (must be ≥ 1).
|
|
81
|
+
* @param mapper - Async work for a single chunk; second argument is the chunk index (0-based).
|
|
82
|
+
* @returns One result per chunk.
|
|
83
|
+
*/
|
|
84
|
+
export async function batchesAllWithChunks(items, chunkSize, batchSize, mapper) {
|
|
85
|
+
const itemChunks = chunks(items, chunkSize);
|
|
86
|
+
return batchesAll(itemChunks, batchSize, async (chunk, chunkIndex) => mapper(chunk, chunkIndex));
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=async.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"async.mjs","sourceRoot":"","sources":["../../../src/utils/async/async.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Splits items into chunks of a given size.\n *\n * @param items - Input items; order is preserved in the returned chunks.\n * @param chunkSize - Size of each chunk (must be ≥ 1).\n * @returns An array of chunks, each containing `chunkSize` items.\n */\nexport function chunks<TItem>(\n items: readonly TItem[],\n chunkSize: number,\n): TItem[][] {\n if (chunkSize < 1) {\n throw new RangeError('chunkSize must be at least 1');\n }\n\n const itemsChunks: TItem[][] = [];\n for (let index = 0; index < items.length; index += chunkSize) {\n itemsChunks.push(items.slice(index, index + chunkSize));\n }\n return itemsChunks;\n}\n\n/**\n * Runs async work on items in fixed-size waves, using {@link Promise.all} per wave.\n * The next wave starts only after the current wave completes; any rejection fails the whole call.\n *\n * @param items - Input items; order is preserved in the returned results.\n * @param batchSize - Maximum concurrent mapper invocations per wave (must be ≥ 1).\n * @param mapper - Async function for each item; receives the global index in `items`.\n * @returns One result per item, in the same order as `items`.\n */\nexport async function batchesAll<TItem, TResult>(\n items: readonly TItem[],\n batchSize: number,\n mapper: (item: TItem, index: number) => Promise<TResult>,\n): Promise<TResult[]> {\n if (batchSize < 1) {\n throw new RangeError('batchSize must be at least 1');\n }\n\n const results: TResult[] = [];\n\n for (let index = 0; index < items.length; index += batchSize) {\n const batch = items.slice(index, index + batchSize);\n const batchResults = await Promise.all(\n batch.map(async (item, batchOffset) => mapper(item, index + batchOffset)),\n );\n results.push(...batchResults);\n }\n\n return results;\n}\n\n/**\n * Runs async work on items in fixed-size waves, using {@link Promise.allSettled} per wave.\n * The next wave starts only after the current one settles, limiting concurrency to `batchSize`.\n *\n * @param items - Input items; order is preserved in the returned results.\n * @param batchSize - Maximum concurrent mapper invocations per wave (must be ≥ 1).\n * @param mapper - Async function for each item; receives the global index in `items`.\n * @returns One settled result per item, in the same order as `items`.\n */\nexport async function batchesAllSettled<TItem, TResult>(\n items: readonly TItem[],\n batchSize: number,\n mapper: (item: TItem, index: number) => Promise<TResult>,\n): Promise<PromiseSettledResult<TResult>[]> {\n if (batchSize < 1) {\n throw new RangeError('batchSize must be at least 1');\n }\n\n const results: PromiseSettledResult<TResult>[] = [];\n\n for (let index = 0; index < items.length; index += batchSize) {\n const batch = items.slice(index, index + batchSize);\n const settled = await Promise.allSettled(\n batch.map(async (item, batchOffset) => mapper(item, index + batchOffset)),\n );\n results.push(...settled);\n }\n\n return results;\n}\n\n/**\n * Splits `items` into consecutive chunks of `chunkSize`, then runs {@link batchesAllSettled} on those chunks.\n * Each mapper call receives one chunk; settled results are in chunk order (same order as {@link chunks}).\n *\n * @param items - Flat input items.\n * @param chunkSize - Items per chunk (must be ≥ 1).\n * @param batchSize - Max concurrent chunk mappers per wave (must be ≥ 1).\n * @param mapper - Async work for a single chunk; second argument is the chunk index (0-based).\n * @returns One settled result per chunk.\n */\nexport async function batchesAllSettledWithChunks<TItem, TResult>(\n items: readonly TItem[],\n chunkSize: number,\n batchSize: number,\n mapper: (chunk: TItem[], chunkIndex: number) => Promise<TResult>,\n): Promise<PromiseSettledResult<TResult>[]> {\n const itemChunks = chunks(items, chunkSize);\n return batchesAllSettled(itemChunks, batchSize, async (chunk, chunkIndex) =>\n mapper(chunk, chunkIndex),\n );\n}\n\n/**\n * Splits `items` into consecutive chunks of `chunkSize`, then runs {@link batchesAll} on those chunks.\n * Each mapper call receives one chunk; results are in chunk order (same order as {@link chunks}).\n *\n * @param items - Flat input items.\n * @param chunkSize - Items per chunk (must be ≥ 1).\n * @param batchSize - Max concurrent chunk mappers per wave (must be ≥ 1).\n * @param mapper - Async work for a single chunk; second argument is the chunk index (0-based).\n * @returns One result per chunk.\n */\nexport async function batchesAllWithChunks<TItem, TResult>(\n items: readonly TItem[],\n chunkSize: number,\n batchSize: number,\n mapper: (chunk: TItem[], chunkIndex: number) => Promise<TResult>,\n): Promise<TResult[]> {\n const itemChunks = chunks(items, chunkSize);\n return batchesAll(itemChunks, batchSize, async (chunk, chunkIndex) =>\n mapper(chunk, chunkIndex),\n );\n}\n"]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildUrl = buildUrl;
|
|
4
|
+
const superstruct_1 = require("@metamask/superstruct");
|
|
5
|
+
const sanitize_1 = require("../sanitize/sanitize.cjs");
|
|
6
|
+
const urlStruct_1 = require("../urlStruct/urlStruct.cjs");
|
|
7
|
+
/**
|
|
8
|
+
* Builds a safe URL from a base URL, path, and optional parameters.
|
|
9
|
+
*
|
|
10
|
+
* @param params - The parameters to build the URL from.
|
|
11
|
+
* @returns The validated, sanitized URL.
|
|
12
|
+
*/
|
|
13
|
+
function buildUrl(params) {
|
|
14
|
+
const { baseUrl, path, pathParams, queryParams, encodePathParams = true, } = params;
|
|
15
|
+
// Validate and sanitize base URL
|
|
16
|
+
const sanitizedBaseUrl = (0, sanitize_1.sanitizeUri)(baseUrl);
|
|
17
|
+
if (sanitizedBaseUrl === '') {
|
|
18
|
+
throw new Error('Invalid URL format');
|
|
19
|
+
}
|
|
20
|
+
(0, superstruct_1.assert)(sanitizedBaseUrl, urlStruct_1.UrlStruct);
|
|
21
|
+
const pathWithParams = path.replace(/\{(\w+)\}/gu, (_, key) => {
|
|
22
|
+
const value = pathParams?.[key];
|
|
23
|
+
if (value === undefined) {
|
|
24
|
+
throw new Error(`Path parameter ${key} is undefined`);
|
|
25
|
+
}
|
|
26
|
+
// Sanitize path parameter values to remove control characters
|
|
27
|
+
const sanitizedValue = (0, sanitize_1.sanitizeControlCharacters)(value);
|
|
28
|
+
return encodePathParams
|
|
29
|
+
? encodeURIComponent(sanitizedValue)
|
|
30
|
+
: sanitizedValue;
|
|
31
|
+
});
|
|
32
|
+
const cleanPath = pathWithParams
|
|
33
|
+
.replace(/^\/+/u, '')
|
|
34
|
+
.replace(/\/+/gu, '/')
|
|
35
|
+
.replace(/\/+$/u, '');
|
|
36
|
+
const normalizedBaseUrl = sanitizedBaseUrl.endsWith('/')
|
|
37
|
+
? sanitizedBaseUrl
|
|
38
|
+
: `${sanitizedBaseUrl}/`;
|
|
39
|
+
const url = new URL(cleanPath, normalizedBaseUrl);
|
|
40
|
+
Object.entries(queryParams ?? {})
|
|
41
|
+
.filter(([_, value]) => value !== undefined)
|
|
42
|
+
.filter(([_, value]) => value !== null)
|
|
43
|
+
.forEach(([key, value]) => {
|
|
44
|
+
if (value) {
|
|
45
|
+
// Sanitize query parameter values to remove control characters
|
|
46
|
+
const sanitizedValue = (0, sanitize_1.sanitizeControlCharacters)(value);
|
|
47
|
+
url.searchParams.append(key, sanitizedValue);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
const builtUrl = url.toString();
|
|
51
|
+
(0, superstruct_1.assert)(builtUrl, urlStruct_1.UrlStruct);
|
|
52
|
+
return builtUrl;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=buildUrl.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildUrl.cjs","sourceRoot":"","sources":["../../../src/utils/buildUrl/buildUrl.ts"],"names":[],"mappings":";;AAmBA,4BAqDC;AAxED,uDAA+C;AAE/C,uDAA8E;AAC9E,0DAAmD;AAUnD;;;;;GAKG;AACH,SAAgB,QAAQ,CAAC,MAAsB;IAC7C,MAAM,EACJ,OAAO,EACP,IAAI,EACJ,UAAU,EACV,WAAW,EACX,gBAAgB,GAAG,IAAI,GACxB,GAAG,MAAM,CAAC;IAEX,iCAAiC;IACjC,MAAM,gBAAgB,GAAG,IAAA,sBAAW,EAAC,OAAO,CAAC,CAAC;IAC9C,IAAI,gBAAgB,KAAK,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACxC,CAAC;IACD,IAAA,oBAAM,EAAC,gBAAgB,EAAE,qBAAS,CAAC,CAAC;IAEpC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,GAAW,EAAE,EAAE;QACpE,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,eAAe,CAAC,CAAC;QACxD,CAAC;QACD,8DAA8D;QAC9D,MAAM,cAAc,GAAG,IAAA,oCAAyB,EAAC,KAAK,CAAC,CAAC;QACxD,OAAO,gBAAgB;YACrB,CAAC,CAAC,kBAAkB,CAAC,cAAc,CAAC;YACpC,CAAC,CAAC,cAAc,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,cAAc;SAC7B,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;SACpB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAExB,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC;QACtD,CAAC,CAAC,gBAAgB;QAClB,CAAC,CAAC,GAAG,gBAAgB,GAAG,CAAC;IAE3B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;IAElD,MAAM,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;SAC9B,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC;SAC3C,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC;SACtC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACxB,IAAI,KAAK,EAAE,CAAC;YACV,+DAA+D;YAC/D,MAAM,cAAc,GAAG,IAAA,oCAAyB,EAAC,KAAK,CAAC,CAAC;YACxD,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;IAChC,IAAA,oBAAM,EAAC,QAAQ,EAAE,qBAAS,CAAC,CAAC;IAC5B,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import { assert } from '@metamask/superstruct';\n\nimport { sanitizeControlCharacters, sanitizeUri } from '../sanitize/sanitize';\nimport { UrlStruct } from '../urlStruct/urlStruct';\n\nexport type BuildUrlParams = {\n baseUrl: string;\n path: string;\n pathParams?: Record<string, string> | undefined;\n queryParams?: Record<string, string> | undefined;\n encodePathParams?: boolean;\n};\n\n/**\n * Builds a safe URL from a base URL, path, and optional parameters.\n *\n * @param params - The parameters to build the URL from.\n * @returns The validated, sanitized URL.\n */\nexport function buildUrl(params: BuildUrlParams): string {\n const {\n baseUrl,\n path,\n pathParams,\n queryParams,\n encodePathParams = true,\n } = params;\n\n // Validate and sanitize base URL\n const sanitizedBaseUrl = sanitizeUri(baseUrl);\n if (sanitizedBaseUrl === '') {\n throw new Error('Invalid URL format');\n }\n assert(sanitizedBaseUrl, UrlStruct);\n\n const pathWithParams = path.replace(/\\{(\\w+)\\}/gu, (_, key: string) => {\n const value = pathParams?.[key];\n if (value === undefined) {\n throw new Error(`Path parameter ${key} is undefined`);\n }\n // Sanitize path parameter values to remove control characters\n const sanitizedValue = sanitizeControlCharacters(value);\n return encodePathParams\n ? encodeURIComponent(sanitizedValue)\n : sanitizedValue;\n });\n\n const cleanPath = pathWithParams\n .replace(/^\\/+/u, '')\n .replace(/\\/+/gu, '/')\n .replace(/\\/+$/u, '');\n\n const normalizedBaseUrl = sanitizedBaseUrl.endsWith('/')\n ? sanitizedBaseUrl\n : `${sanitizedBaseUrl}/`;\n\n const url = new URL(cleanPath, normalizedBaseUrl);\n\n Object.entries(queryParams ?? {})\n .filter(([_, value]) => value !== undefined)\n .filter(([_, value]) => value !== null)\n .forEach(([key, value]) => {\n if (value) {\n // Sanitize query parameter values to remove control characters\n const sanitizedValue = sanitizeControlCharacters(value);\n url.searchParams.append(key, sanitizedValue);\n }\n });\n\n const builtUrl = url.toString();\n assert(builtUrl, UrlStruct);\n return builtUrl;\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type BuildUrlParams = {
|
|
2
|
+
baseUrl: string;
|
|
3
|
+
path: string;
|
|
4
|
+
pathParams?: Record<string, string> | undefined;
|
|
5
|
+
queryParams?: Record<string, string> | undefined;
|
|
6
|
+
encodePathParams?: boolean;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Builds a safe URL from a base URL, path, and optional parameters.
|
|
10
|
+
*
|
|
11
|
+
* @param params - The parameters to build the URL from.
|
|
12
|
+
* @returns The validated, sanitized URL.
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildUrl(params: BuildUrlParams): string;
|
|
15
|
+
//# sourceMappingURL=buildUrl.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildUrl.d.cts","sourceRoot":"","sources":["../../../src/utils/buildUrl/buildUrl.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACjD,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAqDvD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type BuildUrlParams = {
|
|
2
|
+
baseUrl: string;
|
|
3
|
+
path: string;
|
|
4
|
+
pathParams?: Record<string, string> | undefined;
|
|
5
|
+
queryParams?: Record<string, string> | undefined;
|
|
6
|
+
encodePathParams?: boolean;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Builds a safe URL from a base URL, path, and optional parameters.
|
|
10
|
+
*
|
|
11
|
+
* @param params - The parameters to build the URL from.
|
|
12
|
+
* @returns The validated, sanitized URL.
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildUrl(params: BuildUrlParams): string;
|
|
15
|
+
//# sourceMappingURL=buildUrl.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildUrl.d.mts","sourceRoot":"","sources":["../../../src/utils/buildUrl/buildUrl.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACjD,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAqDvD"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { assert } from "@metamask/superstruct";
|
|
2
|
+
import { sanitizeControlCharacters, sanitizeUri } from "../sanitize/sanitize.mjs";
|
|
3
|
+
import { UrlStruct } from "../urlStruct/urlStruct.mjs";
|
|
4
|
+
/**
|
|
5
|
+
* Builds a safe URL from a base URL, path, and optional parameters.
|
|
6
|
+
*
|
|
7
|
+
* @param params - The parameters to build the URL from.
|
|
8
|
+
* @returns The validated, sanitized URL.
|
|
9
|
+
*/
|
|
10
|
+
export function buildUrl(params) {
|
|
11
|
+
const { baseUrl, path, pathParams, queryParams, encodePathParams = true, } = params;
|
|
12
|
+
// Validate and sanitize base URL
|
|
13
|
+
const sanitizedBaseUrl = sanitizeUri(baseUrl);
|
|
14
|
+
if (sanitizedBaseUrl === '') {
|
|
15
|
+
throw new Error('Invalid URL format');
|
|
16
|
+
}
|
|
17
|
+
assert(sanitizedBaseUrl, UrlStruct);
|
|
18
|
+
const pathWithParams = path.replace(/\{(\w+)\}/gu, (_, key) => {
|
|
19
|
+
const value = pathParams?.[key];
|
|
20
|
+
if (value === undefined) {
|
|
21
|
+
throw new Error(`Path parameter ${key} is undefined`);
|
|
22
|
+
}
|
|
23
|
+
// Sanitize path parameter values to remove control characters
|
|
24
|
+
const sanitizedValue = sanitizeControlCharacters(value);
|
|
25
|
+
return encodePathParams
|
|
26
|
+
? encodeURIComponent(sanitizedValue)
|
|
27
|
+
: sanitizedValue;
|
|
28
|
+
});
|
|
29
|
+
const cleanPath = pathWithParams
|
|
30
|
+
.replace(/^\/+/u, '')
|
|
31
|
+
.replace(/\/+/gu, '/')
|
|
32
|
+
.replace(/\/+$/u, '');
|
|
33
|
+
const normalizedBaseUrl = sanitizedBaseUrl.endsWith('/')
|
|
34
|
+
? sanitizedBaseUrl
|
|
35
|
+
: `${sanitizedBaseUrl}/`;
|
|
36
|
+
const url = new URL(cleanPath, normalizedBaseUrl);
|
|
37
|
+
Object.entries(queryParams ?? {})
|
|
38
|
+
.filter(([_, value]) => value !== undefined)
|
|
39
|
+
.filter(([_, value]) => value !== null)
|
|
40
|
+
.forEach(([key, value]) => {
|
|
41
|
+
if (value) {
|
|
42
|
+
// Sanitize query parameter values to remove control characters
|
|
43
|
+
const sanitizedValue = sanitizeControlCharacters(value);
|
|
44
|
+
url.searchParams.append(key, sanitizedValue);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
const builtUrl = url.toString();
|
|
48
|
+
assert(builtUrl, UrlStruct);
|
|
49
|
+
return builtUrl;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=buildUrl.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildUrl.mjs","sourceRoot":"","sources":["../../../src/utils/buildUrl/buildUrl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,8BAA8B;AAE/C,OAAO,EAAE,yBAAyB,EAAE,WAAW,EAAE,iCAA6B;AAC9E,OAAO,EAAE,SAAS,EAAE,mCAA+B;AAUnD;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAsB;IAC7C,MAAM,EACJ,OAAO,EACP,IAAI,EACJ,UAAU,EACV,WAAW,EACX,gBAAgB,GAAG,IAAI,GACxB,GAAG,MAAM,CAAC;IAEX,iCAAiC;IACjC,MAAM,gBAAgB,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAC9C,IAAI,gBAAgB,KAAK,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACxC,CAAC;IACD,MAAM,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;IAEpC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,GAAW,EAAE,EAAE;QACpE,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,eAAe,CAAC,CAAC;QACxD,CAAC;QACD,8DAA8D;QAC9D,MAAM,cAAc,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC;QACxD,OAAO,gBAAgB;YACrB,CAAC,CAAC,kBAAkB,CAAC,cAAc,CAAC;YACpC,CAAC,CAAC,cAAc,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,cAAc;SAC7B,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;SACpB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAExB,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC;QACtD,CAAC,CAAC,gBAAgB;QAClB,CAAC,CAAC,GAAG,gBAAgB,GAAG,CAAC;IAE3B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;IAElD,MAAM,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;SAC9B,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC;SAC3C,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC;SACtC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACxB,IAAI,KAAK,EAAE,CAAC;YACV,+DAA+D;YAC/D,MAAM,cAAc,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC;YACxD,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;IAChC,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC5B,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import { assert } from '@metamask/superstruct';\n\nimport { sanitizeControlCharacters, sanitizeUri } from '../sanitize/sanitize';\nimport { UrlStruct } from '../urlStruct/urlStruct';\n\nexport type BuildUrlParams = {\n baseUrl: string;\n path: string;\n pathParams?: Record<string, string> | undefined;\n queryParams?: Record<string, string> | undefined;\n encodePathParams?: boolean;\n};\n\n/**\n * Builds a safe URL from a base URL, path, and optional parameters.\n *\n * @param params - The parameters to build the URL from.\n * @returns The validated, sanitized URL.\n */\nexport function buildUrl(params: BuildUrlParams): string {\n const {\n baseUrl,\n path,\n pathParams,\n queryParams,\n encodePathParams = true,\n } = params;\n\n // Validate and sanitize base URL\n const sanitizedBaseUrl = sanitizeUri(baseUrl);\n if (sanitizedBaseUrl === '') {\n throw new Error('Invalid URL format');\n }\n assert(sanitizedBaseUrl, UrlStruct);\n\n const pathWithParams = path.replace(/\\{(\\w+)\\}/gu, (_, key: string) => {\n const value = pathParams?.[key];\n if (value === undefined) {\n throw new Error(`Path parameter ${key} is undefined`);\n }\n // Sanitize path parameter values to remove control characters\n const sanitizedValue = sanitizeControlCharacters(value);\n return encodePathParams\n ? encodeURIComponent(sanitizedValue)\n : sanitizedValue;\n });\n\n const cleanPath = pathWithParams\n .replace(/^\\/+/u, '')\n .replace(/\\/+/gu, '/')\n .replace(/\\/+$/u, '');\n\n const normalizedBaseUrl = sanitizedBaseUrl.endsWith('/')\n ? sanitizedBaseUrl\n : `${sanitizedBaseUrl}/`;\n\n const url = new URL(cleanPath, normalizedBaseUrl);\n\n Object.entries(queryParams ?? {})\n .filter(([_, value]) => value !== undefined)\n .filter(([_, value]) => value !== null)\n .forEach(([key, value]) => {\n if (value) {\n // Sanitize query parameter values to remove control characters\n const sanitizedValue = sanitizeControlCharacters(value);\n url.searchParams.append(key, sanitizedValue);\n }\n });\n\n const builtUrl = url.toString();\n assert(builtUrl, UrlStruct);\n return builtUrl;\n}\n"]}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InMemoryCache = void 0;
|
|
4
|
+
const utils_1 = require("@metamask/utils");
|
|
5
|
+
/**
|
|
6
|
+
* A simple in-memory cache implementation supporting TTL (Time To Live) functionality.
|
|
7
|
+
*
|
|
8
|
+
* WARNINGS:
|
|
9
|
+
* - This cache is not persistent and will be lost when the process is restarted.
|
|
10
|
+
*/
|
|
11
|
+
class InMemoryCache {
|
|
12
|
+
#cache = new Map();
|
|
13
|
+
#logger;
|
|
14
|
+
constructor(logger) {
|
|
15
|
+
this.#logger = logger;
|
|
16
|
+
}
|
|
17
|
+
#validateTtlOrThrow(ttlMilliseconds) {
|
|
18
|
+
if (ttlMilliseconds === undefined) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (typeof ttlMilliseconds !== 'number') {
|
|
22
|
+
throw new Error('TTL must be a number');
|
|
23
|
+
}
|
|
24
|
+
if (ttlMilliseconds < 0) {
|
|
25
|
+
throw new Error('TTL must be positive');
|
|
26
|
+
}
|
|
27
|
+
if (ttlMilliseconds > Number.MAX_SAFE_INTEGER) {
|
|
28
|
+
throw new Error('TTL must be less than 2^53 - 1');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
#isExpired(cacheEntry) {
|
|
32
|
+
return cacheEntry.expiresAt < Date.now();
|
|
33
|
+
}
|
|
34
|
+
async #cleanupExpiredEntries() {
|
|
35
|
+
const expiredKeys = [];
|
|
36
|
+
for (const [key, entry] of this.#cache.entries()) {
|
|
37
|
+
if (this.#isExpired(entry)) {
|
|
38
|
+
expiredKeys.push(key);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
await this.mdelete(expiredKeys);
|
|
42
|
+
}
|
|
43
|
+
async get(key) {
|
|
44
|
+
const result = await this.mget([key]);
|
|
45
|
+
return result[key];
|
|
46
|
+
}
|
|
47
|
+
async set(key, value, ttlMilliseconds = Number.MAX_SAFE_INTEGER) {
|
|
48
|
+
this.#validateTtlOrThrow(ttlMilliseconds);
|
|
49
|
+
this.#cache.set(key, {
|
|
50
|
+
value,
|
|
51
|
+
expiresAt: Math.min(Date.now() + ttlMilliseconds, Number.MAX_SAFE_INTEGER),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
async delete(key) {
|
|
55
|
+
const result = await this.mdelete([key]);
|
|
56
|
+
return result[key] ?? false;
|
|
57
|
+
}
|
|
58
|
+
async clear() {
|
|
59
|
+
this.#cache.clear();
|
|
60
|
+
}
|
|
61
|
+
async has(key) {
|
|
62
|
+
const cacheEntry = this.#cache.get(key);
|
|
63
|
+
if (!cacheEntry) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
if (this.#isExpired(cacheEntry)) {
|
|
67
|
+
this.#cache.delete(key);
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
async keys() {
|
|
73
|
+
await this.#cleanupExpiredEntries();
|
|
74
|
+
return Array.from(this.#cache.keys());
|
|
75
|
+
}
|
|
76
|
+
async size() {
|
|
77
|
+
await this.#cleanupExpiredEntries();
|
|
78
|
+
return this.#cache.size;
|
|
79
|
+
}
|
|
80
|
+
async peek(key) {
|
|
81
|
+
const cacheEntry = this.#cache.get(key);
|
|
82
|
+
if (!cacheEntry) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
if (this.#isExpired(cacheEntry)) {
|
|
86
|
+
this.#cache.delete(key);
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
return cacheEntry.value;
|
|
90
|
+
}
|
|
91
|
+
async mget(keys) {
|
|
92
|
+
await this.#cleanupExpiredEntries();
|
|
93
|
+
const result = {};
|
|
94
|
+
for (const key of keys) {
|
|
95
|
+
const cacheEntry = this.#cache.get(key);
|
|
96
|
+
if (!cacheEntry) {
|
|
97
|
+
this.#logger.info(`[InMemoryCache] ❌ Cache miss for key "${key}"`);
|
|
98
|
+
result[key] = undefined;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
this.#logger.info(`[InMemoryCache] 🎉 Cache hit for key "${key}"`);
|
|
102
|
+
result[key] = cacheEntry.value;
|
|
103
|
+
}
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
async mset(entries) {
|
|
107
|
+
if (entries.length === 0) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (entries.length === 1) {
|
|
111
|
+
(0, utils_1.assert)(entries[0]); // Enforce type narrowing as TS cannot infer that entries[0] is defined
|
|
112
|
+
const { key, value, ttlMilliseconds } = entries[0];
|
|
113
|
+
await this.set(key, value, ttlMilliseconds);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
entries.forEach(({ ttlMilliseconds }) => {
|
|
117
|
+
this.#validateTtlOrThrow(ttlMilliseconds);
|
|
118
|
+
});
|
|
119
|
+
entries.forEach(({ key, value, ttlMilliseconds }) => {
|
|
120
|
+
if (value === undefined) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
this.#cache.set(key, {
|
|
124
|
+
value,
|
|
125
|
+
expiresAt: Math.min(Date.now() + (ttlMilliseconds ?? Number.MAX_SAFE_INTEGER), Number.MAX_SAFE_INTEGER),
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
async mdelete(keys) {
|
|
130
|
+
return Object.fromEntries(keys.map((key) => [key, this.#cache.delete(key)]));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
exports.InMemoryCache = InMemoryCache;
|
|
134
|
+
//# sourceMappingURL=InMemoryCache.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InMemoryCache.cjs","sourceRoot":"","sources":["../../../src/utils/cache/InMemoryCache.ts"],"names":[],"mappings":"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","sourcesContent":["import { assert } from '@metamask/utils';\n\nimport type { Logger } from '../logger/Logger';\nimport type { Serializable } from '../serialization/types';\nimport type { CacheEntry, ICache } from './types';\n\n/**\n * A simple in-memory cache implementation supporting TTL (Time To Live) functionality.\n *\n * WARNINGS:\n * - This cache is not persistent and will be lost when the process is restarted.\n */\nexport class InMemoryCache implements ICache<Serializable> {\n readonly #cache: Map<string, CacheEntry> = new Map();\n\n readonly #logger: Logger;\n\n constructor(logger: Logger) {\n this.#logger = logger;\n }\n\n #validateTtlOrThrow(ttlMilliseconds?: number): void {\n if (ttlMilliseconds === undefined) {\n return;\n }\n\n if (typeof ttlMilliseconds !== 'number') {\n throw new Error('TTL must be a number');\n }\n\n if (ttlMilliseconds < 0) {\n throw new Error('TTL must be positive');\n }\n\n if (ttlMilliseconds > Number.MAX_SAFE_INTEGER) {\n throw new Error('TTL must be less than 2^53 - 1');\n }\n }\n\n #isExpired(cacheEntry: CacheEntry): boolean {\n return cacheEntry.expiresAt < Date.now();\n }\n\n async #cleanupExpiredEntries(): Promise<void> {\n const expiredKeys: string[] = [];\n for (const [key, entry] of this.#cache.entries()) {\n if (this.#isExpired(entry)) {\n expiredKeys.push(key);\n }\n }\n await this.mdelete(expiredKeys);\n }\n\n async get(key: string): Promise<Serializable | undefined> {\n const result = await this.mget([key]);\n return result[key];\n }\n\n async set(\n key: string,\n value: Serializable,\n ttlMilliseconds = Number.MAX_SAFE_INTEGER,\n ): Promise<void> {\n this.#validateTtlOrThrow(ttlMilliseconds);\n\n this.#cache.set(key, {\n value,\n expiresAt: Math.min(\n Date.now() + ttlMilliseconds,\n Number.MAX_SAFE_INTEGER,\n ),\n });\n }\n\n async delete(key: string): Promise<boolean> {\n const result = await this.mdelete([key]);\n return result[key] ?? false;\n }\n\n async clear(): Promise<void> {\n this.#cache.clear();\n }\n\n async has(key: string): Promise<boolean> {\n const cacheEntry = this.#cache.get(key);\n if (!cacheEntry) {\n return false;\n }\n\n if (this.#isExpired(cacheEntry)) {\n this.#cache.delete(key);\n return false;\n }\n\n return true;\n }\n\n async keys(): Promise<string[]> {\n await this.#cleanupExpiredEntries();\n return Array.from(this.#cache.keys());\n }\n\n async size(): Promise<number> {\n await this.#cleanupExpiredEntries();\n return this.#cache.size;\n }\n\n async peek(key: string): Promise<Serializable | undefined> {\n const cacheEntry = this.#cache.get(key);\n if (!cacheEntry) {\n return undefined;\n }\n\n if (this.#isExpired(cacheEntry)) {\n this.#cache.delete(key);\n return undefined;\n }\n\n return cacheEntry.value;\n }\n\n async mget(\n keys: string[],\n ): Promise<Record<string, Serializable | undefined>> {\n await this.#cleanupExpiredEntries();\n\n const result: Record<string, Serializable | undefined> = {};\n\n for (const key of keys) {\n const cacheEntry = this.#cache.get(key);\n if (!cacheEntry) {\n this.#logger.info(`[InMemoryCache] ❌ Cache miss for key \"${key}\"`);\n result[key] = undefined;\n continue;\n }\n\n this.#logger.info(`[InMemoryCache] 🎉 Cache hit for key \"${key}\"`);\n result[key] = cacheEntry.value;\n }\n\n return result;\n }\n\n async mset(\n entries: { key: string; value: Serializable; ttlMilliseconds?: number }[],\n ): Promise<void> {\n if (entries.length === 0) {\n return;\n }\n\n if (entries.length === 1) {\n assert(entries[0]); // Enforce type narrowing as TS cannot infer that entries[0] is defined\n const { key, value, ttlMilliseconds } = entries[0];\n await this.set(key, value, ttlMilliseconds);\n return;\n }\n\n entries.forEach(({ ttlMilliseconds }) => {\n this.#validateTtlOrThrow(ttlMilliseconds);\n });\n\n entries.forEach(({ key, value, ttlMilliseconds }) => {\n if (value === undefined) {\n return;\n }\n this.#cache.set(key, {\n value,\n expiresAt: Math.min(\n Date.now() + (ttlMilliseconds ?? Number.MAX_SAFE_INTEGER),\n Number.MAX_SAFE_INTEGER,\n ),\n });\n });\n }\n\n async mdelete(keys: string[]): Promise<Record<string, boolean>> {\n return Object.fromEntries(\n keys.map((key) => [key, this.#cache.delete(key)]),\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Logger } from "../logger/Logger.cjs";
|
|
2
|
+
import type { Serializable } from "../serialization/types.cjs";
|
|
3
|
+
import type { ICache } from "./types.cjs";
|
|
4
|
+
/**
|
|
5
|
+
* A simple in-memory cache implementation supporting TTL (Time To Live) functionality.
|
|
6
|
+
*
|
|
7
|
+
* WARNINGS:
|
|
8
|
+
* - This cache is not persistent and will be lost when the process is restarted.
|
|
9
|
+
*/
|
|
10
|
+
export declare class InMemoryCache implements ICache<Serializable> {
|
|
11
|
+
#private;
|
|
12
|
+
constructor(logger: Logger);
|
|
13
|
+
get(key: string): Promise<Serializable | undefined>;
|
|
14
|
+
set(key: string, value: Serializable, ttlMilliseconds?: number): Promise<void>;
|
|
15
|
+
delete(key: string): Promise<boolean>;
|
|
16
|
+
clear(): Promise<void>;
|
|
17
|
+
has(key: string): Promise<boolean>;
|
|
18
|
+
keys(): Promise<string[]>;
|
|
19
|
+
size(): Promise<number>;
|
|
20
|
+
peek(key: string): Promise<Serializable | undefined>;
|
|
21
|
+
mget(keys: string[]): Promise<Record<string, Serializable | undefined>>;
|
|
22
|
+
mset(entries: {
|
|
23
|
+
key: string;
|
|
24
|
+
value: Serializable;
|
|
25
|
+
ttlMilliseconds?: number;
|
|
26
|
+
}[]): Promise<void>;
|
|
27
|
+
mdelete(keys: string[]): Promise<Record<string, boolean>>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=InMemoryCache.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InMemoryCache.d.cts","sourceRoot":"","sources":["../../../src/utils/cache/InMemoryCache.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,6BAAyB;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,mCAA+B;AAC3D,OAAO,KAAK,EAAc,MAAM,EAAE,oBAAgB;AAElD;;;;;GAKG;AACH,qBAAa,aAAc,YAAW,MAAM,CAAC,YAAY,CAAC;;gBAK5C,MAAM,EAAE,MAAM;IAoCpB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAKnD,GAAG,CACP,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,YAAY,EACnB,eAAe,SAA0B,GACxC,OAAO,CAAC,IAAI,CAAC;IAYV,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAclC,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAKzB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAKvB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAcpD,IAAI,CACR,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC,CAAC;IAoB9C,IAAI,CACR,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,YAAY,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,GACxE,OAAO,CAAC,IAAI,CAAC;IA8BV,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAKhE"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Logger } from "../logger/Logger.mjs";
|
|
2
|
+
import type { Serializable } from "../serialization/types.mjs";
|
|
3
|
+
import type { ICache } from "./types.mjs";
|
|
4
|
+
/**
|
|
5
|
+
* A simple in-memory cache implementation supporting TTL (Time To Live) functionality.
|
|
6
|
+
*
|
|
7
|
+
* WARNINGS:
|
|
8
|
+
* - This cache is not persistent and will be lost when the process is restarted.
|
|
9
|
+
*/
|
|
10
|
+
export declare class InMemoryCache implements ICache<Serializable> {
|
|
11
|
+
#private;
|
|
12
|
+
constructor(logger: Logger);
|
|
13
|
+
get(key: string): Promise<Serializable | undefined>;
|
|
14
|
+
set(key: string, value: Serializable, ttlMilliseconds?: number): Promise<void>;
|
|
15
|
+
delete(key: string): Promise<boolean>;
|
|
16
|
+
clear(): Promise<void>;
|
|
17
|
+
has(key: string): Promise<boolean>;
|
|
18
|
+
keys(): Promise<string[]>;
|
|
19
|
+
size(): Promise<number>;
|
|
20
|
+
peek(key: string): Promise<Serializable | undefined>;
|
|
21
|
+
mget(keys: string[]): Promise<Record<string, Serializable | undefined>>;
|
|
22
|
+
mset(entries: {
|
|
23
|
+
key: string;
|
|
24
|
+
value: Serializable;
|
|
25
|
+
ttlMilliseconds?: number;
|
|
26
|
+
}[]): Promise<void>;
|
|
27
|
+
mdelete(keys: string[]): Promise<Record<string, boolean>>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=InMemoryCache.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InMemoryCache.d.mts","sourceRoot":"","sources":["../../../src/utils/cache/InMemoryCache.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,6BAAyB;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,mCAA+B;AAC3D,OAAO,KAAK,EAAc,MAAM,EAAE,oBAAgB;AAElD;;;;;GAKG;AACH,qBAAa,aAAc,YAAW,MAAM,CAAC,YAAY,CAAC;;gBAK5C,MAAM,EAAE,MAAM;IAoCpB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAKnD,GAAG,CACP,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,YAAY,EACnB,eAAe,SAA0B,GACxC,OAAO,CAAC,IAAI,CAAC;IAYV,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAclC,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAKzB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAKvB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAcpD,IAAI,CACR,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC,CAAC;IAoB9C,IAAI,CACR,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,YAAY,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,GACxE,OAAO,CAAC,IAAI,CAAC;IA8BV,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAKhE"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { assert } from "@metamask/utils";
|
|
2
|
+
/**
|
|
3
|
+
* A simple in-memory cache implementation supporting TTL (Time To Live) functionality.
|
|
4
|
+
*
|
|
5
|
+
* WARNINGS:
|
|
6
|
+
* - This cache is not persistent and will be lost when the process is restarted.
|
|
7
|
+
*/
|
|
8
|
+
export class InMemoryCache {
|
|
9
|
+
#cache = new Map();
|
|
10
|
+
#logger;
|
|
11
|
+
constructor(logger) {
|
|
12
|
+
this.#logger = logger;
|
|
13
|
+
}
|
|
14
|
+
#validateTtlOrThrow(ttlMilliseconds) {
|
|
15
|
+
if (ttlMilliseconds === undefined) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (typeof ttlMilliseconds !== 'number') {
|
|
19
|
+
throw new Error('TTL must be a number');
|
|
20
|
+
}
|
|
21
|
+
if (ttlMilliseconds < 0) {
|
|
22
|
+
throw new Error('TTL must be positive');
|
|
23
|
+
}
|
|
24
|
+
if (ttlMilliseconds > Number.MAX_SAFE_INTEGER) {
|
|
25
|
+
throw new Error('TTL must be less than 2^53 - 1');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
#isExpired(cacheEntry) {
|
|
29
|
+
return cacheEntry.expiresAt < Date.now();
|
|
30
|
+
}
|
|
31
|
+
async #cleanupExpiredEntries() {
|
|
32
|
+
const expiredKeys = [];
|
|
33
|
+
for (const [key, entry] of this.#cache.entries()) {
|
|
34
|
+
if (this.#isExpired(entry)) {
|
|
35
|
+
expiredKeys.push(key);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
await this.mdelete(expiredKeys);
|
|
39
|
+
}
|
|
40
|
+
async get(key) {
|
|
41
|
+
const result = await this.mget([key]);
|
|
42
|
+
return result[key];
|
|
43
|
+
}
|
|
44
|
+
async set(key, value, ttlMilliseconds = Number.MAX_SAFE_INTEGER) {
|
|
45
|
+
this.#validateTtlOrThrow(ttlMilliseconds);
|
|
46
|
+
this.#cache.set(key, {
|
|
47
|
+
value,
|
|
48
|
+
expiresAt: Math.min(Date.now() + ttlMilliseconds, Number.MAX_SAFE_INTEGER),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async delete(key) {
|
|
52
|
+
const result = await this.mdelete([key]);
|
|
53
|
+
return result[key] ?? false;
|
|
54
|
+
}
|
|
55
|
+
async clear() {
|
|
56
|
+
this.#cache.clear();
|
|
57
|
+
}
|
|
58
|
+
async has(key) {
|
|
59
|
+
const cacheEntry = this.#cache.get(key);
|
|
60
|
+
if (!cacheEntry) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
if (this.#isExpired(cacheEntry)) {
|
|
64
|
+
this.#cache.delete(key);
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
async keys() {
|
|
70
|
+
await this.#cleanupExpiredEntries();
|
|
71
|
+
return Array.from(this.#cache.keys());
|
|
72
|
+
}
|
|
73
|
+
async size() {
|
|
74
|
+
await this.#cleanupExpiredEntries();
|
|
75
|
+
return this.#cache.size;
|
|
76
|
+
}
|
|
77
|
+
async peek(key) {
|
|
78
|
+
const cacheEntry = this.#cache.get(key);
|
|
79
|
+
if (!cacheEntry) {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
if (this.#isExpired(cacheEntry)) {
|
|
83
|
+
this.#cache.delete(key);
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
return cacheEntry.value;
|
|
87
|
+
}
|
|
88
|
+
async mget(keys) {
|
|
89
|
+
await this.#cleanupExpiredEntries();
|
|
90
|
+
const result = {};
|
|
91
|
+
for (const key of keys) {
|
|
92
|
+
const cacheEntry = this.#cache.get(key);
|
|
93
|
+
if (!cacheEntry) {
|
|
94
|
+
this.#logger.info(`[InMemoryCache] ❌ Cache miss for key "${key}"`);
|
|
95
|
+
result[key] = undefined;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
this.#logger.info(`[InMemoryCache] 🎉 Cache hit for key "${key}"`);
|
|
99
|
+
result[key] = cacheEntry.value;
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
async mset(entries) {
|
|
104
|
+
if (entries.length === 0) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (entries.length === 1) {
|
|
108
|
+
assert(entries[0]); // Enforce type narrowing as TS cannot infer that entries[0] is defined
|
|
109
|
+
const { key, value, ttlMilliseconds } = entries[0];
|
|
110
|
+
await this.set(key, value, ttlMilliseconds);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
entries.forEach(({ ttlMilliseconds }) => {
|
|
114
|
+
this.#validateTtlOrThrow(ttlMilliseconds);
|
|
115
|
+
});
|
|
116
|
+
entries.forEach(({ key, value, ttlMilliseconds }) => {
|
|
117
|
+
if (value === undefined) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
this.#cache.set(key, {
|
|
121
|
+
value,
|
|
122
|
+
expiresAt: Math.min(Date.now() + (ttlMilliseconds ?? Number.MAX_SAFE_INTEGER), Number.MAX_SAFE_INTEGER),
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
async mdelete(keys) {
|
|
127
|
+
return Object.fromEntries(keys.map((key) => [key, this.#cache.delete(key)]));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=InMemoryCache.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InMemoryCache.mjs","sourceRoot":"","sources":["../../../src/utils/cache/InMemoryCache.ts"],"names":[],"mappings":"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","sourcesContent":["import { assert } from '@metamask/utils';\n\nimport type { Logger } from '../logger/Logger';\nimport type { Serializable } from '../serialization/types';\nimport type { CacheEntry, ICache } from './types';\n\n/**\n * A simple in-memory cache implementation supporting TTL (Time To Live) functionality.\n *\n * WARNINGS:\n * - This cache is not persistent and will be lost when the process is restarted.\n */\nexport class InMemoryCache implements ICache<Serializable> {\n readonly #cache: Map<string, CacheEntry> = new Map();\n\n readonly #logger: Logger;\n\n constructor(logger: Logger) {\n this.#logger = logger;\n }\n\n #validateTtlOrThrow(ttlMilliseconds?: number): void {\n if (ttlMilliseconds === undefined) {\n return;\n }\n\n if (typeof ttlMilliseconds !== 'number') {\n throw new Error('TTL must be a number');\n }\n\n if (ttlMilliseconds < 0) {\n throw new Error('TTL must be positive');\n }\n\n if (ttlMilliseconds > Number.MAX_SAFE_INTEGER) {\n throw new Error('TTL must be less than 2^53 - 1');\n }\n }\n\n #isExpired(cacheEntry: CacheEntry): boolean {\n return cacheEntry.expiresAt < Date.now();\n }\n\n async #cleanupExpiredEntries(): Promise<void> {\n const expiredKeys: string[] = [];\n for (const [key, entry] of this.#cache.entries()) {\n if (this.#isExpired(entry)) {\n expiredKeys.push(key);\n }\n }\n await this.mdelete(expiredKeys);\n }\n\n async get(key: string): Promise<Serializable | undefined> {\n const result = await this.mget([key]);\n return result[key];\n }\n\n async set(\n key: string,\n value: Serializable,\n ttlMilliseconds = Number.MAX_SAFE_INTEGER,\n ): Promise<void> {\n this.#validateTtlOrThrow(ttlMilliseconds);\n\n this.#cache.set(key, {\n value,\n expiresAt: Math.min(\n Date.now() + ttlMilliseconds,\n Number.MAX_SAFE_INTEGER,\n ),\n });\n }\n\n async delete(key: string): Promise<boolean> {\n const result = await this.mdelete([key]);\n return result[key] ?? false;\n }\n\n async clear(): Promise<void> {\n this.#cache.clear();\n }\n\n async has(key: string): Promise<boolean> {\n const cacheEntry = this.#cache.get(key);\n if (!cacheEntry) {\n return false;\n }\n\n if (this.#isExpired(cacheEntry)) {\n this.#cache.delete(key);\n return false;\n }\n\n return true;\n }\n\n async keys(): Promise<string[]> {\n await this.#cleanupExpiredEntries();\n return Array.from(this.#cache.keys());\n }\n\n async size(): Promise<number> {\n await this.#cleanupExpiredEntries();\n return this.#cache.size;\n }\n\n async peek(key: string): Promise<Serializable | undefined> {\n const cacheEntry = this.#cache.get(key);\n if (!cacheEntry) {\n return undefined;\n }\n\n if (this.#isExpired(cacheEntry)) {\n this.#cache.delete(key);\n return undefined;\n }\n\n return cacheEntry.value;\n }\n\n async mget(\n keys: string[],\n ): Promise<Record<string, Serializable | undefined>> {\n await this.#cleanupExpiredEntries();\n\n const result: Record<string, Serializable | undefined> = {};\n\n for (const key of keys) {\n const cacheEntry = this.#cache.get(key);\n if (!cacheEntry) {\n this.#logger.info(`[InMemoryCache] ❌ Cache miss for key \"${key}\"`);\n result[key] = undefined;\n continue;\n }\n\n this.#logger.info(`[InMemoryCache] 🎉 Cache hit for key \"${key}\"`);\n result[key] = cacheEntry.value;\n }\n\n return result;\n }\n\n async mset(\n entries: { key: string; value: Serializable; ttlMilliseconds?: number }[],\n ): Promise<void> {\n if (entries.length === 0) {\n return;\n }\n\n if (entries.length === 1) {\n assert(entries[0]); // Enforce type narrowing as TS cannot infer that entries[0] is defined\n const { key, value, ttlMilliseconds } = entries[0];\n await this.set(key, value, ttlMilliseconds);\n return;\n }\n\n entries.forEach(({ ttlMilliseconds }) => {\n this.#validateTtlOrThrow(ttlMilliseconds);\n });\n\n entries.forEach(({ key, value, ttlMilliseconds }) => {\n if (value === undefined) {\n return;\n }\n this.#cache.set(key, {\n value,\n expiresAt: Math.min(\n Date.now() + (ttlMilliseconds ?? Number.MAX_SAFE_INTEGER),\n Number.MAX_SAFE_INTEGER,\n ),\n });\n });\n }\n\n async mdelete(keys: string[]): Promise<Record<string, boolean>> {\n return Object.fromEntries(\n keys.map((key) => [key, this.#cache.delete(key)]),\n );\n }\n}\n"]}
|