pinata 1.0.5 → 1.1.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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils/custom-errors.ts","../src/core/authentication/testAuthentication.ts","../src/core/uploads/file.ts","../src/core/uploads/base64.ts","../src/core/uploads/url.ts","../src/core/uploads/json.ts","../src/core/files/delete.ts","../src/core/files/list.ts","../src/core/files/updateFile.ts","../src/core/gateway/getCid.ts","../src/core/keys/createKey.ts","../src/core/keys/listKeys.ts","../src/core/keys/revokeKeys.ts","../src/core/groups/createGroup.ts","../src/core/groups/listGroups.ts","../src/core/groups/getGroup.ts","../src/core/groups/updateGroup.ts","../src/core/groups/deleteGroup.ts","../src/core/gateway/createSignedURL.ts","../src/core/pinataSDK.ts"],"sourcesContent":["export * from \"./core/pinataSDK\";\nexport * from \"./core/types\";\n","export class PinataError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic statusCode?: number,\n\t\tpublic details?: any,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"PinataError\";\n\t}\n}\n\nexport class NetworkError extends PinataError {\n\tconstructor(message: string, statusCode?: number, details?: any) {\n\t\tsuper(message, statusCode, details);\n\t\tthis.name = \"NetworkError\";\n\t}\n}\n\nexport class AuthenticationError extends PinataError {\n\tconstructor(message: string, statusCode?: number, details?: any) {\n\t\tsuper(message, statusCode, details);\n\t\tthis.name = \"AuthenticationError\";\n\t}\n}\n\nexport class ValidationError extends PinataError {\n\tconstructor(message: string, details?: any) {\n\t\tsuper(message, undefined, details);\n\t\tthis.name = \"ValidationError\";\n\t}\n}\n","/**\n * Tests the authentication of the current Pinata configuration.\n *\n * This function sends a request to the Pinata API to verify if the provided\n * authentication credentials (JWT) are valid and working correctly.\n *\n * @async\n * @function testAuthentication\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @returns {Promise<AuthTestResponse>} A promise that resolves to an object containing a message about the authentication status.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the authentication process.\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const auth = await pinata.testAuthentication()\n */\n\nimport type { PinataConfig, AuthTestResponse } from \"../types\";\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const testAuthentication = async (config: PinataConfig | undefined) => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tlet headers: Record<string, string>;\n\tlet endpoint: string = \"https://api.pinata.cloud\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\tSource: \"sdk/testAuthentication\",\n\t\t};\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/data/testAuthentication`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: headers,\n\t\t});\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res: AuthTestResponse = await request.json();\n\t\treturn res;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(\n\t\t\t\t`Error processing authentication: ${error.message}`,\n\t\t\t);\n\t\t}\n\t\tthrow new PinataError(\n\t\t\t\"An unknown error occurred while testing authentication\",\n\t\t);\n\t}\n};\n","/**\n * Uploads a file to IPFS via Pinata.\n *\n * This function allows you to upload a single file to IPFS and pin it to Pinata.\n * It's useful for adding individual files to your Pinata account and IPFS network.\n *\n * @async\n * @function uploadFile\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {File} file - The file object to be uploaded.\n * @param {UploadOptions} [options] - Optional parameters for the upload.\n * @param {PinataMetadata} [options.metadata] - Metadata for the uploaded file.\n * @param {string} [options.metadata.name] - Custom name for the file (defaults to the original filename if not provided).\n * @param {Record<string, string | number>} [options.metadata.keyValues] - Custom key-value pairs for the file metadata.\n * @param {string} [options.keys] - Custom JWT to use for this specific upload.\n * @param {string} [options.groupId] - ID of the group to add the uploaded file to.\n * @param {0 | 1} [options.cidVersion] - Version of CID to use (0 or 1).\n * @returns {Promise<PinResponse>} A promise that resolves to an object containing the IPFS hash and other upload details.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the upload process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const file = new File([\"hello world!\"], \"hello.txt\", { type: \"text/plain\" })\n * const upload = await pinata.upload.file(file)\n */\n\nimport type { PinataConfig, UploadResponse, UploadOptions } from \"../types\";\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const uploadFile = async (\n\tconfig: PinataConfig | undefined,\n\tfile: File,\n\toptions?: UploadOptions,\n) => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tconst jwt: string | undefined = options?.keys || config.pinataJwt;\n\n\tconst data = new FormData();\n\tdata.append(\"file\", file, file.name);\n\tdata.append(\"name\", options?.metadata?.name || file.name || \"File from SDK\");\n\tif (options?.groupId) {\n\t\tdata.append(\"group_id\", options.groupId);\n\t}\n\n\t// data.append(\n\t// \t\"pinataOptions\",\n\t// \tJSON.stringify({\n\t// \t\tcidVersion: options?.cidVersion,\n\t// \t\tgroupId: options?.groupId,\n\t// \t}),\n\t// );\n\n\t// data.append(\n\t// \t\"pinataMetadata\",\n\t// \tJSON.stringify({\n\t// \t\tname: options?.metadata?.name || file.name || \"File from SDK\",\n\t// \t\tkeyvalues: options?.metadata?.keyValues,\n\t// \t}),\n\t// );\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${jwt}`,\n\t\t\tSource: \"sdk/file\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://uploads.pinata.cloud/v3\";\n\n\tif (config.uploadUrl) {\n\t\tendpoint = config.uploadUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: headers,\n\t\t\tbody: data,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\t\tconst res: UploadResponse = await request.json();\n\t\treturn res;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error uploading file: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while uploading the file\");\n\t}\n};\n","/**\n * Uploads a base64-encoded string to IPFS via Pinata.\n *\n * This function allows you to upload content to IPFS that is encoded as a base64 string.\n * It's particularly useful for uploading binary data or files that have been converted to base64.\n *\n * @async\n * @function uploadBase64\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {string} base64String - The base64-encoded string to be uploaded.\n * @param {UploadOptions} [options] - Optional parameters for the upload.\n * @param {PinataMetadata} [options.metadata] - Metadata for the uploaded file.\n * @param {string} [options.metadata.name] - Name for the uploaded file (default is \"base64 string\").\n * @param {Record<string, string | number>} [options.metadata.keyvalues] - Custom key-value pairs for the file metadata.\n * @param {string} [options.keys] - Custom JWT to use for this specific upload.\n * @param {string} [options.groupId] - ID of the group to add the uploaded file to.\n * @param {0 | 1} [options.cidVersion] - Version of CID to use (0 or 1).\n * @returns {Promise<PinResponse>} A promise that resolves to an object containing the IPFS hash and other upload details.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the upload process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const upload = await pinata.upload.base64(\"SGVsbG8gV29ybGQh\")\n */\n\nimport type { PinataConfig, UploadResponse, UploadOptions } from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const uploadBase64 = async (\n\tconfig: PinataConfig | undefined,\n\tbase64String: string,\n\toptions?: UploadOptions,\n) => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tconst jwt: string | undefined = options?.keys || config?.pinataJwt;\n\n\tconst name = options?.metadata?.name\n\t\t? options?.metadata?.name\n\t\t: \"base64 string\";\n\n\tconst buffer = Buffer.from(base64String, \"base64\");\n\n\tconst blob = new Blob([buffer]);\n\n\tconst data = new FormData();\n\n\tdata.append(\"file\", blob, name);\n\tdata.append(\"name\", name);\n\tif (options?.groupId) {\n\t\tdata.append(\"group_id\", options.groupId);\n\t}\n\n\t// data.append(\n\t// \t\"pinataOptions\",\n\t// \tJSON.stringify({\n\t// \t\tcidVersion: options?.cidVersion,\n\t// \t\tgroupId: options?.groupId,\n\t// \t}),\n\t// );\n\n\t// data.append(\n\t// \t\"pinataMetadata\",\n\t// \tJSON.stringify({\n\t// \t\tname: name,\n\t// \t\tkeyvalues: options?.metadata?.keyValues,\n\t// \t}),\n\t// );\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${jwt}`,\n\t\t\tSource: \"sdk/base64\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://uploads.pinata.cloud/v3\";\n\n\tif (config.uploadUrl) {\n\t\tendpoint = config.uploadUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: headers,\n\t\t\tbody: data,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res: UploadResponse = await request.json();\n\t\treturn res;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing base64: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\n\t\t\t\"An unknown error occurred while trying to upload base64\",\n\t\t);\n\t}\n};\n","/**\n * Uploads content from a URL to IPFS via Pinata.\n *\n * This function allows you to upload content from a specified URL to IPFS and pin it to Pinata.\n * It's useful for adding remote content to your Pinata account and IPFS network without\n * first downloading it locally.\n *\n * @async\n * @function uploadUrl\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {string} url - The URL of the content to be uploaded.\n * @param {UploadOptions} [options] - Optional parameters for the upload.\n * @param {PinataMetadata} [options.metadata] - Metadata for the uploaded content.\n * @param {string} [options.metadata.name] - Custom name for the content (defaults to \"url_upload\" if not provided).\n * @param {Record<string, string | number>} [options.metadata.keyValues] - Custom key-value pairs for the content metadata.\n * @param {string} [options.keys] - Custom JWT to use for this specific upload.\n * @param {string} [options.groupId] - ID of the group to add the uploaded content to.\n * @param {0 | 1} [options.cidVersion] - Version of CID to use (0 or 1).\n * @returns {Promise<PinResponse>} A promise that resolves to an object containing the IPFS hash and other upload details.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request or URL fetch.\n * @throws {PinataError} For any other errors that occur during the upload process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const upload = await pinata.upload.url(\"https://i.imgur.com/u4mGk5b.gif\")\n */\n\nimport type { PinataConfig, UploadResponse, UploadOptions } from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const uploadUrl = async (\n\tconfig: PinataConfig | undefined,\n\turl: string,\n\toptions?: UploadOptions,\n) => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tconst jwt: string | undefined = options?.keys || config?.pinataJwt;\n\tconst data = new FormData();\n\n\tconst stream = await fetch(url);\n\n\tif (!stream.ok) {\n\t\tconst errorData = await stream.text();\n\t\tthrow new NetworkError(\n\t\t\t`HTTP error: ${errorData}`,\n\t\t\tstream.status,\n\t\t\terrorData,\n\t\t);\n\t}\n\n\tconst arrayBuffer = await stream.arrayBuffer();\n\n\tconst blob = new Blob([arrayBuffer]);\n\n\tconst name = options?.metadata?.name ?? \"url_upload\";\n\n\tconst file = new File([blob], name);\n\n\tdata.append(\"file\", file, name);\n\tdata.append(\"name\", name);\n\tif (options?.groupId) {\n\t\tdata.append(\"group_id\", options.groupId);\n\t}\n\n\t// data.append(\n\t// \t\"pinataOptions\",\n\t// \tJSON.stringify({\n\t// \t\tcidVersion: options?.cidVersion,\n\t// \t\tgroupId: options?.groupId,\n\t// \t}),\n\t// );\n\n\t// data.append(\n\t// \t\"pinataMetadata\",\n\t// \tJSON.stringify({\n\t// \t\tname: name,\n\t// \t\tkeyvalues: options?.metadata?.keyValues,\n\t// \t}),\n\t// );\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${jwt}`,\n\t\t\tSource: \"sdk/url\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://uploads.pinata.cloud/v3\";\n\n\tif (config.uploadUrl) {\n\t\tendpoint = config.uploadUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: headers,\n\t\t\tbody: data,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res: UploadResponse = await request.json();\n\t\treturn res;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing url: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while uploading by url\");\n\t}\n};\n","/**\n * Uploads JSON data to IPFS via Pinata.\n *\n * This function allows you to upload JSON data directly to IPFS and pin it to Pinata.\n * It's useful for adding structured data, configurations, or any JSON-serializable content\n * to your Pinata account and IPFS network.\n *\n * @async\n * @function uploadJson\n * @template T\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {T} jsonData - The JSON data to be uploaded. Must be a valid JavaScript object that can be JSON-stringified.\n * @param {UploadOptions} [options] - Optional parameters for the upload.\n * @param {PinataMetadata} [options.metadata] - Metadata for the uploaded JSON.\n * @param {string} [options.metadata.name] - Custom name for the JSON content (defaults to \"json\" if not provided).\n * @param {Record<string, string | number>} [options.metadata.keyValues] - Custom key-value pairs for the JSON metadata.\n * @param {string} [options.keys] - Custom JWT to use for this specific upload.\n * @param {string} [options.groupId] - ID of the group to add the uploaded JSON to.\n * @param {0 | 1} [options.cidVersion] - Version of CID to use (0 or 1).\n * @returns {Promise<PinResponse>} A promise that resolves to an object containing the IPFS hash and other upload details.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the upload process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const upload = await pinata.upload.json({\n * name: \"Pinnie NFT\",\n * description: \"A Pinnie NFT from Pinata\",\n * image: \"ipfs://bafkreih5aznjvttude6c3wbvqeebb6rlx5wkbzyppv7garjiubll2ceym4\"\n * })\n */\n\nimport type {\n\tPinataConfig,\n\tUploadResponse,\n\tUploadOptions,\n\tJsonBody,\n} from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const uploadJson = async <T extends JsonBody>(\n\tconfig: PinataConfig | undefined,\n\tjsonData: T,\n\toptions?: UploadOptions,\n) => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tconst jwt: string | undefined = options?.keys || config?.pinataJwt;\n\n\tconst json = JSON.stringify(jsonData);\n\tconst blob = new Blob([json]);\n\tconst file = new File([blob], \"data.json\", { type: \"application/json\" });\n\n\tconst data = new FormData();\n\tdata.append(\"file\", file, file.name);\n\tdata.append(\"name\", options?.metadata?.name || file.name || \"File from SDK\");\n\tif (options?.groupId) {\n\t\tdata.append(\"group_id\", options.groupId);\n\t}\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${jwt}`,\n\t\t\tSource: \"sdk/json\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://uploads.pinata.cloud/v3\";\n\n\tif (config.uploadUrl) {\n\t\tendpoint = config.uploadUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: headers,\n\t\t\tbody: data,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res: UploadResponse = await request.json();\n\t\treturn res;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing json: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while uploading json\");\n\t}\n};\n","/**\n * Unpins multiple files from Pinata and IPFS.\n *\n * This function allows you to remove pins for multiple files from your Pinata account.\n * Unpinning a file means that Pinata will no longer guarantee its availability on IPFS,\n * although the content may still be available if pinned by other IPFS nodes.\n *\n * @async\n * @function unpinFile\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {string[]} files - An array of IPFS hashes (CIDs) of the files to unpin.\n * @returns {Promise<DeleteResponse[]>} A promise that resolves to an array of objects, each containing the status of the unpin operation for each file.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the unpinning process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const unpin = await pinata.unpin([\n * \"bafkreih5aznjvttude6c3wbvqeebb6rlx5wkbzyppv7garjiubll2ceym4\"\n * ])\n */\n\nimport type { PinataConfig, DeleteResponse } from \"../types\";\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nconst wait = (milliseconds: number): Promise<void> => {\n\treturn new Promise((resolve) => {\n\t\tsetTimeout(resolve, milliseconds);\n\t});\n};\n\nexport const deleteFile = async (\n\tconfig: PinataConfig | undefined,\n\tfiles: string[],\n): Promise<DeleteResponse[]> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tconst responses: DeleteResponse[] = [];\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\tSource: \"sdk/unpin\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\tfor (const id of files) {\n\t\ttry {\n\t\t\tconst response = await fetch(`${endpoint}/files/${id}`, {\n\t\t\t\tmethod: \"DELETE\",\n\t\t\t\theaders: headers,\n\t\t\t});\n\n\t\t\tawait wait(300);\n\n\t\t\tif (!response.ok) {\n\t\t\t\tconst errorData = await response.text();\n\t\t\t\tif (response.status === 401) {\n\t\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\t\tresponse.status,\n\t\t\t\t\t\terrorData,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow new NetworkError(\n\t\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\t\tresponse.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tresponses.push({\n\t\t\t\tid: id,\n\t\t\t\tstatus: response.statusText,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tlet errorMessage: string;\n\n\t\t\tif (error instanceof PinataError) {\n\t\t\t\terrorMessage = error.message;\n\t\t\t} else if (error instanceof Error) {\n\t\t\t\terrorMessage = `Error deleting file ${id}: ${error.message}`;\n\t\t\t} else {\n\t\t\t\terrorMessage = `An unknown error occurred while deleting file ${id}`;\n\t\t\t}\n\n\t\t\tresponses.push({\n\t\t\t\tid: id,\n\t\t\t\tstatus: errorMessage,\n\t\t\t});\n\t\t}\n\t}\n\treturn responses;\n};\n","/**\n * Lists files pinned to Pinata based on the provided configuration and options.\n *\n * This function fetches a list of pinned files from the Pinata API, allowing for\n * various filtering and pagination options.\n *\n * @async\n * @function listFiles\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {FileListQuery} [options] - Optional query parameters to filter and paginate the results.\n * @param {string} [options.cid] - Filter by the CID of the file.\n * @param {string} [options.pinStart] - Filter by the start date of pinning (ISO 8601 format).\n * @param {string} [options.pinEnd] - Filter by the end date of pinning (ISO 8601 format).\n * @param {number} [options.pinSizeMin] - Filter by minimum pin size in bytes.\n * @param {number} [options.pinSizeMax] - Filter by maximum pin size in bytes.\n * @param {number} [options.pageLimit] - Number of items to return per page.\n * @param {number} [options.pageOffset] - Number of items to skip (for pagination).\n * @param {string} [options.name] - Filter by the name of the file.\n * @param {string} [options.key] - Metadata key to filter by (used with value and operator).\n * @param {string | number} [options.value] - Metadata value to filter by (used with key and operator).\n * @param {string} [options.operator] - Comparison operator for metadata filtering.\n * @param {string} [options.groupId] - Filter by group ID.\n * @returns {Promise<FileListItem[]>} A promise that resolves to an array of FileListItem objects.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the file listing process.\n *//**\n * Lists files pinned to Pinata based on the provided configuration and options.\n *\n * This function fetches a list of pinned files from the Pinata API, allowing for\n * various filtering and pagination options.\n *\n * @async\n * @function listFiles\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {FileListQuery} [options] - Optional query parameters to filter and paginate the results.\n * @param {string} [options.cid] - Filter by the CID of the file.\n * @param {string} [options.pinStart] - Filter by the start date of pinning (ISO 8601 format).\n * @param {string} [options.pinEnd] - Filter by the end date of pinning (ISO 8601 format).\n * @param {number} [options.pinSizeMin] - Filter by minimum pin size in bytes.\n * @param {number} [options.pinSizeMax] - Filter by maximum pin size in bytes.\n * @param {number} [options.pageLimit] - Number of items to return per page.\n * @param {number} [options.pageOffset] - Number of items to skip (for pagination).\n * @param {string} [options.name] - Filter by the name of the file.\n * @param {string} [options.key] - Metadata key to filter by (used with value and operator).\n * @param {string | number} [options.value] - Metadata value to filter by (used with key and operator).\n * @param {string} [options.operator] - Comparison operator for metadata filtering.\n * @param {string} [options.groupId] - Filter by group ID.\n * @returns {Promise<FileListItem[]>} A promise that resolves to an array of FileListItem objects.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the file listing process.\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const files = await pinata.listFiles().name(\"pinnie\")\n */\n\nimport type { FileListQuery, FileListResponse, PinataConfig } from \"../types\";\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const listFiles = async (\n\tconfig: PinataConfig | undefined,\n\toptions?: FileListQuery,\n): Promise<FileListResponse> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tconst params = new URLSearchParams();\n\n\tif (options) {\n\t\tconst { limit, pageToken, cidPending } = options;\n\n\t\tif (limit) params.append(\"limit\", limit.toString());\n\t\tif (pageToken) params.append(\"pageToken\", pageToken);\n\t\tif (cidPending) params.append(\"cidPending\", \"true\");\n\t}\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\tconst url = `${endpoint}/files?${params.toString()}`;\n\n\ttry {\n\t\tlet headers: Record<string, string>;\n\n\t\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\t\theaders = { ...config.customHeaders };\n\t\t} else {\n\t\t\theaders = {\n\t\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\tSource: \"sdk/listFiles\",\n\t\t\t};\n\t\t}\n\n\t\tconst request = await fetch(url, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: headers,\n\t\t});\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res = await request.json();\n\t\tconst resData: FileListResponse = res.data;\n\t\treturn resData;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing list files: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while listing files\");\n\t}\n};\n","/**\n * Updates the metadata for a pinned file on Pinata.\n *\n * This function allows you to modify the name and/or key-value pairs associated\n * with a file that has already been pinned to Pinata. This is useful for\n * organizing and categorizing your pinned content.\n *\n * @async\n * @function updateMetadata\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {UpdateFileOptions} options - The options for updating the metadata.\n * @param {string} options.cid - The Content Identifier (CID) of the pinned file to update.\n * @param {string} [options.name] - The new name to assign to the pinned file (optional).\n * @param {Record<string, string | number>} [options.keyValues] - Key-value pairs to associate with the pinned file (optional).\n * @returns {Promise<string>} A promise that resolves to a string confirming the update.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the metadata update process.\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const update = await pinata.updateMedatadata({\n * cid: \"bafkreih5aznjvttude6c3wbvqeebb6rlx5wkbzyppv7garjiubll2ceym4\",\n * name: \"Pinnie V2\",\n * keyValues: {\n * whimsey: 200\n * }\n * })\n */\n\nimport type { FileListItem, PinataConfig, UpdateFileOptions } from \"../types\";\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const updateFile = async (\n\tconfig: PinataConfig | undefined,\n\toptions: UpdateFileOptions,\n): Promise<FileListItem> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\tconst data = JSON.stringify({\n\t\tname: options.name,\n\t});\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tSource: \"sdk/updateMetadata\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files/${options.id}`, {\n\t\t\tmethod: \"PUT\",\n\t\t\theaders: headers,\n\t\t\tbody: data,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res = await request.json();\n\t\tconst resData: FileListItem = res.data;\n\t\treturn resData;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing updateFile: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while updating file\");\n\t}\n};\n","/**\n * Retrieves the content of a file from IPFS using its Content Identifier (CID).\n *\n * This function fetches the content associated with a given CID from the specified\n * Pinata gateway. It can handle various content types and returns the data along\n * with the content type information.\n *\n * @async\n * @function getCid\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT and gateway information.\n * @param {string} cid - The Content Identifier (CID) of the file to retrieve.\n * @returns {Promise<GetCIDResponse>} A promise that resolves to an object containing the file data and content type.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the retrieval process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const upload = await pinata.gateways.get(\"QmVLwvmGehsrNEvhcCnnsw5RQNseohgEkFNN1848zNzdng\"* )\n *\n */\n\nimport type {\n\tGetCIDResponse,\n\tPinataConfig,\n\tOptimizeImageOptions,\n} from \"../types\";\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const getCid = async (\n\tconfig: PinataConfig | undefined,\n\tcid: string,\n\t// options?: OptimizeImageOptions,\n): Promise<GetCIDResponse> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tlet data: JSON | string | Blob;\n\tlet newUrl: string = `${config?.pinataGateway}/files/${cid}`;\n\n\tconst params = new URLSearchParams();\n\n\tconst date = Math.floor(new Date().getTime() / 1000);\n\n\tconst payload = JSON.stringify({\n\t\turl: newUrl,\n\t\tdate: date,\n\t\texpires: 30,\n\t\tmethod: \"GET\",\n\t});\n\n\tconst signedUrlRequest = await fetch(\n\t\t\"https://api.pinata.cloud/v3/files/sign\",\n\t\t{\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\tAuthorization: `Bearer ${config?.pinataJwt}`,\n\t\t\t},\n\t\t\tbody: payload,\n\t\t},\n\t);\n\n\tconst signedUrl = await signedUrlRequest.json();\n\n\t// if (config?.pinataGatewayKey) {\n\t// \tparams.append(\"pinataGatewayToken\", config.pinataGatewayKey);\n\t// }\n\n\t// if (options) {\n\t// \tif (options.width) params.append(\"img-width\", options.width.toString());\n\t// \tif (options.height) params.append(\"img-height\", options.height.toString());\n\t// \tif (options.dpr) params.append(\"img-dpr\", options.dpr.toString());\n\t// \tif (options.fit) params.append(\"img-fit\", options.fit);\n\t// \tif (options.gravity) params.append(\"img-gravity\", options.gravity);\n\t// \tif (options.quality)\n\t// \t\tparams.append(\"img-quality\", options.quality.toString());\n\t// \tif (options.format) params.append(\"img-format\", options.format);\n\t// \tif (options.animation !== undefined)\n\t// \t\tparams.append(\"img-anim\", options.animation.toString());\n\t// \tif (options.sharpen)\n\t// \t\tparams.append(\"img-sharpen\", options.sharpen.toString());\n\t// \tif (options.onError === true) params.append(\"img-onerror\", \"redirect\");\n\t// \tif (options.metadata) params.append(\"img-metadata\", options.metadata);\n\t// }\n\n\t// const queryString = params.toString();\n\t// if (queryString) {\n\t// \tnewUrl += `?${queryString}`;\n\t// }\n\n\ttry {\n\t\tconst request = await fetch(signedUrl.data);\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication Failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst contentType: string | null = request.headers.get(\"content-type\");\n\n\t\tif (contentType?.includes(\"application/json\")) {\n\t\t\tdata = await request.json();\n\t\t} else if (contentType?.includes(\"text/\")) {\n\t\t\tdata = await request.text();\n\t\t} else {\n\t\t\tdata = await request.blob();\n\t\t}\n\n\t\tconst res: GetCIDResponse = {\n\t\t\tdata: data,\n\t\t\tcontentType: contentType,\n\t\t};\n\n\t\treturn res;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing getCid: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\n\t\t\t\"An unknown error occurred while getting CID contents\",\n\t\t);\n\t}\n};\n","/**\n * Creates a new API key for Pinata services.\n *\n * This function allows you to generate a new API key with specific permissions\n * for use with Pinata's IPFS pinning services. It's useful for creating keys\n * with limited access or for specific applications.\n *\n * @async\n * @function createKey\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {KeyOptions} options - The options for creating a new API key.\n * @param {string} options.keyName - The name to assign to the new API key.\n * @param {KeyPermissions} options.permissions - The permissions to assign to the new key.\n * @param {number} [options.maxUses] - Optional. The maximum number of times the key can be used.\n * @returns {Promise<KeyResponse>} A promise that resolves to an object containing the new API key details.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the key creation process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const key = await pinata.keys.create({\n * keyName: \"user 1\",\n * permissions: {\n * admin: true,\n * },\n * maxUses: 1,\n * });\n */\n\nimport type { PinataConfig, KeyOptions, KeyResponse } from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const createKey = async (\n\tconfig: PinataConfig | undefined,\n\toptions: KeyOptions,\n): Promise<KeyResponse> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tSource: \"sdk/createKey\",\n\t\t};\n\t}\n\n\tconst data = JSON.stringify(options);\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/pinata/keys`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: headers,\n\t\t\tbody: data,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res: KeyResponse = await request.json();\n\t\treturn res;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing createKey: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while creating API key\");\n\t}\n};\n","/**\n * Retrieves a list of API keys associated with the Pinata account.\n *\n * This function allows you to fetch and optionally filter the API keys linked to your Pinata account.\n * It's useful for managing your API keys, checking their status, or auditing key usage.\n *\n * @async\n * @function listKeys\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {KeyListQuery} [options] - Optional query parameters to filter the list of keys.\n * @param {number} [options.offset] - The number of items to skip before starting to collect the result set.\n * @param {boolean} [options.revoked] - If true, includes revoked keys in the results.\n * @param {boolean} [options.limitedUse] - If true, only returns keys with usage limits.\n * @param {boolean} [options.exhausted] - If true, only returns keys that have reached their usage limit.\n * @param {string} [options.name] - Filters keys by name (partial match).\n * @returns {Promise<KeyListItem[]>} A promise that resolves to an array of key objects matching the query.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the key listing process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const keys = await pinata.keys\n * .list()\n * .name(\"Admin\")\n * .revoked(false)\n */\n\nimport type {\n\tKeyListItem,\n\tKeyListQuery,\n\tKeyListResponse,\n\tPinataConfig,\n} from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const listKeys = async (\n\tconfig: PinataConfig | undefined,\n\toptions?: KeyListQuery,\n): Promise<KeyListItem[]> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tSource: \"sdk/listKeys\",\n\t\t};\n\t}\n\n\tconst params = new URLSearchParams();\n\n\tif (options) {\n\t\tconst { offset, name, revoked, limitedUse, exhausted } = options;\n\n\t\tif (offset) params.append(\"offset\", offset.toString());\n\t\tif (revoked !== undefined) params.append(\"revoked\", revoked.toString());\n\t\tif (limitedUse !== undefined)\n\t\t\tparams.append(\"limitedUse\", limitedUse.toString());\n\t\tif (exhausted !== undefined)\n\t\t\tparams.append(\"exhausted\", exhausted.toString());\n\t\tif (name) params.append(\"name\", name);\n\t}\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(\n\t\t\t`${endpoint}/pinata/keys?${params.toString()}`,\n\t\t\t{\n\t\t\t\tmethod: \"GET\",\n\t\t\t\theaders: headers,\n\t\t\t},\n\t\t);\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res: KeyListResponse = await request.json();\n\t\treturn res.keys;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing listKeys: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while listing API keys\");\n\t}\n};\n","/**\n * Revokes multiple API keys from the Pinata account.\n *\n * This function allows you to revoke (invalidate) multiple API keys at once.\n * It's useful for security purposes, such as when keys may have been compromised\n * or are no longer needed.\n *\n * @async\n * @function revokeKeys\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {string[]} keys - An array of API key strings to be revoked.\n * @returns {Promise<RevokeKeyResponse[]>} A promise that resolves to an array of objects,\n * each containing the status of the revocation attempt for each key.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the key revocation process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const revoke = await pinata.keys.revoke([\n * \"94566af5e63833e260be\"\n * ]);\n */\n\nimport type { PinataConfig, RevokeKeyResponse } from \"../types\";\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nconst wait = (milliseconds: number): Promise<void> => {\n\treturn new Promise((resolve) => {\n\t\tsetTimeout(resolve, milliseconds);\n\t});\n};\n\nexport const revokeKeys = async (\n\tconfig: PinataConfig | undefined,\n\tkeys: string[],\n): Promise<RevokeKeyResponse[]> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tSource: \"sdk/revokeKeys\",\n\t\t};\n\t}\n\n\tconst responses: RevokeKeyResponse[] = [];\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\tfor (const key of keys) {\n\t\ttry {\n\t\t\tconst request = await fetch(`${endpoint}/pinata/keys/${key}`, {\n\t\t\t\tmethod: \"PUT\",\n\t\t\t\theaders: headers,\n\t\t\t});\n\n\t\t\tawait wait(300);\n\n\t\t\tif (!request.ok) {\n\t\t\t\tconst errorData = await request.text();\n\t\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\t\trequest.status,\n\t\t\t\t\t\terrorData,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow new NetworkError(\n\t\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst result: string = await request.json();\n\t\t\tresponses.push({\n\t\t\t\tkey: key,\n\t\t\t\tstatus: result,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tlet errorMessage: string;\n\n\t\t\tif (error instanceof PinataError) {\n\t\t\t\terrorMessage = error.message;\n\t\t\t} else if (error instanceof Error) {\n\t\t\t\terrorMessage = `Error revoking key ${key}: ${error.message}`;\n\t\t\t} else {\n\t\t\t\terrorMessage = `An unknown error occurred while revoking key ${key}`;\n\t\t\t}\n\n\t\t\tresponses.push({\n\t\t\t\tkey: key,\n\t\t\t\tstatus: errorMessage,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn responses;\n};\n","/**\n * Creates a new group in Pinata for organizing pinned content.\n *\n * This function allows you to create a new group in your Pinata account.\n * Groups can be used to organize and manage your pinned content more effectively.\n *\n * @async\n * @function createGroup\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {GroupOptions} options - The options for creating a new group.\n * @param {string} options.name - The name of the group to be created.\n * @returns {Promise<GroupResponseItem>} A promise that resolves to an object containing details of the created group.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the group creation process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const group = await pinata.groups.create({\n *\tname: \"My New Group\",\n * });\n */\n\nimport type { PinataConfig, GroupOptions, GroupResponseItem } from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const createGroup = async (\n\tconfig: PinataConfig | undefined,\n\toptions: GroupOptions,\n): Promise<GroupResponseItem> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tconst data = JSON.stringify({\n\t\tname: options.name,\n\t\tis_public: options.isPublic,\n\t});\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tSource: \"sdk/createGroup\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files/groups`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: headers,\n\t\t\tbody: data,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res = await request.json();\n\t\tconst resData: GroupResponseItem = res.data;\n\t\treturn resData;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing createGroup: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while creating a group\");\n\t}\n};\n","/**\n * Retrieves a list of groups from Pinata.\n *\n * This function fetches a list of groups associated with your Pinata account.\n * It supports pagination and filtering by name.\n *\n * @async\n * @function listGroups\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {GroupQueryOptions} [options] - Optional query parameters to filter and paginate the results.\n * @param {number} [options.offset] - The number of items to skip before starting to collect the result set.\n * @param {string} [options.nameContains] - Filter groups by name (case-insensitive partial match).\n * @param {number} [options.limit] - The numbers of items to return.\n * @returns {Promise<GroupResponseItem[]>} A promise that resolves to an array of group objects.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the group listing process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const groups = await pinata.groups\n * .list()\n * .name(\"Greetings\");\n */\n\nimport type {\n\tPinataConfig,\n\tGroupResponseItem,\n\tGroupQueryOptions,\n\tGroupListResponse,\n} from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const listGroups = async (\n\tconfig: PinataConfig | undefined,\n\toptions?: GroupQueryOptions,\n): Promise<GroupListResponse> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tSource: \"sdk/listGroups\",\n\t\t};\n\t}\n\n\tconst params = new URLSearchParams();\n\n\tif (options) {\n\t\tconst { pageToken, nameContains, limit, isPublic } = options;\n\n\t\tif (pageToken) params.append(\"pageToken\", pageToken.toString());\n\t\tif (isPublic) params.append(\"isPublic\", isPublic.toString());\n\t\tif (nameContains !== undefined)\n\t\t\tparams.append(\"nameContains\", nameContains.toString());\n\t\tif (limit !== undefined) params.append(\"limit\", limit.toString());\n\t}\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(\n\t\t\t`${endpoint}/files/groups?${params.toString()}`,\n\t\t\t{\n\t\t\t\tmethod: \"GET\",\n\t\t\t\theaders: headers,\n\t\t\t},\n\t\t);\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res = await request.json();\n\t\tconst resData: GroupListResponse = res.data;\n\t\treturn resData;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing listGroups: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while listing groups\");\n\t}\n};\n","/**\n * Retrieves information about a specific group from Pinata.\n *\n * This function fetches details about a group in your Pinata account using its ID.\n * It provides information such as the group's name, creation date, and last update time.\n *\n * @async\n * @function getGroup\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {GetGroupOptions} options - The options for retrieving a group.\n * @param {string} options.groupId - The ID of the group to retrieve.\n * @returns {Promise<GroupResponseItem>} A promise that resolves to an object containing the group's details.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the group retrieval process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const groups = await pinata.groups.get({\n *\tgroupId: \"3778c10d-452e-4def-8299-ee6bc548bdb0\",\n * });\n */\n\nimport type {\n\tPinataConfig,\n\tGroupResponseItem,\n\tGetGroupOptions,\n} from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const getGroup = async (\n\tconfig: PinataConfig | undefined,\n\toptions: GetGroupOptions,\n): Promise<GroupResponseItem> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tSource: \"sdk/getGroup\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files/groups/${options.groupId}`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: headers,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res = await request.json();\n\t\tconst resData: GroupResponseItem = res.data;\n\t\treturn resData;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing getGroup: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\n\t\t\t\"An unknown error occurred while getting info for a group\",\n\t\t);\n\t}\n};\n","/**\n * Updates the information of a specified group in Pinata.\n *\n * This function allows you to modify the name of an existing group in your Pinata account.\n * It's useful for renaming groups to better organize your pinned content.\n *\n * @async\n * @function updateGroup\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {UpdateGroupOptions} options - The options for updating a group.\n * @param {string} options.groupId - The ID of the group to be updated.\n * @param {string} options.name - The new name for the group.\n * @returns {Promise<GroupResponseItem>} A promise that resolves to an object containing the updated group's details.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the group update process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const groups = await pinata.groups.update({\n *\tgroupId: \"3778c10d-452e-4def-8299-ee6bc548bdb0\",\n *\tname: \"My New Group 2\"\n * });\n */\n\nimport type {\n\tPinataConfig,\n\tGroupResponseItem,\n\tUpdateGroupOptions,\n} from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const updateGroup = async (\n\tconfig: PinataConfig | undefined,\n\toptions: UpdateGroupOptions,\n): Promise<GroupResponseItem> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tconst data = JSON.stringify({\n\t\tname: options.name,\n\t\tis_public: options.isPublic,\n\t});\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tSource: \"sdk/updateGroup\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files/groups/${options.groupId}`, {\n\t\t\tmethod: \"PUT\",\n\t\t\theaders: headers,\n\t\t\tbody: data,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res = await request.json();\n\t\tconst resData: GroupResponseItem = res.data;\n\t\treturn resData;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing updateGroup: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while updating group\");\n\t}\n};\n","/**\n * Deletes a specified group from Pinata.\n *\n * This function allows you to remove a group from your Pinata account.\n * Note that deleting a group does not delete the files within the group,\n * it only removes the group association.\n *\n * @async\n * @function deleteGroup\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {GetGroupOptions} options - The options for deleting a group.\n * @param {string} options.groupId - The ID of the group to be deleted.\n * @returns {Promise<string>} A promise that resolves to a string confirming the deletion.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the group deletion process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const groups = await pinata.groups.delete({\n *\tgroupId: \"3778c10d-452e-4def-8299-ee6bc548bdb0\",\n * });\n */\n\nimport type { GetGroupOptions, PinataConfig } from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const deleteGroup = async (\n\tconfig: PinataConfig | undefined,\n\toptions: GetGroupOptions,\n): Promise<string> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tSource: \"sdk/deleteGroup\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files/groups/${options.groupId}`, {\n\t\t\tmethod: \"DELETE\",\n\t\t\theaders: headers,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res: string = request.statusText;\n\t\treturn res;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing deleteGroup: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while deleting a group\");\n\t}\n};\n","import type {\n\tPinataConfig,\n\tOptimizeImageOptions,\n\tSignedUrlOptions,\n} from \"../types\";\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const createSignedURL = async (\n\tconfig: PinataConfig | undefined,\n\toptions: SignedUrlOptions,\n): Promise<string> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tlet newUrl: string = `${config?.pinataGateway}/files/${options.cid}`;\n\n\tconst date = options?.date || Math.floor(new Date().getTime() / 1000);\n\n\tconst payload = JSON.stringify({\n\t\turl: newUrl,\n\t\tdate: date,\n\t\texpires: options.expires,\n\t\tmethod: \"GET\",\n\t});\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\t// const params = new URLSearchParams();\n\t// if (config?.pinataGatewayKey) {\n\t// \tparams.append(\"pinataGatewayToken\", config.pinataGatewayKey);\n\t// }\n\n\t// if (options) {\n\t// \tif (options.width) params.append(\"img-width\", options.width.toString());\n\t// \tif (options.height) params.append(\"img-height\", options.height.toString());\n\t// \tif (options.dpr) params.append(\"img-dpr\", options.dpr.toString());\n\t// \tif (options.fit) params.append(\"img-fit\", options.fit);\n\t// \tif (options.gravity) params.append(\"img-gravity\", options.gravity);\n\t// \tif (options.quality)\n\t// \t\tparams.append(\"img-quality\", options.quality.toString());\n\t// \tif (options.format) params.append(\"img-format\", options.format);\n\t// \tif (options.animation !== undefined)\n\t// \t\tparams.append(\"img-anim\", options.animation.toString());\n\t// \tif (options.sharpen)\n\t// \t\tparams.append(\"img-sharpen\", options.sharpen.toString());\n\t// \tif (options.onError === true) params.append(\"img-onerror\", \"redirect\");\n\t// \tif (options.metadata) params.append(\"img-metadata\", options.metadata);\n\t// }\n\n\t// const queryString = params.toString();\n\t// if (queryString) {\n\t// \tnewUrl += `?${queryString}`;\n\t// }\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files/sign`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\tAuthorization: `Bearer ${config?.pinataJwt}`,\n\t\t\t},\n\t\t\tbody: payload,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication Failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res = await request.json();\n\t\treturn res.data;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(\n\t\t\t\t`Error processing createSignedURL: ${error.message}`,\n\t\t\t);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while getting signed url\");\n\t}\n};\n","import type {\n\tFileObject,\n\tFileListItem,\n\tFileListQuery,\n\tUploadResponse,\n\tPinataConfig,\n\tPinataMetadata,\n\tUpdateFileOptions,\n\tUploadOptions,\n\tGetCIDResponse,\n\tKeyOptions,\n\tKeyResponse,\n\tKeyListQuery,\n\tKeyListItem,\n\tGroupOptions,\n\tGroupResponseItem,\n\tUpdateGroupOptions,\n\tGroupCIDOptions,\n\tGroupQueryOptions,\n\tGetGroupOptions,\n\tAuthTestResponse,\n\tDeleteResponse,\n\tRevokeKeyResponse,\n\tSignatureOptions,\n\tSignatureResponse,\n\tTopGatewayAnalyticsQuery,\n\tTopGatewayAnalyticsItem,\n\tTimeIntervalGatewayAnalyticsQuery,\n\tGatewayAnalyticsQuery,\n\tTimeIntervalGatewayAnalyticsResponse,\n\tSwapCidOptions,\n\tSwapCidResponse,\n\tSwapHistoryOptions,\n\tContainsCIDResponse,\n\tOptimizeImageOptions,\n\tGroupListResponse,\n\tSignedUrlOptions,\n} from \"./types\";\nimport { testAuthentication } from \"./authentication/testAuthentication\";\nimport { uploadFile } from \"./uploads/file\";\nimport { uploadFileArray } from \"./uploads/fileArray\";\nimport { uploadBase64 } from \"./uploads/base64\";\nimport { uploadUrl } from \"./uploads/url\";\nimport { uploadJson } from \"./uploads/json\";\nimport { deleteFile } from \"./files/delete\";\nimport { listFiles } from \"./files/list\";\nimport { updateFile } from \"./files/updateFile\";\nimport { getCid } from \"./gateway/getCid\";\nimport { convertIPFSUrl } from \"./gateway/convertIPFSUrl\";\n// import { pinnedFileCount } from \"./files/pinnedFileUsage\";\n// import { totalStorageUsage } from \"./files/totalStorageUsage\";\nimport { createKey } from \"./keys/createKey\";\nimport { listKeys } from \"./keys/listKeys\";\nimport { revokeKeys } from \"./keys/revokeKeys\";\nimport { createGroup } from \"./groups/createGroup\";\nimport { listGroups } from \"./groups/listGroups\";\nimport { getGroup } from \"./groups/getGroup\";\nimport { addToGroup } from \"./groups/addToGroup\";\nimport { updateGroup } from \"./groups/updateGroup\";\nimport { removeFromGroup } from \"./groups/removeFromGroup\";\nimport { deleteGroup } from \"./groups/deleteGroup\";\n// import { addSignature } from \"./signatures/addSignature\";\n// import { getSignature } from \"./signatures/getSignature\";\n// import { removeSignature } from \"./signatures/removeSignature\";\nimport { analyticsTopUsage } from \"./gateway/analyticsTopUsage\";\nimport { analyticsDateInterval } from \"./gateway/analyticsDateInterval\";\nimport { swapCid } from \"./gateway/swapCid\";\nimport { swapHistory } from \"./gateway/swapHistory\";\nimport { deleteSwap } from \"./gateway/deleteSwap\";\nimport { containsCID } from \"../utils/gateway-tools\";\nimport { createSignedURL } from \"./gateway/createSignedURL\";\n\nconst formatConfig = (config: PinataConfig | undefined) => {\n\tlet gateway = config?.pinataGateway;\n\tif (config && gateway) {\n\t\tif (gateway && !gateway.startsWith(\"https://\")) {\n\t\t\tgateway = `https://${gateway}`;\n\t\t}\n\t\tconfig.pinataGateway = gateway;\n\t}\n\treturn config;\n};\n\nexport class PinataSDK {\n\tconfig: PinataConfig | undefined;\n\tfiles: Files;\n\tupload: Upload;\n\tgateways: Gateways;\n\t//\tusage: Usage;\n\tkeys: Keys;\n\tgroups: Groups;\n\t//signatures: Signatures;\n\n\tconstructor(config?: PinataConfig) {\n\t\tthis.config = formatConfig(config);\n\t\tthis.files = new Files(this.config);\n\t\tthis.upload = new Upload(this.config);\n\t\tthis.gateways = new Gateways(this.config);\n\t\t//\t\tthis.usage = new Usage(this.config);\n\t\tthis.keys = new Keys(this.config);\n\t\tthis.groups = new Groups(this.config);\n\t\t//\t\tthis.signatures = new Signatures(this.config);\n\t}\n\n\tsetNewHeaders(headers: Record<string, string>): void {\n\t\tif (!this.config) {\n\t\t\tthis.config = { pinataJwt: \"\", customHeaders: {} };\n\t\t}\n\t\tthis.config.customHeaders = { ...this.config.customHeaders, ...headers };\n\n\t\t// Update headers for all sub-modules\n\t\tthis.files.updateConfig(this.config);\n\t\tthis.upload.updateConfig(this.config);\n\t\tthis.gateways.updateConfig(this.config);\n\t\t//\t\tthis.usage.updateConfig(this.config);\n\t\tthis.keys.updateConfig(this.config);\n\t\tthis.groups.updateConfig(this.config);\n\t\t//\t\tthis.signatures.updateConfig(this.config);\n\t}\n\n\ttestAuthentication(): Promise<AuthTestResponse> {\n\t\treturn testAuthentication(this.config);\n\t}\n}\n\nclass Files {\n\tconfig: PinataConfig | undefined;\n\n\tconstructor(config?: PinataConfig) {\n\t\tthis.config = formatConfig(config);\n\t}\n\n\tupdateConfig(newConfig: PinataConfig): void {\n\t\tthis.config = newConfig;\n\t}\n\n\tlist(): FilterFiles {\n\t\treturn new FilterFiles(this.config);\n\t}\n\n\tdelete(files: string[]): Promise<DeleteResponse[]> {\n\t\treturn deleteFile(this.config, files);\n\t}\n\n\tupdate(options: UpdateFileOptions): Promise<FileListItem> {\n\t\treturn updateFile(this.config, options);\n\t}\n}\n\nclass UploadBuilder<T> {\n\tprivate config: PinataConfig | undefined;\n\tprivate uploadFunction: (\n\t\tconfig: PinataConfig | undefined,\n\t\t...args: any[]\n\t) => Promise<T>;\n\tprivate args: any[];\n\tprivate metadata: PinataMetadata | undefined;\n\tprivate keys: string | undefined;\n\tprivate groupId: string | undefined;\n\n\tconstructor(\n\t\tconfig: PinataConfig | undefined,\n\t\tuploadFunction: (\n\t\t\tconfig: PinataConfig | undefined,\n\t\t\t...args: any[]\n\t\t) => Promise<T>,\n\t\t...args: any[]\n\t) {\n\t\tthis.config = config;\n\t\tthis.uploadFunction = uploadFunction;\n\t\tthis.args = args;\n\t}\n\n\taddMetadata(metadata: PinataMetadata): UploadBuilder<T> {\n\t\tthis.metadata = metadata;\n\t\treturn this;\n\t}\n\n\tkey(jwt: string): UploadBuilder<T> {\n\t\tthis.keys = jwt;\n\t\treturn this;\n\t}\n\n\t// cidVersion(v: 0 | 1): UploadBuilder<T> {\n\t// \tthis.version = v;\n\t// \treturn this;\n\t// }\n\n\tgroup(groupId: string): UploadBuilder<T> {\n\t\tthis.groupId = groupId;\n\t\treturn this;\n\t}\n\n\tthen<TResult1 = T, TResult2 = never>(\n\t\tonfulfilled?:\n\t\t\t| ((value: T) => TResult1 | PromiseLike<TResult1>)\n\t\t\t| null\n\t\t\t| undefined,\n\t\tonrejected?:\n\t\t\t| ((reason: any) => TResult2 | PromiseLike<TResult2>)\n\t\t\t| null\n\t\t\t| undefined,\n\t): Promise<TResult1 | TResult2> {\n\t\tconst options: UploadOptions = this.args[this.args.length - 1] || {};\n\t\tif (this.metadata) {\n\t\t\toptions.metadata = this.metadata;\n\t\t}\n\t\tif (this.keys) {\n\t\t\toptions.keys = this.keys;\n\t\t}\n\t\tif (this.groupId) {\n\t\t\toptions.groupId = this.groupId;\n\t\t}\n\t\tthis.args[this.args.length - 1] = options;\n\t\treturn this.uploadFunction(this.config, ...this.args).then(\n\t\t\tonfulfilled,\n\t\t\tonrejected,\n\t\t);\n\t}\n}\n\nclass Upload {\n\tconfig: PinataConfig | undefined;\n\n\tconstructor(config?: PinataConfig) {\n\t\tthis.config = formatConfig(config);\n\t}\n\n\tupdateConfig(newConfig: PinataConfig): void {\n\t\tthis.config = newConfig;\n\t}\n\n\tfile(\n\t\tfile: FileObject,\n\t\toptions?: UploadOptions,\n\t): UploadBuilder<UploadResponse> {\n\t\treturn new UploadBuilder(this.config, uploadFile, file, options);\n\t}\n\n\t// fileArray(\n\t// \tfiles: FileObject[],\n\t// \toptions?: UploadOptions,\n\t// ): UploadBuilder<UploadResponse> {\n\t// \treturn new UploadBuilder(this.config, uploadFileArray, files, options);\n\t// }\n\n\tbase64(\n\t\tbase64String: string,\n\t\toptions?: UploadOptions,\n\t): UploadBuilder<UploadResponse> {\n\t\treturn new UploadBuilder(this.config, uploadBase64, base64String, options);\n\t}\n\n\turl(url: string, options?: UploadOptions): UploadBuilder<UploadResponse> {\n\t\treturn new UploadBuilder(this.config, uploadUrl, url, options);\n\t}\n\n\tjson(data: object, options?: UploadOptions): UploadBuilder<UploadResponse> {\n\t\treturn new UploadBuilder(this.config, uploadJson, data, options);\n\t}\n}\n\nclass FilterFiles {\n\tprivate config: PinataConfig | undefined;\n\tprivate query: FileListQuery = {};\n\tprivate currentPageToken: string | undefined;\n\t// rate limit vars\n\t// private requestCount = 0;\n\t// private lastRequestTime = 0;\n\t// private readonly MAX_REQUESTS_PER_MINUTE = 30;\n\t// private readonly MINUTE_IN_MS = 60000;\n\n\tconstructor(config: PinataConfig | undefined) {\n\t\tthis.config = config;\n\t}\n\n\tlimit(limit: number): FilterFiles {\n\t\tthis.query.limit = limit;\n\t\treturn this;\n\t}\n\n\tcidPending(cidPending: boolean): FilterFiles {\n\t\tthis.query.cidPending = cidPending;\n\t\treturn this;\n\t}\n\n\tthen(onfulfilled?: ((value: FileListItem[]) => any) | null): Promise<any> {\n\t\treturn this.fetchPage().then(onfulfilled);\n\t}\n\n\tprivate async fetchPage(): Promise<FileListItem[]> {\n\t\tif (this.currentPageToken) {\n\t\t\tthis.query.pageToken = this.currentPageToken;\n\t\t}\n\t\tconst response = await listFiles(this.config, this.query);\n\t\tthis.currentPageToken = response.next_page_token;\n\t\treturn response.files;\n\t}\n\n\t// // rate limit, hopefully temporary?\n\t// private async rateLimit(): Promise<void> {\n\t// \tthis.requestCount++;\n\t// \tconst now = Date.now();\n\t// \tif (this.requestCount >= this.MAX_REQUESTS_PER_MINUTE) {\n\t// \t\tconst timePassedSinceLastRequest = now - this.lastRequestTime;\n\t// \t\tif (timePassedSinceLastRequest < this.MINUTE_IN_MS) {\n\t// \t\t\tconst delayTime = this.MINUTE_IN_MS - timePassedSinceLastRequest;\n\t// \t\t\tawait new Promise((resolve) => setTimeout(resolve, delayTime));\n\t// \t\t}\n\t// \t\tthis.requestCount = 0;\n\t// \t}\n\t// \tthis.lastRequestTime = Date.now();\n\t// }\n\n\tasync *[Symbol.asyncIterator](): AsyncGenerator<FileListItem, void, unknown> {\n\t\twhile (true) {\n\t\t\tconst items = await this.fetchPage();\n\t\t\tfor (const item of items) {\n\t\t\t\tyield item;\n\t\t\t}\n\t\t\tif (!this.currentPageToken) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync all(): Promise<FileListItem[]> {\n\t\tconst allItems: FileListItem[] = [];\n\t\tfor await (const item of this) {\n\t\t\tallItems.push(item);\n\t\t}\n\t\treturn allItems;\n\t}\n}\n\nclass Gateways {\n\tconfig: PinataConfig | undefined;\n\n\tconstructor(config?: PinataConfig) {\n\t\tthis.config = formatConfig(config);\n\t}\n\n\tupdateConfig(newConfig: PinataConfig): void {\n\t\tthis.config = newConfig;\n\t}\n\n\tget(cid: string): Promise<GetCIDResponse> {\n\t\treturn getCid(this.config, cid);\n\t}\n\n\tcreateSignedURL(options: SignedUrlOptions): Promise<string> {\n\t\treturn createSignedURL(this.config, options);\n\t}\n\n\t// get(cid: string): OptimizeImage {\n\t// \treturn new OptimizeImage(this.config, cid);\n\t// }\n\n\t// convert(url: string, gatewayPrefix?: string): Promise<string> {\n\t// \treturn convertIPFSUrl(this.config, url, gatewayPrefix);\n\t// }\n\n\t// containsCID(cid: string): Promise<ContainsCIDResponse> {\n\t// \treturn containsCID(cid);\n\t// }\n\n\t// topUsageAnalytics(options: {\n\t// \tdomain: string;\n\t// \tstart: string;\n\t// \tend: string;\n\t// \tsortBy: \"requests\" | \"bandwidth\";\n\t// \tattribute:\n\t// \t\t| \"cid\"\n\t// \t\t| \"country\"\n\t// \t\t| \"region\"\n\t// \t\t| \"user_agent\"\n\t// \t\t| \"referer\"\n\t// \t\t| \"file_name\";\n\t// }): TopGatewayAnalyticsBuilder {\n\t// \treturn new TopGatewayAnalyticsBuilder(\n\t// \t\tthis.config,\n\t// \t\toptions.domain,\n\t// \t\toptions.start,\n\t// \t\toptions.end,\n\t// \t\toptions.sortBy,\n\t// \t\toptions.attribute,\n\t// \t);\n\t// }\n\n\t// dateIntervalAnalytics(options: {\n\t// \tdomain: string;\n\t// \tstart: string;\n\t// \tend: string;\n\t// \tinterval: \"day\" | \"week\";\n\t// }): TimeIntervalGatewayAnalyticsBuilder {\n\t// \treturn new TimeIntervalGatewayAnalyticsBuilder(\n\t// \t\tthis.config,\n\t// \t\toptions.domain,\n\t// \t\toptions.start,\n\t// \t\toptions.end,\n\t// \t\toptions.interval,\n\t// \t);\n\t// }\n\n\t// swapCid(options: SwapCidOptions): Promise<SwapCidResponse> {\n\t// \treturn swapCid(this.config, options);\n\t// }\n\n\t// swapHistory(options: SwapHistoryOptions): Promise<SwapCidResponse[]> {\n\t// \treturn swapHistory(this.config, options);\n\t// }\n\n\t// deleteSwap(cid: string): Promise<string> {\n\t// \treturn deleteSwap(this.config, cid);\n\t// }\n}\n\n// class OptimizeImage {\n// \tprivate config: PinataConfig | undefined;\n// \tprivate cid: string;\n// \tprivate options: OptimizeImageOptions = {};\n\n// \tconstructor(config: PinataConfig | undefined, cid: string) {\n// \t\tthis.config = config;\n// \t\tthis.cid = cid;\n// \t}\n\n// \toptimizeImage(options: OptimizeImageOptions): OptimizeImage {\n// \t\tthis.options = { ...this.options, ...options };\n// \t\treturn this;\n// \t}\n\n// \tthen(onfulfilled?: ((value: GetCIDResponse) => any) | null): Promise<any> {\n// \t\treturn getCid(this.config, this.cid, this.options).then(onfulfilled);\n// \t}\n// }\n\n// class Usage {\n// \tconfig: PinataConfig | undefined;\n\n// \tconstructor(config?: PinataConfig) {\n// \t\tthis.config = formatConfig(config);\n// \t}\n\n// \tupdateConfig(newConfig: PinataConfig): void {\n// \t\tthis.config = newConfig;\n// \t}\n\n// \tpinnedFileCount(): Promise<number> {\n// \t\treturn pinnedFileCount(this.config);\n// \t}\n\n// \ttotalStorageSize(): Promise<number> {\n// \t\treturn totalStorageUsage(this.config);\n// \t}\n// }\n\nclass Keys {\n\tconfig: PinataConfig | undefined;\n\n\tconstructor(config?: PinataConfig) {\n\t\tthis.config = formatConfig(config);\n\t}\n\n\tupdateConfig(newConfig: PinataConfig): void {\n\t\tthis.config = newConfig;\n\t}\n\n\tcreate(options: KeyOptions): Promise<KeyResponse> {\n\t\treturn createKey(this.config, options);\n\t}\n\n\tlist(): FilterKeys {\n\t\treturn new FilterKeys(this.config);\n\t}\n\n\trevoke(keys: string[]): Promise<RevokeKeyResponse[]> {\n\t\treturn revokeKeys(this.config, keys);\n\t}\n}\n\nclass FilterKeys {\n\tprivate config: PinataConfig | undefined;\n\tprivate query: KeyListQuery = {};\n\t// rate limit vars\n\t// private requestCount = 0;\n\t// private lastRequestTime = 0;\n\t// private readonly MAX_REQUESTS_PER_MINUTE = 30;\n\t// private readonly MINUTE_IN_MS = 60000;\n\n\tconstructor(config: PinataConfig | undefined) {\n\t\tthis.config = config;\n\t}\n\n\toffset(offset: number): FilterKeys {\n\t\tthis.query.offset = offset;\n\t\treturn this;\n\t}\n\n\trevoked(revoked: boolean): FilterKeys {\n\t\tthis.query.revoked = revoked;\n\t\treturn this;\n\t}\n\n\tlimitedUse(limitedUse: boolean): FilterKeys {\n\t\tthis.query.limitedUse = limitedUse;\n\t\treturn this;\n\t}\n\n\texhausted(exhausted: boolean): FilterKeys {\n\t\tthis.query.exhausted = exhausted;\n\t\treturn this;\n\t}\n\n\tname(name: string): FilterKeys {\n\t\tthis.query.name = name;\n\t\treturn this;\n\t}\n\n\tthen(onfulfilled?: ((value: KeyListItem[]) => any) | null): Promise<any> {\n\t\treturn listKeys(this.config, this.query).then(onfulfilled);\n\t}\n\n\t// private async rateLimit(): Promise<void> {\n\t// \tthis.requestCount++;\n\t// \tconst now = Date.now();\n\t// \tif (this.requestCount >= this.MAX_REQUESTS_PER_MINUTE) {\n\t// \t\tconst timePassedSinceLastRequest = now - this.lastRequestTime;\n\t// \t\tif (timePassedSinceLastRequest < this.MINUTE_IN_MS) {\n\t// \t\t\tconst delayTime = this.MINUTE_IN_MS - timePassedSinceLastRequest;\n\t// \t\t\tawait new Promise((resolve) => setTimeout(resolve, delayTime));\n\t// \t\t}\n\t// \t\tthis.requestCount = 0;\n\t// \t}\n\t// \tthis.lastRequestTime = Date.now();\n\t// }\n\n\tasync *[Symbol.asyncIterator](): AsyncGenerator<KeyListItem, void, unknown> {\n\t\tlet hasMore = true;\n\t\tlet offset = 0;\n\n\t\twhile (hasMore) {\n\t\t\t//await this.rateLimit(); // applying rate limit\n\t\t\tthis.query.offset = offset;\n\n\t\t\tconst items = await listKeys(this.config, this.query);\n\n\t\t\tfor (const item of items) {\n\t\t\t\tyield item;\n\t\t\t}\n\n\t\t\tif (items.length === 0) {\n\t\t\t\thasMore = false;\n\t\t\t} else {\n\t\t\t\toffset += items.length;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync all(): Promise<KeyListItem[]> {\n\t\tconst allItems: KeyListItem[] = [];\n\t\tfor await (const item of this) {\n\t\t\tallItems.push(item);\n\t\t}\n\t\treturn allItems;\n\t}\n}\n\nclass Groups {\n\tconfig: PinataConfig | undefined;\n\n\tconstructor(config?: PinataConfig) {\n\t\tthis.config = formatConfig(config);\n\t}\n\n\tupdateConfig(newConfig: PinataConfig): void {\n\t\tthis.config = newConfig;\n\t}\n\n\tcreate(options: GroupOptions): Promise<GroupResponseItem> {\n\t\treturn createGroup(this.config, options);\n\t}\n\n\tlist(): FilterGroups {\n\t\treturn new FilterGroups(this.config);\n\t}\n\n\tget(options: GetGroupOptions): Promise<GroupResponseItem> {\n\t\treturn getGroup(this.config, options);\n\t}\n\n\t// addFiles(options: GroupCIDOptions): Promise<string> {\n\t// \treturn addToGroup(this.config, options);\n\t// }\n\n\t// removeFiles(options: GroupCIDOptions): Promise<string> {\n\t// \treturn removeFromGroup(this.config, options);\n\t// }\n\n\tupdate(options: UpdateGroupOptions): Promise<GroupResponseItem> {\n\t\treturn updateGroup(this.config, options);\n\t}\n\n\tdelete(options: GetGroupOptions): Promise<string> {\n\t\treturn deleteGroup(this.config, options);\n\t}\n}\n\nclass FilterGroups {\n\tprivate config: PinataConfig | undefined;\n\tprivate query: GroupQueryOptions = {};\n\t// rate limit vars\n\t// private requestCount = 0;\n\t// private lastRequestTime = 0;\n\t// private readonly MAX_REQUESTS_PER_MINUTE = 30;\n\t// private readonly MINUTE_IN_MS = 60000;\n\tprivate nextPageToken: string | undefined;\n\n\tconstructor(config: PinataConfig | undefined) {\n\t\tthis.config = config;\n\t}\n\n\t// name(nameContains: string): FilterGroups {\n\t// \tthis.query.nameContains = nameContains;\n\t// \treturn this;\n\t// }\n\n\tlimit(limit: number): FilterGroups {\n\t\tthis.query.limit = limit;\n\t\treturn this;\n\t}\n\n\tisPublic(isPublic: boolean): FilterGroups {\n\t\tthis.query.isPublic = isPublic;\n\t\treturn this;\n\t}\n\n\tthen(\n\t\tonfulfilled?: ((value: GroupResponseItem[]) => any) | null,\n\t): Promise<GroupResponseItem[]> {\n\t\treturn this.fetchPage()\n\t\t\t.then((response) => {\n\t\t\t\tthis.nextPageToken = response.next_page_token;\n\t\t\t\treturn response.groups;\n\t\t\t})\n\t\t\t.then(onfulfilled);\n\t}\n\n\tprivate async fetchPage(): Promise<GroupListResponse> {\n\t\tif (this.nextPageToken) {\n\t\t\tthis.query.pageToken = this.nextPageToken;\n\t\t}\n\t\treturn listGroups(this.config, this.query);\n\t}\n\n\t// rate limit, hopefully temporary?\n\t// private async rateLimit(): Promise<void> {\n\t// \tthis.requestCount++;\n\t// \tconst now = Date.now();\n\t// \tif (this.requestCount >= this.MAX_REQUESTS_PER_MINUTE) {\n\t// \t\tconst timePassedSinceLastRequest = now - this.lastRequestTime;\n\t// \t\tif (timePassedSinceLastRequest < this.MINUTE_IN_MS) {\n\t// \t\t\tconst delayTime = this.MINUTE_IN_MS - timePassedSinceLastRequest;\n\t// \t\t\tawait new Promise((resolve) => setTimeout(resolve, delayTime));\n\t// \t\t}\n\t// \t\tthis.requestCount = 0;\n\t// \t}\n\t// \tthis.lastRequestTime = Date.now();\n\t// }\n\n\tasync *[Symbol.asyncIterator](): AsyncGenerator<\n\t\tGroupResponseItem,\n\t\tvoid,\n\t\tunknown\n\t> {\n\t\twhile (true) {\n\t\t\tconst response = await this.fetchPage();\n\t\t\tfor (const item of response.groups) {\n\t\t\t\tyield item;\n\t\t\t}\n\t\t\tif (!response.next_page_token) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tthis.nextPageToken = response.next_page_token;\n\t\t}\n\t}\n\n\tasync all(): Promise<GroupResponseItem[]> {\n\t\tconst allItems: GroupResponseItem[] = [];\n\t\tfor await (const item of this) {\n\t\t\tallItems.push(item);\n\t\t}\n\t\treturn allItems;\n\t}\n}\n\n// class Signatures {\n// \tconfig: PinataConfig | undefined;\n\n// \tconstructor(config?: PinataConfig) {\n// \t\tthis.config = formatConfig(config);\n// \t}\n\n// \tupdateConfig(newConfig: PinataConfig): void {\n// \t\tthis.config = newConfig;\n// \t}\n\n// \tadd(options: SignatureOptions): Promise<SignatureResponse> {\n// \t\treturn addSignature(this.config, options);\n// \t}\n\n// \tget(cid: string): Promise<SignatureResponse> {\n// \t\treturn getSignature(this.config, cid);\n// \t}\n\n// \tdelete(cid: string): Promise<string> {\n// \t\treturn removeSignature(this.config, cid);\n// \t}\n// }\n\n// class GatewayAnalyticsBuilder<T extends GatewayAnalyticsQuery, R> {\n// \tprotected config: PinataConfig | undefined;\n// \tprotected query: T;\n// \tprivate requestCount = 0;\n// \tprivate lastRequestTime = 0;\n// \tprivate readonly MAX_REQUESTS_PER_MINUTE = 30;\n// \tprivate readonly MINUTE_IN_MS = 60000;\n\n// \tconstructor(config: PinataConfig | undefined, query: T) {\n// \t\tthis.config = config;\n// \t\tthis.query = query;\n// \t}\n\n// \tcid(cid: string): this {\n// \t\tthis.query.cid = cid;\n// \t\treturn this;\n// \t}\n\n// \tfileName(fileName: string): this {\n// \t\tthis.query.file_name = fileName;\n// \t\treturn this;\n// \t}\n\n// \tuserAgent(userAgent: string): this {\n// \t\tthis.query.user_agent = userAgent;\n// \t\treturn this;\n// \t}\n\n// \tcountry(country: string): this {\n// \t\tthis.query.country = country;\n// \t\treturn this;\n// \t}\n\n// \tregion(region: string): this {\n// \t\tthis.query.region = region;\n// \t\treturn this;\n// \t}\n\n// \treferer(referer: string): this {\n// \t\tthis.query.referer = referer;\n// \t\treturn this;\n// \t}\n\n// \tlimit(limit: number): this {\n// \t\tthis.query.limit = limit;\n// \t\treturn this;\n// \t}\n\n// \tsort(order: \"asc\" | \"desc\"): this {\n// \t\tthis.query.sort_order = order;\n// \t\treturn this;\n// \t}\n\n// \tprivate async rateLimit(): Promise<void> {\n// \t\tthis.requestCount++;\n// \t\tconst now = Date.now();\n// \t\tif (this.requestCount >= this.MAX_REQUESTS_PER_MINUTE) {\n// \t\t\tconst timePassedSinceLastRequest = now - this.lastRequestTime;\n// \t\t\tif (timePassedSinceLastRequest < this.MINUTE_IN_MS) {\n// \t\t\t\tconst delayTime = this.MINUTE_IN_MS - timePassedSinceLastRequest;\n// \t\t\t\tawait new Promise((resolve) => setTimeout(resolve, delayTime));\n// \t\t\t}\n// \t\t\tthis.requestCount = 0;\n// \t\t}\n// \t\tthis.lastRequestTime = Date.now();\n// \t}\n\n// \tprotected async getAnalytics(): Promise<R> {\n// \t\tawait this.rateLimit();\n// \t\tthrow new Error(\"getAnalytics method must be implemented in derived class\");\n// \t}\n\n// \tthen(onfulfilled?: ((value: R) => any) | null): Promise<any> {\n// \t\treturn this.getAnalytics().then(onfulfilled);\n// \t}\n// }\n\n// class TopGatewayAnalyticsBuilder extends GatewayAnalyticsBuilder<\n// \tTopGatewayAnalyticsQuery,\n// \tTopGatewayAnalyticsItem[]\n// > {\n// \tconstructor(\n// \t\tconfig: PinataConfig | undefined,\n// \t\tdomain: string,\n// \t\tstart: string,\n// \t\tend: string,\n// \t\tsortBy: \"requests\" | \"bandwidth\",\n// \t\tattribute:\n// \t\t\t| \"cid\"\n// \t\t\t| \"country\"\n// \t\t\t| \"region\"\n// \t\t\t| \"user_agent\"\n// \t\t\t| \"referer\"\n// \t\t\t| \"file_name\",\n// \t) {\n// \t\tsuper(config, {\n// \t\t\tgateway_domain: domain,\n// \t\t\tstart_date: start,\n// \t\t\tend_date: end,\n// \t\t\tsort_by: sortBy,\n// \t\t\tattribute: attribute,\n// \t\t});\n// \t}\n\n// \tprotected async getAnalytics(): Promise<TopGatewayAnalyticsItem[]> {\n// \t\treturn analyticsTopUsage(this.config, this.query);\n// \t}\n\n// \tasync all(): Promise<TopGatewayAnalyticsItem[]> {\n// \t\treturn this.getAnalytics();\n// \t}\n// }\n\n// class TimeIntervalGatewayAnalyticsBuilder extends GatewayAnalyticsBuilder<\n// \tTimeIntervalGatewayAnalyticsQuery,\n// \tTimeIntervalGatewayAnalyticsResponse\n// > {\n// \tconstructor(\n// \t\tconfig: PinataConfig | undefined,\n// \t\tdomain: string,\n// \t\tstart: string,\n// \t\tend: string,\n// \t\tdateInterval: \"day\" | \"week\",\n// \t) {\n// \t\tsuper(config, {\n// \t\t\tgateway_domain: domain,\n// \t\t\tstart_date: start,\n// \t\t\tend_date: end,\n// \t\t\tdate_interval: dateInterval,\n// \t\t});\n// \t}\n\n// \tsortBy(sortBy: \"requests\" | \"bandwidth\"): this {\n// \t\tthis.query.sort_by = sortBy;\n// \t\treturn this;\n// \t}\n\n// \tprotected async getAnalytics(): Promise<TimeIntervalGatewayAnalyticsResponse> {\n// \t\treturn analyticsDateInterval(this.config, this.query);\n// \t}\n\n// \tasync all(): Promise<TimeIntervalGatewayAnalyticsResponse> {\n// \t\treturn this.getAnalytics();\n// \t}\n// }\n"],"mappings":"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","names":["wait"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils/custom-errors.ts","../src/core/authentication/testAuthentication.ts","../src/core/uploads/file.ts","../src/core/uploads/base64.ts","../src/core/uploads/url.ts","../src/core/uploads/json.ts","../src/core/files/delete.ts","../src/core/files/list.ts","../src/core/files/updateFile.ts","../src/core/gateway/getCid.ts","../src/core/keys/createKey.ts","../src/core/keys/listKeys.ts","../src/core/keys/revokeKeys.ts","../src/core/groups/createGroup.ts","../src/core/groups/listGroups.ts","../src/core/groups/getGroup.ts","../src/core/groups/updateGroup.ts","../src/core/groups/deleteGroup.ts","../src/core/gateway/createSignedURL.ts","../src/core/pinataSDK.ts"],"sourcesContent":["export * from \"./core/pinataSDK\";\nexport * from \"./core/types\";\n","export class PinataError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic statusCode?: number,\n\t\tpublic details?: any,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"PinataError\";\n\t}\n}\n\nexport class NetworkError extends PinataError {\n\tconstructor(message: string, statusCode?: number, details?: any) {\n\t\tsuper(message, statusCode, details);\n\t\tthis.name = \"NetworkError\";\n\t}\n}\n\nexport class AuthenticationError extends PinataError {\n\tconstructor(message: string, statusCode?: number, details?: any) {\n\t\tsuper(message, statusCode, details);\n\t\tthis.name = \"AuthenticationError\";\n\t}\n}\n\nexport class ValidationError extends PinataError {\n\tconstructor(message: string, details?: any) {\n\t\tsuper(message, undefined, details);\n\t\tthis.name = \"ValidationError\";\n\t}\n}\n","/**\n * Tests the authentication of the current Pinata configuration.\n *\n * This function sends a request to the Pinata API to verify if the provided\n * authentication credentials (JWT) are valid and working correctly.\n *\n * @async\n * @function testAuthentication\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @returns {Promise<AuthTestResponse>} A promise that resolves to an object containing a message about the authentication status.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the authentication process.\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const auth = await pinata.testAuthentication()\n */\n\nimport type { PinataConfig, AuthTestResponse } from \"../types\";\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const testAuthentication = async (config: PinataConfig | undefined) => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tlet headers: Record<string, string>;\n\tlet endpoint: string = \"https://api.pinata.cloud\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\tSource: \"sdk/testAuthentication\",\n\t\t};\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/data/testAuthentication`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: headers,\n\t\t});\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res: AuthTestResponse = await request.json();\n\t\treturn res;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(\n\t\t\t\t`Error processing authentication: ${error.message}`,\n\t\t\t);\n\t\t}\n\t\tthrow new PinataError(\n\t\t\t\"An unknown error occurred while testing authentication\",\n\t\t);\n\t}\n};\n","/**\n * Uploads a file to IPFS via Pinata.\n *\n * This function allows you to upload a single file to IPFS and pin it to Pinata.\n * It's useful for adding individual files to your Pinata account and IPFS network.\n *\n * @async\n * @function uploadFile\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {File} file - The file object to be uploaded.\n * @param {UploadOptions} [options] - Optional parameters for the upload.\n * @param {PinataMetadata} [options.metadata] - Metadata for the uploaded file.\n * @param {string} [options.metadata.name] - Custom name for the file (defaults to the original filename if not provided).\n * @param {Record<string, string | number>} [options.metadata.keyValues] - Custom key-value pairs for the file metadata.\n * @param {string} [options.keys] - Custom JWT to use for this specific upload.\n * @param {string} [options.groupId] - ID of the group to add the uploaded file to.\n * @param {0 | 1} [options.cidVersion] - Version of CID to use (0 or 1).\n * @returns {Promise<PinResponse>} A promise that resolves to an object containing the IPFS hash and other upload details.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the upload process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const file = new File([\"hello world!\"], \"hello.txt\", { type: \"text/plain\" })\n * const upload = await pinata.upload.file(file)\n */\n\nimport type { PinataConfig, UploadResponse, UploadOptions } from \"../types\";\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const uploadFile = async (\n\tconfig: PinataConfig | undefined,\n\tfile: File,\n\toptions?: UploadOptions,\n) => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tconst jwt: string | undefined = options?.keys || config.pinataJwt;\n\n\tconst data = new FormData();\n\tdata.append(\"file\", file, file.name);\n\tdata.append(\"name\", options?.metadata?.name || file.name || \"File from SDK\");\n\tif (options?.groupId) {\n\t\tdata.append(\"group_id\", options.groupId);\n\t}\n\n\t// data.append(\n\t// \t\"pinataOptions\",\n\t// \tJSON.stringify({\n\t// \t\tcidVersion: options?.cidVersion,\n\t// \t\tgroupId: options?.groupId,\n\t// \t}),\n\t// );\n\n\t// data.append(\n\t// \t\"pinataMetadata\",\n\t// \tJSON.stringify({\n\t// \t\tname: options?.metadata?.name || file.name || \"File from SDK\",\n\t// \t\tkeyvalues: options?.metadata?.keyValues,\n\t// \t}),\n\t// );\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${jwt}`,\n\t\t\tSource: \"sdk/file\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://uploads.pinata.cloud/v3\";\n\n\tif (config.uploadUrl) {\n\t\tendpoint = config.uploadUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: headers,\n\t\t\tbody: data,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\t\tconst res = await request.json();\n\t\tconst resData: UploadResponse = res.data;\n\t\treturn resData;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error uploading file: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while uploading the file\");\n\t}\n};\n","/**\n * Uploads a base64-encoded string to IPFS via Pinata.\n *\n * This function allows you to upload content to IPFS that is encoded as a base64 string.\n * It's particularly useful for uploading binary data or files that have been converted to base64.\n *\n * @async\n * @function uploadBase64\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {string} base64String - The base64-encoded string to be uploaded.\n * @param {UploadOptions} [options] - Optional parameters for the upload.\n * @param {PinataMetadata} [options.metadata] - Metadata for the uploaded file.\n * @param {string} [options.metadata.name] - Name for the uploaded file (default is \"base64 string\").\n * @param {Record<string, string | number>} [options.metadata.keyvalues] - Custom key-value pairs for the file metadata.\n * @param {string} [options.keys] - Custom JWT to use for this specific upload.\n * @param {string} [options.groupId] - ID of the group to add the uploaded file to.\n * @param {0 | 1} [options.cidVersion] - Version of CID to use (0 or 1).\n * @returns {Promise<PinResponse>} A promise that resolves to an object containing the IPFS hash and other upload details.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the upload process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const upload = await pinata.upload.base64(\"SGVsbG8gV29ybGQh\")\n */\n\nimport type { PinataConfig, UploadResponse, UploadOptions } from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const uploadBase64 = async (\n\tconfig: PinataConfig | undefined,\n\tbase64String: string,\n\toptions?: UploadOptions,\n) => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tconst jwt: string | undefined = options?.keys || config?.pinataJwt;\n\n\tconst name = options?.metadata?.name\n\t\t? options?.metadata?.name\n\t\t: \"base64 string\";\n\n\tconst buffer = Buffer.from(base64String, \"base64\");\n\n\tconst blob = new Blob([buffer]);\n\n\tconst data = new FormData();\n\n\tdata.append(\"file\", blob, name);\n\tdata.append(\"name\", name);\n\tif (options?.groupId) {\n\t\tdata.append(\"group_id\", options.groupId);\n\t}\n\n\t// data.append(\n\t// \t\"pinataOptions\",\n\t// \tJSON.stringify({\n\t// \t\tcidVersion: options?.cidVersion,\n\t// \t\tgroupId: options?.groupId,\n\t// \t}),\n\t// );\n\n\t// data.append(\n\t// \t\"pinataMetadata\",\n\t// \tJSON.stringify({\n\t// \t\tname: name,\n\t// \t\tkeyvalues: options?.metadata?.keyValues,\n\t// \t}),\n\t// );\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${jwt}`,\n\t\t\tSource: \"sdk/base64\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://uploads.pinata.cloud/v3\";\n\n\tif (config.uploadUrl) {\n\t\tendpoint = config.uploadUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: headers,\n\t\t\tbody: data,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res = await request.json();\n\t\tconst resData: UploadResponse = res.data;\n\t\treturn resData;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing base64: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\n\t\t\t\"An unknown error occurred while trying to upload base64\",\n\t\t);\n\t}\n};\n","/**\n * Uploads content from a URL to IPFS via Pinata.\n *\n * This function allows you to upload content from a specified URL to IPFS and pin it to Pinata.\n * It's useful for adding remote content to your Pinata account and IPFS network without\n * first downloading it locally.\n *\n * @async\n * @function uploadUrl\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {string} url - The URL of the content to be uploaded.\n * @param {UploadOptions} [options] - Optional parameters for the upload.\n * @param {PinataMetadata} [options.metadata] - Metadata for the uploaded content.\n * @param {string} [options.metadata.name] - Custom name for the content (defaults to \"url_upload\" if not provided).\n * @param {Record<string, string | number>} [options.metadata.keyValues] - Custom key-value pairs for the content metadata.\n * @param {string} [options.keys] - Custom JWT to use for this specific upload.\n * @param {string} [options.groupId] - ID of the group to add the uploaded content to.\n * @param {0 | 1} [options.cidVersion] - Version of CID to use (0 or 1).\n * @returns {Promise<PinResponse>} A promise that resolves to an object containing the IPFS hash and other upload details.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request or URL fetch.\n * @throws {PinataError} For any other errors that occur during the upload process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const upload = await pinata.upload.url(\"https://i.imgur.com/u4mGk5b.gif\")\n */\n\nimport type { PinataConfig, UploadResponse, UploadOptions } from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const uploadUrl = async (\n\tconfig: PinataConfig | undefined,\n\turl: string,\n\toptions?: UploadOptions,\n) => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tconst jwt: string | undefined = options?.keys || config?.pinataJwt;\n\tconst data = new FormData();\n\n\tconst stream = await fetch(url);\n\n\tif (!stream.ok) {\n\t\tconst errorData = await stream.text();\n\t\tthrow new NetworkError(\n\t\t\t`HTTP error: ${errorData}`,\n\t\t\tstream.status,\n\t\t\terrorData,\n\t\t);\n\t}\n\n\tconst arrayBuffer = await stream.arrayBuffer();\n\n\tconst blob = new Blob([arrayBuffer]);\n\n\tconst name = options?.metadata?.name ?? \"url_upload\";\n\n\tconst file = new File([blob], name);\n\n\tdata.append(\"file\", file, name);\n\tdata.append(\"name\", name);\n\tif (options?.groupId) {\n\t\tdata.append(\"group_id\", options.groupId);\n\t}\n\n\t// data.append(\n\t// \t\"pinataOptions\",\n\t// \tJSON.stringify({\n\t// \t\tcidVersion: options?.cidVersion,\n\t// \t\tgroupId: options?.groupId,\n\t// \t}),\n\t// );\n\n\t// data.append(\n\t// \t\"pinataMetadata\",\n\t// \tJSON.stringify({\n\t// \t\tname: name,\n\t// \t\tkeyvalues: options?.metadata?.keyValues,\n\t// \t}),\n\t// );\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${jwt}`,\n\t\t\tSource: \"sdk/url\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://uploads.pinata.cloud/v3\";\n\n\tif (config.uploadUrl) {\n\t\tendpoint = config.uploadUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: headers,\n\t\t\tbody: data,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res = await request.json();\n\t\tconst resData: UploadResponse = res.data;\n\t\treturn resData;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing url: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while uploading by url\");\n\t}\n};\n","/**\n * Uploads JSON data to IPFS via Pinata.\n *\n * This function allows you to upload JSON data directly to IPFS and pin it to Pinata.\n * It's useful for adding structured data, configurations, or any JSON-serializable content\n * to your Pinata account and IPFS network.\n *\n * @async\n * @function uploadJson\n * @template T\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {T} jsonData - The JSON data to be uploaded. Must be a valid JavaScript object that can be JSON-stringified.\n * @param {UploadOptions} [options] - Optional parameters for the upload.\n * @param {PinataMetadata} [options.metadata] - Metadata for the uploaded JSON.\n * @param {string} [options.metadata.name] - Custom name for the JSON content (defaults to \"json\" if not provided).\n * @param {Record<string, string | number>} [options.metadata.keyValues] - Custom key-value pairs for the JSON metadata.\n * @param {string} [options.keys] - Custom JWT to use for this specific upload.\n * @param {string} [options.groupId] - ID of the group to add the uploaded JSON to.\n * @param {0 | 1} [options.cidVersion] - Version of CID to use (0 or 1).\n * @returns {Promise<PinResponse>} A promise that resolves to an object containing the IPFS hash and other upload details.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the upload process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const upload = await pinata.upload.json({\n * name: \"Pinnie NFT\",\n * description: \"A Pinnie NFT from Pinata\",\n * image: \"ipfs://bafkreih5aznjvttude6c3wbvqeebb6rlx5wkbzyppv7garjiubll2ceym4\"\n * })\n */\n\nimport type {\n\tPinataConfig,\n\tUploadResponse,\n\tUploadOptions,\n\tJsonBody,\n} from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const uploadJson = async <T extends JsonBody>(\n\tconfig: PinataConfig | undefined,\n\tjsonData: T,\n\toptions?: UploadOptions,\n) => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tconst jwt: string | undefined = options?.keys || config?.pinataJwt;\n\n\tconst json = JSON.stringify(jsonData);\n\tconst blob = new Blob([json]);\n\tconst file = new File([blob], \"data.json\", { type: \"application/json\" });\n\n\tconst data = new FormData();\n\tdata.append(\"file\", file, file.name);\n\tdata.append(\"name\", options?.metadata?.name || file.name || \"File from SDK\");\n\tif (options?.groupId) {\n\t\tdata.append(\"group_id\", options.groupId);\n\t}\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${jwt}`,\n\t\t\tSource: \"sdk/json\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://uploads.pinata.cloud/v3\";\n\n\tif (config.uploadUrl) {\n\t\tendpoint = config.uploadUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: headers,\n\t\t\tbody: data,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res = await request.json();\n\t\tconst resData: UploadResponse = res.data;\n\t\treturn resData;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing json: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while uploading json\");\n\t}\n};\n","/**\n * Unpins multiple files from Pinata and IPFS.\n *\n * This function allows you to remove pins for multiple files from your Pinata account.\n * Unpinning a file means that Pinata will no longer guarantee its availability on IPFS,\n * although the content may still be available if pinned by other IPFS nodes.\n *\n * @async\n * @function unpinFile\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {string[]} files - An array of IPFS hashes (CIDs) of the files to unpin.\n * @returns {Promise<DeleteResponse[]>} A promise that resolves to an array of objects, each containing the status of the unpin operation for each file.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the unpinning process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const unpin = await pinata.unpin([\n * \"bafkreih5aznjvttude6c3wbvqeebb6rlx5wkbzyppv7garjiubll2ceym4\"\n * ])\n */\n\nimport type { PinataConfig, DeleteResponse } from \"../types\";\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nconst wait = (milliseconds: number): Promise<void> => {\n\treturn new Promise((resolve) => {\n\t\tsetTimeout(resolve, milliseconds);\n\t});\n};\n\nexport const deleteFile = async (\n\tconfig: PinataConfig | undefined,\n\tfiles: string[],\n): Promise<DeleteResponse[]> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tconst responses: DeleteResponse[] = [];\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\tSource: \"sdk/unpin\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\tfor (const id of files) {\n\t\ttry {\n\t\t\tconst response = await fetch(`${endpoint}/files/${id}`, {\n\t\t\t\tmethod: \"DELETE\",\n\t\t\t\theaders: headers,\n\t\t\t});\n\n\t\t\tawait wait(300);\n\n\t\t\tif (!response.ok) {\n\t\t\t\tconst errorData = await response.text();\n\t\t\t\tif (response.status === 401) {\n\t\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\t\tresponse.status,\n\t\t\t\t\t\terrorData,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow new NetworkError(\n\t\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\t\tresponse.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tresponses.push({\n\t\t\t\tid: id,\n\t\t\t\tstatus: response.statusText,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tlet errorMessage: string;\n\n\t\t\tif (error instanceof PinataError) {\n\t\t\t\terrorMessage = error.message;\n\t\t\t} else if (error instanceof Error) {\n\t\t\t\terrorMessage = `Error deleting file ${id}: ${error.message}`;\n\t\t\t} else {\n\t\t\t\terrorMessage = `An unknown error occurred while deleting file ${id}`;\n\t\t\t}\n\n\t\t\tresponses.push({\n\t\t\t\tid: id,\n\t\t\t\tstatus: errorMessage,\n\t\t\t});\n\t\t}\n\t}\n\treturn responses;\n};\n","/**\n * Lists files pinned to Pinata based on the provided configuration and options.\n *\n * This function fetches a list of pinned files from the Pinata API, allowing for\n * various filtering and pagination options.\n *\n * @async\n * @function listFiles\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {FileListQuery} [options] - Optional query parameters to filter and paginate the results.\n * @param {string} [options.cid] - Filter by the CID of the file.\n * @param {string} [options.pinStart] - Filter by the start date of pinning (ISO 8601 format).\n * @param {string} [options.pinEnd] - Filter by the end date of pinning (ISO 8601 format).\n * @param {number} [options.pinSizeMin] - Filter by minimum pin size in bytes.\n * @param {number} [options.pinSizeMax] - Filter by maximum pin size in bytes.\n * @param {number} [options.pageLimit] - Number of items to return per page.\n * @param {number} [options.pageOffset] - Number of items to skip (for pagination).\n * @param {string} [options.name] - Filter by the name of the file.\n * @param {string} [options.key] - Metadata key to filter by (used with value and operator).\n * @param {string | number} [options.value] - Metadata value to filter by (used with key and operator).\n * @param {string} [options.operator] - Comparison operator for metadata filtering.\n * @param {string} [options.groupId] - Filter by group ID.\n * @returns {Promise<FileListItem[]>} A promise that resolves to an array of FileListItem objects.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the file listing process.\n *//**\n * Lists files pinned to Pinata based on the provided configuration and options.\n *\n * This function fetches a list of pinned files from the Pinata API, allowing for\n * various filtering and pagination options.\n *\n * @async\n * @function listFiles\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {FileListQuery} [options] - Optional query parameters to filter and paginate the results.\n * @param {string} [options.cid] - Filter by the CID of the file.\n * @param {string} [options.pinStart] - Filter by the start date of pinning (ISO 8601 format).\n * @param {string} [options.pinEnd] - Filter by the end date of pinning (ISO 8601 format).\n * @param {number} [options.pinSizeMin] - Filter by minimum pin size in bytes.\n * @param {number} [options.pinSizeMax] - Filter by maximum pin size in bytes.\n * @param {number} [options.pageLimit] - Number of items to return per page.\n * @param {number} [options.pageOffset] - Number of items to skip (for pagination).\n * @param {string} [options.name] - Filter by the name of the file.\n * @param {string} [options.key] - Metadata key to filter by (used with value and operator).\n * @param {string | number} [options.value] - Metadata value to filter by (used with key and operator).\n * @param {string} [options.operator] - Comparison operator for metadata filtering.\n * @param {string} [options.groupId] - Filter by group ID.\n * @returns {Promise<FileListItem[]>} A promise that resolves to an array of FileListItem objects.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the file listing process.\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const files = await pinata.listFiles().name(\"pinnie\")\n */\n\nimport type { FileListQuery, FileListResponse, PinataConfig } from \"../types\";\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const listFiles = async (\n\tconfig: PinataConfig | undefined,\n\toptions?: FileListQuery,\n): Promise<FileListResponse> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tconst params = new URLSearchParams();\n\n\tif (options) {\n\t\tconst { limit, pageToken, cidPending } = options;\n\n\t\tif (limit) params.append(\"limit\", limit.toString());\n\t\tif (pageToken) params.append(\"pageToken\", pageToken);\n\t\tif (cidPending) params.append(\"cidPending\", \"true\");\n\t}\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\tconst url = `${endpoint}/files?${params.toString()}`;\n\n\ttry {\n\t\tlet headers: Record<string, string>;\n\n\t\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\t\theaders = { ...config.customHeaders };\n\t\t} else {\n\t\t\theaders = {\n\t\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\tSource: \"sdk/listFiles\",\n\t\t\t};\n\t\t}\n\n\t\tconst request = await fetch(url, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: headers,\n\t\t});\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res = await request.json();\n\t\tconst resData: FileListResponse = res.data;\n\t\treturn resData;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing list files: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while listing files\");\n\t}\n};\n","/**\n * Updates the metadata for a pinned file on Pinata.\n *\n * This function allows you to modify the name and/or key-value pairs associated\n * with a file that has already been pinned to Pinata. This is useful for\n * organizing and categorizing your pinned content.\n *\n * @async\n * @function updateMetadata\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {UpdateFileOptions} options - The options for updating the metadata.\n * @param {string} options.cid - The Content Identifier (CID) of the pinned file to update.\n * @param {string} [options.name] - The new name to assign to the pinned file (optional).\n * @param {Record<string, string | number>} [options.keyValues] - Key-value pairs to associate with the pinned file (optional).\n * @returns {Promise<string>} A promise that resolves to a string confirming the update.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the metadata update process.\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const update = await pinata.updateMedatadata({\n * cid: \"bafkreih5aznjvttude6c3wbvqeebb6rlx5wkbzyppv7garjiubll2ceym4\",\n * name: \"Pinnie V2\",\n * keyValues: {\n * whimsey: 200\n * }\n * })\n */\n\nimport type { FileListItem, PinataConfig, UpdateFileOptions } from \"../types\";\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const updateFile = async (\n\tconfig: PinataConfig | undefined,\n\toptions: UpdateFileOptions,\n): Promise<FileListItem> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\tconst data = JSON.stringify({\n\t\tname: options.name,\n\t});\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tSource: \"sdk/updateMetadata\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files/${options.id}`, {\n\t\t\tmethod: \"PUT\",\n\t\t\theaders: headers,\n\t\t\tbody: data,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res = await request.json();\n\t\tconst resData: FileListItem = res.data;\n\t\treturn resData;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing updateFile: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while updating file\");\n\t}\n};\n","/**\n * Retrieves the content of a file from IPFS using its Content Identifier (CID).\n *\n * This function fetches the content associated with a given CID from the specified\n * Pinata gateway. It can handle various content types and returns the data along\n * with the content type information.\n *\n * @async\n * @function getCid\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT and gateway information.\n * @param {string} cid - The Content Identifier (CID) of the file to retrieve.\n * @returns {Promise<GetCIDResponse>} A promise that resolves to an object containing the file data and content type.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the retrieval process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const upload = await pinata.gateways.get(\"QmVLwvmGehsrNEvhcCnnsw5RQNseohgEkFNN1848zNzdng\"* )\n *\n */\n\nimport type {\n\tGetCIDResponse,\n\tPinataConfig,\n\tOptimizeImageOptions,\n} from \"../types\";\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const getCid = async (\n\tconfig: PinataConfig | undefined,\n\tcid: string,\n\t// options?: OptimizeImageOptions,\n): Promise<GetCIDResponse> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tlet data: JSON | string | Blob;\n\tlet newUrl: string = `${config?.pinataGateway}/files/${cid}`;\n\n\tconst params = new URLSearchParams();\n\n\tconst date = Math.floor(new Date().getTime() / 1000);\n\n\tconst payload = JSON.stringify({\n\t\turl: newUrl,\n\t\tdate: date,\n\t\texpires: 30,\n\t\tmethod: \"GET\",\n\t});\n\n\tconst signedUrlRequest = await fetch(\n\t\t\"https://api.pinata.cloud/v3/files/sign\",\n\t\t{\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\tAuthorization: `Bearer ${config?.pinataJwt}`,\n\t\t\t},\n\t\t\tbody: payload,\n\t\t},\n\t);\n\n\tconst signedUrl = await signedUrlRequest.json();\n\n\t// if (config?.pinataGatewayKey) {\n\t// \tparams.append(\"pinataGatewayToken\", config.pinataGatewayKey);\n\t// }\n\n\t// if (options) {\n\t// \tif (options.width) params.append(\"img-width\", options.width.toString());\n\t// \tif (options.height) params.append(\"img-height\", options.height.toString());\n\t// \tif (options.dpr) params.append(\"img-dpr\", options.dpr.toString());\n\t// \tif (options.fit) params.append(\"img-fit\", options.fit);\n\t// \tif (options.gravity) params.append(\"img-gravity\", options.gravity);\n\t// \tif (options.quality)\n\t// \t\tparams.append(\"img-quality\", options.quality.toString());\n\t// \tif (options.format) params.append(\"img-format\", options.format);\n\t// \tif (options.animation !== undefined)\n\t// \t\tparams.append(\"img-anim\", options.animation.toString());\n\t// \tif (options.sharpen)\n\t// \t\tparams.append(\"img-sharpen\", options.sharpen.toString());\n\t// \tif (options.onError === true) params.append(\"img-onerror\", \"redirect\");\n\t// \tif (options.metadata) params.append(\"img-metadata\", options.metadata);\n\t// }\n\n\t// const queryString = params.toString();\n\t// if (queryString) {\n\t// \tnewUrl += `?${queryString}`;\n\t// }\n\n\ttry {\n\t\tconst request = await fetch(signedUrl.data);\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication Failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst contentType: string | null = request.headers.get(\"content-type\");\n\n\t\tif (contentType?.includes(\"application/json\")) {\n\t\t\tdata = await request.json();\n\t\t} else if (contentType?.includes(\"text/\")) {\n\t\t\tdata = await request.text();\n\t\t} else {\n\t\t\tdata = await request.blob();\n\t\t}\n\n\t\tconst res: GetCIDResponse = {\n\t\t\tdata: data,\n\t\t\tcontentType: contentType,\n\t\t};\n\n\t\treturn res;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing getCid: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\n\t\t\t\"An unknown error occurred while getting CID contents\",\n\t\t);\n\t}\n};\n","/**\n * Creates a new API key for Pinata services.\n *\n * This function allows you to generate a new API key with specific permissions\n * for use with Pinata's IPFS pinning services. It's useful for creating keys\n * with limited access or for specific applications.\n *\n * @async\n * @function createKey\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {KeyOptions} options - The options for creating a new API key.\n * @param {string} options.keyName - The name to assign to the new API key.\n * @param {KeyPermissions} options.permissions - The permissions to assign to the new key.\n * @param {number} [options.maxUses] - Optional. The maximum number of times the key can be used.\n * @returns {Promise<KeyResponse>} A promise that resolves to an object containing the new API key details.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the key creation process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const key = await pinata.keys.create({\n * keyName: \"user 1\",\n * permissions: {\n * admin: true,\n * },\n * maxUses: 1,\n * });\n */\n\nimport type { PinataConfig, KeyOptions, KeyResponse } from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const createKey = async (\n\tconfig: PinataConfig | undefined,\n\toptions: KeyOptions,\n): Promise<KeyResponse> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tSource: \"sdk/createKey\",\n\t\t};\n\t}\n\n\tconst data = JSON.stringify(options);\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/pinata/keys`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: headers,\n\t\t\tbody: data,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res: KeyResponse = await request.json();\n\t\treturn res;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing createKey: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while creating API key\");\n\t}\n};\n","/**\n * Retrieves a list of API keys associated with the Pinata account.\n *\n * This function allows you to fetch and optionally filter the API keys linked to your Pinata account.\n * It's useful for managing your API keys, checking their status, or auditing key usage.\n *\n * @async\n * @function listKeys\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {KeyListQuery} [options] - Optional query parameters to filter the list of keys.\n * @param {number} [options.offset] - The number of items to skip before starting to collect the result set.\n * @param {boolean} [options.revoked] - If true, includes revoked keys in the results.\n * @param {boolean} [options.limitedUse] - If true, only returns keys with usage limits.\n * @param {boolean} [options.exhausted] - If true, only returns keys that have reached their usage limit.\n * @param {string} [options.name] - Filters keys by name (partial match).\n * @returns {Promise<KeyListItem[]>} A promise that resolves to an array of key objects matching the query.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the key listing process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const keys = await pinata.keys\n * .list()\n * .name(\"Admin\")\n * .revoked(false)\n */\n\nimport type {\n\tKeyListItem,\n\tKeyListQuery,\n\tKeyListResponse,\n\tPinataConfig,\n} from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const listKeys = async (\n\tconfig: PinataConfig | undefined,\n\toptions?: KeyListQuery,\n): Promise<KeyListItem[]> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tSource: \"sdk/listKeys\",\n\t\t};\n\t}\n\n\tconst params = new URLSearchParams();\n\n\tif (options) {\n\t\tconst { offset, name, revoked, limitedUse, exhausted } = options;\n\n\t\tif (offset) params.append(\"offset\", offset.toString());\n\t\tif (revoked !== undefined) params.append(\"revoked\", revoked.toString());\n\t\tif (limitedUse !== undefined)\n\t\t\tparams.append(\"limitedUse\", limitedUse.toString());\n\t\tif (exhausted !== undefined)\n\t\t\tparams.append(\"exhausted\", exhausted.toString());\n\t\tif (name) params.append(\"name\", name);\n\t}\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(\n\t\t\t`${endpoint}/pinata/keys?${params.toString()}`,\n\t\t\t{\n\t\t\t\tmethod: \"GET\",\n\t\t\t\theaders: headers,\n\t\t\t},\n\t\t);\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res: KeyListResponse = await request.json();\n\t\treturn res.keys;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing listKeys: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while listing API keys\");\n\t}\n};\n","/**\n * Revokes multiple API keys from the Pinata account.\n *\n * This function allows you to revoke (invalidate) multiple API keys at once.\n * It's useful for security purposes, such as when keys may have been compromised\n * or are no longer needed.\n *\n * @async\n * @function revokeKeys\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {string[]} keys - An array of API key strings to be revoked.\n * @returns {Promise<RevokeKeyResponse[]>} A promise that resolves to an array of objects,\n * each containing the status of the revocation attempt for each key.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the key revocation process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const revoke = await pinata.keys.revoke([\n * \"94566af5e63833e260be\"\n * ]);\n */\n\nimport type { PinataConfig, RevokeKeyResponse } from \"../types\";\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nconst wait = (milliseconds: number): Promise<void> => {\n\treturn new Promise((resolve) => {\n\t\tsetTimeout(resolve, milliseconds);\n\t});\n};\n\nexport const revokeKeys = async (\n\tconfig: PinataConfig | undefined,\n\tkeys: string[],\n): Promise<RevokeKeyResponse[]> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tSource: \"sdk/revokeKeys\",\n\t\t};\n\t}\n\n\tconst responses: RevokeKeyResponse[] = [];\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\tfor (const key of keys) {\n\t\ttry {\n\t\t\tconst request = await fetch(`${endpoint}/pinata/keys/${key}`, {\n\t\t\t\tmethod: \"PUT\",\n\t\t\t\theaders: headers,\n\t\t\t});\n\n\t\t\tawait wait(300);\n\n\t\t\tif (!request.ok) {\n\t\t\t\tconst errorData = await request.text();\n\t\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\t\trequest.status,\n\t\t\t\t\t\terrorData,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow new NetworkError(\n\t\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst result: string = await request.json();\n\t\t\tresponses.push({\n\t\t\t\tkey: key,\n\t\t\t\tstatus: result,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tlet errorMessage: string;\n\n\t\t\tif (error instanceof PinataError) {\n\t\t\t\terrorMessage = error.message;\n\t\t\t} else if (error instanceof Error) {\n\t\t\t\terrorMessage = `Error revoking key ${key}: ${error.message}`;\n\t\t\t} else {\n\t\t\t\terrorMessage = `An unknown error occurred while revoking key ${key}`;\n\t\t\t}\n\n\t\t\tresponses.push({\n\t\t\t\tkey: key,\n\t\t\t\tstatus: errorMessage,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn responses;\n};\n","/**\n * Creates a new group in Pinata for organizing pinned content.\n *\n * This function allows you to create a new group in your Pinata account.\n * Groups can be used to organize and manage your pinned content more effectively.\n *\n * @async\n * @function createGroup\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {GroupOptions} options - The options for creating a new group.\n * @param {string} options.name - The name of the group to be created.\n * @returns {Promise<GroupResponseItem>} A promise that resolves to an object containing details of the created group.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the group creation process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const group = await pinata.groups.create({\n *\tname: \"My New Group\",\n * });\n */\n\nimport type { PinataConfig, GroupOptions, GroupResponseItem } from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const createGroup = async (\n\tconfig: PinataConfig | undefined,\n\toptions: GroupOptions,\n): Promise<GroupResponseItem> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tconst data = JSON.stringify({\n\t\tname: options.name,\n\t\tis_public: options.isPublic,\n\t});\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tSource: \"sdk/createGroup\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files/groups`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: headers,\n\t\t\tbody: data,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res = await request.json();\n\t\tconst resData: GroupResponseItem = res.data;\n\t\treturn resData;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing createGroup: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while creating a group\");\n\t}\n};\n","/**\n * Retrieves a list of groups from Pinata.\n *\n * This function fetches a list of groups associated with your Pinata account.\n * It supports pagination and filtering by name.\n *\n * @async\n * @function listGroups\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {GroupQueryOptions} [options] - Optional query parameters to filter and paginate the results.\n * @param {number} [options.offset] - The number of items to skip before starting to collect the result set.\n * @param {string} [options.nameContains] - Filter groups by name (case-insensitive partial match).\n * @param {number} [options.limit] - The numbers of items to return.\n * @returns {Promise<GroupResponseItem[]>} A promise that resolves to an array of group objects.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the group listing process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const groups = await pinata.groups\n * .list()\n * .name(\"Greetings\");\n */\n\nimport type {\n\tPinataConfig,\n\tGroupResponseItem,\n\tGroupQueryOptions,\n\tGroupListResponse,\n} from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const listGroups = async (\n\tconfig: PinataConfig | undefined,\n\toptions?: GroupQueryOptions,\n): Promise<GroupListResponse> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tSource: \"sdk/listGroups\",\n\t\t};\n\t}\n\n\tconst params = new URLSearchParams();\n\n\tif (options) {\n\t\tconst { pageToken, nameContains, limit, isPublic } = options;\n\n\t\tif (pageToken) params.append(\"pageToken\", pageToken.toString());\n\t\tif (isPublic) params.append(\"isPublic\", isPublic.toString());\n\t\tif (nameContains !== undefined)\n\t\t\tparams.append(\"nameContains\", nameContains.toString());\n\t\tif (limit !== undefined) params.append(\"limit\", limit.toString());\n\t}\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(\n\t\t\t`${endpoint}/files/groups?${params.toString()}`,\n\t\t\t{\n\t\t\t\tmethod: \"GET\",\n\t\t\t\theaders: headers,\n\t\t\t},\n\t\t);\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res = await request.json();\n\t\tconst resData: GroupListResponse = res.data;\n\t\treturn resData;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing listGroups: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while listing groups\");\n\t}\n};\n","/**\n * Retrieves information about a specific group from Pinata.\n *\n * This function fetches details about a group in your Pinata account using its ID.\n * It provides information such as the group's name, creation date, and last update time.\n *\n * @async\n * @function getGroup\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {GetGroupOptions} options - The options for retrieving a group.\n * @param {string} options.groupId - The ID of the group to retrieve.\n * @returns {Promise<GroupResponseItem>} A promise that resolves to an object containing the group's details.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the group retrieval process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const groups = await pinata.groups.get({\n *\tgroupId: \"3778c10d-452e-4def-8299-ee6bc548bdb0\",\n * });\n */\n\nimport type {\n\tPinataConfig,\n\tGroupResponseItem,\n\tGetGroupOptions,\n} from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const getGroup = async (\n\tconfig: PinataConfig | undefined,\n\toptions: GetGroupOptions,\n): Promise<GroupResponseItem> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tSource: \"sdk/getGroup\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files/groups/${options.groupId}`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: headers,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res = await request.json();\n\t\tconst resData: GroupResponseItem = res.data;\n\t\treturn resData;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing getGroup: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\n\t\t\t\"An unknown error occurred while getting info for a group\",\n\t\t);\n\t}\n};\n","/**\n * Updates the information of a specified group in Pinata.\n *\n * This function allows you to modify the name of an existing group in your Pinata account.\n * It's useful for renaming groups to better organize your pinned content.\n *\n * @async\n * @function updateGroup\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {UpdateGroupOptions} options - The options for updating a group.\n * @param {string} options.groupId - The ID of the group to be updated.\n * @param {string} options.name - The new name for the group.\n * @returns {Promise<GroupResponseItem>} A promise that resolves to an object containing the updated group's details.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the group update process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const groups = await pinata.groups.update({\n *\tgroupId: \"3778c10d-452e-4def-8299-ee6bc548bdb0\",\n *\tname: \"My New Group 2\"\n * });\n */\n\nimport type {\n\tPinataConfig,\n\tGroupResponseItem,\n\tUpdateGroupOptions,\n} from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const updateGroup = async (\n\tconfig: PinataConfig | undefined,\n\toptions: UpdateGroupOptions,\n): Promise<GroupResponseItem> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tconst data = JSON.stringify({\n\t\tname: options.name,\n\t\tis_public: options.isPublic,\n\t});\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tSource: \"sdk/updateGroup\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files/groups/${options.groupId}`, {\n\t\t\tmethod: \"PUT\",\n\t\t\theaders: headers,\n\t\t\tbody: data,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res = await request.json();\n\t\tconst resData: GroupResponseItem = res.data;\n\t\treturn resData;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing updateGroup: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while updating group\");\n\t}\n};\n","/**\n * Deletes a specified group from Pinata.\n *\n * This function allows you to remove a group from your Pinata account.\n * Note that deleting a group does not delete the files within the group,\n * it only removes the group association.\n *\n * @async\n * @function deleteGroup\n * @param {PinataConfig | undefined} config - The Pinata configuration object containing the JWT.\n * @param {GetGroupOptions} options - The options for deleting a group.\n * @param {string} options.groupId - The ID of the group to be deleted.\n * @returns {Promise<string>} A promise that resolves to a string confirming the deletion.\n * @throws {ValidationError} If the Pinata configuration or JWT is missing.\n * @throws {AuthenticationError} If the authentication fails (e.g., invalid JWT).\n * @throws {NetworkError} If there's a network-related error during the API request.\n * @throws {PinataError} For any other errors that occur during the group deletion process.\n *\n * @example\n * import { PinataSDK } from \"pinata\";\n *\n * const pinata = new PinataSDK({\n * pinataJwt: process.env.PINATA_JWT!,\n * pinataGateway: \"example-gateway.mypinata.cloud\",\n * });\n *\n * const groups = await pinata.groups.delete({\n *\tgroupId: \"3778c10d-452e-4def-8299-ee6bc548bdb0\",\n * });\n */\n\nimport type { GetGroupOptions, PinataConfig } from \"../types\";\n\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const deleteGroup = async (\n\tconfig: PinataConfig | undefined,\n\toptions: GetGroupOptions,\n): Promise<string> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tlet headers: Record<string, string>;\n\n\tif (config.customHeaders && Object.keys(config.customHeaders).length > 0) {\n\t\theaders = { ...config.customHeaders };\n\t} else {\n\t\theaders = {\n\t\t\tAuthorization: `Bearer ${config.pinataJwt}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tSource: \"sdk/deleteGroup\",\n\t\t};\n\t}\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files/groups/${options.groupId}`, {\n\t\t\tmethod: \"DELETE\",\n\t\t\theaders: headers,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res: string = request.statusText;\n\t\treturn res;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(`Error processing deleteGroup: ${error.message}`);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while deleting a group\");\n\t}\n};\n","import type {\n\tPinataConfig,\n\tOptimizeImageOptions,\n\tSignedUrlOptions,\n} from \"../types\";\nimport {\n\tPinataError,\n\tNetworkError,\n\tAuthenticationError,\n\tValidationError,\n} from \"../../utils/custom-errors\";\n\nexport const createSignedURL = async (\n\tconfig: PinataConfig | undefined,\n\toptions: SignedUrlOptions,\n): Promise<string> => {\n\tif (!config) {\n\t\tthrow new ValidationError(\"Pinata configuration is missing\");\n\t}\n\n\tlet newUrl: string = `${config?.pinataGateway}/files/${options.cid}`;\n\n\tconst date = options?.date || Math.floor(new Date().getTime() / 1000);\n\n\tconst payload = JSON.stringify({\n\t\turl: newUrl,\n\t\tdate: date,\n\t\texpires: options.expires,\n\t\tmethod: \"GET\",\n\t});\n\n\tlet endpoint: string = \"https://api.pinata.cloud/v3\";\n\n\tif (config.endpointUrl) {\n\t\tendpoint = config.endpointUrl;\n\t}\n\n\t// const params = new URLSearchParams();\n\t// if (config?.pinataGatewayKey) {\n\t// \tparams.append(\"pinataGatewayToken\", config.pinataGatewayKey);\n\t// }\n\n\t// if (options) {\n\t// \tif (options.width) params.append(\"img-width\", options.width.toString());\n\t// \tif (options.height) params.append(\"img-height\", options.height.toString());\n\t// \tif (options.dpr) params.append(\"img-dpr\", options.dpr.toString());\n\t// \tif (options.fit) params.append(\"img-fit\", options.fit);\n\t// \tif (options.gravity) params.append(\"img-gravity\", options.gravity);\n\t// \tif (options.quality)\n\t// \t\tparams.append(\"img-quality\", options.quality.toString());\n\t// \tif (options.format) params.append(\"img-format\", options.format);\n\t// \tif (options.animation !== undefined)\n\t// \t\tparams.append(\"img-anim\", options.animation.toString());\n\t// \tif (options.sharpen)\n\t// \t\tparams.append(\"img-sharpen\", options.sharpen.toString());\n\t// \tif (options.onError === true) params.append(\"img-onerror\", \"redirect\");\n\t// \tif (options.metadata) params.append(\"img-metadata\", options.metadata);\n\t// }\n\n\t// const queryString = params.toString();\n\t// if (queryString) {\n\t// \tnewUrl += `?${queryString}`;\n\t// }\n\n\ttry {\n\t\tconst request = await fetch(`${endpoint}/files/sign`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\tAuthorization: `Bearer ${config?.pinataJwt}`,\n\t\t\t},\n\t\t\tbody: payload,\n\t\t});\n\n\t\tif (!request.ok) {\n\t\t\tconst errorData = await request.text();\n\t\t\tif (request.status === 401 || request.status === 403) {\n\t\t\t\tthrow new AuthenticationError(\n\t\t\t\t\t`Authentication Failed: ${errorData}`,\n\t\t\t\t\trequest.status,\n\t\t\t\t\terrorData,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new NetworkError(\n\t\t\t\t`HTTP error: ${errorData}`,\n\t\t\t\trequest.status,\n\t\t\t\terrorData,\n\t\t\t);\n\t\t}\n\n\t\tconst res = await request.json();\n\t\treturn res.data;\n\t} catch (error) {\n\t\tif (error instanceof PinataError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new PinataError(\n\t\t\t\t`Error processing createSignedURL: ${error.message}`,\n\t\t\t);\n\t\t}\n\t\tthrow new PinataError(\"An unknown error occurred while getting signed url\");\n\t}\n};\n","import type {\n\tFileObject,\n\tFileListItem,\n\tFileListQuery,\n\tUploadResponse,\n\tPinataConfig,\n\tPinataMetadata,\n\tUpdateFileOptions,\n\tUploadOptions,\n\tGetCIDResponse,\n\tKeyOptions,\n\tKeyResponse,\n\tKeyListQuery,\n\tKeyListItem,\n\tGroupOptions,\n\tGroupResponseItem,\n\tUpdateGroupOptions,\n\tGroupCIDOptions,\n\tGroupQueryOptions,\n\tGetGroupOptions,\n\tAuthTestResponse,\n\tDeleteResponse,\n\tRevokeKeyResponse,\n\tSignatureOptions,\n\tSignatureResponse,\n\tTopGatewayAnalyticsQuery,\n\tTopGatewayAnalyticsItem,\n\tTimeIntervalGatewayAnalyticsQuery,\n\tGatewayAnalyticsQuery,\n\tTimeIntervalGatewayAnalyticsResponse,\n\tSwapCidOptions,\n\tSwapCidResponse,\n\tSwapHistoryOptions,\n\tContainsCIDResponse,\n\tOptimizeImageOptions,\n\tGroupListResponse,\n\tSignedUrlOptions,\n\tFileListResponse,\n} from \"./types\";\nimport { testAuthentication } from \"./authentication/testAuthentication\";\nimport { uploadFile } from \"./uploads/file\";\nimport { uploadFileArray } from \"./uploads/fileArray\";\nimport { uploadBase64 } from \"./uploads/base64\";\nimport { uploadUrl } from \"./uploads/url\";\nimport { uploadJson } from \"./uploads/json\";\nimport { deleteFile } from \"./files/delete\";\nimport { listFiles } from \"./files/list\";\nimport { updateFile } from \"./files/updateFile\";\nimport { getCid } from \"./gateway/getCid\";\nimport { convertIPFSUrl } from \"./gateway/convertIPFSUrl\";\n// import { pinnedFileCount } from \"./files/pinnedFileUsage\";\n// import { totalStorageUsage } from \"./files/totalStorageUsage\";\nimport { createKey } from \"./keys/createKey\";\nimport { listKeys } from \"./keys/listKeys\";\nimport { revokeKeys } from \"./keys/revokeKeys\";\nimport { createGroup } from \"./groups/createGroup\";\nimport { listGroups } from \"./groups/listGroups\";\nimport { getGroup } from \"./groups/getGroup\";\nimport { addToGroup } from \"./groups/addToGroup\";\nimport { updateGroup } from \"./groups/updateGroup\";\nimport { removeFromGroup } from \"./groups/removeFromGroup\";\nimport { deleteGroup } from \"./groups/deleteGroup\";\n// import { addSignature } from \"./signatures/addSignature\";\n// import { getSignature } from \"./signatures/getSignature\";\n// import { removeSignature } from \"./signatures/removeSignature\";\nimport { analyticsTopUsage } from \"./gateway/analyticsTopUsage\";\nimport { analyticsDateInterval } from \"./gateway/analyticsDateInterval\";\nimport { swapCid } from \"./gateway/swapCid\";\nimport { swapHistory } from \"./gateway/swapHistory\";\nimport { deleteSwap } from \"./gateway/deleteSwap\";\nimport { containsCID } from \"../utils/gateway-tools\";\nimport { createSignedURL } from \"./gateway/createSignedURL\";\n\nconst formatConfig = (config: PinataConfig | undefined) => {\n\tlet gateway = config?.pinataGateway;\n\tif (config && gateway) {\n\t\tif (gateway && !gateway.startsWith(\"https://\")) {\n\t\t\tgateway = `https://${gateway}`;\n\t\t}\n\t\tconfig.pinataGateway = gateway;\n\t}\n\treturn config;\n};\n\nexport class PinataSDK {\n\tconfig: PinataConfig | undefined;\n\tfiles: Files;\n\tupload: Upload;\n\tgateways: Gateways;\n\t//\tusage: Usage;\n\tkeys: Keys;\n\tgroups: Groups;\n\t//signatures: Signatures;\n\n\tconstructor(config?: PinataConfig) {\n\t\tthis.config = formatConfig(config);\n\t\tthis.files = new Files(this.config);\n\t\tthis.upload = new Upload(this.config);\n\t\tthis.gateways = new Gateways(this.config);\n\t\t//\t\tthis.usage = new Usage(this.config);\n\t\tthis.keys = new Keys(this.config);\n\t\tthis.groups = new Groups(this.config);\n\t\t//\t\tthis.signatures = new Signatures(this.config);\n\t}\n\n\tsetNewHeaders(headers: Record<string, string>): void {\n\t\tif (!this.config) {\n\t\t\tthis.config = { pinataJwt: \"\", customHeaders: {} };\n\t\t}\n\t\tthis.config.customHeaders = { ...this.config.customHeaders, ...headers };\n\n\t\t// Update headers for all sub-modules\n\t\tthis.files.updateConfig(this.config);\n\t\tthis.upload.updateConfig(this.config);\n\t\tthis.gateways.updateConfig(this.config);\n\t\t//\t\tthis.usage.updateConfig(this.config);\n\t\tthis.keys.updateConfig(this.config);\n\t\tthis.groups.updateConfig(this.config);\n\t\t//\t\tthis.signatures.updateConfig(this.config);\n\t}\n\n\ttestAuthentication(): Promise<AuthTestResponse> {\n\t\treturn testAuthentication(this.config);\n\t}\n}\n\nclass Files {\n\tconfig: PinataConfig | undefined;\n\n\tconstructor(config?: PinataConfig) {\n\t\tthis.config = formatConfig(config);\n\t}\n\n\tupdateConfig(newConfig: PinataConfig): void {\n\t\tthis.config = newConfig;\n\t}\n\n\tlist(): FilterFiles {\n\t\treturn new FilterFiles(this.config);\n\t}\n\n\tdelete(files: string[]): Promise<DeleteResponse[]> {\n\t\treturn deleteFile(this.config, files);\n\t}\n\n\tupdate(options: UpdateFileOptions): Promise<FileListItem> {\n\t\treturn updateFile(this.config, options);\n\t}\n}\n\nclass UploadBuilder<T> {\n\tprivate config: PinataConfig | undefined;\n\tprivate uploadFunction: (\n\t\tconfig: PinataConfig | undefined,\n\t\t...args: any[]\n\t) => Promise<T>;\n\tprivate args: any[];\n\tprivate metadata: PinataMetadata | undefined;\n\tprivate keys: string | undefined;\n\tprivate groupId: string | undefined;\n\n\tconstructor(\n\t\tconfig: PinataConfig | undefined,\n\t\tuploadFunction: (\n\t\t\tconfig: PinataConfig | undefined,\n\t\t\t...args: any[]\n\t\t) => Promise<T>,\n\t\t...args: any[]\n\t) {\n\t\tthis.config = config;\n\t\tthis.uploadFunction = uploadFunction;\n\t\tthis.args = args;\n\t}\n\n\taddMetadata(metadata: PinataMetadata): UploadBuilder<T> {\n\t\tthis.metadata = metadata;\n\t\treturn this;\n\t}\n\n\tkey(jwt: string): UploadBuilder<T> {\n\t\tthis.keys = jwt;\n\t\treturn this;\n\t}\n\n\t// cidVersion(v: 0 | 1): UploadBuilder<T> {\n\t// \tthis.version = v;\n\t// \treturn this;\n\t// }\n\n\tgroup(groupId: string): UploadBuilder<T> {\n\t\tthis.groupId = groupId;\n\t\treturn this;\n\t}\n\n\tthen<TResult1 = T, TResult2 = never>(\n\t\tonfulfilled?:\n\t\t\t| ((value: T) => TResult1 | PromiseLike<TResult1>)\n\t\t\t| null\n\t\t\t| undefined,\n\t\tonrejected?:\n\t\t\t| ((reason: any) => TResult2 | PromiseLike<TResult2>)\n\t\t\t| null\n\t\t\t| undefined,\n\t): Promise<TResult1 | TResult2> {\n\t\tconst options: UploadOptions = this.args[this.args.length - 1] || {};\n\t\tif (this.metadata) {\n\t\t\toptions.metadata = this.metadata;\n\t\t}\n\t\tif (this.keys) {\n\t\t\toptions.keys = this.keys;\n\t\t}\n\t\tif (this.groupId) {\n\t\t\toptions.groupId = this.groupId;\n\t\t}\n\t\tthis.args[this.args.length - 1] = options;\n\t\treturn this.uploadFunction(this.config, ...this.args).then(\n\t\t\tonfulfilled,\n\t\t\tonrejected,\n\t\t);\n\t}\n}\n\nclass Upload {\n\tconfig: PinataConfig | undefined;\n\n\tconstructor(config?: PinataConfig) {\n\t\tthis.config = formatConfig(config);\n\t}\n\n\tupdateConfig(newConfig: PinataConfig): void {\n\t\tthis.config = newConfig;\n\t}\n\n\tfile(\n\t\tfile: FileObject,\n\t\toptions?: UploadOptions,\n\t): UploadBuilder<UploadResponse> {\n\t\treturn new UploadBuilder(this.config, uploadFile, file, options);\n\t}\n\n\t// fileArray(\n\t// \tfiles: FileObject[],\n\t// \toptions?: UploadOptions,\n\t// ): UploadBuilder<UploadResponse> {\n\t// \treturn new UploadBuilder(this.config, uploadFileArray, files, options);\n\t// }\n\n\tbase64(\n\t\tbase64String: string,\n\t\toptions?: UploadOptions,\n\t): UploadBuilder<UploadResponse> {\n\t\treturn new UploadBuilder(this.config, uploadBase64, base64String, options);\n\t}\n\n\turl(url: string, options?: UploadOptions): UploadBuilder<UploadResponse> {\n\t\treturn new UploadBuilder(this.config, uploadUrl, url, options);\n\t}\n\n\tjson(data: object, options?: UploadOptions): UploadBuilder<UploadResponse> {\n\t\treturn new UploadBuilder(this.config, uploadJson, data, options);\n\t}\n}\n\nclass FilterFiles {\n\tprivate config: PinataConfig | undefined;\n\tprivate query: FileListQuery = {};\n\tprivate currentPageToken: string | undefined;\n\t// rate limit vars\n\t// private requestCount = 0;\n\t// private lastRequestTime = 0;\n\t// private readonly MAX_REQUESTS_PER_MINUTE = 30;\n\t// private readonly MINUTE_IN_MS = 60000;\n\n\tconstructor(config: PinataConfig | undefined) {\n\t\tthis.config = config;\n\t}\n\n\tlimit(limit: number): FilterFiles {\n\t\tthis.query.limit = limit;\n\t\treturn this;\n\t}\n\n\tcidPending(cidPending: boolean): FilterFiles {\n\t\tthis.query.cidPending = cidPending;\n\t\treturn this;\n\t}\n\n\tpageToken(pageToken: string): FilterFiles {\n\t\tthis.query.pageToken = pageToken;\n\t\treturn this;\n\t}\n\n\tthen(onfulfilled?: ((value: FileListResponse) => any) | null): Promise<any> {\n\t\treturn this.fetchPage().then(onfulfilled);\n\t}\n\n\tprivate async fetchPage(): Promise<FileListResponse> {\n\t\tif (this.currentPageToken) {\n\t\t\tthis.query.pageToken = this.currentPageToken;\n\t\t}\n\t\tconst response = await listFiles(this.config, this.query);\n\t\tthis.currentPageToken = response.next_page_token;\n\t\treturn response;\n\t}\n\n\t// // rate limit, hopefully temporary?\n\t// private async rateLimit(): Promise<void> {\n\t// \tthis.requestCount++;\n\t// \tconst now = Date.now();\n\t// \tif (this.requestCount >= this.MAX_REQUESTS_PER_MINUTE) {\n\t// \t\tconst timePassedSinceLastRequest = now - this.lastRequestTime;\n\t// \t\tif (timePassedSinceLastRequest < this.MINUTE_IN_MS) {\n\t// \t\t\tconst delayTime = this.MINUTE_IN_MS - timePassedSinceLastRequest;\n\t// \t\t\tawait new Promise((resolve) => setTimeout(resolve, delayTime));\n\t// \t\t}\n\t// \t\tthis.requestCount = 0;\n\t// \t}\n\t// \tthis.lastRequestTime = Date.now();\n\t// }\n\n\tasync *[Symbol.asyncIterator](): AsyncGenerator<FileListItem, void, unknown> {\n\t\twhile (true) {\n\t\t\tconst items = await this.fetchPage();\n\t\t\tfor (const item of items.files) {\n\t\t\t\tyield item;\n\t\t\t}\n\t\t\tif (!this.currentPageToken) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync all(): Promise<FileListItem[]> {\n\t\tconst allItems: FileListItem[] = [];\n\t\tfor await (const item of this) {\n\t\t\tallItems.push(item);\n\t\t}\n\t\treturn allItems;\n\t}\n}\n\nclass Gateways {\n\tconfig: PinataConfig | undefined;\n\n\tconstructor(config?: PinataConfig) {\n\t\tthis.config = formatConfig(config);\n\t}\n\n\tupdateConfig(newConfig: PinataConfig): void {\n\t\tthis.config = newConfig;\n\t}\n\n\tget(cid: string): Promise<GetCIDResponse> {\n\t\treturn getCid(this.config, cid);\n\t}\n\n\tcreateSignedURL(options: SignedUrlOptions): Promise<string> {\n\t\treturn createSignedURL(this.config, options);\n\t}\n\n\t// get(cid: string): OptimizeImage {\n\t// \treturn new OptimizeImage(this.config, cid);\n\t// }\n\n\t// convert(url: string, gatewayPrefix?: string): Promise<string> {\n\t// \treturn convertIPFSUrl(this.config, url, gatewayPrefix);\n\t// }\n\n\t// containsCID(cid: string): Promise<ContainsCIDResponse> {\n\t// \treturn containsCID(cid);\n\t// }\n\n\t// topUsageAnalytics(options: {\n\t// \tdomain: string;\n\t// \tstart: string;\n\t// \tend: string;\n\t// \tsortBy: \"requests\" | \"bandwidth\";\n\t// \tattribute:\n\t// \t\t| \"cid\"\n\t// \t\t| \"country\"\n\t// \t\t| \"region\"\n\t// \t\t| \"user_agent\"\n\t// \t\t| \"referer\"\n\t// \t\t| \"file_name\";\n\t// }): TopGatewayAnalyticsBuilder {\n\t// \treturn new TopGatewayAnalyticsBuilder(\n\t// \t\tthis.config,\n\t// \t\toptions.domain,\n\t// \t\toptions.start,\n\t// \t\toptions.end,\n\t// \t\toptions.sortBy,\n\t// \t\toptions.attribute,\n\t// \t);\n\t// }\n\n\t// dateIntervalAnalytics(options: {\n\t// \tdomain: string;\n\t// \tstart: string;\n\t// \tend: string;\n\t// \tinterval: \"day\" | \"week\";\n\t// }): TimeIntervalGatewayAnalyticsBuilder {\n\t// \treturn new TimeIntervalGatewayAnalyticsBuilder(\n\t// \t\tthis.config,\n\t// \t\toptions.domain,\n\t// \t\toptions.start,\n\t// \t\toptions.end,\n\t// \t\toptions.interval,\n\t// \t);\n\t// }\n\n\t// swapCid(options: SwapCidOptions): Promise<SwapCidResponse> {\n\t// \treturn swapCid(this.config, options);\n\t// }\n\n\t// swapHistory(options: SwapHistoryOptions): Promise<SwapCidResponse[]> {\n\t// \treturn swapHistory(this.config, options);\n\t// }\n\n\t// deleteSwap(cid: string): Promise<string> {\n\t// \treturn deleteSwap(this.config, cid);\n\t// }\n}\n\n// class OptimizeImage {\n// \tprivate config: PinataConfig | undefined;\n// \tprivate cid: string;\n// \tprivate options: OptimizeImageOptions = {};\n\n// \tconstructor(config: PinataConfig | undefined, cid: string) {\n// \t\tthis.config = config;\n// \t\tthis.cid = cid;\n// \t}\n\n// \toptimizeImage(options: OptimizeImageOptions): OptimizeImage {\n// \t\tthis.options = { ...this.options, ...options };\n// \t\treturn this;\n// \t}\n\n// \tthen(onfulfilled?: ((value: GetCIDResponse) => any) | null): Promise<any> {\n// \t\treturn getCid(this.config, this.cid, this.options).then(onfulfilled);\n// \t}\n// }\n\n// class Usage {\n// \tconfig: PinataConfig | undefined;\n\n// \tconstructor(config?: PinataConfig) {\n// \t\tthis.config = formatConfig(config);\n// \t}\n\n// \tupdateConfig(newConfig: PinataConfig): void {\n// \t\tthis.config = newConfig;\n// \t}\n\n// \tpinnedFileCount(): Promise<number> {\n// \t\treturn pinnedFileCount(this.config);\n// \t}\n\n// \ttotalStorageSize(): Promise<number> {\n// \t\treturn totalStorageUsage(this.config);\n// \t}\n// }\n\nclass Keys {\n\tconfig: PinataConfig | undefined;\n\n\tconstructor(config?: PinataConfig) {\n\t\tthis.config = formatConfig(config);\n\t}\n\n\tupdateConfig(newConfig: PinataConfig): void {\n\t\tthis.config = newConfig;\n\t}\n\n\tcreate(options: KeyOptions): Promise<KeyResponse> {\n\t\treturn createKey(this.config, options);\n\t}\n\n\tlist(): FilterKeys {\n\t\treturn new FilterKeys(this.config);\n\t}\n\n\trevoke(keys: string[]): Promise<RevokeKeyResponse[]> {\n\t\treturn revokeKeys(this.config, keys);\n\t}\n}\n\nclass FilterKeys {\n\tprivate config: PinataConfig | undefined;\n\tprivate query: KeyListQuery = {};\n\t// rate limit vars\n\t// private requestCount = 0;\n\t// private lastRequestTime = 0;\n\t// private readonly MAX_REQUESTS_PER_MINUTE = 30;\n\t// private readonly MINUTE_IN_MS = 60000;\n\n\tconstructor(config: PinataConfig | undefined) {\n\t\tthis.config = config;\n\t}\n\n\toffset(offset: number): FilterKeys {\n\t\tthis.query.offset = offset;\n\t\treturn this;\n\t}\n\n\trevoked(revoked: boolean): FilterKeys {\n\t\tthis.query.revoked = revoked;\n\t\treturn this;\n\t}\n\n\tlimitedUse(limitedUse: boolean): FilterKeys {\n\t\tthis.query.limitedUse = limitedUse;\n\t\treturn this;\n\t}\n\n\texhausted(exhausted: boolean): FilterKeys {\n\t\tthis.query.exhausted = exhausted;\n\t\treturn this;\n\t}\n\n\tname(name: string): FilterKeys {\n\t\tthis.query.name = name;\n\t\treturn this;\n\t}\n\n\tthen(onfulfilled?: ((value: KeyListItem[]) => any) | null): Promise<any> {\n\t\treturn listKeys(this.config, this.query).then(onfulfilled);\n\t}\n\n\t// private async rateLimit(): Promise<void> {\n\t// \tthis.requestCount++;\n\t// \tconst now = Date.now();\n\t// \tif (this.requestCount >= this.MAX_REQUESTS_PER_MINUTE) {\n\t// \t\tconst timePassedSinceLastRequest = now - this.lastRequestTime;\n\t// \t\tif (timePassedSinceLastRequest < this.MINUTE_IN_MS) {\n\t// \t\t\tconst delayTime = this.MINUTE_IN_MS - timePassedSinceLastRequest;\n\t// \t\t\tawait new Promise((resolve) => setTimeout(resolve, delayTime));\n\t// \t\t}\n\t// \t\tthis.requestCount = 0;\n\t// \t}\n\t// \tthis.lastRequestTime = Date.now();\n\t// }\n\n\tasync *[Symbol.asyncIterator](): AsyncGenerator<KeyListItem, void, unknown> {\n\t\tlet hasMore = true;\n\t\tlet offset = 0;\n\n\t\twhile (hasMore) {\n\t\t\t//await this.rateLimit(); // applying rate limit\n\t\t\tthis.query.offset = offset;\n\n\t\t\tconst items = await listKeys(this.config, this.query);\n\n\t\t\tfor (const item of items) {\n\t\t\t\tyield item;\n\t\t\t}\n\n\t\t\tif (items.length === 0) {\n\t\t\t\thasMore = false;\n\t\t\t} else {\n\t\t\t\toffset += items.length;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync all(): Promise<KeyListItem[]> {\n\t\tconst allItems: KeyListItem[] = [];\n\t\tfor await (const item of this) {\n\t\t\tallItems.push(item);\n\t\t}\n\t\treturn allItems;\n\t}\n}\n\nclass Groups {\n\tconfig: PinataConfig | undefined;\n\n\tconstructor(config?: PinataConfig) {\n\t\tthis.config = formatConfig(config);\n\t}\n\n\tupdateConfig(newConfig: PinataConfig): void {\n\t\tthis.config = newConfig;\n\t}\n\n\tcreate(options: GroupOptions): Promise<GroupResponseItem> {\n\t\treturn createGroup(this.config, options);\n\t}\n\n\tlist(): FilterGroups {\n\t\treturn new FilterGroups(this.config);\n\t}\n\n\tget(options: GetGroupOptions): Promise<GroupResponseItem> {\n\t\treturn getGroup(this.config, options);\n\t}\n\n\t// addFiles(options: GroupCIDOptions): Promise<string> {\n\t// \treturn addToGroup(this.config, options);\n\t// }\n\n\t// removeFiles(options: GroupCIDOptions): Promise<string> {\n\t// \treturn removeFromGroup(this.config, options);\n\t// }\n\n\tupdate(options: UpdateGroupOptions): Promise<GroupResponseItem> {\n\t\treturn updateGroup(this.config, options);\n\t}\n\n\tdelete(options: GetGroupOptions): Promise<string> {\n\t\treturn deleteGroup(this.config, options);\n\t}\n}\n\nclass FilterGroups {\n\tprivate config: PinataConfig | undefined;\n\tprivate query: GroupQueryOptions = {};\n\t// rate limit vars\n\t// private requestCount = 0;\n\t// private lastRequestTime = 0;\n\t// private readonly MAX_REQUESTS_PER_MINUTE = 30;\n\t// private readonly MINUTE_IN_MS = 60000;\n\tprivate nextPageToken: string | undefined;\n\n\tconstructor(config: PinataConfig | undefined) {\n\t\tthis.config = config;\n\t}\n\n\t// name(nameContains: string): FilterGroups {\n\t// \tthis.query.nameContains = nameContains;\n\t// \treturn this;\n\t// }\n\n\tlimit(limit: number): FilterGroups {\n\t\tthis.query.limit = limit;\n\t\treturn this;\n\t}\n\n\tisPublic(isPublic: boolean): FilterGroups {\n\t\tthis.query.isPublic = isPublic;\n\t\treturn this;\n\t}\n\n\tpageToken(pageToken: string): FilterGroups {\n\t\tthis.query.pageToken = pageToken;\n\t\treturn this;\n\t}\n\n\tthen(\n\t\tonfulfilled?: ((value: GroupListResponse) => any) | null,\n\t): Promise<GroupListResponse> {\n\t\treturn this.fetchPage()\n\t\t\t.then((response) => {\n\t\t\t\tthis.nextPageToken = response.next_page_token;\n\t\t\t\treturn response;\n\t\t\t})\n\t\t\t.then(onfulfilled);\n\t}\n\n\tprivate async fetchPage(): Promise<GroupListResponse> {\n\t\tif (this.nextPageToken) {\n\t\t\tthis.query.pageToken = this.nextPageToken;\n\t\t}\n\t\treturn listGroups(this.config, this.query);\n\t}\n\n\t// rate limit, hopefully temporary?\n\t// private async rateLimit(): Promise<void> {\n\t// \tthis.requestCount++;\n\t// \tconst now = Date.now();\n\t// \tif (this.requestCount >= this.MAX_REQUESTS_PER_MINUTE) {\n\t// \t\tconst timePassedSinceLastRequest = now - this.lastRequestTime;\n\t// \t\tif (timePassedSinceLastRequest < this.MINUTE_IN_MS) {\n\t// \t\t\tconst delayTime = this.MINUTE_IN_MS - timePassedSinceLastRequest;\n\t// \t\t\tawait new Promise((resolve) => setTimeout(resolve, delayTime));\n\t// \t\t}\n\t// \t\tthis.requestCount = 0;\n\t// \t}\n\t// \tthis.lastRequestTime = Date.now();\n\t// }\n\n\tasync *[Symbol.asyncIterator](): AsyncGenerator<\n\t\tGroupResponseItem,\n\t\tvoid,\n\t\tunknown\n\t> {\n\t\twhile (true) {\n\t\t\tconst response = await this.fetchPage();\n\t\t\tfor (const item of response.groups) {\n\t\t\t\tyield item;\n\t\t\t}\n\t\t\tif (!response.next_page_token) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tthis.nextPageToken = response.next_page_token;\n\t\t}\n\t}\n\n\tasync all(): Promise<GroupResponseItem[]> {\n\t\tconst allItems: GroupResponseItem[] = [];\n\t\tfor await (const item of this) {\n\t\t\tallItems.push(item);\n\t\t}\n\t\treturn allItems;\n\t}\n}\n\n// class Signatures {\n// \tconfig: PinataConfig | undefined;\n\n// \tconstructor(config?: PinataConfig) {\n// \t\tthis.config = formatConfig(config);\n// \t}\n\n// \tupdateConfig(newConfig: PinataConfig): void {\n// \t\tthis.config = newConfig;\n// \t}\n\n// \tadd(options: SignatureOptions): Promise<SignatureResponse> {\n// \t\treturn addSignature(this.config, options);\n// \t}\n\n// \tget(cid: string): Promise<SignatureResponse> {\n// \t\treturn getSignature(this.config, cid);\n// \t}\n\n// \tdelete(cid: string): Promise<string> {\n// \t\treturn removeSignature(this.config, cid);\n// \t}\n// }\n\n// class GatewayAnalyticsBuilder<T extends GatewayAnalyticsQuery, R> {\n// \tprotected config: PinataConfig | undefined;\n// \tprotected query: T;\n// \tprivate requestCount = 0;\n// \tprivate lastRequestTime = 0;\n// \tprivate readonly MAX_REQUESTS_PER_MINUTE = 30;\n// \tprivate readonly MINUTE_IN_MS = 60000;\n\n// \tconstructor(config: PinataConfig | undefined, query: T) {\n// \t\tthis.config = config;\n// \t\tthis.query = query;\n// \t}\n\n// \tcid(cid: string): this {\n// \t\tthis.query.cid = cid;\n// \t\treturn this;\n// \t}\n\n// \tfileName(fileName: string): this {\n// \t\tthis.query.file_name = fileName;\n// \t\treturn this;\n// \t}\n\n// \tuserAgent(userAgent: string): this {\n// \t\tthis.query.user_agent = userAgent;\n// \t\treturn this;\n// \t}\n\n// \tcountry(country: string): this {\n// \t\tthis.query.country = country;\n// \t\treturn this;\n// \t}\n\n// \tregion(region: string): this {\n// \t\tthis.query.region = region;\n// \t\treturn this;\n// \t}\n\n// \treferer(referer: string): this {\n// \t\tthis.query.referer = referer;\n// \t\treturn this;\n// \t}\n\n// \tlimit(limit: number): this {\n// \t\tthis.query.limit = limit;\n// \t\treturn this;\n// \t}\n\n// \tsort(order: \"asc\" | \"desc\"): this {\n// \t\tthis.query.sort_order = order;\n// \t\treturn this;\n// \t}\n\n// \tprivate async rateLimit(): Promise<void> {\n// \t\tthis.requestCount++;\n// \t\tconst now = Date.now();\n// \t\tif (this.requestCount >= this.MAX_REQUESTS_PER_MINUTE) {\n// \t\t\tconst timePassedSinceLastRequest = now - this.lastRequestTime;\n// \t\t\tif (timePassedSinceLastRequest < this.MINUTE_IN_MS) {\n// \t\t\t\tconst delayTime = this.MINUTE_IN_MS - timePassedSinceLastRequest;\n// \t\t\t\tawait new Promise((resolve) => setTimeout(resolve, delayTime));\n// \t\t\t}\n// \t\t\tthis.requestCount = 0;\n// \t\t}\n// \t\tthis.lastRequestTime = Date.now();\n// \t}\n\n// \tprotected async getAnalytics(): Promise<R> {\n// \t\tawait this.rateLimit();\n// \t\tthrow new Error(\"getAnalytics method must be implemented in derived class\");\n// \t}\n\n// \tthen(onfulfilled?: ((value: R) => any) | null): Promise<any> {\n// \t\treturn this.getAnalytics().then(onfulfilled);\n// \t}\n// }\n\n// class TopGatewayAnalyticsBuilder extends GatewayAnalyticsBuilder<\n// \tTopGatewayAnalyticsQuery,\n// \tTopGatewayAnalyticsItem[]\n// > {\n// \tconstructor(\n// \t\tconfig: PinataConfig | undefined,\n// \t\tdomain: string,\n// \t\tstart: string,\n// \t\tend: string,\n// \t\tsortBy: \"requests\" | \"bandwidth\",\n// \t\tattribute:\n// \t\t\t| \"cid\"\n// \t\t\t| \"country\"\n// \t\t\t| \"region\"\n// \t\t\t| \"user_agent\"\n// \t\t\t| \"referer\"\n// \t\t\t| \"file_name\",\n// \t) {\n// \t\tsuper(config, {\n// \t\t\tgateway_domain: domain,\n// \t\t\tstart_date: start,\n// \t\t\tend_date: end,\n// \t\t\tsort_by: sortBy,\n// \t\t\tattribute: attribute,\n// \t\t});\n// \t}\n\n// \tprotected async getAnalytics(): Promise<TopGatewayAnalyticsItem[]> {\n// \t\treturn analyticsTopUsage(this.config, this.query);\n// \t}\n\n// \tasync all(): Promise<TopGatewayAnalyticsItem[]> {\n// \t\treturn this.getAnalytics();\n// \t}\n// }\n\n// class TimeIntervalGatewayAnalyticsBuilder extends GatewayAnalyticsBuilder<\n// \tTimeIntervalGatewayAnalyticsQuery,\n// \tTimeIntervalGatewayAnalyticsResponse\n// > {\n// \tconstructor(\n// \t\tconfig: PinataConfig | undefined,\n// \t\tdomain: string,\n// \t\tstart: string,\n// \t\tend: string,\n// \t\tdateInterval: \"day\" | \"week\",\n// \t) {\n// \t\tsuper(config, {\n// \t\t\tgateway_domain: domain,\n// \t\t\tstart_date: start,\n// \t\t\tend_date: end,\n// \t\t\tdate_interval: dateInterval,\n// \t\t});\n// \t}\n\n// \tsortBy(sortBy: \"requests\" | \"bandwidth\"): this {\n// \t\tthis.query.sort_by = sortBy;\n// \t\treturn this;\n// \t}\n\n// \tprotected async getAnalytics(): Promise<TimeIntervalGatewayAnalyticsResponse> {\n// \t\treturn analyticsDateInterval(this.config, this.query);\n// \t}\n\n// \tasync all(): Promise<TimeIntervalGatewayAnalyticsResponse> {\n// \t\treturn this.getAnalytics();\n// \t}\n// }\n"],"mappings":"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","names":["wait"]}