diff --git a/sdk/cosmosdb/cosmos/src/request/defaultAgent-react-native.mts b/sdk/cosmosdb/cosmos/src/request/defaultAgent-react-native.mts new file mode 100644 index 000000000000..d6565d17d2bc --- /dev/null +++ b/sdk/cosmosdb/cosmos/src/request/defaultAgent-react-native.mts @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +import type { Agent } from "node:http"; +/** + * @hidden + */ +export let defaultHttpAgent: Agent; +/** + * @hidden + */ +export let defaultHttpsAgent: Agent; diff --git a/sdk/cosmosdb/cosmos/src/utils/atob-react-native.mts b/sdk/cosmosdb/cosmos/src/utils/atob-react-native.mts new file mode 100644 index 000000000000..940b04e8ed75 --- /dev/null +++ b/sdk/cosmosdb/cosmos/src/utils/atob-react-native.mts @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +// Use the same polyfill implementation as browser for React Native +let safeatob: (data: string) => string; + +// base64 character set, plus padding character (=) +const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; +// Regular expression to check formal correctness of base64 encoded strings +const b64re = /^(?:[A-Za-z\d+/]{4})*?(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/; + +if (typeof atob === "undefined") { + // Custom atob implementation for React Native + safeatob = (str: string): string => { + let fixedStr = String(str).replace(/[\t\n\f\r ]+/g, ""); + if (!b64re.test(fixedStr)) { + throw new TypeError( + "Failed to execute 'atob': The string to be decoded is not correctly encoded.", + ); + } + + fixedStr += "==".slice(2 - (fixedStr.length & 3)); + let bitmap; + let result = ""; + let r1; + let r2; + let i = 0; + for (; i < fixedStr.length;) { + bitmap = + (b64.indexOf(fixedStr.charAt(i++)) << 18) | + (b64.indexOf(fixedStr.charAt(i++)) << 12) | + ((r1 = b64.indexOf(fixedStr.charAt(i++))) << 6) | + (r2 = b64.indexOf(fixedStr.charAt(i++))); + + result += + r1 === 64 + ? String.fromCharCode((bitmap >> 16) & 255) + : r2 === 64 + ? String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255) + : String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255, bitmap & 255); + } + return result; + }; +} else { + safeatob = atob; +} + +export default safeatob; diff --git a/sdk/cosmosdb/cosmos/src/utils/envUtils-react-native.mts b/sdk/cosmosdb/cosmos/src/utils/envUtils-react-native.mts new file mode 100644 index 000000000000..3d11238bcbbf --- /dev/null +++ b/sdk/cosmosdb/cosmos/src/utils/envUtils-react-native.mts @@ -0,0 +1,4 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +export const diagnosticLevelFromEnv: string | undefined = undefined; diff --git a/sdk/cosmosdb/cosmos/src/utils/hmac-react-native.mts b/sdk/cosmosdb/cosmos/src/utils/hmac-react-native.mts new file mode 100644 index 000000000000..c88631aea52f --- /dev/null +++ b/sdk/cosmosdb/cosmos/src/utils/hmac-react-native.mts @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { encodeUTF8, encodeBase64 } from "./encode.js"; +import atob from "./atob.js"; +import { globalCrypto } from "./globalCrypto.js"; + +export async function hmac(key: string, message: string): Promise { + const importParams: HmacImportParams = { name: "HMAC", hash: { name: "SHA-256" } }; + const encodedMessage = new Uint8Array( + [...unescape(encodeURIComponent(message))].map((c) => c.charCodeAt(0)), + ); + const encodedKey = encodeUTF8(atob(key)); + const cryptoKey = await globalCrypto.subtle.importKey("raw", encodedKey, importParams, false, [ + "sign", + ]); + const signature = await globalCrypto.subtle.sign(importParams, cryptoKey, encodedMessage); + + return encodeBase64(signature); +}