@oxy.so/core 1.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/LICENSE +202 -0
- package/NOTICE +16 -0
- package/README.md +221 -0
- package/dist/cjs/.tsbuildinfo +1 -0
- package/dist/cjs/HttpService.js +1270 -0
- package/dist/cjs/OxyServices.base.js +390 -0
- package/dist/cjs/OxyServices.errors.js +95 -0
- package/dist/cjs/OxyServices.js +72 -0
- package/dist/cjs/boot/sessionColdBoot.js +395 -0
- package/dist/cjs/constants/version.js +16 -0
- package/dist/cjs/crypto/aead.js +79 -0
- package/dist/cjs/crypto/ecdh.js +35 -0
- package/dist/cjs/crypto/identityMarker.js +255 -0
- package/dist/cjs/crypto/kdf.js +39 -0
- package/dist/cjs/crypto/keyManager.js +2234 -0
- package/dist/cjs/crypto/polyfill.js +131 -0
- package/dist/cjs/crypto/recoveryPhrase.js +242 -0
- package/dist/cjs/crypto/signatureService.js +273 -0
- package/dist/cjs/i18n/accountCategoryLabels.js +44 -0
- package/dist/cjs/i18n/accountRoleLabels.js +27 -0
- package/dist/cjs/i18n/index.js +90 -0
- package/dist/cjs/i18n/locales/ar-SA.json +282 -0
- package/dist/cjs/i18n/locales/ca-ES.json +282 -0
- package/dist/cjs/i18n/locales/de-DE.json +282 -0
- package/dist/cjs/i18n/locales/en-US.json +2161 -0
- package/dist/cjs/i18n/locales/es-ES.json +2161 -0
- package/dist/cjs/i18n/locales/fr-FR.json +282 -0
- package/dist/cjs/i18n/locales/it-IT.json +282 -0
- package/dist/cjs/i18n/locales/ja-JP.json +282 -0
- package/dist/cjs/i18n/locales/ko-KR.json +282 -0
- package/dist/cjs/i18n/locales/locales/ar-SA.json +282 -0
- package/dist/cjs/i18n/locales/locales/ca-ES.json +282 -0
- package/dist/cjs/i18n/locales/locales/de-DE.json +282 -0
- package/dist/cjs/i18n/locales/locales/en-US.json +2161 -0
- package/dist/cjs/i18n/locales/locales/es-ES.json +2161 -0
- package/dist/cjs/i18n/locales/locales/fr-FR.json +282 -0
- package/dist/cjs/i18n/locales/locales/it-IT.json +282 -0
- package/dist/cjs/i18n/locales/locales/ja-JP.json +282 -0
- package/dist/cjs/i18n/locales/locales/ko-KR.json +282 -0
- package/dist/cjs/i18n/locales/locales/pt-PT.json +282 -0
- package/dist/cjs/i18n/locales/locales/zh-CN.json +282 -0
- package/dist/cjs/i18n/locales/pt-PT.json +282 -0
- package/dist/cjs/i18n/locales/zh-CN.json +282 -0
- package/dist/cjs/i18n/reputationCategoryLabels.js +20 -0
- package/dist/cjs/i18n/trustTierLabels.js +19 -0
- package/dist/cjs/index.js +498 -0
- package/dist/cjs/inference/OxyInferenceClient.js +544 -0
- package/dist/cjs/logger/index.js +149 -0
- package/dist/cjs/mixins/OxyServices.accounts.js +555 -0
- package/dist/cjs/mixins/OxyServices.analytics.js +49 -0
- package/dist/cjs/mixins/OxyServices.appData.js +108 -0
- package/dist/cjs/mixins/OxyServices.assets.js +764 -0
- package/dist/cjs/mixins/OxyServices.auth.js +1254 -0
- package/dist/cjs/mixins/OxyServices.chains.js +73 -0
- package/dist/cjs/mixins/OxyServices.civic.js +611 -0
- package/dist/cjs/mixins/OxyServices.connectedApps.js +78 -0
- package/dist/cjs/mixins/OxyServices.contacts.js +50 -0
- package/dist/cjs/mixins/OxyServices.deviceBoot.js +191 -0
- package/dist/cjs/mixins/OxyServices.deviceTransfer.js +314 -0
- package/dist/cjs/mixins/OxyServices.devices.js +116 -0
- package/dist/cjs/mixins/OxyServices.features.js +335 -0
- package/dist/cjs/mixins/OxyServices.followGraph.js +221 -0
- package/dist/cjs/mixins/OxyServices.identity.js +461 -0
- package/dist/cjs/mixins/OxyServices.identityBackup.js +172 -0
- package/dist/cjs/mixins/OxyServices.inference.js +59 -0
- package/dist/cjs/mixins/OxyServices.language.js +125 -0
- package/dist/cjs/mixins/OxyServices.links.js +72 -0
- package/dist/cjs/mixins/OxyServices.location.js +43 -0
- package/dist/cjs/mixins/OxyServices.nodes.js +175 -0
- package/dist/cjs/mixins/OxyServices.notifications.js +63 -0
- package/dist/cjs/mixins/OxyServices.payment.js +158 -0
- package/dist/cjs/mixins/OxyServices.privacy.js +199 -0
- package/dist/cjs/mixins/OxyServices.reputation.js +289 -0
- package/dist/cjs/mixins/OxyServices.security.js +89 -0
- package/dist/cjs/mixins/OxyServices.store.js +266 -0
- package/dist/cjs/mixins/OxyServices.topics.js +137 -0
- package/dist/cjs/mixins/OxyServices.user.js +902 -0
- package/dist/cjs/mixins/OxyServices.utility.js +1098 -0
- package/dist/cjs/mixins/index.js +135 -0
- package/dist/cjs/mixins/mixinHelpers.js +53 -0
- package/dist/cjs/models/Topic.js +16 -0
- package/dist/cjs/models/interfaces.js +20 -0
- package/dist/cjs/models/session.js +2 -0
- package/dist/cjs/server/auth.js +167 -0
- package/dist/cjs/server/capabilityTicket.js +192 -0
- package/dist/cjs/server/cors.js +225 -0
- package/dist/cjs/server/index.js +97 -0
- package/dist/cjs/server/rateLimit.js +207 -0
- package/dist/cjs/server/safeFetch.js +458 -0
- package/dist/cjs/server/securityHeaders.js +377 -0
- package/dist/cjs/server/userInvalidation.js +156 -0
- package/dist/cjs/server/verifySecret.js +50 -0
- package/dist/cjs/session/SessionClient.js +865 -0
- package/dist/cjs/session/accountDelegationAccess.js +48 -0
- package/dist/cjs/session/accountDialogController.js +1131 -0
- package/dist/cjs/session/accountSwitchTargets.js +81 -0
- package/dist/cjs/session/authStateStore.js +404 -0
- package/dist/cjs/session/createSessionClient.js +32 -0
- package/dist/cjs/session/deviceDirectory.js +143 -0
- package/dist/cjs/session/deviceSwitcherRows.js +76 -0
- package/dist/cjs/session/identityPin.js +256 -0
- package/dist/cjs/session/identitySession.js +135 -0
- package/dist/cjs/session/projectSessionState.js +121 -0
- package/dist/cjs/session/refresh.js +398 -0
- package/dist/cjs/session/sessionClientHost.js +34 -0
- package/dist/cjs/session/sharedDeviceCredential.js +247 -0
- package/dist/cjs/session/socketLoader.js +55 -0
- package/dist/cjs/shared/utils/colorUtils.js +153 -0
- package/dist/cjs/shared/utils/errorUtils.js +183 -0
- package/dist/cjs/shared/utils/index.js +49 -0
- package/dist/cjs/shared/utils/networkUtils.js +183 -0
- package/dist/cjs/shared/utils/themeUtils.js +106 -0
- package/dist/cjs/utils/accountCacheSweep.js +80 -0
- package/dist/cjs/utils/accountUtils.js +140 -0
- package/dist/cjs/utils/activityId.js +6 -0
- package/dist/cjs/utils/apiUtils.js +91 -0
- package/dist/cjs/utils/asyncUtils.js +222 -0
- package/dist/cjs/utils/authHelpers.js +120 -0
- package/dist/cjs/utils/authWebUrl.js +19 -0
- package/dist/cjs/utils/avatarUtils.js +29 -0
- package/dist/cjs/utils/cache.js +235 -0
- package/dist/cjs/utils/cacheKey.js +85 -0
- package/dist/cjs/utils/coldBoot.js +122 -0
- package/dist/cjs/utils/commonsApproval.js +31 -0
- package/dist/cjs/utils/commonsDelivery.js +59 -0
- package/dist/cjs/utils/deviceManager.js +174 -0
- package/dist/cjs/utils/displayNamePolicyRanges.generated.js +60 -0
- package/dist/cjs/utils/edgeRegion.js +6 -0
- package/dist/cjs/utils/errorUtils.js +243 -0
- package/dist/cjs/utils/identityCacheSweep.js +97 -0
- package/dist/cjs/utils/languageUtils.js +224 -0
- package/dist/cjs/utils/oauthPkce.js +311 -0
- package/dist/cjs/utils/officialOrigins.js +64 -0
- package/dist/cjs/utils/oxyServiceEnvironment.js +19 -0
- package/dist/cjs/utils/platform.js +119 -0
- package/dist/cjs/utils/profileLinks.js +63 -0
- package/dist/cjs/utils/redactUrl.js +29 -0
- package/dist/cjs/utils/registrableApex.js +45 -0
- package/dist/cjs/utils/requestUtils.js +209 -0
- package/dist/cjs/utils/sessionUtils.js +181 -0
- package/dist/cjs/utils/textNormalization.js +158 -0
- package/dist/cjs/utils/userHandle.js +37 -0
- package/dist/cjs/utils/userIdentity.js +50 -0
- package/dist/cjs/utils/validationUtils.js +370 -0
- package/dist/cjs/utils/webauthnOrigin.js +51 -0
- package/dist/esm/.tsbuildinfo +1 -0
- package/dist/esm/HttpService.js +1266 -0
- package/dist/esm/OxyServices.base.js +386 -0
- package/dist/esm/OxyServices.errors.js +88 -0
- package/dist/esm/OxyServices.js +66 -0
- package/dist/esm/boot/sessionColdBoot.js +392 -0
- package/dist/esm/constants/version.js +13 -0
- package/dist/esm/crypto/aead.js +74 -0
- package/dist/esm/crypto/ecdh.js +32 -0
- package/dist/esm/crypto/identityMarker.js +248 -0
- package/dist/esm/crypto/kdf.js +36 -0
- package/dist/esm/crypto/keyManager.js +2227 -0
- package/dist/esm/crypto/polyfill.js +129 -0
- package/dist/esm/crypto/recoveryPhrase.js +238 -0
- package/dist/esm/crypto/signatureService.js +269 -0
- package/dist/esm/i18n/accountCategoryLabels.js +37 -0
- package/dist/esm/i18n/accountRoleLabels.js +20 -0
- package/dist/esm/i18n/index.js +83 -0
- package/dist/esm/i18n/locales/ar-SA.json +282 -0
- package/dist/esm/i18n/locales/ca-ES.json +282 -0
- package/dist/esm/i18n/locales/de-DE.json +282 -0
- package/dist/esm/i18n/locales/en-US.json +2161 -0
- package/dist/esm/i18n/locales/es-ES.json +2161 -0
- package/dist/esm/i18n/locales/fr-FR.json +282 -0
- package/dist/esm/i18n/locales/it-IT.json +282 -0
- package/dist/esm/i18n/locales/ja-JP.json +282 -0
- package/dist/esm/i18n/locales/ko-KR.json +282 -0
- package/dist/esm/i18n/locales/locales/ar-SA.json +282 -0
- package/dist/esm/i18n/locales/locales/ca-ES.json +282 -0
- package/dist/esm/i18n/locales/locales/de-DE.json +282 -0
- package/dist/esm/i18n/locales/locales/en-US.json +2161 -0
- package/dist/esm/i18n/locales/locales/es-ES.json +2161 -0
- package/dist/esm/i18n/locales/locales/fr-FR.json +282 -0
- package/dist/esm/i18n/locales/locales/it-IT.json +282 -0
- package/dist/esm/i18n/locales/locales/ja-JP.json +282 -0
- package/dist/esm/i18n/locales/locales/ko-KR.json +282 -0
- package/dist/esm/i18n/locales/locales/pt-PT.json +282 -0
- package/dist/esm/i18n/locales/locales/zh-CN.json +282 -0
- package/dist/esm/i18n/locales/pt-PT.json +282 -0
- package/dist/esm/i18n/locales/zh-CN.json +282 -0
- package/dist/esm/i18n/reputationCategoryLabels.js +13 -0
- package/dist/esm/i18n/trustTierLabels.js +12 -0
- package/dist/esm/index.js +254 -0
- package/dist/esm/inference/OxyInferenceClient.js +538 -0
- package/dist/esm/logger/index.js +140 -0
- package/dist/esm/mixins/OxyServices.accounts.js +543 -0
- package/dist/esm/mixins/OxyServices.analytics.js +46 -0
- package/dist/esm/mixins/OxyServices.appData.js +103 -0
- package/dist/esm/mixins/OxyServices.assets.js +761 -0
- package/dist/esm/mixins/OxyServices.auth.js +1247 -0
- package/dist/esm/mixins/OxyServices.chains.js +70 -0
- package/dist/esm/mixins/OxyServices.civic.js +605 -0
- package/dist/esm/mixins/OxyServices.connectedApps.js +75 -0
- package/dist/esm/mixins/OxyServices.contacts.js +47 -0
- package/dist/esm/mixins/OxyServices.deviceBoot.js +186 -0
- package/dist/esm/mixins/OxyServices.deviceTransfer.js +311 -0
- package/dist/esm/mixins/OxyServices.devices.js +113 -0
- package/dist/esm/mixins/OxyServices.features.js +332 -0
- package/dist/esm/mixins/OxyServices.followGraph.js +218 -0
- package/dist/esm/mixins/OxyServices.identity.js +457 -0
- package/dist/esm/mixins/OxyServices.identityBackup.js +169 -0
- package/dist/esm/mixins/OxyServices.inference.js +56 -0
- package/dist/esm/mixins/OxyServices.language.js +122 -0
- package/dist/esm/mixins/OxyServices.links.js +69 -0
- package/dist/esm/mixins/OxyServices.location.js +40 -0
- package/dist/esm/mixins/OxyServices.nodes.js +172 -0
- package/dist/esm/mixins/OxyServices.notifications.js +60 -0
- package/dist/esm/mixins/OxyServices.payment.js +155 -0
- package/dist/esm/mixins/OxyServices.privacy.js +196 -0
- package/dist/esm/mixins/OxyServices.reputation.js +286 -0
- package/dist/esm/mixins/OxyServices.security.js +86 -0
- package/dist/esm/mixins/OxyServices.store.js +263 -0
- package/dist/esm/mixins/OxyServices.topics.js +134 -0
- package/dist/esm/mixins/OxyServices.user.js +899 -0
- package/dist/esm/mixins/OxyServices.utility.js +1095 -0
- package/dist/esm/mixins/index.js +132 -0
- package/dist/esm/mixins/mixinHelpers.js +48 -0
- package/dist/esm/models/Topic.js +13 -0
- package/dist/esm/models/interfaces.js +17 -0
- package/dist/esm/models/session.js +1 -0
- package/dist/esm/server/auth.js +154 -0
- package/dist/esm/server/capabilityTicket.js +183 -0
- package/dist/esm/server/cors.js +220 -0
- package/dist/esm/server/index.js +47 -0
- package/dist/esm/server/rateLimit.js +201 -0
- package/dist/esm/server/safeFetch.js +447 -0
- package/dist/esm/server/securityHeaders.js +364 -0
- package/dist/esm/server/userInvalidation.js +152 -0
- package/dist/esm/server/verifySecret.js +47 -0
- package/dist/esm/session/SessionClient.js +861 -0
- package/dist/esm/session/accountDelegationAccess.js +45 -0
- package/dist/esm/session/accountDialogController.js +1126 -0
- package/dist/esm/session/accountSwitchTargets.js +77 -0
- package/dist/esm/session/authStateStore.js +398 -0
- package/dist/esm/session/createSessionClient.js +29 -0
- package/dist/esm/session/deviceDirectory.js +135 -0
- package/dist/esm/session/deviceSwitcherRows.js +72 -0
- package/dist/esm/session/identityPin.js +249 -0
- package/dist/esm/session/identitySession.js +131 -0
- package/dist/esm/session/projectSessionState.js +114 -0
- package/dist/esm/session/refresh.js +390 -0
- package/dist/esm/session/sessionClientHost.js +31 -0
- package/dist/esm/session/sharedDeviceCredential.js +239 -0
- package/dist/esm/session/socketLoader.js +19 -0
- package/dist/esm/shared/utils/colorUtils.js +143 -0
- package/dist/esm/shared/utils/errorUtils.js +170 -0
- package/dist/esm/shared/utils/index.js +15 -0
- package/dist/esm/shared/utils/networkUtils.js +173 -0
- package/dist/esm/shared/utils/themeUtils.js +98 -0
- package/dist/esm/utils/accountCacheSweep.js +75 -0
- package/dist/esm/utils/accountUtils.js +131 -0
- package/dist/esm/utils/activityId.js +2 -0
- package/dist/esm/utils/apiUtils.js +84 -0
- package/dist/esm/utils/asyncUtils.js +207 -0
- package/dist/esm/utils/authHelpers.js +111 -0
- package/dist/esm/utils/authWebUrl.js +16 -0
- package/dist/esm/utils/avatarUtils.js +26 -0
- package/dist/esm/utils/cache.js +227 -0
- package/dist/esm/utils/cacheKey.js +80 -0
- package/dist/esm/utils/coldBoot.js +119 -0
- package/dist/esm/utils/commonsApproval.js +27 -0
- package/dist/esm/utils/commonsDelivery.js +54 -0
- package/dist/esm/utils/deviceManager.js +170 -0
- package/dist/esm/utils/displayNamePolicyRanges.generated.js +57 -0
- package/dist/esm/utils/edgeRegion.js +2 -0
- package/dist/esm/utils/errorUtils.js +232 -0
- package/dist/esm/utils/identityCacheSweep.js +92 -0
- package/dist/esm/utils/languageUtils.js +212 -0
- package/dist/esm/utils/oauthPkce.js +297 -0
- package/dist/esm/utils/officialOrigins.js +59 -0
- package/dist/esm/utils/oxyServiceEnvironment.js +16 -0
- package/dist/esm/utils/platform.js +110 -0
- package/dist/esm/utils/profileLinks.js +60 -0
- package/dist/esm/utils/redactUrl.js +26 -0
- package/dist/esm/utils/registrableApex.js +42 -0
- package/dist/esm/utils/requestUtils.js +203 -0
- package/dist/esm/utils/sessionUtils.js +171 -0
- package/dist/esm/utils/textNormalization.js +154 -0
- package/dist/esm/utils/userHandle.js +33 -0
- package/dist/esm/utils/userIdentity.js +45 -0
- package/dist/esm/utils/validationUtils.js +350 -0
- package/dist/esm/utils/webauthnOrigin.js +48 -0
- package/dist/types/.tsbuildinfo +1 -0
- package/dist/types/HttpService.d.ts +413 -0
- package/dist/types/OxyServices.base.d.ts +187 -0
- package/dist/types/OxyServices.d.ts +139 -0
- package/dist/types/OxyServices.errors.d.ts +84 -0
- package/dist/types/boot/sessionColdBoot.d.ts +140 -0
- package/dist/types/constants/version.d.ts +13 -0
- package/dist/types/crypto/aead.d.ts +56 -0
- package/dist/types/crypto/ecdh.d.ts +29 -0
- package/dist/types/crypto/identityMarker.d.ts +94 -0
- package/dist/types/crypto/kdf.d.ts +25 -0
- package/dist/types/crypto/keyManager.d.ts +582 -0
- package/dist/types/crypto/polyfill.d.ts +25 -0
- package/dist/types/crypto/recoveryPhrase.d.ts +173 -0
- package/dist/types/crypto/signatureService.d.ts +136 -0
- package/dist/types/i18n/accountCategoryLabels.d.ts +34 -0
- package/dist/types/i18n/accountRoleLabels.d.ts +10 -0
- package/dist/types/i18n/index.d.ts +3 -0
- package/dist/types/i18n/reputationCategoryLabels.d.ts +10 -0
- package/dist/types/i18n/trustTierLabels.d.ts +9 -0
- package/dist/types/index.d.ts +145 -0
- package/dist/types/inference/OxyInferenceClient.d.ts +342 -0
- package/dist/types/logger/index.d.ts +104 -0
- package/dist/types/mixins/OxyServices.accounts.d.ts +868 -0
- package/dist/types/mixins/OxyServices.analytics.d.ts +72 -0
- package/dist/types/mixins/OxyServices.appData.d.ts +108 -0
- package/dist/types/mixins/OxyServices.assets.d.ts +329 -0
- package/dist/types/mixins/OxyServices.auth.d.ts +908 -0
- package/dist/types/mixins/OxyServices.chains.d.ts +156 -0
- package/dist/types/mixins/OxyServices.civic.d.ts +510 -0
- package/dist/types/mixins/OxyServices.connectedApps.d.ts +169 -0
- package/dist/types/mixins/OxyServices.contacts.d.ts +100 -0
- package/dist/types/mixins/OxyServices.deviceBoot.d.ts +185 -0
- package/dist/types/mixins/OxyServices.deviceTransfer.d.ts +149 -0
- package/dist/types/mixins/OxyServices.devices.d.ts +103 -0
- package/dist/types/mixins/OxyServices.features.d.ts +250 -0
- package/dist/types/mixins/OxyServices.followGraph.d.ts +223 -0
- package/dist/types/mixins/OxyServices.identity.d.ts +351 -0
- package/dist/types/mixins/OxyServices.identityBackup.d.ts +129 -0
- package/dist/types/mixins/OxyServices.inference.d.ts +95 -0
- package/dist/types/mixins/OxyServices.language.d.ts +87 -0
- package/dist/types/mixins/OxyServices.links.d.ts +104 -0
- package/dist/types/mixins/OxyServices.location.d.ts +70 -0
- package/dist/types/mixins/OxyServices.nodes.d.ts +198 -0
- package/dist/types/mixins/OxyServices.notifications.d.ts +143 -0
- package/dist/types/mixins/OxyServices.payment.d.ts +117 -0
- package/dist/types/mixins/OxyServices.privacy.d.ts +146 -0
- package/dist/types/mixins/OxyServices.reputation.d.ts +202 -0
- package/dist/types/mixins/OxyServices.security.d.ts +84 -0
- package/dist/types/mixins/OxyServices.store.d.ts +334 -0
- package/dist/types/mixins/OxyServices.topics.d.ts +110 -0
- package/dist/types/mixins/OxyServices.user.d.ts +558 -0
- package/dist/types/mixins/OxyServices.utility.d.ts +393 -0
- package/dist/types/mixins/index.d.ts +87 -0
- package/dist/types/mixins/mixinHelpers.d.ts +31 -0
- package/dist/types/models/Topic.d.ts +42 -0
- package/dist/types/models/interfaces.d.ts +675 -0
- package/dist/types/models/session.d.ts +51 -0
- package/dist/types/server/auth.d.ts +130 -0
- package/dist/types/server/capabilityTicket.d.ts +41 -0
- package/dist/types/server/cors.d.ts +98 -0
- package/dist/types/server/index.d.ts +35 -0
- package/dist/types/server/rateLimit.d.ts +40 -0
- package/dist/types/server/safeFetch.d.ts +137 -0
- package/dist/types/server/securityHeaders.d.ts +221 -0
- package/dist/types/server/userInvalidation.d.ts +114 -0
- package/dist/types/server/verifySecret.d.ts +29 -0
- package/dist/types/session/SessionClient.d.ts +418 -0
- package/dist/types/session/accountDelegationAccess.d.ts +40 -0
- package/dist/types/session/accountDialogController.d.ts +648 -0
- package/dist/types/session/accountSwitchTargets.d.ts +70 -0
- package/dist/types/session/authStateStore.d.ts +153 -0
- package/dist/types/session/createSessionClient.d.ts +30 -0
- package/dist/types/session/deviceDirectory.d.ts +182 -0
- package/dist/types/session/deviceSwitcherRows.d.ts +92 -0
- package/dist/types/session/identityPin.d.ts +87 -0
- package/dist/types/session/identitySession.d.ts +105 -0
- package/dist/types/session/projectSessionState.d.ts +74 -0
- package/dist/types/session/refresh.d.ts +179 -0
- package/dist/types/session/sessionClientHost.d.ts +18 -0
- package/dist/types/session/sharedDeviceCredential.d.ts +202 -0
- package/dist/types/session/socketLoader.d.ts +11 -0
- package/dist/types/shared/utils/colorUtils.d.ts +104 -0
- package/dist/types/shared/utils/errorUtils.d.ts +97 -0
- package/dist/types/shared/utils/index.d.ts +13 -0
- package/dist/types/shared/utils/networkUtils.d.ts +139 -0
- package/dist/types/shared/utils/themeUtils.d.ts +90 -0
- package/dist/types/utils/accountCacheSweep.d.ts +75 -0
- package/dist/types/utils/accountUtils.d.ts +100 -0
- package/dist/types/utils/activityId.d.ts +2 -0
- package/dist/types/utils/apiUtils.d.ts +95 -0
- package/dist/types/utils/asyncUtils.d.ts +62 -0
- package/dist/types/utils/authHelpers.d.ts +58 -0
- package/dist/types/utils/authWebUrl.d.ts +16 -0
- package/dist/types/utils/avatarUtils.d.ts +16 -0
- package/dist/types/utils/cache.d.ts +130 -0
- package/dist/types/utils/cacheKey.d.ts +66 -0
- package/dist/types/utils/coldBoot.d.ts +131 -0
- package/dist/types/utils/commonsApproval.d.ts +13 -0
- package/dist/types/utils/commonsDelivery.d.ts +105 -0
- package/dist/types/utils/deviceManager.d.ts +65 -0
- package/dist/types/utils/displayNamePolicyRanges.generated.d.ts +57 -0
- package/dist/types/utils/edgeRegion.d.ts +2 -0
- package/dist/types/utils/errorUtils.d.ts +125 -0
- package/dist/types/utils/identityCacheSweep.d.ts +80 -0
- package/dist/types/utils/languageUtils.d.ts +100 -0
- package/dist/types/utils/oauthPkce.d.ts +157 -0
- package/dist/types/utils/officialOrigins.d.ts +13 -0
- package/dist/types/utils/oxyServiceEnvironment.d.ts +17 -0
- package/dist/types/utils/platform.d.ts +49 -0
- package/dist/types/utils/profileLinks.d.ts +44 -0
- package/dist/types/utils/redactUrl.d.ts +17 -0
- package/dist/types/utils/registrableApex.d.ts +27 -0
- package/dist/types/utils/requestUtils.d.ts +123 -0
- package/dist/types/utils/sessionUtils.d.ts +54 -0
- package/dist/types/utils/textNormalization.d.ts +103 -0
- package/dist/types/utils/userHandle.d.ts +26 -0
- package/dist/types/utils/userIdentity.d.ts +21 -0
- package/dist/types/utils/validationUtils.d.ts +268 -0
- package/dist/types/utils/webauthnOrigin.d.ts +32 -0
- package/package.json +168 -0
- package/src/HttpService.ts +1553 -0
- package/src/OxyServices.base.ts +478 -0
- package/src/OxyServices.errors.ts +122 -0
- package/src/OxyServices.ts +172 -0
- package/src/__tests__/authSocket.test.ts +96 -0
- package/src/__tests__/httpServiceActivityId.test.ts +49 -0
- package/src/__tests__/httpServiceAuthSelfAwait.test.ts +108 -0
- package/src/__tests__/httpServiceCache.test.ts +318 -0
- package/src/__tests__/httpServiceCsrf.test.ts +235 -0
- package/src/__tests__/httpServiceFormEncoded.test.ts +142 -0
- package/src/__tests__/httpServiceQueueDeadlock.test.ts +128 -0
- package/src/__tests__/httpServiceUnwrapEnvelope.test.ts +115 -0
- package/src/__tests__/inSessionRefresh.test.ts +260 -0
- package/src/__tests__/linkedClient.test.ts +370 -0
- package/src/__tests__/parseHttpErrorBody.test.ts +116 -0
- package/src/__tests__/serverValueImportsDeclared.test.ts +120 -0
- package/src/__tests__/userIdentity.test.ts +143 -0
- package/src/boot/__tests__/sessionColdBoot.identity.test.ts +393 -0
- package/src/boot/__tests__/sessionColdBoot.sharedDevice.test.ts +325 -0
- package/src/boot/__tests__/sessionColdBoot.test.ts +570 -0
- package/src/boot/sessionColdBoot.ts +529 -0
- package/src/constants/version.ts +15 -0
- package/src/crypto/__tests__/backupMaterial.test.ts +86 -0
- package/src/crypto/__tests__/cryptoPrimitives.test.ts +226 -0
- package/src/crypto/__tests__/identityMocks.ts +125 -0
- package/src/crypto/__tests__/keyManager.atomicity.test.ts +272 -0
- package/src/crypto/__tests__/keyManager.cacheSafety.test.ts +175 -0
- package/src/crypto/__tests__/keyManager.identityStatus.test.ts +217 -0
- package/src/crypto/__tests__/keyManager.recoveryLadder.test.ts +179 -0
- package/src/crypto/__tests__/keyManager.recoveryMnemonic.test.ts +138 -0
- package/src/crypto/__tests__/keyManager.storageMigration.test.ts +227 -0
- package/src/crypto/__tests__/keyManager.test.ts +329 -0
- package/src/crypto/__tests__/polyfill.test.ts +109 -0
- package/src/crypto/__tests__/recoveryPhrase.test.ts +61 -0
- package/src/crypto/__tests__/scopedSeed.test.ts +126 -0
- package/src/crypto/__tests__/signChallengeShared.test.ts +63 -0
- package/src/crypto/__tests__/signedRecord.test.ts +230 -0
- package/src/crypto/aead.ts +97 -0
- package/src/crypto/ecdh.ts +37 -0
- package/src/crypto/identityMarker.ts +291 -0
- package/src/crypto/kdf.ts +43 -0
- package/src/crypto/keyManager.ts +2607 -0
- package/src/crypto/polyfill.ts +143 -0
- package/src/crypto/recoveryPhrase.ts +337 -0
- package/src/crypto/signatureService.ts +350 -0
- package/src/i18n/__tests__/accountCategoryLabels.test.ts +62 -0
- package/src/i18n/__tests__/accountRoleLabels.test.ts +54 -0
- package/src/i18n/__tests__/reputationCategoryLabels.test.ts +56 -0
- package/src/i18n/__tests__/trustTierLabels.test.ts +47 -0
- package/src/i18n/accountCategoryLabels.ts +44 -0
- package/src/i18n/accountRoleLabels.ts +26 -0
- package/src/i18n/index.ts +88 -0
- package/src/i18n/locales/ar-SA.json +282 -0
- package/src/i18n/locales/ca-ES.json +282 -0
- package/src/i18n/locales/de-DE.json +282 -0
- package/src/i18n/locales/en-US.json +2161 -0
- package/src/i18n/locales/es-ES.json +2161 -0
- package/src/i18n/locales/fr-FR.json +282 -0
- package/src/i18n/locales/it-IT.json +282 -0
- package/src/i18n/locales/ja-JP.json +282 -0
- package/src/i18n/locales/ko-KR.json +282 -0
- package/src/i18n/locales/pt-PT.json +282 -0
- package/src/i18n/locales/zh-CN.json +282 -0
- package/src/i18n/reputationCategoryLabels.ts +20 -0
- package/src/i18n/trustTierLabels.ts +18 -0
- package/src/index.ts +881 -0
- package/src/inference/OxyInferenceClient.ts +888 -0
- package/src/inference/__tests__/OxyInferenceClient.test.ts +834 -0
- package/src/logger/__tests__/logger.test.ts +207 -0
- package/src/logger/index.ts +217 -0
- package/src/mixins/OxyServices.accounts.ts +1330 -0
- package/src/mixins/OxyServices.analytics.ts +53 -0
- package/src/mixins/OxyServices.appData.ts +158 -0
- package/src/mixins/OxyServices.assets.ts +861 -0
- package/src/mixins/OxyServices.auth.ts +1858 -0
- package/src/mixins/OxyServices.chains.ts +134 -0
- package/src/mixins/OxyServices.civic.ts +945 -0
- package/src/mixins/OxyServices.connectedApps.ts +174 -0
- package/src/mixins/OxyServices.contacts.ts +73 -0
- package/src/mixins/OxyServices.deviceBoot.ts +210 -0
- package/src/mixins/OxyServices.deviceTransfer.ts +393 -0
- package/src/mixins/OxyServices.devices.ts +120 -0
- package/src/mixins/OxyServices.features.ts +454 -0
- package/src/mixins/OxyServices.followGraph.ts +293 -0
- package/src/mixins/OxyServices.identity.ts +705 -0
- package/src/mixins/OxyServices.identityBackup.ts +250 -0
- package/src/mixins/OxyServices.inference.ts +57 -0
- package/src/mixins/OxyServices.language.ts +144 -0
- package/src/mixins/OxyServices.links.ts +107 -0
- package/src/mixins/OxyServices.location.ts +46 -0
- package/src/mixins/OxyServices.nodes.ts +337 -0
- package/src/mixins/OxyServices.notifications.ts +142 -0
- package/src/mixins/OxyServices.payment.ts +163 -0
- package/src/mixins/OxyServices.privacy.ts +219 -0
- package/src/mixins/OxyServices.reputation.ts +436 -0
- package/src/mixins/OxyServices.security.ts +110 -0
- package/src/mixins/OxyServices.store.ts +585 -0
- package/src/mixins/OxyServices.topics.ts +169 -0
- package/src/mixins/OxyServices.user.ts +1137 -0
- package/src/mixins/OxyServices.utility.ts +1370 -0
- package/src/mixins/__tests__/OxyServices.civic.test.ts +1095 -0
- package/src/mixins/__tests__/OxyServices.deviceBoot.test.ts +124 -0
- package/src/mixins/__tests__/OxyServices.deviceTransfer.test.ts +271 -0
- package/src/mixins/__tests__/OxyServices.identity.test.ts +376 -0
- package/src/mixins/__tests__/OxyServices.links.test.ts +154 -0
- package/src/mixins/__tests__/OxyServices.nodes.test.ts +341 -0
- package/src/mixins/__tests__/OxyServices.rotateKey.test.ts +276 -0
- package/src/mixins/__tests__/OxyServices.serviceAssetMetadata.test.ts +192 -0
- package/src/mixins/__tests__/OxyServices.serviceAssetMetadataBySha.test.ts +135 -0
- package/src/mixins/__tests__/accounts.test.ts +727 -0
- package/src/mixins/__tests__/appData.test.ts +203 -0
- package/src/mixins/__tests__/assetCredentials.test.ts +47 -0
- package/src/mixins/__tests__/assetUpload.test.ts +191 -0
- package/src/mixins/__tests__/backgroundCredential.httpIntegration.test.ts +135 -0
- package/src/mixins/__tests__/chains.test.ts +113 -0
- package/src/mixins/__tests__/commonsSignIn.test.ts +1144 -0
- package/src/mixins/__tests__/connectedApps.test.ts +123 -0
- package/src/mixins/__tests__/deviceTokenMintPinned.test.ts +113 -0
- package/src/mixins/__tests__/discoveryErrorHandling.test.ts +266 -0
- package/src/mixins/__tests__/followCacheInvalidation.test.ts +173 -0
- package/src/mixins/__tests__/followGraph.test.ts +147 -0
- package/src/mixins/__tests__/followGraphPagination.test.ts +271 -0
- package/src/mixins/__tests__/getFileDownloadUrl.test.ts +346 -0
- package/src/mixins/__tests__/getFollowStatuses.test.ts +95 -0
- package/src/mixins/__tests__/getUsersByIds.test.ts +149 -0
- package/src/mixins/__tests__/identityBackup.test.ts +315 -0
- package/src/mixins/__tests__/identityWriteCacheInvalidation.test.ts +407 -0
- package/src/mixins/__tests__/inferenceFactory.test.ts +58 -0
- package/src/mixins/__tests__/onTokensChanged.test.ts +129 -0
- package/src/mixins/__tests__/preSessionSkipAuth.test.ts +284 -0
- package/src/mixins/__tests__/privacyCacheInvalidation.test.ts +155 -0
- package/src/mixins/__tests__/reputation.test.ts +522 -0
- package/src/mixins/__tests__/serviceAuth.test.ts +832 -0
- package/src/mixins/__tests__/serviceTokenJwks.test.ts +208 -0
- package/src/mixins/__tests__/store.test.ts +304 -0
- package/src/mixins/__tests__/topics.test.ts +156 -0
- package/src/mixins/__tests__/userReadCacheBypass.test.ts +129 -0
- package/src/mixins/__tests__/userTokenAuth.test.ts +746 -0
- package/src/mixins/__tests__/verifyChallenge.test.ts +130 -0
- package/src/mixins/__tests__/verifyServiceActingAs.test.ts +167 -0
- package/src/mixins/__tests__/webauthnAuth.test.ts +205 -0
- package/src/mixins/index.ts +201 -0
- package/src/mixins/mixinHelpers.ts +69 -0
- package/src/models/Topic.ts +46 -0
- package/src/models/interfaces.ts +786 -0
- package/src/models/session.ts +55 -0
- package/src/server/__tests__/auth.test.ts +78 -0
- package/src/server/__tests__/capabilityTicket.test.ts +111 -0
- package/src/server/__tests__/cors.socket.test.ts +225 -0
- package/src/server/__tests__/cors.test.ts +158 -0
- package/src/server/__tests__/rateLimit.test.ts +257 -0
- package/src/server/__tests__/safeFetch.test.ts +232 -0
- package/src/server/__tests__/securityHeaders.test.ts +348 -0
- package/src/server/__tests__/serviceTokenAttribution.test.ts +396 -0
- package/src/server/__tests__/userInvalidation.test.ts +203 -0
- package/src/server/__tests__/verifySecret.test.ts +40 -0
- package/src/server/auth.ts +271 -0
- package/src/server/capabilityTicket.ts +258 -0
- package/src/server/cors.ts +277 -0
- package/src/server/index.ts +136 -0
- package/src/server/rateLimit.ts +313 -0
- package/src/server/safeFetch.ts +586 -0
- package/src/server/securityHeaders.ts +467 -0
- package/src/server/userInvalidation.ts +199 -0
- package/src/server/verifySecret.ts +52 -0
- package/src/session/SessionClient.ts +1001 -0
- package/src/session/__tests__/SessionClient.additive.test.ts +153 -0
- package/src/session/__tests__/SessionClient.broadcastChannel.test.ts +114 -0
- package/src/session/__tests__/SessionClient.diagnostics.test.ts +91 -0
- package/src/session/__tests__/SessionClient.directory.test.ts +688 -0
- package/src/session/__tests__/SessionClient.httpIntegration.test.ts +65 -0
- package/src/session/__tests__/SessionClient.identityPin.test.ts +175 -0
- package/src/session/__tests__/SessionClient.rest.test.ts +119 -0
- package/src/session/__tests__/SessionClient.serverEvents.test.ts +72 -0
- package/src/session/__tests__/SessionClient.socket.test.ts +202 -0
- package/src/session/__tests__/SessionClient.socketFactory.test.ts +81 -0
- package/src/session/__tests__/SessionClient.state.test.ts +78 -0
- package/src/session/__tests__/SessionClient.switchTokenOrder.test.ts +170 -0
- package/src/session/__tests__/accountDelegationAccess.test.ts +104 -0
- package/src/session/__tests__/accountDialogController.test.ts +1969 -0
- package/src/session/__tests__/accountDialogShape.test.ts +118 -0
- package/src/session/__tests__/accountSwitchTargets.test.ts +137 -0
- package/src/session/__tests__/authStateStore.test.ts +451 -0
- package/src/session/__tests__/deviceDirectory.test.ts +422 -0
- package/src/session/__tests__/deviceSwitcherRows.test.ts +223 -0
- package/src/session/__tests__/identityPin.test.ts +131 -0
- package/src/session/__tests__/identitySession.test.ts +194 -0
- package/src/session/__tests__/projectSessionState.test.ts +105 -0
- package/src/session/__tests__/refresh.identityPin.test.ts +307 -0
- package/src/session/__tests__/refresh.test.ts +443 -0
- package/src/session/__tests__/sessionIntegration.test.ts +209 -0
- package/src/session/__tests__/sharedDeviceCredential.test.ts +300 -0
- package/src/session/accountDelegationAccess.ts +72 -0
- package/src/session/accountDialogController.ts +1494 -0
- package/src/session/accountSwitchTargets.ts +93 -0
- package/src/session/authStateStore.ts +502 -0
- package/src/session/createSessionClient.ts +39 -0
- package/src/session/deviceDirectory.ts +269 -0
- package/src/session/deviceSwitcherRows.ts +145 -0
- package/src/session/identityPin.ts +310 -0
- package/src/session/identitySession.ts +206 -0
- package/src/session/projectSessionState.ts +137 -0
- package/src/session/refresh.ts +517 -0
- package/src/session/sessionClientHost.ts +39 -0
- package/src/session/sharedDeviceCredential.ts +349 -0
- package/src/session/socketLoader.ts +30 -0
- package/src/shared/utils/colorUtils.ts +155 -0
- package/src/shared/utils/errorUtils.ts +181 -0
- package/src/shared/utils/index.ts +59 -0
- package/src/shared/utils/networkUtils.ts +248 -0
- package/src/shared/utils/themeUtils.ts +115 -0
- package/src/types/buffer.d.ts +97 -0
- package/src/types/expo-crypto.d.ts +16 -0
- package/src/types/expo-secure-store.d.ts +17 -0
- package/src/utils/__tests__/accountUtils.test.ts +151 -0
- package/src/utils/__tests__/activityId.test.ts +45 -0
- package/src/utils/__tests__/asyncUtils.test.ts +187 -0
- package/src/utils/__tests__/authWebUrl.test.ts +15 -0
- package/src/utils/__tests__/cacheKey.test.ts +0 -0
- package/src/utils/__tests__/coldBoot.test.ts +496 -0
- package/src/utils/__tests__/commonsApproval.test.ts +60 -0
- package/src/utils/__tests__/identityCacheSweep.test.ts +151 -0
- package/src/utils/__tests__/languageUtils.test.ts +219 -0
- package/src/utils/__tests__/oauthPkce.test.ts +272 -0
- package/src/utils/__tests__/officialOrigins.test.ts +31 -0
- package/src/utils/__tests__/oxyServiceEnvironment.test.ts +7 -0
- package/src/utils/__tests__/profileLinks.test.ts +180 -0
- package/src/utils/__tests__/redactUrl.test.ts +33 -0
- package/src/utils/__tests__/registrableApex.test.ts +62 -0
- package/src/utils/__tests__/textNormalization.test.ts +205 -0
- package/src/utils/__tests__/validationUtils.test.ts +703 -0
- package/src/utils/__tests__/webauthnOrigin.test.ts +83 -0
- package/src/utils/accountCacheSweep.ts +93 -0
- package/src/utils/accountUtils.ts +194 -0
- package/src/utils/activityId.ts +2 -0
- package/src/utils/apiUtils.ts +137 -0
- package/src/utils/asyncUtils.ts +280 -0
- package/src/utils/authHelpers.ts +148 -0
- package/src/utils/authWebUrl.ts +17 -0
- package/src/utils/avatarUtils.ts +39 -0
- package/src/utils/cache.ts +273 -0
- package/src/utils/cacheKey.ts +93 -0
- package/src/utils/coldBoot.ts +218 -0
- package/src/utils/commonsApproval.ts +39 -0
- package/src/utils/commonsDelivery.ts +132 -0
- package/src/utils/deviceManager.ts +203 -0
- package/src/utils/displayNamePolicyRanges.generated.ts +69 -0
- package/src/utils/edgeRegion.ts +2 -0
- package/src/utils/errorUtils.ts +352 -0
- package/src/utils/identityCacheSweep.ts +104 -0
- package/src/utils/languageUtils.ts +256 -0
- package/src/utils/oauthPkce.ts +392 -0
- package/src/utils/officialOrigins.ts +62 -0
- package/src/utils/oxyServiceEnvironment.ts +17 -0
- package/src/utils/platform.ts +139 -0
- package/src/utils/profileLinks.ts +91 -0
- package/src/utils/redactUrl.ts +28 -0
- package/src/utils/registrableApex.ts +41 -0
- package/src/utils/requestUtils.ts +237 -0
- package/src/utils/sessionUtils.ts +206 -0
- package/src/utils/textNormalization.ts +162 -0
- package/src/utils/userHandle.ts +49 -0
- package/src/utils/userIdentity.ts +60 -0
- package/src/utils/validationUtils.ts +390 -0
- package/src/utils/webauthnOrigin.ts +52 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request utilities for HTTP clients
|
|
3
|
+
*
|
|
4
|
+
* Provides reusable components for request deduplication, queuing, and logging
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Request deduplication - prevents duplicate concurrent requests
|
|
8
|
+
*
|
|
9
|
+
* When multiple requests with the same key are made simultaneously,
|
|
10
|
+
* only one request is executed and all callers receive the same result.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const deduplicator = new RequestDeduplicator();
|
|
15
|
+
*
|
|
16
|
+
* // Multiple calls with same key will share the same promise
|
|
17
|
+
* const promise1 = deduplicator.deduplicate('user-123', () => fetchUser('123'));
|
|
18
|
+
* const promise2 = deduplicator.deduplicate('user-123', () => fetchUser('123'));
|
|
19
|
+
* // promise1 === promise2, only one API call is made
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export class RequestDeduplicator {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.pendingRequests = new Map();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Deduplicate a request by key
|
|
28
|
+
* @param key Unique key for the request
|
|
29
|
+
* @param requestFn Function that returns a promise
|
|
30
|
+
* @returns Promise that will be shared if key already exists
|
|
31
|
+
*/
|
|
32
|
+
async deduplicate(key, requestFn) {
|
|
33
|
+
const existing = this.pendingRequests.get(key);
|
|
34
|
+
if (existing) {
|
|
35
|
+
return existing;
|
|
36
|
+
}
|
|
37
|
+
const promise = requestFn()
|
|
38
|
+
.finally(() => {
|
|
39
|
+
this.pendingRequests.delete(key);
|
|
40
|
+
});
|
|
41
|
+
this.pendingRequests.set(key, promise);
|
|
42
|
+
return promise;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Clear all pending requests
|
|
46
|
+
*/
|
|
47
|
+
clear() {
|
|
48
|
+
this.pendingRequests.clear();
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get number of pending requests
|
|
52
|
+
*/
|
|
53
|
+
size() {
|
|
54
|
+
return this.pendingRequests.size;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Request queue with concurrency control
|
|
59
|
+
*
|
|
60
|
+
* Limits the number of concurrent requests and queues excess requests.
|
|
61
|
+
* Useful for rate limiting and preventing request flooding.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* const queue = new RequestQueue(5, 100); // Max 5 concurrent, queue up to 100
|
|
66
|
+
*
|
|
67
|
+
* // All requests will be queued and processed with max 5 concurrent
|
|
68
|
+
* await queue.enqueue(() => fetchUser('1'));
|
|
69
|
+
* await queue.enqueue(() => fetchUser('2'));
|
|
70
|
+
* // ...
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export class RequestQueue {
|
|
74
|
+
/**
|
|
75
|
+
* Create a new request queue
|
|
76
|
+
* @param maxConcurrent Maximum number of concurrent requests (default: 10)
|
|
77
|
+
* @param maxQueueSize Maximum queue size (default: 100)
|
|
78
|
+
*/
|
|
79
|
+
constructor(maxConcurrent = 10, maxQueueSize = 100) {
|
|
80
|
+
this.queue = [];
|
|
81
|
+
this.running = 0;
|
|
82
|
+
this.maxConcurrent = maxConcurrent;
|
|
83
|
+
this.maxQueueSize = maxQueueSize;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Enqueue a request
|
|
87
|
+
* @param requestFn Function that returns a promise
|
|
88
|
+
* @returns Promise that resolves when request completes
|
|
89
|
+
*/
|
|
90
|
+
async enqueue(requestFn) {
|
|
91
|
+
if (this.queue.length >= this.maxQueueSize) {
|
|
92
|
+
throw new Error('Request queue is full');
|
|
93
|
+
}
|
|
94
|
+
return new Promise((resolve, reject) => {
|
|
95
|
+
this.queue.push(async () => {
|
|
96
|
+
try {
|
|
97
|
+
const result = await requestFn();
|
|
98
|
+
resolve(result);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
reject(error);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
this.process();
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Process queued requests
|
|
109
|
+
*/
|
|
110
|
+
async process() {
|
|
111
|
+
if (this.running >= this.maxConcurrent || this.queue.length === 0) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
this.running++;
|
|
115
|
+
const requestFn = this.queue.shift();
|
|
116
|
+
if (requestFn) {
|
|
117
|
+
try {
|
|
118
|
+
await requestFn();
|
|
119
|
+
}
|
|
120
|
+
finally {
|
|
121
|
+
this.running--;
|
|
122
|
+
this.process();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
this.running--;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Clear all queued requests
|
|
131
|
+
*/
|
|
132
|
+
clear() {
|
|
133
|
+
this.queue = [];
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Get queue size
|
|
137
|
+
*/
|
|
138
|
+
size() {
|
|
139
|
+
return this.queue.length;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get number of currently running requests
|
|
143
|
+
*/
|
|
144
|
+
runningCount() {
|
|
145
|
+
return this.running;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Simple logger with level support
|
|
150
|
+
*
|
|
151
|
+
* Lightweight logger for HTTP clients and utilities.
|
|
152
|
+
* For structured, namespaced, level-gated logging, use `@oxy.so/core/logger`.
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* ```typescript
|
|
156
|
+
* const logger = new SimpleLogger(true, 'debug');
|
|
157
|
+
* logger.debug('Debug message');
|
|
158
|
+
* logger.info('Info message');
|
|
159
|
+
* logger.error('Error message');
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
162
|
+
export class SimpleLogger {
|
|
163
|
+
/**
|
|
164
|
+
* Create a new simple logger
|
|
165
|
+
* @param enabled Whether logging is enabled
|
|
166
|
+
* @param level Minimum log level
|
|
167
|
+
* @param prefix Prefix for log messages (default: '')
|
|
168
|
+
*/
|
|
169
|
+
constructor(enabled = false, level = 'error', prefix = '') {
|
|
170
|
+
this.enabled = enabled;
|
|
171
|
+
this.level = level;
|
|
172
|
+
this.prefix = prefix;
|
|
173
|
+
}
|
|
174
|
+
shouldLog(level) {
|
|
175
|
+
if (!this.enabled || this.level === 'none')
|
|
176
|
+
return false;
|
|
177
|
+
const levels = ['none', 'error', 'warn', 'info', 'debug'];
|
|
178
|
+
return levels.indexOf(level) <= levels.indexOf(this.level);
|
|
179
|
+
}
|
|
180
|
+
formatMessage(...args) {
|
|
181
|
+
return this.prefix ? [`[${this.prefix}]`, ...args] : args;
|
|
182
|
+
}
|
|
183
|
+
error(...args) {
|
|
184
|
+
if (this.shouldLog('error')) {
|
|
185
|
+
console.error(...this.formatMessage(...args));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
warn(...args) {
|
|
189
|
+
if (this.shouldLog('warn')) {
|
|
190
|
+
console.warn(...this.formatMessage(...args));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
info(...args) {
|
|
194
|
+
if (this.shouldLog('info')) {
|
|
195
|
+
console.info(...this.formatMessage(...args));
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
debug(...args) {
|
|
199
|
+
if (this.shouldLog('debug')) {
|
|
200
|
+
console.log(...this.formatMessage(...args));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session management utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides consistent session normalization, deduplication, and sorting
|
|
5
|
+
* to ensure sessions are always displayed in a predictable order.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Normalize a session to ensure all required fields are present
|
|
9
|
+
*/
|
|
10
|
+
export function normalizeSession(session) {
|
|
11
|
+
const now = new Date().toISOString();
|
|
12
|
+
return {
|
|
13
|
+
sessionId: session.sessionId,
|
|
14
|
+
deviceId: session.deviceId || '',
|
|
15
|
+
expiresAt: session.expiresAt || now,
|
|
16
|
+
lastActive: session.lastActive || now,
|
|
17
|
+
userId: session.userId || '',
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Compare two sessions for equality
|
|
22
|
+
*/
|
|
23
|
+
export function sessionsEqual(a, b) {
|
|
24
|
+
return a.sessionId === b.sessionId;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Sort sessions by lastActive (most recent first), then by sessionId for stability
|
|
28
|
+
*/
|
|
29
|
+
export function sortSessions(sessions) {
|
|
30
|
+
return [...sessions].sort((a, b) => {
|
|
31
|
+
// Sort by lastActive descending (most recent first)
|
|
32
|
+
const timeA = new Date(a.lastActive).getTime();
|
|
33
|
+
const timeB = new Date(b.lastActive).getTime();
|
|
34
|
+
if (timeA !== timeB) {
|
|
35
|
+
return timeB - timeA; // Descending order
|
|
36
|
+
}
|
|
37
|
+
// If lastActive is the same, sort by sessionId for stability
|
|
38
|
+
return a.sessionId.localeCompare(b.sessionId);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Deduplicate sessions by sessionId, keeping the most recent version
|
|
43
|
+
*/
|
|
44
|
+
export function deduplicateSessions(sessions) {
|
|
45
|
+
const sessionMap = new Map();
|
|
46
|
+
for (const session of sessions) {
|
|
47
|
+
const existing = sessionMap.get(session.sessionId);
|
|
48
|
+
if (!existing) {
|
|
49
|
+
sessionMap.set(session.sessionId, session);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// Keep the one with more recent lastActive
|
|
53
|
+
const existingTime = new Date(existing.lastActive).getTime();
|
|
54
|
+
const currentTime = new Date(session.lastActive).getTime();
|
|
55
|
+
if (currentTime > existingTime) {
|
|
56
|
+
sessionMap.set(session.sessionId, session);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return Array.from(sessionMap.values());
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Deduplicate sessions by userId, keeping only one session per user
|
|
64
|
+
* Priority: 1) Active session (if provided), 2) Most recent session
|
|
65
|
+
* This prevents showing duplicate accounts for the same user
|
|
66
|
+
*/
|
|
67
|
+
export function deduplicateSessionsByUserId(sessions, activeSessionId) {
|
|
68
|
+
if (!sessions.length)
|
|
69
|
+
return [];
|
|
70
|
+
const userSessionMap = new Map();
|
|
71
|
+
for (const session of sessions) {
|
|
72
|
+
if (!session.userId)
|
|
73
|
+
continue; // Skip sessions without userId
|
|
74
|
+
const existing = userSessionMap.get(session.userId);
|
|
75
|
+
if (!existing) {
|
|
76
|
+
userSessionMap.set(session.userId, session);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// Prioritize active session
|
|
80
|
+
const isCurrentActive = activeSessionId && session.sessionId === activeSessionId;
|
|
81
|
+
const isExistingActive = activeSessionId && existing.sessionId === activeSessionId;
|
|
82
|
+
if (isCurrentActive && !isExistingActive) {
|
|
83
|
+
userSessionMap.set(session.userId, session);
|
|
84
|
+
}
|
|
85
|
+
else if (!isCurrentActive && isExistingActive) {
|
|
86
|
+
// Keep existing (active) session
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
// Neither is active, keep the one with more recent lastActive
|
|
91
|
+
const existingTime = new Date(existing.lastActive).getTime();
|
|
92
|
+
const currentTime = new Date(session.lastActive).getTime();
|
|
93
|
+
if (currentTime > existingTime) {
|
|
94
|
+
userSessionMap.set(session.userId, session);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return Array.from(userSessionMap.values());
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Normalize, deduplicate, and sort sessions
|
|
103
|
+
* This ensures consistent session ordering across the application
|
|
104
|
+
*
|
|
105
|
+
* @param sessions - Array of sessions to normalize
|
|
106
|
+
* @param activeSessionId - Optional active session ID to prioritize
|
|
107
|
+
* @param deduplicateByUserId - If true, deduplicate by userId (one account per user). Default: true
|
|
108
|
+
*/
|
|
109
|
+
export function normalizeAndSortSessions(sessions, activeSessionId, deduplicateByUserId = true) {
|
|
110
|
+
if (!sessions.length)
|
|
111
|
+
return [];
|
|
112
|
+
// Normalize all sessions
|
|
113
|
+
const normalized = sessions.map(normalizeSession);
|
|
114
|
+
// First deduplicate by sessionId (exact duplicates)
|
|
115
|
+
const deduplicatedBySessionId = deduplicateSessions(normalized);
|
|
116
|
+
// Then deduplicate by userId if requested (one account per user)
|
|
117
|
+
const finalSessions = deduplicateByUserId
|
|
118
|
+
? deduplicateSessionsByUserId(deduplicatedBySessionId, activeSessionId)
|
|
119
|
+
: deduplicatedBySessionId;
|
|
120
|
+
// Sort consistently
|
|
121
|
+
return sortSessions(finalSessions);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Merge two session arrays, prioritizing newer data
|
|
125
|
+
* Returns normalized, deduplicated, and sorted sessions
|
|
126
|
+
*
|
|
127
|
+
* @param existing - Existing sessions array
|
|
128
|
+
* @param incoming - New sessions to merge in
|
|
129
|
+
* @param activeSessionId - Optional active session ID to prioritize
|
|
130
|
+
* @param deduplicateByUserId - If true, deduplicate by userId (one account per user). Default: true
|
|
131
|
+
*/
|
|
132
|
+
export function mergeSessions(existing, incoming, activeSessionId, deduplicateByUserId = true) {
|
|
133
|
+
if (!existing.length && !incoming.length)
|
|
134
|
+
return [];
|
|
135
|
+
if (!existing.length)
|
|
136
|
+
return normalizeAndSortSessions(incoming, activeSessionId, deduplicateByUserId);
|
|
137
|
+
if (!incoming.length)
|
|
138
|
+
return normalizeAndSortSessions(existing, activeSessionId, deduplicateByUserId);
|
|
139
|
+
// Normalize both arrays
|
|
140
|
+
const normalizedExisting = existing.map(normalizeSession);
|
|
141
|
+
const normalizedIncoming = incoming.map(normalizeSession);
|
|
142
|
+
// Create a map with existing sessions (by sessionId)
|
|
143
|
+
const sessionMap = new Map();
|
|
144
|
+
// Add existing sessions first
|
|
145
|
+
for (const session of normalizedExisting) {
|
|
146
|
+
sessionMap.set(session.sessionId, session);
|
|
147
|
+
}
|
|
148
|
+
// Merge incoming sessions - backend data always replaces existing
|
|
149
|
+
for (const session of normalizedIncoming) {
|
|
150
|
+
sessionMap.set(session.sessionId, session);
|
|
151
|
+
}
|
|
152
|
+
// Convert to array
|
|
153
|
+
const merged = Array.from(sessionMap.values());
|
|
154
|
+
// Apply userId deduplication if requested
|
|
155
|
+
const finalSessions = deduplicateByUserId
|
|
156
|
+
? deduplicateSessionsByUserId(merged, activeSessionId)
|
|
157
|
+
: merged;
|
|
158
|
+
// Sort consistently
|
|
159
|
+
return sortSessions(finalSessions);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Check if two session arrays are equal (same sessionIds in same order)
|
|
163
|
+
*/
|
|
164
|
+
export function sessionsArraysEqual(a, b) {
|
|
165
|
+
if (a.length !== b.length) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
const sortedA = sortSessions(a);
|
|
169
|
+
const sortedB = sortSessions(b);
|
|
170
|
+
return sortedA.every((session, index) => sessionsEqual(session, sortedB[index]));
|
|
171
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical text normalization for the Oxy ecosystem.
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS EXISTS
|
|
5
|
+
* ---------------
|
|
6
|
+
* Third-party text (federated actor display names, spoiler/CW text, image alt
|
|
7
|
+
* text, bios, `<title>` / `og:site_name` of scraped remote pages, …) arrives
|
|
8
|
+
* with the whitespace the remote author's markup happened to contain. A real
|
|
9
|
+
* bug: a remote page served
|
|
10
|
+
*
|
|
11
|
+
* <title>
|
|
12
|
+
* Mi título
|
|
13
|
+
* </title>
|
|
14
|
+
*
|
|
15
|
+
* and the extracted string — newlines and indentation included — was stored
|
|
16
|
+
* verbatim. Clients render text with React Native Web `Text`, which maps to
|
|
17
|
+
* CSS `white-space: pre-wrap`: unlike HTML, newlines and repeated spaces are
|
|
18
|
+
* NOT collapsed at render time, so the user saw a blank line and a six-space
|
|
19
|
+
* indent inside the link preview.
|
|
20
|
+
*
|
|
21
|
+
* Storage-time normalization is therefore the ONLY place this can be fixed:
|
|
22
|
+
* every renderer downstream is faithful by design.
|
|
23
|
+
*
|
|
24
|
+
* WHICH HELPER DO I USE?
|
|
25
|
+
* ----------------------
|
|
26
|
+
* - {@link normalizeInlineText} — the value is conceptually ONE LINE, and a
|
|
27
|
+
* line break in it is always an accident of the source markup: page titles,
|
|
28
|
+
* `siteName`, display names, image `alt`, handles, profile field labels.
|
|
29
|
+
* Every line break becomes a space.
|
|
30
|
+
*
|
|
31
|
+
* - {@link normalizeMultilineText} — the value is a BODY whose line breaks are
|
|
32
|
+
* the author's own paragraphs and must survive: post text, bios/summaries.
|
|
33
|
+
* Line breaks are preserved (capped at one blank line); only the surrounding
|
|
34
|
+
* whitespace noise is cleaned.
|
|
35
|
+
*
|
|
36
|
+
* Using the multiline helper on a title would keep the newlines and reproduce
|
|
37
|
+
* the original bug; using the inline helper on a post body would flatten the
|
|
38
|
+
* author's paragraphs into a single run-on line. Pick deliberately.
|
|
39
|
+
*
|
|
40
|
+
* Neither helper truncates, strips markup, or enforces a character policy —
|
|
41
|
+
* those are separate, product-specific concerns (see `isValidDisplayName` for
|
|
42
|
+
* the display-name character policy). These functions do exactly one thing:
|
|
43
|
+
* normalize whitespace and Unicode form.
|
|
44
|
+
*/
|
|
45
|
+
/** Any run of whitespace, including tabs, line breaks and Unicode spaces. */
|
|
46
|
+
const ANY_WHITESPACE_RUN = /\s+/g;
|
|
47
|
+
/**
|
|
48
|
+
* Every line-break form, unified to `\n` before the multiline passes run:
|
|
49
|
+
* CRLF (Windows), a lone CR (classic Mac / stray `\r`), and the Unicode LINE
|
|
50
|
+
* SEPARATOR (U+2028) / PARAGRAPH SEPARATOR (U+2029), which are mandatory breaks
|
|
51
|
+
* in Unicode and a well-known hazard in JSON/JS payloads. CRLF must be matched
|
|
52
|
+
* before the lone `\r` alternative or it would yield two breaks. The separators
|
|
53
|
+
* are matched by their code-point ESCAPES (`\u2028` = LINE SEPARATOR, `\u2029` =
|
|
54
|
+
* PARAGRAPH SEPARATOR) rather than by their Unicode Line_Separator /
|
|
55
|
+
* Paragraph_Separator property escapes: React Native's Hermes engine ships with
|
|
56
|
+
* Unicode property escapes compiled OUT and rejects those subcategory property
|
|
57
|
+
* names with "Invalid RegExp: Invalid property name", whereas the `\uXXXX`
|
|
58
|
+
* escapes are exactly equivalent (each property covers exactly its one code
|
|
59
|
+
* point), engine-portable, and drop the now-unneeded `u` flag. (A literal
|
|
60
|
+
* U+2028/U+2029 is itself a LineTerminator and cannot appear in a regex literal.)
|
|
61
|
+
*/
|
|
62
|
+
const LINE_BREAK_FORMS = /\r\n|\r|\u2028|\u2029/g;
|
|
63
|
+
/**
|
|
64
|
+
* A run of HORIZONTAL whitespace: any whitespace that is not a line break.
|
|
65
|
+
* `[^\S\n]` is "whitespace, minus `\n`" — it covers the tab, the vertical tab,
|
|
66
|
+
* the form feed and every Unicode space separator (NBSP U+00A0, the U+2000
|
|
67
|
+
* block, the ideographic space U+3000, the zero-width no-break space U+FEFF).
|
|
68
|
+
* Applied AFTER {@link LINE_BREAK_FORMS}, so no line break can hide in it.
|
|
69
|
+
*/
|
|
70
|
+
const HORIZONTAL_WHITESPACE_RUN = /[^\S\n]+/g;
|
|
71
|
+
/**
|
|
72
|
+
* Horizontal whitespace at the END of a line — the blank-line spoiler: it is
|
|
73
|
+
* what makes an "empty" line non-empty and hides it from {@link EXCESS_BLANK_LINES}.
|
|
74
|
+
*/
|
|
75
|
+
const TRAILING_HORIZONTAL_WHITESPACE = / +\n/g;
|
|
76
|
+
/**
|
|
77
|
+
* Horizontal whitespace at the START of a line: source-markup indentation. HTML
|
|
78
|
+
* collapses it by spec, so it is invisible where the text came from and carries
|
|
79
|
+
* no meaning — it only becomes visible once a client renders the value with
|
|
80
|
+
* `white-space: pre-wrap`.
|
|
81
|
+
*/
|
|
82
|
+
const LEADING_HORIZONTAL_WHITESPACE = /\n +/g;
|
|
83
|
+
/** Three or more line breaks: more than one blank line between paragraphs. */
|
|
84
|
+
const EXCESS_BLANK_LINES = /\n{3,}/g;
|
|
85
|
+
/**
|
|
86
|
+
* Normalize a SINGLE-LINE text value: page/link-preview titles, `siteName`,
|
|
87
|
+
* display names, image alt text, handles, profile field labels.
|
|
88
|
+
*
|
|
89
|
+
* A line break in such a value is never meaningful — it is an artifact of the
|
|
90
|
+
* markup the value was extracted from (`<title>\n Título\n</title>`) — and it
|
|
91
|
+
* survives into the UI because RN Web renders `Text` with `white-space:
|
|
92
|
+
* pre-wrap`. So ALL whitespace, line breaks included, collapses to one space.
|
|
93
|
+
*
|
|
94
|
+
* 1. NFC-normalize, so visually identical strings store and compare
|
|
95
|
+
* identically (a decomposed `e`+◌́ recomposes into `é`).
|
|
96
|
+
* 2. Collapse every run of whitespace — spaces, tabs, `\n`, `\r`, and Unicode
|
|
97
|
+
* spaces such as NBSP — to a single plain space.
|
|
98
|
+
* 3. Trim both ends.
|
|
99
|
+
*
|
|
100
|
+
* Length is NOT capped: a maximum length is a product rule of the specific
|
|
101
|
+
* field (see `MAX_DISPLAY_NAME_LENGTH`), not a property of text normalization.
|
|
102
|
+
* Markup is NOT stripped: run the caller's sanitizer first if the source can
|
|
103
|
+
* contain HTML.
|
|
104
|
+
*
|
|
105
|
+
* A value that is empty or whitespace-only returns `''`. Callers decide whether
|
|
106
|
+
* that means "omit the field" (`|| undefined`) or "store an empty string".
|
|
107
|
+
*
|
|
108
|
+
* Idempotent: `f(f(x)) === f(x)`.
|
|
109
|
+
*/
|
|
110
|
+
export function normalizeInlineText(value) {
|
|
111
|
+
return value.normalize('NFC').replace(ANY_WHITESPACE_RUN, ' ').trim();
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Normalize a MULTILINE text BODY: post text, bios, summaries — anywhere the
|
|
115
|
+
* line breaks are the author's paragraphs and must be preserved.
|
|
116
|
+
*
|
|
117
|
+
* Cleans the whitespace noise around those paragraphs without destroying them:
|
|
118
|
+
*
|
|
119
|
+
* 1. NFC-normalize (same rationale as {@link normalizeInlineText}).
|
|
120
|
+
* 2. Unify every line-break form (CRLF, lone CR, U+2028, U+2029) to `\n`.
|
|
121
|
+
* 3. Collapse runs of HORIZONTAL whitespace (spaces, tabs, NBSP and friends)
|
|
122
|
+
* to a single space. Line breaks are untouched.
|
|
123
|
+
* 4. Strip the horizontal whitespace at BOTH ends of every line.
|
|
124
|
+
* 5. Collapse three or more line breaks to exactly one blank line (`\n\n`).
|
|
125
|
+
* 6. Trim both ends of the value.
|
|
126
|
+
*
|
|
127
|
+
* STEP 4 MUST PRECEDE STEP 5 — this is the whole point of the function. A
|
|
128
|
+
* "blank" line that actually contains spaces (`"a\n \n \nb"`) breaks the
|
|
129
|
+
* run of `\n` characters, so a bare `\n{3,}` collapse (step 5 alone) never sees
|
|
130
|
+
* it and the extra blank lines survive into the UI. That is exactly the bug in
|
|
131
|
+
* federated post bodies. Trimming each line first turns those lines into real,
|
|
132
|
+
* empty lines, which step 5 then collapses.
|
|
133
|
+
*
|
|
134
|
+
* Every line is trimmed on BOTH sides, so a leading indent is removed outright
|
|
135
|
+
* rather than reduced to one space. Step 3 has already destroyed whatever indent
|
|
136
|
+
* the author wrote (`" Mundo"` → `" Mundo"`), so a surviving space would not
|
|
137
|
+
* be the author's intent — it would be an arbitrary remnant of exactly the
|
|
138
|
+
* source-markup indentation this function exists to erase, and `pre-wrap` renders
|
|
139
|
+
* it. Indentation is invisible in HTML by spec; it must be invisible here too.
|
|
140
|
+
*
|
|
141
|
+
* A value that is empty or whitespace-only returns `''`.
|
|
142
|
+
*
|
|
143
|
+
* Idempotent: `f(f(x)) === f(x)`.
|
|
144
|
+
*/
|
|
145
|
+
export function normalizeMultilineText(value) {
|
|
146
|
+
return value
|
|
147
|
+
.normalize('NFC')
|
|
148
|
+
.replace(LINE_BREAK_FORMS, '\n')
|
|
149
|
+
.replace(HORIZONTAL_WHITESPACE_RUN, ' ')
|
|
150
|
+
.replace(TRAILING_HORIZONTAL_WHITESPACE, '\n')
|
|
151
|
+
.replace(LEADING_HORIZONTAL_WHITESPACE, '\n')
|
|
152
|
+
.replace(EXCESS_BLANK_LINES, '\n\n')
|
|
153
|
+
.trim();
|
|
154
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
function normalizeHandlePart(value) {
|
|
2
|
+
const trimmed = value?.trim().replace(/^@+/, '');
|
|
3
|
+
if (!trimmed || /[/?#]/.test(trimmed))
|
|
4
|
+
return null;
|
|
5
|
+
return trimmed;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Returns the normalized profile handle used by Oxy consumers for display and
|
|
9
|
+
* profile routing.
|
|
10
|
+
*
|
|
11
|
+
* Local users resolve to `username`. Federated users resolve to
|
|
12
|
+
* `username@instance` when the username does not already include an instance.
|
|
13
|
+
* Route-like values are rejected so callers do not accidentally turn paths or
|
|
14
|
+
* query strings into profile destinations.
|
|
15
|
+
*/
|
|
16
|
+
export function getNormalizedUserHandle(user) {
|
|
17
|
+
const username = normalizeHandlePart(user?.username ?? user?.handle);
|
|
18
|
+
if (!username)
|
|
19
|
+
return null;
|
|
20
|
+
const isFederated = user?.isFederated === true || user?.type === 'federated';
|
|
21
|
+
const instance = normalizeHandlePart(user?.instance ?? user?.federation?.domain);
|
|
22
|
+
if (isFederated && instance && !username.includes('@')) {
|
|
23
|
+
return `${username}@${instance}`;
|
|
24
|
+
}
|
|
25
|
+
return username;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Compatibility alias for the first public name shipped with this helper.
|
|
29
|
+
* Prefer {@link getNormalizedUserHandle} in new code.
|
|
30
|
+
*/
|
|
31
|
+
export function getCanonicalUserHandle(user) {
|
|
32
|
+
return getNormalizedUserHandle(user);
|
|
33
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
function stringifyIdentity(value) {
|
|
2
|
+
if (typeof value === 'string') {
|
|
3
|
+
const trimmed = value.trim();
|
|
4
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
5
|
+
}
|
|
6
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
7
|
+
return String(value);
|
|
8
|
+
}
|
|
9
|
+
if (value && typeof value === 'object' && 'toString' in value) {
|
|
10
|
+
const toStringFn = value.toString;
|
|
11
|
+
if (typeof toStringFn === 'function' && toStringFn !== Object.prototype.toString) {
|
|
12
|
+
const rendered = toStringFn.call(value);
|
|
13
|
+
if (typeof rendered === 'string') {
|
|
14
|
+
const trimmed = rendered.trim();
|
|
15
|
+
return trimmed.length > 0 && trimmed !== '[object Object]' ? trimmed : null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Returns the stable SDK user id from API payloads that may use either `id` or
|
|
23
|
+
* Mongo-style `_id`.
|
|
24
|
+
*/
|
|
25
|
+
export function getNormalizedUserId(user) {
|
|
26
|
+
if (!user) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
return stringifyIdentity(user.id) ?? stringifyIdentity(user._id);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Normalizes a user payload to always expose `id`. Throws when the payload does
|
|
33
|
+
* not contain a usable id, because SDK callers should never receive anonymous
|
|
34
|
+
* user objects from authenticated identity endpoints.
|
|
35
|
+
*/
|
|
36
|
+
export function normalizeUserIdentity(user) {
|
|
37
|
+
const id = getNormalizedUserId(user);
|
|
38
|
+
if (!id) {
|
|
39
|
+
throw new Error('User response missing id');
|
|
40
|
+
}
|
|
41
|
+
return { ...user, id };
|
|
42
|
+
}
|
|
43
|
+
export function normalizeUserIdentityOrNull(user) {
|
|
44
|
+
return user ? normalizeUserIdentity(user) : null;
|
|
45
|
+
}
|