@nhost/nhost-js 4.2.1-rc2 → 4.2.2
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/{fetch-2PHmQBIJ.mjs → fetch-2PHmQBIJ.js} +1 -1
- package/dist/{fetch-DWXwEnoe.js.map → fetch-2PHmQBIJ.js.map} +1 -1
- package/dist/{fetch-DWXwEnoe.js → fetch-DWXwEnoe.cjs} +1 -1
- package/dist/{fetch-2PHmQBIJ.mjs.map → fetch-DWXwEnoe.cjs.map} +1 -1
- package/dist/middlewareWithAdminSession-DDApoLkL.cjs +2 -0
- package/dist/{middlewareWithAdminSession-w7fkl0J9.mjs.map → middlewareWithAdminSession-DDApoLkL.cjs.map} +1 -1
- package/dist/{middlewareWithAdminSession-w7fkl0J9.mjs → middlewareWithAdminSession-DLqDQUbW.js} +2 -2
- package/dist/{middlewareWithAdminSession-BtFo6WUj.js.map → middlewareWithAdminSession-DLqDQUbW.js.map} +1 -1
- package/dist/nhost-js/auth.cjs +2 -0
- package/dist/nhost-js/auth.cjs.map +1 -0
- package/dist/nhost-js/{auth.es.js → auth.js} +2 -2
- package/dist/nhost-js/auth.js.map +1 -0
- package/dist/nhost-js/fetch.cjs +2 -0
- package/dist/nhost-js/fetch.cjs.map +1 -0
- package/dist/nhost-js/{fetch.es.js → fetch.js} +3 -3
- package/dist/nhost-js/fetch.js.map +1 -0
- package/dist/nhost-js/functions.cjs +2 -0
- package/dist/nhost-js/functions.cjs.map +1 -0
- package/dist/nhost-js/{functions.es.js → functions.js} +2 -2
- package/dist/nhost-js/functions.js.map +1 -0
- package/dist/nhost-js/graphql.cjs +2 -0
- package/dist/nhost-js/graphql.cjs.map +1 -0
- package/dist/nhost-js/{graphql.es.js → graphql.js} +2 -2
- package/dist/nhost-js/graphql.js.map +1 -0
- package/dist/nhost-js/session.cjs +2 -0
- package/dist/nhost-js/session.cjs.map +1 -0
- package/dist/nhost-js/{session.es.js → session.js} +2 -2
- package/dist/nhost-js/session.js.map +1 -0
- package/dist/nhost-js/storage.cjs +2 -0
- package/dist/nhost-js/storage.cjs.map +1 -0
- package/dist/nhost-js/{storage.es.js → storage.js} +2 -2
- package/dist/nhost-js/storage.js.map +1 -0
- package/dist/nhost-js.cjs +2 -0
- package/dist/nhost-js.cjs.map +1 -0
- package/dist/{nhost-js.es.js → nhost-js.js} +8 -8
- package/dist/nhost-js.js.map +1 -0
- package/dist/{refreshSession-Bw715ZmX.js → refreshSession-Bw715ZmX.cjs} +1 -1
- package/dist/{refreshSession-CG8GIEun.mjs.map → refreshSession-Bw715ZmX.cjs.map} +1 -1
- package/dist/{refreshSession-CG8GIEun.mjs → refreshSession-CG8GIEun.js} +1 -1
- package/dist/{refreshSession-Bw715ZmX.js.map → refreshSession-CG8GIEun.js.map} +1 -1
- package/package.json +18 -17
- package/dist/middlewareWithAdminSession-BtFo6WUj.js +0 -2
- package/dist/nhost-js/auth.cjs.js +0 -2
- package/dist/nhost-js/auth.cjs.js.map +0 -1
- package/dist/nhost-js/auth.es.js.map +0 -1
- package/dist/nhost-js/fetch.cjs.js +0 -2
- package/dist/nhost-js/fetch.cjs.js.map +0 -1
- package/dist/nhost-js/fetch.es.js.map +0 -1
- package/dist/nhost-js/functions.cjs.js +0 -2
- package/dist/nhost-js/functions.cjs.js.map +0 -1
- package/dist/nhost-js/functions.es.js.map +0 -1
- package/dist/nhost-js/graphql.cjs.js +0 -2
- package/dist/nhost-js/graphql.cjs.js.map +0 -1
- package/dist/nhost-js/graphql.es.js.map +0 -1
- package/dist/nhost-js/session.cjs.js +0 -2
- package/dist/nhost-js/session.cjs.js.map +0 -1
- package/dist/nhost-js/session.es.js.map +0 -1
- package/dist/nhost-js/storage.cjs.js +0 -2
- package/dist/nhost-js/storage.cjs.js.map +0 -1
- package/dist/nhost-js/storage.es.js.map +0 -1
- package/dist/nhost-js.cjs.js +0 -2
- package/dist/nhost-js.cjs.js.map +0 -1
- package/dist/nhost-js.es.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sources":["../../src/session/session.ts","../../src/session/storageBackend.ts","../../src/session/storage.ts"],"sourcesContent":["import type { Session as AuthSession } from \"../auth\";\n\n/**\n * Decoded JWT token payload with processed timestamps and Hasura claims\n */\nexport interface DecodedToken {\n /** Token expiration time as Date object */\n exp?: number;\n /** Token issued at time as Date object */\n iat?: number;\n /** Token issuer */\n iss?: string;\n /** Token subject (user ID) */\n sub?: string;\n /** Hasura JWT claims with PostgreSQL arrays converted to JavaScript arrays */\n \"https://hasura.io/jwt/claims\"?: Record<string, unknown>;\n /** Any other JWT claims */\n [key: string]: unknown;\n}\n\nexport interface Session extends AuthSession {\n /** Decoded JWT token payload with processed timestamps and Hasura claims */\n decodedToken: DecodedToken;\n}\n\nexport const decodeUserSession = (accessToken: string): DecodedToken => {\n const s = accessToken.split(\".\");\n if (s.length !== 3 || !s[1]) {\n throw new Error(\"Invalid access token format\");\n }\n\n const decodedToken = JSON.parse(\n typeof atob !== \"undefined\"\n ? atob(s[1])\n : Buffer.from(s[1], \"base64\").toString(\"utf-8\"),\n ) as Record<string, unknown>;\n\n // Convert iat and exp to Date objects\n const iat =\n typeof decodedToken[\"iat\"] === \"number\"\n ? decodedToken[\"iat\"] * 1000 // Convert seconds to milliseconds\n : undefined;\n const exp =\n typeof decodedToken[\"exp\"] === \"number\"\n ? decodedToken[\"exp\"] * 1000 // Convert seconds to milliseconds\n : undefined;\n\n // Process Hasura claims - dynamically convert PostgreSQL array notation to arrays\n const hasuraClaims = decodedToken[\"https://hasura.io/jwt/claims\"] as\n | Record<string, unknown>\n | undefined;\n const processedClaims = hasuraClaims\n ? Object.entries(hasuraClaims).reduce(\n (acc, [key, value]) => {\n if (typeof value === \"string\" && isPostgresArray(value)) {\n acc[key] = parsePostgresArray(value);\n } else {\n acc[key] = value;\n }\n return acc;\n },\n {} as Record<string, unknown>,\n )\n : undefined;\n\n return {\n ...decodedToken,\n iat,\n exp,\n \"https://hasura.io/jwt/claims\": processedClaims,\n };\n};\n\nconst isPostgresArray = (value: string): boolean => {\n return value.startsWith(\"{\") && value.endsWith(\"}\");\n};\n\nconst parsePostgresArray = (value: string): string[] => {\n if (!value || value === \"{}\") return [];\n // Remove curly braces and split by comma, handling quoted values\n return value\n .slice(1, -1)\n .split(\",\")\n .map((item) => item.trim().replace(/^\"(.*)\"$/, \"$1\"));\n};\n","/**\n * Storage implementations for session persistence in different environments.\n *\n * This module provides different storage adapters for persisting authentication sessions\n * across page reloads and browser sessions.\n */\n\nimport type { Session } from \"./session\";\n\n/**\n * Session storage interface for session persistence.\n * This interface can be implemented to provide custom storage solutions.\n */\nexport interface SessionStorageBackend {\n /**\n * Get the current session from storage\n * @returns The stored session or null if not found\n */\n get(): Session | null;\n\n /**\n * Set the session in storage\n * @param value - The session to store\n */\n set(value: Session): void;\n\n /**\n * Remove the session from storage\n */\n remove(): void;\n}\n\n/**\n * Default storage key used for storing the Nhost session\n */\nexport const DEFAULT_SESSION_KEY = \"nhostSession\";\n\n/**\n * Browser localStorage implementation of StorageInterface.\n * Persists the session across page reloads and browser restarts.\n */\nexport class LocalStorage implements SessionStorageBackend {\n private readonly storageKey: string;\n\n /**\n * Creates a new LocalStorage instance\n * @param options - Configuration options\n * @param options.storageKey - The key to use in localStorage (defaults to \"nhostSession\")\n */\n constructor(options?: { storageKey?: string }) {\n this.storageKey = options?.storageKey || DEFAULT_SESSION_KEY;\n }\n\n /**\n * Gets the session from localStorage\n * @returns The stored session or null if not found\n */\n get(): Session | null {\n try {\n const value = window.localStorage.getItem(this.storageKey);\n return value ? (JSON.parse(value) as Session) : null;\n } catch {\n this.remove();\n return null;\n }\n }\n\n /**\n * Sets the session in localStorage\n * @param value - The session to store\n */\n set(value: Session): void {\n window.localStorage.setItem(this.storageKey, JSON.stringify(value));\n }\n\n /**\n * Removes the session from localStorage\n */\n remove(): void {\n window.localStorage.removeItem(this.storageKey);\n }\n}\n\n/**\n * In-memory storage implementation for non-browser environments or when\n * persistent storage is not available or desirable.\n */\nexport class MemoryStorage implements SessionStorageBackend {\n private session: Session | null = null;\n\n /**\n * Gets the session from memory\n * @returns The stored session or null if not set\n */\n get(): Session | null {\n return this.session;\n }\n\n /**\n * Sets the session in memory\n * @param value - The session to store\n */\n set(value: Session): void {\n this.session = value;\n }\n\n /**\n * Clears the session from memory\n */\n remove(): void {\n this.session = null;\n }\n}\n\n/**\n * Cookie-based storage implementation.\n * This storage uses web browser cookies to store the session so it's not\n * available in server-side environments. It is useful though for synchronizing\n * sessions between client and server environments.\n */\nexport class CookieStorage implements SessionStorageBackend {\n private readonly cookieName: string;\n private readonly expirationDays: number;\n private readonly secure: boolean;\n private readonly sameSite: \"strict\" | \"lax\" | \"none\";\n\n /**\n * Creates a new CookieStorage instance\n * @param options - Configuration options\n * @param options.cookieName - Name of the cookie to use (defaults to \"nhostSession\")\n * @param options.expirationDays - Number of days until the cookie expires (defaults to 30)\n * @param options.secure - Whether to set the Secure flag on the cookie (defaults to true)\n * @param options.sameSite - SameSite policy for the cookie (defaults to \"lax\")\n */\n constructor(options?: {\n cookieName?: string;\n expirationDays?: number;\n secure?: boolean;\n sameSite?: \"strict\" | \"lax\" | \"none\";\n }) {\n this.cookieName = options?.cookieName || DEFAULT_SESSION_KEY;\n this.expirationDays = options?.expirationDays ?? 30;\n this.secure = options?.secure ?? true;\n this.sameSite = options?.sameSite || \"lax\";\n }\n\n /**\n * Gets the session from cookies\n * @returns The stored session or null if not found\n */\n get(): Session | null {\n const cookies = document.cookie.split(\";\");\n for (const cookie of cookies) {\n const [name, value] = cookie.trim().split(\"=\");\n if (name === this.cookieName) {\n try {\n return JSON.parse(decodeURIComponent(value || \"\")) as Session;\n } catch {\n this.remove();\n return null;\n }\n }\n }\n return null;\n }\n\n /**\n * Sets the session in a cookie\n * @param value - The session to store\n */\n set(value: Session): void {\n const expires = new Date();\n expires.setTime(\n expires.getTime() + this.expirationDays * 24 * 60 * 60 * 1000,\n );\n\n const cookieValue = encodeURIComponent(JSON.stringify(value));\n const cookieString = `${this.cookieName}=${cookieValue}; expires=${expires.toUTCString()}; path=/; ${this.secure ? \"secure; \" : \"\"}SameSite=${this.sameSite}`;\n\n // biome-ignore lint/suspicious/noDocumentCookie: this is unnecessary\n document.cookie = cookieString;\n }\n\n /**\n * Removes the session cookie\n */\n remove(): void {\n // biome-ignore lint/suspicious/noDocumentCookie: this is unnecessary\n document.cookie = `${this.cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; ${this.secure ? \"secure; \" : \"\"}SameSite=${this.sameSite}`;\n }\n}\n","/**\n * Storage implementations for session persistence in different environments.\n *\n * This module provides different storage adapters for persisting authentication sessions\n * across page reloads and browser sessions.\n */\n\nimport type { Session as AuthSession } from \"../auth\";\nimport { decodeUserSession, type Session } from \"./session\";\nimport {\n LocalStorage,\n MemoryStorage,\n type SessionStorageBackend,\n} from \"./storageBackend\";\n\n/**\n * Callback function type for session change subscriptions\n */\nexport type SessionChangeCallback = (session: Session | null) => void;\n\n/**\n * A wrapper around any SessionStorageInterface implementation that adds\n * the ability to subscribe to session changes.\n */\nexport class SessionStorage {\n private readonly storage: SessionStorageBackend;\n private subscribers = new Set<SessionChangeCallback>();\n\n /**\n * Creates a new SessionStorage instance\n * @param storage - The underlying storage implementation to use\n */\n constructor(storage: SessionStorageBackend) {\n this.storage = storage;\n }\n\n /**\n * Gets the session from the underlying storage\n * @returns The stored session or null if not found\n */\n get(): Session | null {\n return this.storage.get();\n }\n\n /**\n * Sets the session in the underlying storage and notifies subscribers\n * @param value - The session to store\n */\n set(value: AuthSession): void {\n const decodedToken = decodeUserSession(value.accessToken);\n const decodedSession = {\n ...value,\n decodedToken: decodedToken,\n };\n\n this.storage.set(decodedSession);\n this.notifySubscribers(decodedSession);\n }\n\n /**\n * Removes the session from the underlying storage and notifies subscribers\n */\n remove(): void {\n this.storage.remove();\n this.notifySubscribers(null);\n }\n\n /**\n * Subscribe to session changes\n * @param callback - Function that will be called when the session changes\n * @returns An unsubscribe function to remove this subscription\n */\n onChange(callback: SessionChangeCallback) {\n this.subscribers.add(callback);\n\n return () => {\n this.subscribers.delete(callback);\n };\n }\n\n /**\n * Notify all subscribers of a session change\n * @param session - The new session value or null if removed\n */\n private notifySubscribers(session: Session | null): void {\n for (const subscriber of this.subscribers) {\n try {\n subscriber(session);\n } catch (error) {\n console.error(\"Error notifying subscriber:\", error);\n }\n }\n }\n}\n\n/**\n * Detects the best available storage implementation for the current environment.\n *\n * The detection process follows this order:\n * 1. Try to use localStorage if we're in a browser environment\n * 2. Fall back to in-memory storage if localStorage isn't available\n *\n * @returns The best available storage implementation as a SessionStorageBackend\n */\nexport const detectStorage = (): SessionStorageBackend => {\n if (typeof window !== \"undefined\") {\n return new LocalStorage();\n }\n return new MemoryStorage();\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("../fetch-DWXwEnoe.cjs");exports.createAPIClient=(e,s=[])=>{let a=t.createEnhancedFetch(s);return{baseURL:e,pushChainFunction:e=>{s.push(e),a=t.createEnhancedFetch(s)},uploadFiles:async(s,r)=>{const n=`${e}/files`,d=new FormData,i="undefined"!=typeof navigator&&"ReactNative"===navigator.product;void 0!==s["bucket-id"]&&d.append("bucket-id",s["bucket-id"]),void 0!==s["metadata[]"]&&s["metadata[]"].forEach((t=>{i?d.append("metadata[]",{string:JSON.stringify(t),type:"application/json",name:""}):d.append("metadata[]",new Blob([JSON.stringify(t)],{type:"application/json"}),"")})),void 0!==s["file[]"]&&s["file[]"].forEach((t=>{d.append("file[]",t)}));const o=await a(n,{...r,method:"POST",body:d});if(o.status>=300){const e=[412].includes(o.status)?null:await o.text(),s=e?JSON.parse(e):{};throw new t.FetchError(s,o.status,o.headers)}const u=[204,205,304].includes(o.status)?null:await o.text();return{body:u?JSON.parse(u):{},status:o.status,headers:o.headers}},deleteFile:async(s,r)=>{const n=`${e}/files/${s}`,d=await a(n,{...r,method:"DELETE",headers:{...r?.headers}});if(d.status>=300){const e=[412].includes(d.status)?null:await d.text(),s=e?JSON.parse(e):{};throw new t.FetchError(s,d.status,d.headers)}return{body:void 0,status:d.status,headers:d.headers}},getFile:async(s,r,n)=>{const d=r&&Object.entries(r).flatMap((([t,e])=>{const s=Array.isArray(e)?e.join(","):"object"==typeof e&&null!==e?JSON.stringify(e):String(e);return[`${t}=${encodeURIComponent(s)}`]})).join("&"),i=d?`${e}/files/${s}?${d}`:`${e}/files/${s}`,o=await a(i,{...n,method:"GET",headers:{...n?.headers}});if(o.status>=300){const e=[412].includes(o.status)?null:await o.text(),s=e?JSON.parse(e):{};throw new t.FetchError(s,o.status,o.headers)}return{body:await o.blob(),status:o.status,headers:o.headers}},getFileMetadataHeaders:async(s,r,n)=>{const d=r&&Object.entries(r).flatMap((([t,e])=>{const s=Array.isArray(e)?e.join(","):"object"==typeof e&&null!==e?JSON.stringify(e):String(e);return[`${t}=${encodeURIComponent(s)}`]})).join("&"),i=d?`${e}/files/${s}?${d}`:`${e}/files/${s}`,o=await a(i,{...n,method:"HEAD",headers:{...n?.headers}});if(o.status>=300){const e=[412].includes(o.status)?null:await o.text(),s=e?JSON.parse(e):{};throw new t.FetchError(s,o.status,o.headers)}return{body:void 0,status:o.status,headers:o.headers}},replaceFile:async(s,r,n)=>{const d=`${e}/files/${s}`,i=new FormData,o="undefined"!=typeof navigator&&"ReactNative"===navigator.product;void 0!==r.metadata&&(o?i.append("metadata",{string:JSON.stringify(r.metadata),type:"application/json",name:""}):i.append("metadata",new Blob([JSON.stringify(r.metadata)],{type:"application/json"}),"")),void 0!==r.file&&i.append("file",r.file);const u=await a(d,{...n,method:"PUT",body:i});if(u.status>=300){const e=[412].includes(u.status)?null:await u.text(),s=e?JSON.parse(e):{};throw new t.FetchError(s,u.status,u.headers)}const l=[204,205,304].includes(u.status)?null:await u.text();return{body:l?JSON.parse(l):{},status:u.status,headers:u.headers}},getFilePresignedURL:async(s,r)=>{const n=`${e}/files/${s}/presignedurl`,d=await a(n,{...r,method:"GET",headers:{...r?.headers}});if(d.status>=300){const e=[412].includes(d.status)?null:await d.text(),s=e?JSON.parse(e):{};throw new t.FetchError(s,d.status,d.headers)}const i=[204,205,304].includes(d.status)?null:await d.text();return{body:i?JSON.parse(i):{},status:d.status,headers:d.headers}},deleteBrokenMetadata:async s=>{const r=`${e}/ops/delete-broken-metadata`,n=await a(r,{...s,method:"POST",headers:{...s?.headers}});if(n.status>=300){const e=[412].includes(n.status)?null:await n.text(),s=e?JSON.parse(e):{};throw new t.FetchError(s,n.status,n.headers)}const d=[204,205,304].includes(n.status)?null:await n.text();return{body:d?JSON.parse(d):{},status:n.status,headers:n.headers}},deleteOrphanedFiles:async s=>{const r=`${e}/ops/delete-orphans`,n=await a(r,{...s,method:"POST",headers:{...s?.headers}});if(n.status>=300){const e=[412].includes(n.status)?null:await n.text(),s=e?JSON.parse(e):{};throw new t.FetchError(s,n.status,n.headers)}const d=[204,205,304].includes(n.status)?null:await n.text();return{body:d?JSON.parse(d):{},status:n.status,headers:n.headers}},listBrokenMetadata:async s=>{const r=`${e}/ops/list-broken-metadata`,n=await a(r,{...s,method:"POST",headers:{...s?.headers}});if(n.status>=300){const e=[412].includes(n.status)?null:await n.text(),s=e?JSON.parse(e):{};throw new t.FetchError(s,n.status,n.headers)}const d=[204,205,304].includes(n.status)?null:await n.text();return{body:d?JSON.parse(d):{},status:n.status,headers:n.headers}},listFilesNotUploaded:async s=>{const r=`${e}/ops/list-not-uploaded`,n=await a(r,{...s,method:"POST",headers:{...s?.headers}});if(n.status>=300){const e=[412].includes(n.status)?null:await n.text(),s=e?JSON.parse(e):{};throw new t.FetchError(s,n.status,n.headers)}const d=[204,205,304].includes(n.status)?null:await n.text();return{body:d?JSON.parse(d):{},status:n.status,headers:n.headers}},listOrphanedFiles:async s=>{const r=`${e}/ops/list-orphans`,n=await a(r,{...s,method:"POST",headers:{...s?.headers}});if(n.status>=300){const e=[412].includes(n.status)?null:await n.text(),s=e?JSON.parse(e):{};throw new t.FetchError(s,n.status,n.headers)}const d=[204,205,304].includes(n.status)?null:await n.text();return{body:d?JSON.parse(d):{},status:n.status,headers:n.headers}},getVersion:async s=>{const r=`${e}/version`,n=await a(r,{...s,method:"GET",headers:{...s?.headers}});if(n.status>=300){const e=[412].includes(n.status)?null:await n.text(),s=e?JSON.parse(e):{};throw new t.FetchError(s,n.status,n.headers)}const d=[204,205,304].includes(n.status)?null:await n.text();return{body:d?JSON.parse(d):{},status:n.status,headers:n.headers}}}};
|
|
2
|
+
//# sourceMappingURL=storage.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.cjs","sources":["../../src/storage/client.ts"],"sourcesContent":["/**\n * This file is auto-generated. Do not edit manually.\n */\n\nimport type { ChainFunction, FetchResponse } from \"../fetch\";\nimport { createEnhancedFetch, FetchError } from \"../fetch\";\n\n/**\n * Date in RFC 2822 format\n */\nexport type RFC2822Date = string;\n\n/**\n * Error details.\n @property message (`string`) - Human-readable error message.\n * Example - `\"File not found\"`\n @property data? (`Record<string, unknown>`) - Additional data related to the error, if any.*/\nexport interface ErrorResponseError {\n /**\n * Human-readable error message.\n * Example - `\"File not found\"`\n */\n message: string;\n /**\n * Additional data related to the error, if any.\n */\n data?: Record<string, unknown>;\n}\n\n/**\n * Error information returned by the API.\n @property error? (`ErrorResponseError`) - Error details.*/\nexport interface ErrorResponse {\n /**\n * Error details.\n */\n error?: ErrorResponseError;\n}\n\n/**\n * Error details.\n @property message (`string`) - Human-readable error message.\n * Example - `\"File not found\"`\n @property data? (`Record<string, unknown>`) - Additional data related to the error, if any.*/\nexport interface ErrorResponseWithProcessedFilesError {\n /**\n * Human-readable error message.\n * Example - `\"File not found\"`\n */\n message: string;\n /**\n * Additional data related to the error, if any.\n */\n data?: Record<string, unknown>;\n}\n\n/**\n * Error information returned by the API.\n @property processedFiles? (`FileMetadata[]`) - List of files that were successfully processed before the error occurred.\n @property error? (`ErrorResponseWithProcessedFilesError`) - Error details.*/\nexport interface ErrorResponseWithProcessedFiles {\n /**\n * List of files that were successfully processed before the error occurred.\n */\n processedFiles?: FileMetadata[];\n /**\n * Error details.\n */\n error?: ErrorResponseWithProcessedFilesError;\n}\n\n/**\n * Comprehensive metadata information about a file in storage.\n @property id (`string`) - Unique identifier for the file.\n * Example - `\"d5e76ceb-77a2-4153-b7da-1f7c115b2ff2\"`\n @property name (`string`) - Name of the file including extension.\n * Example - `\"profile-picture.jpg\"`\n @property size (`number`) - Size of the file in bytes.\n * Example - `245678`\n * Format - int64\n @property bucketId (`string`) - ID of the bucket containing the file.\n * Example - `\"users-bucket\"`\n @property etag (`string`) - Entity tag for cache validation.\n * Example - `\"\\\"a1b2c3d4e5f6\\\"\"`\n @property createdAt (`string`) - Timestamp when the file was created.\n * Example - `\"2023-01-15T12:34:56Z\"`\n * Format - date-time\n @property updatedAt (`string`) - Timestamp when the file was last updated.\n * Example - `\"2023-01-16T09:45:32Z\"`\n * Format - date-time\n @property isUploaded (`boolean`) - Whether the file has been successfully uploaded.\n * Example - `true`\n @property mimeType (`string`) - MIME type of the file.\n * Example - `\"image/jpeg\"`\n @property uploadedByUserId? (`string`) - ID of the user who uploaded the file.\n * Example - `\"abc123def456\"`\n @property metadata? (`Record<string, unknown>`) - Custom metadata associated with the file.\n * Example - `{\"alt\":\"Profile picture\",\"category\":\"avatar\"}`*/\nexport interface FileMetadata {\n /**\n * Unique identifier for the file.\n * Example - `\"d5e76ceb-77a2-4153-b7da-1f7c115b2ff2\"`\n */\n id: string;\n /**\n * Name of the file including extension.\n * Example - `\"profile-picture.jpg\"`\n */\n name: string;\n /**\n * Size of the file in bytes.\n * Example - `245678`\n * Format - int64\n */\n size: number;\n /**\n * ID of the bucket containing the file.\n * Example - `\"users-bucket\"`\n */\n bucketId: string;\n /**\n * Entity tag for cache validation.\n * Example - `\"\\\"a1b2c3d4e5f6\\\"\"`\n */\n etag: string;\n /**\n * Timestamp when the file was created.\n * Example - `\"2023-01-15T12:34:56Z\"`\n * Format - date-time\n */\n createdAt: string;\n /**\n * Timestamp when the file was last updated.\n * Example - `\"2023-01-16T09:45:32Z\"`\n * Format - date-time\n */\n updatedAt: string;\n /**\n * Whether the file has been successfully uploaded.\n * Example - `true`\n */\n isUploaded: boolean;\n /**\n * MIME type of the file.\n * Example - `\"image/jpeg\"`\n */\n mimeType: string;\n /**\n * ID of the user who uploaded the file.\n * Example - `\"abc123def456\"`\n */\n uploadedByUserId?: string;\n /**\n * Custom metadata associated with the file.\n * Example - `{\"alt\":\"Profile picture\",\"category\":\"avatar\"}`\n */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Basic information about a file in storage.\n @property id (`string`) - Unique identifier for the file.\n * Example - `\"d5e76ceb-77a2-4153-b7da-1f7c115b2ff2\"`\n @property name (`string`) - Name of the file including extension.\n * Example - `\"profile-picture.jpg\"`\n @property bucketId (`string`) - ID of the bucket containing the file.\n * Example - `\"users-bucket\"`\n @property isUploaded (`boolean`) - Whether the file has been successfully uploaded.\n * Example - `true`*/\nexport interface FileSummary {\n /**\n * Unique identifier for the file.\n * Example - `\"d5e76ceb-77a2-4153-b7da-1f7c115b2ff2\"`\n */\n id: string;\n /**\n * Name of the file including extension.\n * Example - `\"profile-picture.jpg\"`\n */\n name: string;\n /**\n * ID of the bucket containing the file.\n * Example - `\"users-bucket\"`\n */\n bucketId: string;\n /**\n * Whether the file has been successfully uploaded.\n * Example - `true`\n */\n isUploaded: boolean;\n}\n\n/**\n * Contains a presigned URL for direct file operations.\n @property url (`string`) - The presigned URL for file operations.\n * Example - `\"https://storage.example.com/files/abc123?signature=xyz\"`\n @property expiration (`number`) - The time in seconds until the URL expires.\n * Example - `3600`*/\nexport interface PresignedURLResponse {\n /**\n * The presigned URL for file operations.\n * Example - `\"https://storage.example.com/files/abc123?signature=xyz\"`\n */\n url: string;\n /**\n * The time in seconds until the URL expires.\n * Example - `3600`\n */\n expiration: number;\n}\n\n/**\n * Metadata that can be updated for an existing file.\n @property name? (`string`) - New name to assign to the file.\n * Example - `\"renamed-file.jpg\"`\n @property metadata? (`Record<string, unknown>`) - Updated custom metadata to associate with the file.\n * Example - `{\"alt\":\"Updated image description\",\"category\":\"profile\"}`*/\nexport interface UpdateFileMetadata {\n /**\n * New name to assign to the file.\n * Example - `\"renamed-file.jpg\"`\n */\n name?: string;\n /**\n * Updated custom metadata to associate with the file.\n * Example - `{\"alt\":\"Updated image description\",\"category\":\"profile\"}`\n */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Metadata provided when uploading a new file.\n @property id? (`string`) - Optional custom ID for the file. If not provided, a UUID will be generated.\n * Example - `\"custom-id-123\"`\n @property name? (`string`) - Name to assign to the file. If not provided, the original filename will be used.\n * Example - `\"custom-filename.png\"`\n @property metadata? (`Record<string, unknown>`) - Custom metadata to associate with the file.\n * Example - `{\"alt\":\"Custom image\",\"category\":\"document\"}`*/\nexport interface UploadFileMetadata {\n /**\n * Optional custom ID for the file. If not provided, a UUID will be generated.\n * Example - `\"custom-id-123\"`\n */\n id?: string;\n /**\n * Name to assign to the file. If not provided, the original filename will be used.\n * Example - `\"custom-filename.png\"`\n */\n name?: string;\n /**\n * Custom metadata to associate with the file.\n * Example - `{\"alt\":\"Custom image\",\"category\":\"document\"}`\n */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Contains version information about the storage service.\n @property buildVersion (`string`) - The version number of the storage service build.\n * Example - `\"1.2.3\"`*/\nexport interface VersionInformation {\n /**\n * The version number of the storage service build.\n * Example - `\"1.2.3\"`\n */\n buildVersion: string;\n}\n\n/**\n * Output format for image files. Use 'auto' for content negotiation based on Accept header\n */\nexport type OutputImageFormat =\n | \"auto\"\n | \"same\"\n | \"jpeg\"\n | \"webp\"\n | \"png\"\n | \"avif\"\n | \"heic\";\n\n/**\n * \n @property bucket-id? (`string`) - Target bucket identifier where files will be stored.\n * Example - `\"user-uploads\"`\n @property metadata[]? (`UploadFileMetadata[]`) - Optional custom metadata for each uploaded file. Must match the order of the file[] array.\n @property file[] (`Blob[]`) - Array of files to upload.*/\nexport interface UploadFilesBody {\n /**\n * Target bucket identifier where files will be stored.\n * Example - `\"user-uploads\"`\n */\n \"bucket-id\"?: string;\n /**\n * Optional custom metadata for each uploaded file. Must match the order of the file[] array.\n */\n \"metadata[]\"?: UploadFileMetadata[];\n /**\n * Array of files to upload.\n */\n \"file[]\": Blob[];\n}\n\n/**\n * \n @property processedFiles (`FileMetadata[]`) - List of successfully processed files with their metadata.*/\nexport interface UploadFilesResponse201 {\n /**\n * List of successfully processed files with their metadata.\n */\n processedFiles: FileMetadata[];\n}\n\n/**\n * \n @property metadata? (`UpdateFileMetadata`) - Metadata that can be updated for an existing file.\n @property file? (`Blob`) - New file content to replace the existing file\n * Format - binary*/\nexport interface ReplaceFileBody {\n /**\n * Metadata that can be updated for an existing file.\n */\n metadata?: UpdateFileMetadata;\n /**\n * New file content to replace the existing file\n * Format - binary\n */\n file?: Blob;\n}\n\n/**\n * \n @property metadata? (`FileSummary[]`) - */\nexport interface DeleteBrokenMetadataResponse200 {\n /**\n *\n */\n metadata?: FileSummary[];\n}\n\n/**\n * \n @property files? (`string[]`) - */\nexport interface DeleteOrphanedFilesResponse200 {\n /**\n *\n */\n files?: string[];\n}\n\n/**\n * \n @property metadata? (`FileSummary[]`) - */\nexport interface ListBrokenMetadataResponse200 {\n /**\n *\n */\n metadata?: FileSummary[];\n}\n\n/**\n * \n @property metadata? (`FileSummary[]`) - */\nexport interface ListFilesNotUploadedResponse200 {\n /**\n *\n */\n metadata?: FileSummary[];\n}\n\n/**\n * \n @property files? (`string[]`) - */\nexport interface ListOrphanedFilesResponse200 {\n /**\n *\n */\n files?: string[];\n}\n\n/**\n * Parameters for the getFile method.\n @property q? (number) - Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files\n \n @property h? (number) - Maximum height to resize image to while maintaining aspect ratio. Only applies to image files\n \n @property w? (number) - Maximum width to resize image to while maintaining aspect ratio. Only applies to image files\n \n @property b? (number) - Blur the image using this sigma value. Only applies to image files\n \n @property f? (OutputImageFormat) - Output format for image files. Use 'auto' for content negotiation based on Accept header\n \n * Output format for image files. Use 'auto' for content negotiation based on Accept header*/\nexport interface GetFileParams {\n /**\n * Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files\n \n */\n q?: number;\n /**\n * Maximum height to resize image to while maintaining aspect ratio. Only applies to image files\n \n */\n h?: number;\n /**\n * Maximum width to resize image to while maintaining aspect ratio. Only applies to image files\n \n */\n w?: number;\n /**\n * Blur the image using this sigma value. Only applies to image files\n \n */\n b?: number;\n /**\n * Output format for image files. Use 'auto' for content negotiation based on Accept header\n \n * Output format for image files. Use 'auto' for content negotiation based on Accept header\n */\n f?: OutputImageFormat;\n}\n/**\n * Parameters for the getFileMetadataHeaders method.\n @property q? (number) - Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files\n \n @property h? (number) - Maximum height to resize image to while maintaining aspect ratio. Only applies to image files\n \n @property w? (number) - Maximum width to resize image to while maintaining aspect ratio. Only applies to image files\n \n @property b? (number) - Blur the image using this sigma value. Only applies to image files\n \n @property f? (OutputImageFormat) - Output format for image files. Use 'auto' for content negotiation based on Accept header\n \n * Output format for image files. Use 'auto' for content negotiation based on Accept header*/\nexport interface GetFileMetadataHeadersParams {\n /**\n * Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files\n \n */\n q?: number;\n /**\n * Maximum height to resize image to while maintaining aspect ratio. Only applies to image files\n \n */\n h?: number;\n /**\n * Maximum width to resize image to while maintaining aspect ratio. Only applies to image files\n \n */\n w?: number;\n /**\n * Blur the image using this sigma value. Only applies to image files\n \n */\n b?: number;\n /**\n * Output format for image files. Use 'auto' for content negotiation based on Accept header\n \n * Output format for image files. Use 'auto' for content negotiation based on Accept header\n */\n f?: OutputImageFormat;\n}\n\nexport interface Client {\n baseURL: string;\n\n /** Add a middleware function to the fetch chain\n * @param chainFunction - The middleware function to add\n */\n pushChainFunction(chainFunction: ChainFunction): void;\n /**\n Summary: Upload files\n Upload one or more files to a specified bucket. Supports batch uploading with optional custom metadata for each file. If uploading multiple files, either provide metadata for all files or none.\n\n This method may return different T based on the response code:\n - 201: UploadFilesResponse201\n */\n uploadFiles(\n body: UploadFilesBody,\n options?: RequestInit,\n ): Promise<FetchResponse<UploadFilesResponse201>>;\n\n /**\n Summary: Delete file\n Permanently delete a file from storage. This removes both the file content and its associated metadata.\n\n This method may return different T based on the response code:\n - 204: void\n */\n deleteFile(id: string, options?: RequestInit): Promise<FetchResponse<void>>;\n\n /**\n Summary: Download file\n Retrieve and download the complete file content. Supports conditional requests, image transformations, and range requests for partial downloads.\n\n This method may return different T based on the response code:\n - 200: void\n - 206: void\n - 304: void\n - 412: void\n */\n getFile(\n id: string,\n params?: GetFileParams,\n options?: RequestInit,\n ): Promise<FetchResponse<Blob>>;\n\n /**\n Summary: Check file information\n Retrieve file metadata headers without downloading the file content. Supports conditional requests and provides caching information.\n\n This method may return different T based on the response code:\n - 200: void\n - 304: void\n - 412: void\n */\n getFileMetadataHeaders(\n id: string,\n params?: GetFileMetadataHeadersParams,\n options?: RequestInit,\n ): Promise<FetchResponse<void>>;\n\n /**\n Summary: Replace file\n Replace an existing file with new content while preserving the file ID. The operation follows these steps:\n1. The isUploaded flag is set to false to mark the file as being updated\n2. The file content is replaced in the storage backend\n3. File metadata is updated (size, mime-type, isUploaded, etc.)\n\nEach step is atomic, but if a step fails, previous steps will not be automatically rolled back.\n\n\n This method may return different T based on the response code:\n - 200: FileMetadata\n */\n replaceFile(\n id: string,\n body: ReplaceFileBody,\n options?: RequestInit,\n ): Promise<FetchResponse<FileMetadata>>;\n\n /**\n Summary: Retrieve presigned URL to retrieve the file\n Retrieve presigned URL to retrieve the file. Expiration of the URL is\ndetermined by bucket configuration\n\n\n This method may return different T based on the response code:\n - 200: PresignedURLResponse\n */\n getFilePresignedURL(\n id: string,\n options?: RequestInit,\n ): Promise<FetchResponse<PresignedURLResponse>>;\n\n /**\n Summary: Delete broken metadata\n Broken metadata is defined as metadata that has isUploaded = true but there is no file in the storage matching it. This is an admin operation that requires the Hasura admin secret.\n\n This method may return different T based on the response code:\n - 200: DeleteBrokenMetadataResponse200\n */\n deleteBrokenMetadata(\n options?: RequestInit,\n ): Promise<FetchResponse<DeleteBrokenMetadataResponse200>>;\n\n /**\n Summary: Deletes orphaned files\n Orphaned files are files that are present in the storage but have no associated metadata. This is an admin operation that requires the Hasura admin secret.\n\n This method may return different T based on the response code:\n - 200: DeleteOrphanedFilesResponse200\n */\n deleteOrphanedFiles(\n options?: RequestInit,\n ): Promise<FetchResponse<DeleteOrphanedFilesResponse200>>;\n\n /**\n Summary: Lists broken metadata\n Broken metadata is defined as metadata that has isUploaded = true but there is no file in the storage matching it. This is an admin operation that requires the Hasura admin secret.\n\n This method may return different T based on the response code:\n - 200: ListBrokenMetadataResponse200\n */\n listBrokenMetadata(\n options?: RequestInit,\n ): Promise<FetchResponse<ListBrokenMetadataResponse200>>;\n\n /**\n Summary: Lists files that haven't been uploaded\n That is, metadata that has isUploaded = false. This is an admin operation that requires the Hasura admin secret.\n\n This method may return different T based on the response code:\n - 200: ListFilesNotUploadedResponse200\n */\n listFilesNotUploaded(\n options?: RequestInit,\n ): Promise<FetchResponse<ListFilesNotUploadedResponse200>>;\n\n /**\n Summary: Lists orphaned files\n Orphaned files are files that are present in the storage but have no associated metadata. This is an admin operation that requires the Hasura admin secret.\n\n This method may return different T based on the response code:\n - 200: ListOrphanedFilesResponse200\n */\n listOrphanedFiles(\n options?: RequestInit,\n ): Promise<FetchResponse<ListOrphanedFilesResponse200>>;\n\n /**\n Summary: Get service version information\n Retrieves build and version information about the storage service. Useful for monitoring and debugging.\n\n This method may return different T based on the response code:\n - 200: VersionInformation\n */\n getVersion(options?: RequestInit): Promise<FetchResponse<VersionInformation>>;\n}\n\nexport const createAPIClient = (\n baseURL: string,\n chainFunctions: ChainFunction[] = [],\n): Client => {\n let fetch = createEnhancedFetch(chainFunctions);\n\n const pushChainFunction = (chainFunction: ChainFunction) => {\n chainFunctions.push(chainFunction);\n fetch = createEnhancedFetch(chainFunctions);\n };\n const uploadFiles = async (\n body: UploadFilesBody,\n options?: RequestInit,\n ): Promise<FetchResponse<UploadFilesResponse201>> => {\n const url = `${baseURL}/files`;\n const formData = new FormData();\n const isReactNative =\n typeof navigator !== \"undefined\" &&\n (navigator as { product?: string }).product === \"ReactNative\";\n if (body[\"bucket-id\"] !== undefined) {\n formData.append(\"bucket-id\", body[\"bucket-id\"]);\n }\n if (body[\"metadata[]\"] !== undefined) {\n body[\"metadata[]\"].forEach((value) => {\n if (isReactNative) {\n formData.append(\"metadata[]\", {\n string: JSON.stringify(value),\n type: \"application/json\",\n name: \"\",\n } as unknown as Blob);\n } else {\n formData.append(\n \"metadata[]\",\n new Blob([JSON.stringify(value)], { type: \"application/json\" }),\n \"\",\n );\n }\n });\n }\n if (body[\"file[]\"] !== undefined) {\n body[\"file[]\"].forEach((value) => {\n formData.append(\"file[]\", value);\n });\n }\n\n const res = await fetch(url, {\n ...options,\n method: \"POST\",\n body: formData,\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const responseBody = [204, 205, 304].includes(res.status)\n ? null\n : await res.text();\n const payload: UploadFilesResponse201 = responseBody\n ? JSON.parse(responseBody)\n : {};\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<UploadFilesResponse201>;\n };\n\n const deleteFile = async (\n id: string,\n options?: RequestInit,\n ): Promise<FetchResponse<void>> => {\n const url = `${baseURL}/files/${id}`;\n const res = await fetch(url, {\n ...options,\n method: \"DELETE\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const payload: undefined = undefined;\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<void>;\n };\n\n const getFile = async (\n id: string,\n params?: GetFileParams,\n options?: RequestInit,\n ): Promise<FetchResponse<Blob>> => {\n const encodedParameters =\n params &&\n Object.entries(params)\n .flatMap(([key, value]) => {\n // Default handling (scalars or explode: false)\n const stringValue = Array.isArray(value)\n ? value.join(\",\")\n : typeof value === \"object\" && value !== null\n ? JSON.stringify(value)\n : String(value);\n return [`${key}=${encodeURIComponent(stringValue)}`];\n })\n .join(\"&\");\n\n const url = encodedParameters\n ? `${baseURL}/files/${id}?${encodedParameters}`\n : `${baseURL}/files/${id}`;\n const res = await fetch(url, {\n ...options,\n method: \"GET\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const payload: Blob = await res.blob();\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<Blob>;\n };\n\n const getFileMetadataHeaders = async (\n id: string,\n params?: GetFileMetadataHeadersParams,\n options?: RequestInit,\n ): Promise<FetchResponse<void>> => {\n const encodedParameters =\n params &&\n Object.entries(params)\n .flatMap(([key, value]) => {\n // Default handling (scalars or explode: false)\n const stringValue = Array.isArray(value)\n ? value.join(\",\")\n : typeof value === \"object\" && value !== null\n ? JSON.stringify(value)\n : String(value);\n return [`${key}=${encodeURIComponent(stringValue)}`];\n })\n .join(\"&\");\n\n const url = encodedParameters\n ? `${baseURL}/files/${id}?${encodedParameters}`\n : `${baseURL}/files/${id}`;\n const res = await fetch(url, {\n ...options,\n method: \"HEAD\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const payload: undefined = undefined;\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<void>;\n };\n\n const replaceFile = async (\n id: string,\n body: ReplaceFileBody,\n options?: RequestInit,\n ): Promise<FetchResponse<FileMetadata>> => {\n const url = `${baseURL}/files/${id}`;\n const formData = new FormData();\n const isReactNative =\n typeof navigator !== \"undefined\" &&\n (navigator as { product?: string }).product === \"ReactNative\";\n if (body[\"metadata\"] !== undefined) {\n if (isReactNative) {\n formData.append(\"metadata\", {\n string: JSON.stringify(body[\"metadata\"]),\n type: \"application/json\",\n name: \"\",\n } as unknown as Blob);\n } else {\n formData.append(\n \"metadata\",\n new Blob([JSON.stringify(body[\"metadata\"])], {\n type: \"application/json\",\n }),\n \"\",\n );\n }\n }\n if (body[\"file\"] !== undefined) {\n formData.append(\"file\", body[\"file\"]);\n }\n\n const res = await fetch(url, {\n ...options,\n method: \"PUT\",\n body: formData,\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const responseBody = [204, 205, 304].includes(res.status)\n ? null\n : await res.text();\n const payload: FileMetadata = responseBody ? JSON.parse(responseBody) : {};\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<FileMetadata>;\n };\n\n const getFilePresignedURL = async (\n id: string,\n options?: RequestInit,\n ): Promise<FetchResponse<PresignedURLResponse>> => {\n const url = `${baseURL}/files/${id}/presignedurl`;\n const res = await fetch(url, {\n ...options,\n method: \"GET\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const responseBody = [204, 205, 304].includes(res.status)\n ? null\n : await res.text();\n const payload: PresignedURLResponse = responseBody\n ? JSON.parse(responseBody)\n : {};\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<PresignedURLResponse>;\n };\n\n const deleteBrokenMetadata = async (\n options?: RequestInit,\n ): Promise<FetchResponse<DeleteBrokenMetadataResponse200>> => {\n const url = `${baseURL}/ops/delete-broken-metadata`;\n const res = await fetch(url, {\n ...options,\n method: \"POST\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const responseBody = [204, 205, 304].includes(res.status)\n ? null\n : await res.text();\n const payload: DeleteBrokenMetadataResponse200 = responseBody\n ? JSON.parse(responseBody)\n : {};\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<DeleteBrokenMetadataResponse200>;\n };\n\n const deleteOrphanedFiles = async (\n options?: RequestInit,\n ): Promise<FetchResponse<DeleteOrphanedFilesResponse200>> => {\n const url = `${baseURL}/ops/delete-orphans`;\n const res = await fetch(url, {\n ...options,\n method: \"POST\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const responseBody = [204, 205, 304].includes(res.status)\n ? null\n : await res.text();\n const payload: DeleteOrphanedFilesResponse200 = responseBody\n ? JSON.parse(responseBody)\n : {};\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<DeleteOrphanedFilesResponse200>;\n };\n\n const listBrokenMetadata = async (\n options?: RequestInit,\n ): Promise<FetchResponse<ListBrokenMetadataResponse200>> => {\n const url = `${baseURL}/ops/list-broken-metadata`;\n const res = await fetch(url, {\n ...options,\n method: \"POST\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const responseBody = [204, 205, 304].includes(res.status)\n ? null\n : await res.text();\n const payload: ListBrokenMetadataResponse200 = responseBody\n ? JSON.parse(responseBody)\n : {};\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<ListBrokenMetadataResponse200>;\n };\n\n const listFilesNotUploaded = async (\n options?: RequestInit,\n ): Promise<FetchResponse<ListFilesNotUploadedResponse200>> => {\n const url = `${baseURL}/ops/list-not-uploaded`;\n const res = await fetch(url, {\n ...options,\n method: \"POST\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const responseBody = [204, 205, 304].includes(res.status)\n ? null\n : await res.text();\n const payload: ListFilesNotUploadedResponse200 = responseBody\n ? JSON.parse(responseBody)\n : {};\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<ListFilesNotUploadedResponse200>;\n };\n\n const listOrphanedFiles = async (\n options?: RequestInit,\n ): Promise<FetchResponse<ListOrphanedFilesResponse200>> => {\n const url = `${baseURL}/ops/list-orphans`;\n const res = await fetch(url, {\n ...options,\n method: \"POST\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const responseBody = [204, 205, 304].includes(res.status)\n ? null\n : await res.text();\n const payload: ListOrphanedFilesResponse200 = responseBody\n ? JSON.parse(responseBody)\n : {};\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<ListOrphanedFilesResponse200>;\n };\n\n const getVersion = async (\n options?: RequestInit,\n ): Promise<FetchResponse<VersionInformation>> => {\n const url = `${baseURL}/version`;\n const res = await fetch(url, {\n ...options,\n method: \"GET\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const responseBody = [204, 205, 304].includes(res.status)\n ? null\n : await res.text();\n const payload: VersionInformation = responseBody\n ? JSON.parse(responseBody)\n : {};\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<VersionInformation>;\n };\n\n return {\n baseURL,\n pushChainFunction,\n uploadFiles,\n deleteFile,\n getFile,\n getFileMetadataHeaders,\n replaceFile,\n getFilePresignedURL,\n deleteBrokenMetadata,\n deleteOrphanedFiles,\n listBrokenMetadata,\n listFilesNotUploaded,\n listOrphanedFiles,\n getVersion,\n };\n};\n"],"names":["baseURL","chainFunctions","fetch","createEnhancedFetch","pushChainFunction","chainFunction","push","uploadFiles","async","body","options","url","formData","FormData","isReactNative","navigator","product","append","forEach","value","string","JSON","stringify","type","name","Blob","res","method","status","responseBody","includes","text","payload","parse","FetchError","headers","deleteFile","id","getFile","params","encodedParameters","Object","entries","flatMap","key","stringValue","Array","isArray","join","String","encodeURIComponent","blob","getFileMetadataHeaders","replaceFile","getFilePresignedURL","deleteBrokenMetadata","deleteOrphanedFiles","listBrokenMetadata","listFilesNotUploaded","listOrphanedFiles","getVersion"],"mappings":"iJA2mB+B,CAC7BA,EACAC,EAAkC,MAElC,IAAIC,EAAQC,EAAAA,oBAAoBF,GAidhC,MAAO,CACLD,UACAI,kBAjdyBC,IACzBJ,EAAeK,KAAKD,GACpBH,EAAQC,EAAAA,oBAAoBF,EAAc,EAgd1CM,YA9ckBC,MAClBC,EACAC,KAEA,MAAMC,EAAM,GAAGX,UACTY,EAAW,IAAIC,SACfC,EACiB,oBAAdC,WACyC,gBAA/CA,UAAmCC,aACZ,IAAtBP,EAAK,cACPG,EAASK,OAAO,YAAaR,EAAK,mBAET,IAAvBA,EAAK,eACPA,EAAK,cAAcS,SAASC,IACtBL,EACFF,EAASK,OAAO,aAAc,CAC5BG,OAAQC,KAAKC,UAAUH,GACvBI,KAAM,mBACNC,KAAM,KAGRZ,EAASK,OACP,aACA,IAAIQ,KAAK,CAACJ,KAAKC,UAAUH,IAAS,CAAEI,KAAM,qBAC1C,GAEJ,SAGmB,IAAnBd,EAAK,WACPA,EAAK,UAAUS,SAASC,IACtBP,EAASK,OAAO,SAAUE,EAAK,IAInC,MAAMO,QAAYxB,EAAMS,EAAK,IACxBD,EACHiB,OAAQ,OACRlB,KAAMG,IAGR,GAAIc,EAAIE,QAAU,IAAK,CACrB,MAAMC,EAAe,CAAC,KAAKC,SAASJ,EAAIE,QAAU,WAAaF,EAAIK,OAC7DC,EAAmBH,EAAeR,KAAKY,MAAMJ,GAAgB,CAAA,EACnE,MAAM,IAAIK,EAAAA,WAAWF,EAASN,EAAIE,OAAQF,EAAIS,QAChD,CAEA,MAAMN,EAAe,CAAC,IAAK,IAAK,KAAKC,SAASJ,EAAIE,QAC9C,WACMF,EAAIK,OAKd,MAAO,CACLtB,KALsCoB,EACpCR,KAAKY,MAAMJ,GACX,CAAA,EAIFD,OAAQF,EAAIE,OACZO,QAAST,EAAIS,QAAA,EAsZfC,WAlZiB5B,MACjB6B,EACA3B,KAEA,MAAMC,EAAM,GAAGX,WAAiBqC,IAC1BX,QAAYxB,EAAMS,EAAK,IACxBD,EACHiB,OAAQ,SACRQ,QAAS,IACJzB,GAASyB,WAIhB,GAAIT,EAAIE,QAAU,IAAK,CACrB,MAAMC,EAAe,CAAC,KAAKC,SAASJ,EAAIE,QAAU,WAAaF,EAAIK,OAC7DC,EAAmBH,EAAeR,KAAKY,MAAMJ,GAAgB,CAAA,EACnE,MAAM,IAAIK,EAAAA,WAAWF,EAASN,EAAIE,OAAQF,EAAIS,QAChD,CAIA,MAAO,CACL1B,UAHyB,EAIzBmB,OAAQF,EAAIE,OACZO,QAAST,EAAIS,QAAA,EA2XfG,QAvXc9B,MACd6B,EACAE,EACA7B,KAEA,MAAM8B,EACJD,GACAE,OAAOC,QAAQH,GACZI,SAAQ,EAAEC,EAAKzB,MAEd,MAAM0B,EAAcC,MAAMC,QAAQ5B,GAC9BA,EAAM6B,KAAK,KACM,iBAAV7B,GAAgC,OAAVA,EAC3BE,KAAKC,UAAUH,GACf8B,OAAO9B,GACb,MAAO,CAAC,GAAGyB,KAAOM,mBAAmBL,KAAc,IAEpDG,KAAK,KAEJrC,EAAM6B,EACR,GAAGxC,WAAiBqC,KAAMG,IAC1B,GAAGxC,WAAiBqC,IAClBX,QAAYxB,EAAMS,EAAK,IACxBD,EACHiB,OAAQ,MACRQ,QAAS,IACJzB,GAASyB,WAIhB,GAAIT,EAAIE,QAAU,IAAK,CACrB,MAAMC,EAAe,CAAC,KAAKC,SAASJ,EAAIE,QAAU,WAAaF,EAAIK,OAC7DC,EAAmBH,EAAeR,KAAKY,MAAMJ,GAAgB,CAAA,EACnE,MAAM,IAAIK,EAAAA,WAAWF,EAASN,EAAIE,OAAQF,EAAIS,QAChD,CAIA,MAAO,CACL1B,WAH0BiB,EAAIyB,OAI9BvB,OAAQF,EAAIE,OACZO,QAAST,EAAIS,QAAA,EA+UfiB,uBA3U6B5C,MAC7B6B,EACAE,EACA7B,KAEA,MAAM8B,EACJD,GACAE,OAAOC,QAAQH,GACZI,SAAQ,EAAEC,EAAKzB,MAEd,MAAM0B,EAAcC,MAAMC,QAAQ5B,GAC9BA,EAAM6B,KAAK,KACM,iBAAV7B,GAAgC,OAAVA,EAC3BE,KAAKC,UAAUH,GACf8B,OAAO9B,GACb,MAAO,CAAC,GAAGyB,KAAOM,mBAAmBL,KAAc,IAEpDG,KAAK,KAEJrC,EAAM6B,EACR,GAAGxC,WAAiBqC,KAAMG,IAC1B,GAAGxC,WAAiBqC,IAClBX,QAAYxB,EAAMS,EAAK,IACxBD,EACHiB,OAAQ,OACRQ,QAAS,IACJzB,GAASyB,WAIhB,GAAIT,EAAIE,QAAU,IAAK,CACrB,MAAMC,EAAe,CAAC,KAAKC,SAASJ,EAAIE,QAAU,WAAaF,EAAIK,OAC7DC,EAAmBH,EAAeR,KAAKY,MAAMJ,GAAgB,CAAA,EACnE,MAAM,IAAIK,EAAAA,WAAWF,EAASN,EAAIE,OAAQF,EAAIS,QAChD,CAIA,MAAO,CACL1B,UAHyB,EAIzBmB,OAAQF,EAAIE,OACZO,QAAST,EAAIS,QAAA,EAmSfkB,YA/RkB7C,MAClB6B,EACA5B,EACAC,KAEA,MAAMC,EAAM,GAAGX,WAAiBqC,IAC1BzB,EAAW,IAAIC,SACfC,EACiB,oBAAdC,WACyC,gBAA/CA,UAAmCC,aACb,IAArBP,EAAe,WACbK,EACFF,EAASK,OAAO,WAAY,CAC1BG,OAAQC,KAAKC,UAAUb,EAAe,UACtCc,KAAM,mBACNC,KAAM,KAGRZ,EAASK,OACP,WACA,IAAIQ,KAAK,CAACJ,KAAKC,UAAUb,EAAe,WAAK,CAC3Cc,KAAM,qBAER,UAIe,IAAjBd,EAAW,MACbG,EAASK,OAAO,OAAQR,EAAW,MAGrC,MAAMiB,QAAYxB,EAAMS,EAAK,IACxBD,EACHiB,OAAQ,MACRlB,KAAMG,IAGR,GAAIc,EAAIE,QAAU,IAAK,CACrB,MAAMC,EAAe,CAAC,KAAKC,SAASJ,EAAIE,QAAU,WAAaF,EAAIK,OAC7DC,EAAmBH,EAAeR,KAAKY,MAAMJ,GAAgB,CAAA,EACnE,MAAM,IAAIK,EAAAA,WAAWF,EAASN,EAAIE,OAAQF,EAAIS,QAChD,CAEA,MAAMN,EAAe,CAAC,IAAK,IAAK,KAAKC,SAASJ,EAAIE,QAC9C,WACMF,EAAIK,OAGd,MAAO,CACLtB,KAH4BoB,EAAeR,KAAKY,MAAMJ,GAAgB,CAAA,EAItED,OAAQF,EAAIE,OACZO,QAAST,EAAIS,QAAA,EA6OfmB,oBAzO0B9C,MAC1B6B,EACA3B,KAEA,MAAMC,EAAM,GAAGX,WAAiBqC,iBAC1BX,QAAYxB,EAAMS,EAAK,IACxBD,EACHiB,OAAQ,MACRQ,QAAS,IACJzB,GAASyB,WAIhB,GAAIT,EAAIE,QAAU,IAAK,CACrB,MAAMC,EAAe,CAAC,KAAKC,SAASJ,EAAIE,QAAU,WAAaF,EAAIK,OAC7DC,EAAmBH,EAAeR,KAAKY,MAAMJ,GAAgB,CAAA,EACnE,MAAM,IAAIK,EAAAA,WAAWF,EAASN,EAAIE,OAAQF,EAAIS,QAChD,CAEA,MAAMN,EAAe,CAAC,IAAK,IAAK,KAAKC,SAASJ,EAAIE,QAC9C,WACMF,EAAIK,OAKd,MAAO,CACLtB,KALoCoB,EAClCR,KAAKY,MAAMJ,GACX,CAAA,EAIFD,OAAQF,EAAIE,OACZO,QAAST,EAAIS,QAAA,EA6MfoB,qBAzM2B/C,MAC3BE,IAEA,MAAMC,EAAM,GAAGX,+BACT0B,QAAYxB,EAAMS,EAAK,IACxBD,EACHiB,OAAQ,OACRQ,QAAS,IACJzB,GAASyB,WAIhB,GAAIT,EAAIE,QAAU,IAAK,CACrB,MAAMC,EAAe,CAAC,KAAKC,SAASJ,EAAIE,QAAU,WAAaF,EAAIK,OAC7DC,EAAmBH,EAAeR,KAAKY,MAAMJ,GAAgB,CAAA,EACnE,MAAM,IAAIK,EAAAA,WAAWF,EAASN,EAAIE,OAAQF,EAAIS,QAChD,CAEA,MAAMN,EAAe,CAAC,IAAK,IAAK,KAAKC,SAASJ,EAAIE,QAC9C,WACMF,EAAIK,OAKd,MAAO,CACLtB,KAL+CoB,EAC7CR,KAAKY,MAAMJ,GACX,CAAA,EAIFD,OAAQF,EAAIE,OACZO,QAAST,EAAIS,QAAA,EA8KfqB,oBA1K0BhD,MAC1BE,IAEA,MAAMC,EAAM,GAAGX,uBACT0B,QAAYxB,EAAMS,EAAK,IACxBD,EACHiB,OAAQ,OACRQ,QAAS,IACJzB,GAASyB,WAIhB,GAAIT,EAAIE,QAAU,IAAK,CACrB,MAAMC,EAAe,CAAC,KAAKC,SAASJ,EAAIE,QAAU,WAAaF,EAAIK,OAC7DC,EAAmBH,EAAeR,KAAKY,MAAMJ,GAAgB,CAAA,EACnE,MAAM,IAAIK,EAAAA,WAAWF,EAASN,EAAIE,OAAQF,EAAIS,QAChD,CAEA,MAAMN,EAAe,CAAC,IAAK,IAAK,KAAKC,SAASJ,EAAIE,QAC9C,WACMF,EAAIK,OAKd,MAAO,CACLtB,KAL8CoB,EAC5CR,KAAKY,MAAMJ,GACX,CAAA,EAIFD,OAAQF,EAAIE,OACZO,QAAST,EAAIS,QAAA,EA+IfsB,mBA3IyBjD,MACzBE,IAEA,MAAMC,EAAM,GAAGX,6BACT0B,QAAYxB,EAAMS,EAAK,IACxBD,EACHiB,OAAQ,OACRQ,QAAS,IACJzB,GAASyB,WAIhB,GAAIT,EAAIE,QAAU,IAAK,CACrB,MAAMC,EAAe,CAAC,KAAKC,SAASJ,EAAIE,QAAU,WAAaF,EAAIK,OAC7DC,EAAmBH,EAAeR,KAAKY,MAAMJ,GAAgB,CAAA,EACnE,MAAM,IAAIK,EAAAA,WAAWF,EAASN,EAAIE,OAAQF,EAAIS,QAChD,CAEA,MAAMN,EAAe,CAAC,IAAK,IAAK,KAAKC,SAASJ,EAAIE,QAC9C,WACMF,EAAIK,OAKd,MAAO,CACLtB,KAL6CoB,EAC3CR,KAAKY,MAAMJ,GACX,CAAA,EAIFD,OAAQF,EAAIE,OACZO,QAAST,EAAIS,QAAA,EAgHfuB,qBA5G2BlD,MAC3BE,IAEA,MAAMC,EAAM,GAAGX,0BACT0B,QAAYxB,EAAMS,EAAK,IACxBD,EACHiB,OAAQ,OACRQ,QAAS,IACJzB,GAASyB,WAIhB,GAAIT,EAAIE,QAAU,IAAK,CACrB,MAAMC,EAAe,CAAC,KAAKC,SAASJ,EAAIE,QAAU,WAAaF,EAAIK,OAC7DC,EAAmBH,EAAeR,KAAKY,MAAMJ,GAAgB,CAAA,EACnE,MAAM,IAAIK,EAAAA,WAAWF,EAASN,EAAIE,OAAQF,EAAIS,QAChD,CAEA,MAAMN,EAAe,CAAC,IAAK,IAAK,KAAKC,SAASJ,EAAIE,QAC9C,WACMF,EAAIK,OAKd,MAAO,CACLtB,KAL+CoB,EAC7CR,KAAKY,MAAMJ,GACX,CAAA,EAIFD,OAAQF,EAAIE,OACZO,QAAST,EAAIS,QAAA,EAiFfwB,kBA7EwBnD,MACxBE,IAEA,MAAMC,EAAM,GAAGX,qBACT0B,QAAYxB,EAAMS,EAAK,IACxBD,EACHiB,OAAQ,OACRQ,QAAS,IACJzB,GAASyB,WAIhB,GAAIT,EAAIE,QAAU,IAAK,CACrB,MAAMC,EAAe,CAAC,KAAKC,SAASJ,EAAIE,QAAU,WAAaF,EAAIK,OAC7DC,EAAmBH,EAAeR,KAAKY,MAAMJ,GAAgB,CAAA,EACnE,MAAM,IAAIK,EAAAA,WAAWF,EAASN,EAAIE,OAAQF,EAAIS,QAChD,CAEA,MAAMN,EAAe,CAAC,IAAK,IAAK,KAAKC,SAASJ,EAAIE,QAC9C,WACMF,EAAIK,OAKd,MAAO,CACLtB,KAL4CoB,EAC1CR,KAAKY,MAAMJ,GACX,CAAA,EAIFD,OAAQF,EAAIE,OACZO,QAAST,EAAIS,QAAA,EAkDfyB,WA9CiBpD,MACjBE,IAEA,MAAMC,EAAM,GAAGX,YACT0B,QAAYxB,EAAMS,EAAK,IACxBD,EACHiB,OAAQ,MACRQ,QAAS,IACJzB,GAASyB,WAIhB,GAAIT,EAAIE,QAAU,IAAK,CACrB,MAAMC,EAAe,CAAC,KAAKC,SAASJ,EAAIE,QAAU,WAAaF,EAAIK,OAC7DC,EAAmBH,EAAeR,KAAKY,MAAMJ,GAAgB,CAAA,EACnE,MAAM,IAAIK,EAAAA,WAAWF,EAASN,EAAIE,OAAQF,EAAIS,QAChD,CAEA,MAAMN,EAAe,CAAC,IAAK,IAAK,KAAKC,SAASJ,EAAIE,QAC9C,WACMF,EAAIK,OAKd,MAAO,CACLtB,KALkCoB,EAChCR,KAAKY,MAAMJ,GACX,CAAA,EAIFD,OAAQF,EAAIE,OACZO,QAAST,EAAIS,QAAA,EAkBf"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as createEnhancedFetch, F as FetchError } from "../fetch-2PHmQBIJ.
|
|
1
|
+
import { c as createEnhancedFetch, F as FetchError } from "../fetch-2PHmQBIJ.js";
|
|
2
2
|
const createAPIClient = (baseURL, chainFunctions = []) => {
|
|
3
3
|
let fetch = createEnhancedFetch(chainFunctions);
|
|
4
4
|
const pushChainFunction = (chainFunction) => {
|
|
@@ -339,4 +339,4 @@ const createAPIClient = (baseURL, chainFunctions = []) => {
|
|
|
339
339
|
export {
|
|
340
340
|
createAPIClient
|
|
341
341
|
};
|
|
342
|
-
//# sourceMappingURL=storage.
|
|
342
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sources":["../../src/storage/client.ts"],"sourcesContent":["/**\n * This file is auto-generated. Do not edit manually.\n */\n\nimport type { ChainFunction, FetchResponse } from \"../fetch\";\nimport { createEnhancedFetch, FetchError } from \"../fetch\";\n\n/**\n * Date in RFC 2822 format\n */\nexport type RFC2822Date = string;\n\n/**\n * Error details.\n @property message (`string`) - Human-readable error message.\n * Example - `\"File not found\"`\n @property data? (`Record<string, unknown>`) - Additional data related to the error, if any.*/\nexport interface ErrorResponseError {\n /**\n * Human-readable error message.\n * Example - `\"File not found\"`\n */\n message: string;\n /**\n * Additional data related to the error, if any.\n */\n data?: Record<string, unknown>;\n}\n\n/**\n * Error information returned by the API.\n @property error? (`ErrorResponseError`) - Error details.*/\nexport interface ErrorResponse {\n /**\n * Error details.\n */\n error?: ErrorResponseError;\n}\n\n/**\n * Error details.\n @property message (`string`) - Human-readable error message.\n * Example - `\"File not found\"`\n @property data? (`Record<string, unknown>`) - Additional data related to the error, if any.*/\nexport interface ErrorResponseWithProcessedFilesError {\n /**\n * Human-readable error message.\n * Example - `\"File not found\"`\n */\n message: string;\n /**\n * Additional data related to the error, if any.\n */\n data?: Record<string, unknown>;\n}\n\n/**\n * Error information returned by the API.\n @property processedFiles? (`FileMetadata[]`) - List of files that were successfully processed before the error occurred.\n @property error? (`ErrorResponseWithProcessedFilesError`) - Error details.*/\nexport interface ErrorResponseWithProcessedFiles {\n /**\n * List of files that were successfully processed before the error occurred.\n */\n processedFiles?: FileMetadata[];\n /**\n * Error details.\n */\n error?: ErrorResponseWithProcessedFilesError;\n}\n\n/**\n * Comprehensive metadata information about a file in storage.\n @property id (`string`) - Unique identifier for the file.\n * Example - `\"d5e76ceb-77a2-4153-b7da-1f7c115b2ff2\"`\n @property name (`string`) - Name of the file including extension.\n * Example - `\"profile-picture.jpg\"`\n @property size (`number`) - Size of the file in bytes.\n * Example - `245678`\n * Format - int64\n @property bucketId (`string`) - ID of the bucket containing the file.\n * Example - `\"users-bucket\"`\n @property etag (`string`) - Entity tag for cache validation.\n * Example - `\"\\\"a1b2c3d4e5f6\\\"\"`\n @property createdAt (`string`) - Timestamp when the file was created.\n * Example - `\"2023-01-15T12:34:56Z\"`\n * Format - date-time\n @property updatedAt (`string`) - Timestamp when the file was last updated.\n * Example - `\"2023-01-16T09:45:32Z\"`\n * Format - date-time\n @property isUploaded (`boolean`) - Whether the file has been successfully uploaded.\n * Example - `true`\n @property mimeType (`string`) - MIME type of the file.\n * Example - `\"image/jpeg\"`\n @property uploadedByUserId? (`string`) - ID of the user who uploaded the file.\n * Example - `\"abc123def456\"`\n @property metadata? (`Record<string, unknown>`) - Custom metadata associated with the file.\n * Example - `{\"alt\":\"Profile picture\",\"category\":\"avatar\"}`*/\nexport interface FileMetadata {\n /**\n * Unique identifier for the file.\n * Example - `\"d5e76ceb-77a2-4153-b7da-1f7c115b2ff2\"`\n */\n id: string;\n /**\n * Name of the file including extension.\n * Example - `\"profile-picture.jpg\"`\n */\n name: string;\n /**\n * Size of the file in bytes.\n * Example - `245678`\n * Format - int64\n */\n size: number;\n /**\n * ID of the bucket containing the file.\n * Example - `\"users-bucket\"`\n */\n bucketId: string;\n /**\n * Entity tag for cache validation.\n * Example - `\"\\\"a1b2c3d4e5f6\\\"\"`\n */\n etag: string;\n /**\n * Timestamp when the file was created.\n * Example - `\"2023-01-15T12:34:56Z\"`\n * Format - date-time\n */\n createdAt: string;\n /**\n * Timestamp when the file was last updated.\n * Example - `\"2023-01-16T09:45:32Z\"`\n * Format - date-time\n */\n updatedAt: string;\n /**\n * Whether the file has been successfully uploaded.\n * Example - `true`\n */\n isUploaded: boolean;\n /**\n * MIME type of the file.\n * Example - `\"image/jpeg\"`\n */\n mimeType: string;\n /**\n * ID of the user who uploaded the file.\n * Example - `\"abc123def456\"`\n */\n uploadedByUserId?: string;\n /**\n * Custom metadata associated with the file.\n * Example - `{\"alt\":\"Profile picture\",\"category\":\"avatar\"}`\n */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Basic information about a file in storage.\n @property id (`string`) - Unique identifier for the file.\n * Example - `\"d5e76ceb-77a2-4153-b7da-1f7c115b2ff2\"`\n @property name (`string`) - Name of the file including extension.\n * Example - `\"profile-picture.jpg\"`\n @property bucketId (`string`) - ID of the bucket containing the file.\n * Example - `\"users-bucket\"`\n @property isUploaded (`boolean`) - Whether the file has been successfully uploaded.\n * Example - `true`*/\nexport interface FileSummary {\n /**\n * Unique identifier for the file.\n * Example - `\"d5e76ceb-77a2-4153-b7da-1f7c115b2ff2\"`\n */\n id: string;\n /**\n * Name of the file including extension.\n * Example - `\"profile-picture.jpg\"`\n */\n name: string;\n /**\n * ID of the bucket containing the file.\n * Example - `\"users-bucket\"`\n */\n bucketId: string;\n /**\n * Whether the file has been successfully uploaded.\n * Example - `true`\n */\n isUploaded: boolean;\n}\n\n/**\n * Contains a presigned URL for direct file operations.\n @property url (`string`) - The presigned URL for file operations.\n * Example - `\"https://storage.example.com/files/abc123?signature=xyz\"`\n @property expiration (`number`) - The time in seconds until the URL expires.\n * Example - `3600`*/\nexport interface PresignedURLResponse {\n /**\n * The presigned URL for file operations.\n * Example - `\"https://storage.example.com/files/abc123?signature=xyz\"`\n */\n url: string;\n /**\n * The time in seconds until the URL expires.\n * Example - `3600`\n */\n expiration: number;\n}\n\n/**\n * Metadata that can be updated for an existing file.\n @property name? (`string`) - New name to assign to the file.\n * Example - `\"renamed-file.jpg\"`\n @property metadata? (`Record<string, unknown>`) - Updated custom metadata to associate with the file.\n * Example - `{\"alt\":\"Updated image description\",\"category\":\"profile\"}`*/\nexport interface UpdateFileMetadata {\n /**\n * New name to assign to the file.\n * Example - `\"renamed-file.jpg\"`\n */\n name?: string;\n /**\n * Updated custom metadata to associate with the file.\n * Example - `{\"alt\":\"Updated image description\",\"category\":\"profile\"}`\n */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Metadata provided when uploading a new file.\n @property id? (`string`) - Optional custom ID for the file. If not provided, a UUID will be generated.\n * Example - `\"custom-id-123\"`\n @property name? (`string`) - Name to assign to the file. If not provided, the original filename will be used.\n * Example - `\"custom-filename.png\"`\n @property metadata? (`Record<string, unknown>`) - Custom metadata to associate with the file.\n * Example - `{\"alt\":\"Custom image\",\"category\":\"document\"}`*/\nexport interface UploadFileMetadata {\n /**\n * Optional custom ID for the file. If not provided, a UUID will be generated.\n * Example - `\"custom-id-123\"`\n */\n id?: string;\n /**\n * Name to assign to the file. If not provided, the original filename will be used.\n * Example - `\"custom-filename.png\"`\n */\n name?: string;\n /**\n * Custom metadata to associate with the file.\n * Example - `{\"alt\":\"Custom image\",\"category\":\"document\"}`\n */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Contains version information about the storage service.\n @property buildVersion (`string`) - The version number of the storage service build.\n * Example - `\"1.2.3\"`*/\nexport interface VersionInformation {\n /**\n * The version number of the storage service build.\n * Example - `\"1.2.3\"`\n */\n buildVersion: string;\n}\n\n/**\n * Output format for image files. Use 'auto' for content negotiation based on Accept header\n */\nexport type OutputImageFormat =\n | \"auto\"\n | \"same\"\n | \"jpeg\"\n | \"webp\"\n | \"png\"\n | \"avif\"\n | \"heic\";\n\n/**\n * \n @property bucket-id? (`string`) - Target bucket identifier where files will be stored.\n * Example - `\"user-uploads\"`\n @property metadata[]? (`UploadFileMetadata[]`) - Optional custom metadata for each uploaded file. Must match the order of the file[] array.\n @property file[] (`Blob[]`) - Array of files to upload.*/\nexport interface UploadFilesBody {\n /**\n * Target bucket identifier where files will be stored.\n * Example - `\"user-uploads\"`\n */\n \"bucket-id\"?: string;\n /**\n * Optional custom metadata for each uploaded file. Must match the order of the file[] array.\n */\n \"metadata[]\"?: UploadFileMetadata[];\n /**\n * Array of files to upload.\n */\n \"file[]\": Blob[];\n}\n\n/**\n * \n @property processedFiles (`FileMetadata[]`) - List of successfully processed files with their metadata.*/\nexport interface UploadFilesResponse201 {\n /**\n * List of successfully processed files with their metadata.\n */\n processedFiles: FileMetadata[];\n}\n\n/**\n * \n @property metadata? (`UpdateFileMetadata`) - Metadata that can be updated for an existing file.\n @property file? (`Blob`) - New file content to replace the existing file\n * Format - binary*/\nexport interface ReplaceFileBody {\n /**\n * Metadata that can be updated for an existing file.\n */\n metadata?: UpdateFileMetadata;\n /**\n * New file content to replace the existing file\n * Format - binary\n */\n file?: Blob;\n}\n\n/**\n * \n @property metadata? (`FileSummary[]`) - */\nexport interface DeleteBrokenMetadataResponse200 {\n /**\n *\n */\n metadata?: FileSummary[];\n}\n\n/**\n * \n @property files? (`string[]`) - */\nexport interface DeleteOrphanedFilesResponse200 {\n /**\n *\n */\n files?: string[];\n}\n\n/**\n * \n @property metadata? (`FileSummary[]`) - */\nexport interface ListBrokenMetadataResponse200 {\n /**\n *\n */\n metadata?: FileSummary[];\n}\n\n/**\n * \n @property metadata? (`FileSummary[]`) - */\nexport interface ListFilesNotUploadedResponse200 {\n /**\n *\n */\n metadata?: FileSummary[];\n}\n\n/**\n * \n @property files? (`string[]`) - */\nexport interface ListOrphanedFilesResponse200 {\n /**\n *\n */\n files?: string[];\n}\n\n/**\n * Parameters for the getFile method.\n @property q? (number) - Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files\n \n @property h? (number) - Maximum height to resize image to while maintaining aspect ratio. Only applies to image files\n \n @property w? (number) - Maximum width to resize image to while maintaining aspect ratio. Only applies to image files\n \n @property b? (number) - Blur the image using this sigma value. Only applies to image files\n \n @property f? (OutputImageFormat) - Output format for image files. Use 'auto' for content negotiation based on Accept header\n \n * Output format for image files. Use 'auto' for content negotiation based on Accept header*/\nexport interface GetFileParams {\n /**\n * Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files\n \n */\n q?: number;\n /**\n * Maximum height to resize image to while maintaining aspect ratio. Only applies to image files\n \n */\n h?: number;\n /**\n * Maximum width to resize image to while maintaining aspect ratio. Only applies to image files\n \n */\n w?: number;\n /**\n * Blur the image using this sigma value. Only applies to image files\n \n */\n b?: number;\n /**\n * Output format for image files. Use 'auto' for content negotiation based on Accept header\n \n * Output format for image files. Use 'auto' for content negotiation based on Accept header\n */\n f?: OutputImageFormat;\n}\n/**\n * Parameters for the getFileMetadataHeaders method.\n @property q? (number) - Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files\n \n @property h? (number) - Maximum height to resize image to while maintaining aspect ratio. Only applies to image files\n \n @property w? (number) - Maximum width to resize image to while maintaining aspect ratio. Only applies to image files\n \n @property b? (number) - Blur the image using this sigma value. Only applies to image files\n \n @property f? (OutputImageFormat) - Output format for image files. Use 'auto' for content negotiation based on Accept header\n \n * Output format for image files. Use 'auto' for content negotiation based on Accept header*/\nexport interface GetFileMetadataHeadersParams {\n /**\n * Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files\n \n */\n q?: number;\n /**\n * Maximum height to resize image to while maintaining aspect ratio. Only applies to image files\n \n */\n h?: number;\n /**\n * Maximum width to resize image to while maintaining aspect ratio. Only applies to image files\n \n */\n w?: number;\n /**\n * Blur the image using this sigma value. Only applies to image files\n \n */\n b?: number;\n /**\n * Output format for image files. Use 'auto' for content negotiation based on Accept header\n \n * Output format for image files. Use 'auto' for content negotiation based on Accept header\n */\n f?: OutputImageFormat;\n}\n\nexport interface Client {\n baseURL: string;\n\n /** Add a middleware function to the fetch chain\n * @param chainFunction - The middleware function to add\n */\n pushChainFunction(chainFunction: ChainFunction): void;\n /**\n Summary: Upload files\n Upload one or more files to a specified bucket. Supports batch uploading with optional custom metadata for each file. If uploading multiple files, either provide metadata for all files or none.\n\n This method may return different T based on the response code:\n - 201: UploadFilesResponse201\n */\n uploadFiles(\n body: UploadFilesBody,\n options?: RequestInit,\n ): Promise<FetchResponse<UploadFilesResponse201>>;\n\n /**\n Summary: Delete file\n Permanently delete a file from storage. This removes both the file content and its associated metadata.\n\n This method may return different T based on the response code:\n - 204: void\n */\n deleteFile(id: string, options?: RequestInit): Promise<FetchResponse<void>>;\n\n /**\n Summary: Download file\n Retrieve and download the complete file content. Supports conditional requests, image transformations, and range requests for partial downloads.\n\n This method may return different T based on the response code:\n - 200: void\n - 206: void\n - 304: void\n - 412: void\n */\n getFile(\n id: string,\n params?: GetFileParams,\n options?: RequestInit,\n ): Promise<FetchResponse<Blob>>;\n\n /**\n Summary: Check file information\n Retrieve file metadata headers without downloading the file content. Supports conditional requests and provides caching information.\n\n This method may return different T based on the response code:\n - 200: void\n - 304: void\n - 412: void\n */\n getFileMetadataHeaders(\n id: string,\n params?: GetFileMetadataHeadersParams,\n options?: RequestInit,\n ): Promise<FetchResponse<void>>;\n\n /**\n Summary: Replace file\n Replace an existing file with new content while preserving the file ID. The operation follows these steps:\n1. The isUploaded flag is set to false to mark the file as being updated\n2. The file content is replaced in the storage backend\n3. File metadata is updated (size, mime-type, isUploaded, etc.)\n\nEach step is atomic, but if a step fails, previous steps will not be automatically rolled back.\n\n\n This method may return different T based on the response code:\n - 200: FileMetadata\n */\n replaceFile(\n id: string,\n body: ReplaceFileBody,\n options?: RequestInit,\n ): Promise<FetchResponse<FileMetadata>>;\n\n /**\n Summary: Retrieve presigned URL to retrieve the file\n Retrieve presigned URL to retrieve the file. Expiration of the URL is\ndetermined by bucket configuration\n\n\n This method may return different T based on the response code:\n - 200: PresignedURLResponse\n */\n getFilePresignedURL(\n id: string,\n options?: RequestInit,\n ): Promise<FetchResponse<PresignedURLResponse>>;\n\n /**\n Summary: Delete broken metadata\n Broken metadata is defined as metadata that has isUploaded = true but there is no file in the storage matching it. This is an admin operation that requires the Hasura admin secret.\n\n This method may return different T based on the response code:\n - 200: DeleteBrokenMetadataResponse200\n */\n deleteBrokenMetadata(\n options?: RequestInit,\n ): Promise<FetchResponse<DeleteBrokenMetadataResponse200>>;\n\n /**\n Summary: Deletes orphaned files\n Orphaned files are files that are present in the storage but have no associated metadata. This is an admin operation that requires the Hasura admin secret.\n\n This method may return different T based on the response code:\n - 200: DeleteOrphanedFilesResponse200\n */\n deleteOrphanedFiles(\n options?: RequestInit,\n ): Promise<FetchResponse<DeleteOrphanedFilesResponse200>>;\n\n /**\n Summary: Lists broken metadata\n Broken metadata is defined as metadata that has isUploaded = true but there is no file in the storage matching it. This is an admin operation that requires the Hasura admin secret.\n\n This method may return different T based on the response code:\n - 200: ListBrokenMetadataResponse200\n */\n listBrokenMetadata(\n options?: RequestInit,\n ): Promise<FetchResponse<ListBrokenMetadataResponse200>>;\n\n /**\n Summary: Lists files that haven't been uploaded\n That is, metadata that has isUploaded = false. This is an admin operation that requires the Hasura admin secret.\n\n This method may return different T based on the response code:\n - 200: ListFilesNotUploadedResponse200\n */\n listFilesNotUploaded(\n options?: RequestInit,\n ): Promise<FetchResponse<ListFilesNotUploadedResponse200>>;\n\n /**\n Summary: Lists orphaned files\n Orphaned files are files that are present in the storage but have no associated metadata. This is an admin operation that requires the Hasura admin secret.\n\n This method may return different T based on the response code:\n - 200: ListOrphanedFilesResponse200\n */\n listOrphanedFiles(\n options?: RequestInit,\n ): Promise<FetchResponse<ListOrphanedFilesResponse200>>;\n\n /**\n Summary: Get service version information\n Retrieves build and version information about the storage service. Useful for monitoring and debugging.\n\n This method may return different T based on the response code:\n - 200: VersionInformation\n */\n getVersion(options?: RequestInit): Promise<FetchResponse<VersionInformation>>;\n}\n\nexport const createAPIClient = (\n baseURL: string,\n chainFunctions: ChainFunction[] = [],\n): Client => {\n let fetch = createEnhancedFetch(chainFunctions);\n\n const pushChainFunction = (chainFunction: ChainFunction) => {\n chainFunctions.push(chainFunction);\n fetch = createEnhancedFetch(chainFunctions);\n };\n const uploadFiles = async (\n body: UploadFilesBody,\n options?: RequestInit,\n ): Promise<FetchResponse<UploadFilesResponse201>> => {\n const url = `${baseURL}/files`;\n const formData = new FormData();\n const isReactNative =\n typeof navigator !== \"undefined\" &&\n (navigator as { product?: string }).product === \"ReactNative\";\n if (body[\"bucket-id\"] !== undefined) {\n formData.append(\"bucket-id\", body[\"bucket-id\"]);\n }\n if (body[\"metadata[]\"] !== undefined) {\n body[\"metadata[]\"].forEach((value) => {\n if (isReactNative) {\n formData.append(\"metadata[]\", {\n string: JSON.stringify(value),\n type: \"application/json\",\n name: \"\",\n } as unknown as Blob);\n } else {\n formData.append(\n \"metadata[]\",\n new Blob([JSON.stringify(value)], { type: \"application/json\" }),\n \"\",\n );\n }\n });\n }\n if (body[\"file[]\"] !== undefined) {\n body[\"file[]\"].forEach((value) => {\n formData.append(\"file[]\", value);\n });\n }\n\n const res = await fetch(url, {\n ...options,\n method: \"POST\",\n body: formData,\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const responseBody = [204, 205, 304].includes(res.status)\n ? null\n : await res.text();\n const payload: UploadFilesResponse201 = responseBody\n ? JSON.parse(responseBody)\n : {};\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<UploadFilesResponse201>;\n };\n\n const deleteFile = async (\n id: string,\n options?: RequestInit,\n ): Promise<FetchResponse<void>> => {\n const url = `${baseURL}/files/${id}`;\n const res = await fetch(url, {\n ...options,\n method: \"DELETE\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const payload: undefined = undefined;\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<void>;\n };\n\n const getFile = async (\n id: string,\n params?: GetFileParams,\n options?: RequestInit,\n ): Promise<FetchResponse<Blob>> => {\n const encodedParameters =\n params &&\n Object.entries(params)\n .flatMap(([key, value]) => {\n // Default handling (scalars or explode: false)\n const stringValue = Array.isArray(value)\n ? value.join(\",\")\n : typeof value === \"object\" && value !== null\n ? JSON.stringify(value)\n : String(value);\n return [`${key}=${encodeURIComponent(stringValue)}`];\n })\n .join(\"&\");\n\n const url = encodedParameters\n ? `${baseURL}/files/${id}?${encodedParameters}`\n : `${baseURL}/files/${id}`;\n const res = await fetch(url, {\n ...options,\n method: \"GET\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const payload: Blob = await res.blob();\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<Blob>;\n };\n\n const getFileMetadataHeaders = async (\n id: string,\n params?: GetFileMetadataHeadersParams,\n options?: RequestInit,\n ): Promise<FetchResponse<void>> => {\n const encodedParameters =\n params &&\n Object.entries(params)\n .flatMap(([key, value]) => {\n // Default handling (scalars or explode: false)\n const stringValue = Array.isArray(value)\n ? value.join(\",\")\n : typeof value === \"object\" && value !== null\n ? JSON.stringify(value)\n : String(value);\n return [`${key}=${encodeURIComponent(stringValue)}`];\n })\n .join(\"&\");\n\n const url = encodedParameters\n ? `${baseURL}/files/${id}?${encodedParameters}`\n : `${baseURL}/files/${id}`;\n const res = await fetch(url, {\n ...options,\n method: \"HEAD\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const payload: undefined = undefined;\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<void>;\n };\n\n const replaceFile = async (\n id: string,\n body: ReplaceFileBody,\n options?: RequestInit,\n ): Promise<FetchResponse<FileMetadata>> => {\n const url = `${baseURL}/files/${id}`;\n const formData = new FormData();\n const isReactNative =\n typeof navigator !== \"undefined\" &&\n (navigator as { product?: string }).product === \"ReactNative\";\n if (body[\"metadata\"] !== undefined) {\n if (isReactNative) {\n formData.append(\"metadata\", {\n string: JSON.stringify(body[\"metadata\"]),\n type: \"application/json\",\n name: \"\",\n } as unknown as Blob);\n } else {\n formData.append(\n \"metadata\",\n new Blob([JSON.stringify(body[\"metadata\"])], {\n type: \"application/json\",\n }),\n \"\",\n );\n }\n }\n if (body[\"file\"] !== undefined) {\n formData.append(\"file\", body[\"file\"]);\n }\n\n const res = await fetch(url, {\n ...options,\n method: \"PUT\",\n body: formData,\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const responseBody = [204, 205, 304].includes(res.status)\n ? null\n : await res.text();\n const payload: FileMetadata = responseBody ? JSON.parse(responseBody) : {};\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<FileMetadata>;\n };\n\n const getFilePresignedURL = async (\n id: string,\n options?: RequestInit,\n ): Promise<FetchResponse<PresignedURLResponse>> => {\n const url = `${baseURL}/files/${id}/presignedurl`;\n const res = await fetch(url, {\n ...options,\n method: \"GET\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const responseBody = [204, 205, 304].includes(res.status)\n ? null\n : await res.text();\n const payload: PresignedURLResponse = responseBody\n ? JSON.parse(responseBody)\n : {};\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<PresignedURLResponse>;\n };\n\n const deleteBrokenMetadata = async (\n options?: RequestInit,\n ): Promise<FetchResponse<DeleteBrokenMetadataResponse200>> => {\n const url = `${baseURL}/ops/delete-broken-metadata`;\n const res = await fetch(url, {\n ...options,\n method: \"POST\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const responseBody = [204, 205, 304].includes(res.status)\n ? null\n : await res.text();\n const payload: DeleteBrokenMetadataResponse200 = responseBody\n ? JSON.parse(responseBody)\n : {};\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<DeleteBrokenMetadataResponse200>;\n };\n\n const deleteOrphanedFiles = async (\n options?: RequestInit,\n ): Promise<FetchResponse<DeleteOrphanedFilesResponse200>> => {\n const url = `${baseURL}/ops/delete-orphans`;\n const res = await fetch(url, {\n ...options,\n method: \"POST\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const responseBody = [204, 205, 304].includes(res.status)\n ? null\n : await res.text();\n const payload: DeleteOrphanedFilesResponse200 = responseBody\n ? JSON.parse(responseBody)\n : {};\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<DeleteOrphanedFilesResponse200>;\n };\n\n const listBrokenMetadata = async (\n options?: RequestInit,\n ): Promise<FetchResponse<ListBrokenMetadataResponse200>> => {\n const url = `${baseURL}/ops/list-broken-metadata`;\n const res = await fetch(url, {\n ...options,\n method: \"POST\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const responseBody = [204, 205, 304].includes(res.status)\n ? null\n : await res.text();\n const payload: ListBrokenMetadataResponse200 = responseBody\n ? JSON.parse(responseBody)\n : {};\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<ListBrokenMetadataResponse200>;\n };\n\n const listFilesNotUploaded = async (\n options?: RequestInit,\n ): Promise<FetchResponse<ListFilesNotUploadedResponse200>> => {\n const url = `${baseURL}/ops/list-not-uploaded`;\n const res = await fetch(url, {\n ...options,\n method: \"POST\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const responseBody = [204, 205, 304].includes(res.status)\n ? null\n : await res.text();\n const payload: ListFilesNotUploadedResponse200 = responseBody\n ? JSON.parse(responseBody)\n : {};\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<ListFilesNotUploadedResponse200>;\n };\n\n const listOrphanedFiles = async (\n options?: RequestInit,\n ): Promise<FetchResponse<ListOrphanedFilesResponse200>> => {\n const url = `${baseURL}/ops/list-orphans`;\n const res = await fetch(url, {\n ...options,\n method: \"POST\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const responseBody = [204, 205, 304].includes(res.status)\n ? null\n : await res.text();\n const payload: ListOrphanedFilesResponse200 = responseBody\n ? JSON.parse(responseBody)\n : {};\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<ListOrphanedFilesResponse200>;\n };\n\n const getVersion = async (\n options?: RequestInit,\n ): Promise<FetchResponse<VersionInformation>> => {\n const url = `${baseURL}/version`;\n const res = await fetch(url, {\n ...options,\n method: \"GET\",\n headers: {\n ...options?.headers,\n },\n });\n\n if (res.status >= 300) {\n const responseBody = [412].includes(res.status) ? null : await res.text();\n const payload: unknown = responseBody ? JSON.parse(responseBody) : {};\n throw new FetchError(payload, res.status, res.headers);\n }\n\n const responseBody = [204, 205, 304].includes(res.status)\n ? null\n : await res.text();\n const payload: VersionInformation = responseBody\n ? JSON.parse(responseBody)\n : {};\n\n return {\n body: payload,\n status: res.status,\n headers: res.headers,\n } as FetchResponse<VersionInformation>;\n };\n\n return {\n baseURL,\n pushChainFunction,\n uploadFiles,\n deleteFile,\n getFile,\n getFileMetadataHeaders,\n replaceFile,\n getFilePresignedURL,\n deleteBrokenMetadata,\n deleteOrphanedFiles,\n listBrokenMetadata,\n listFilesNotUploaded,\n listOrphanedFiles,\n getVersion,\n };\n};\n"],"names":["responseBody","payload"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./nhost-js/auth.cjs"),s=require("./middlewareWithAdminSession-DDApoLkL.cjs"),t=require("./nhost-js/functions.cjs"),n=require("./nhost-js/graphql.cjs"),o=require("./refreshSession-Bw715ZmX.cjs"),r=require("./nhost-js/session.cjs"),i=require("./nhost-js/storage.cjs"),a=({auth:e,storage:t,graphql:n,functions:o,sessionStorage:r})=>{const i=[s.sessionRefreshMiddleware(e,r),s.updateSessionFromResponseMiddleware(r),s.attachAccessTokenMiddleware(r)];for(const s of i)e.pushChainFunction(s),t.pushChainFunction(s),n.pushChainFunction(s),o.pushChainFunction(s)},c=({auth:e,storage:t,graphql:n,functions:o,sessionStorage:r})=>{const i=[s.updateSessionFromResponseMiddleware(r),s.attachAccessTokenMiddleware(r)];for(const s of i)e.pushChainFunction(s),t.pushChainFunction(s),n.pushChainFunction(s),o.pushChainFunction(s)};class u{auth;storage;graphql;functions;sessionStorage;constructor(e,s,t,n,o){this.auth=e,this.storage=s,this.graphql=t,this.functions=n,this.sessionStorage=o}getUserSession(){return this.sessionStorage.get()}async refreshSession(e=60){return o.refreshSession(this.auth,this.sessionStorage,e)}clearSession(){this.sessionStorage.remove()}}function h(s={}){const{subdomain:o,region:a,authUrl:c,storageUrl:h,graphqlUrl:l,functionsUrl:p,storage:S=r.detectStorage(),configure:d=[]}=s,f=new r.SessionStorage(S),C=g("auth",o,a,c),q=g("storage",o,a,h),w=g("graphql",o,a,l),j=g("functions",o,a,p),F=e.createAPIClient(C),m=i.createAPIClient(q,[]),A=n.createAPIClient(w,[]),M=t.createAPIClient(j,[]);for(const e of d)e({auth:F,storage:m,graphql:A,functions:M,sessionStorage:f});return new u(F,m,A,M,f)}const g=(e,s,t,n)=>n||(s&&t?`https://${s}.${e}.${t}.nhost.run/v1`:`https://local.${e}.local.nhost.run/v1`);exports.createClient=function(e={}){const s=e.storage??r.detectStorage();return h({...e,storage:s,configure:[a,...e.configure??[]]})},exports.createNhostClient=h,exports.createServerClient=function(e){return h({...e,configure:[c,...e.configure??[]]})},exports.generateServiceUrl=g,exports.withAdminSession=function(e){return({storage:t,graphql:n,functions:o})=>{const r=s.withAdminSessionMiddleware(e);t.pushChainFunction(r),n.pushChainFunction(r),o.pushChainFunction(r)}},exports.withClientSideSessionMiddleware=a,exports.withServerSideSessionMiddleware=c;
|
|
2
|
+
//# sourceMappingURL=nhost-js.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nhost-js.cjs","sources":["../src/nhost.ts","../src/index.ts"],"sourcesContent":["import { generateServiceUrl } from \"./\";\nimport {\n type Client as AuthClient,\n createAPIClient as createAuthClient,\n} from \"./auth\";\nimport {\n type AdminSessionOptions,\n attachAccessTokenMiddleware,\n type ChainFunction,\n sessionRefreshMiddleware,\n updateSessionFromResponseMiddleware,\n withAdminSessionMiddleware,\n} from \"./fetch\";\nimport {\n createAPIClient as createFunctionsClient,\n type Client as FunctionsClient,\n} from \"./functions\";\nimport {\n createAPIClient as createGraphQLClient,\n type Client as GraphQLClient,\n} from \"./graphql\";\nimport {\n detectStorage,\n refreshSession,\n type Session,\n SessionStorage,\n type SessionStorageBackend,\n} from \"./session/\";\nimport {\n createAPIClient as createStorageClient,\n type Client as StorageClient,\n} from \"./storage\";\n\n/**\n * Configuration function that receives all clients and can configure them\n * (e.g., by attaching middleware, setting up interceptors, etc.)\n */\nexport type ClientConfigurationFn = (clients: {\n auth: AuthClient;\n storage: StorageClient;\n graphql: GraphQLClient;\n functions: FunctionsClient;\n sessionStorage: SessionStorage;\n}) => void;\n\n/**\n * Built-in configuration for client-side applications.\n * Includes automatic session refresh, token attachment, and session updates.\n */\nexport const withClientSideSessionMiddleware: ClientConfigurationFn = ({\n auth,\n storage,\n graphql,\n functions,\n sessionStorage,\n}) => {\n const mwChain: ChainFunction[] = [\n sessionRefreshMiddleware(auth, sessionStorage),\n updateSessionFromResponseMiddleware(sessionStorage),\n attachAccessTokenMiddleware(sessionStorage),\n ];\n\n for (const mw of mwChain) {\n auth.pushChainFunction(mw);\n storage.pushChainFunction(mw);\n graphql.pushChainFunction(mw);\n functions.pushChainFunction(mw);\n }\n};\n\n/**\n * Built-in configuration for server-side applications.\n * Includes token attachment and session updates, but NOT automatic session refresh\n * to prevent race conditions in server contexts.\n */\nexport const withServerSideSessionMiddleware: ClientConfigurationFn = ({\n auth,\n storage,\n graphql,\n functions,\n sessionStorage,\n}) => {\n const mwChain: ChainFunction[] = [\n updateSessionFromResponseMiddleware(sessionStorage),\n attachAccessTokenMiddleware(sessionStorage),\n ];\n\n for (const mw of mwChain) {\n auth.pushChainFunction(mw);\n storage.pushChainFunction(mw);\n graphql.pushChainFunction(mw);\n functions.pushChainFunction(mw);\n }\n};\n\n/**\n * Configuration for admin clients with elevated privileges.\n * Applies admin session middleware to storage, graphql, and functions clients only.\n *\n * **Security Warning**: Never use this in client-side code. Admin secrets grant\n * unrestricted access to your entire database.\n *\n * @param adminSession - Admin session options including admin secret, role, and session variables\n * @returns Configuration function that sets up admin middleware\n */\nexport function withAdminSession(\n adminSession: AdminSessionOptions,\n): ClientConfigurationFn {\n return ({ storage, graphql, functions }) => {\n const adminMiddleware = withAdminSessionMiddleware(adminSession);\n\n storage.pushChainFunction(adminMiddleware);\n graphql.pushChainFunction(adminMiddleware);\n functions.pushChainFunction(adminMiddleware);\n };\n}\n\n/**\n * Configuration for adding custom chain functions to all clients.\n * Useful for adding custom middleware like logging, caching, or custom headers.\n *\n * @param chainFunctions - Array of chain functions to apply to all clients\n * @returns Configuration function that sets up custom middleware\n */\nexport function withChainFunctions(\n chainFunctions: ChainFunction[],\n): ClientConfigurationFn {\n return ({ auth, storage, graphql, functions }) => {\n for (const mw of chainFunctions) {\n auth.pushChainFunction(mw);\n storage.pushChainFunction(mw);\n graphql.pushChainFunction(mw);\n functions.pushChainFunction(mw);\n }\n };\n}\n\n/**\n * Main client class that provides unified access to all Nhost services.\n * This class serves as the central interface for interacting with Nhost's\n * authentication, storage, GraphQL, and serverless functions capabilities.\n */\nexport class NhostClient {\n /**\n * Authentication client providing methods for user sign-in, sign-up, and session management.\n * Use this client to handle all authentication-related operations.\n */\n auth: AuthClient;\n\n /**\n * Storage client providing methods for file operations (upload, download, delete).\n * Use this client to manage files in your Nhost storage.\n */\n storage: StorageClient;\n\n /**\n * GraphQL client providing methods for executing GraphQL operations against your Hasura backend.\n * Use this client to query and mutate data in your database through GraphQL.\n */\n graphql: GraphQLClient;\n\n /**\n * Functions client providing methods for invoking serverless functions.\n * Use this client to call your custom serverless functions deployed to Nhost.\n */\n functions: FunctionsClient;\n\n /**\n * Storage implementation used for persisting session information.\n * This handles saving, retrieving, and managing authentication sessions across requests.\n */\n sessionStorage: SessionStorage;\n\n /**\n * Create a new Nhost client. This constructor is reserved for advanced use cases.\n * For typical usage, use [createClient](#createclient) or [createServerClient](#createserverclient) instead.\n *\n * @param auth - Authentication client instance\n * @param storage - Storage client instance\n * @param graphql - GraphQL client instance\n * @param functions - Functions client instance\n * @param sessionStorage - Storage implementation for session persistence\n */\n constructor(\n auth: AuthClient,\n storage: StorageClient,\n graphql: GraphQLClient,\n functions: FunctionsClient,\n sessionStorage: SessionStorage,\n ) {\n this.auth = auth;\n this.storage = storage;\n this.graphql = graphql;\n this.functions = functions;\n this.sessionStorage = sessionStorage;\n }\n\n /**\n * Get the current session from storage.\n * This method retrieves the authenticated user's session information if one exists.\n *\n * @returns The current session or null if no session exists\n *\n * @example\n * ```ts\n * const session = nhost.getUserSession();\n * if (session) {\n * console.log('User is authenticated:', session.user.id);\n * } else {\n * console.log('No active session');\n * }\n * ```\n */\n getUserSession(): Session | null {\n return this.sessionStorage.get();\n }\n\n /**\n * Refresh the session using the current refresh token\n * in the storage and update the storage with the new session.\n *\n * This method can be used to proactively refresh tokens before they expire\n * or to force a refresh when needed.\n *\n * @param marginSeconds - The number of seconds before the token expiration to refresh the session. If the token is still valid for this duration, it will not be refreshed. Set to 0 to force the refresh.\n *\n * @returns The new session or null if there is currently no session or if refresh fails\n *\n * @example\n * ```ts\n * // Refresh token if it's about to expire in the next 5 minutes\n * const refreshedSession = await nhost.refreshSession(300);\n *\n * // Force refresh regardless of current token expiration\n * const forcedRefresh = await nhost.refreshSession(0);\n * ```\n */\n async refreshSession(marginSeconds = 60): Promise<Session | null> {\n return refreshSession(this.auth, this.sessionStorage, marginSeconds);\n }\n\n /**\n * Clear the session from storage.\n *\n * This method removes the current authentication session, effectively logging out the user.\n * Note that this is a client-side operation and doesn't invalidate the refresh token on\n * the server, which can be done with `nhost.auth.signOut({refreshToken: session.refreshTokenId})`.\n * If the middle `updateSessionFromResponseMiddleware` is used, the session will be removed\n * from the storage automatically and calling this method is not necessary.\n *\n * @example\n * ```ts\n * // Log out the user\n * nhost.clearSession();\n * ```\n */\n clearSession(): void {\n this.sessionStorage.remove();\n }\n}\n\n/**\n * Configuration options for creating an Nhost client\n */\nexport interface NhostClientOptions {\n /**\n * Nhost project subdomain (e.g., 'abcdefgh'). Used to construct the base URL for services for the Nhost cloud.\n */\n subdomain?: string;\n\n /**\n * Nhost region (e.g., 'eu-central-1'). Used to construct the base URL for services for the Nhost cloud.\n */\n region?: string;\n\n /**\n * Complete base URL for the auth service (overrides subdomain/region)\n */\n authUrl?: string;\n\n /**\n * Complete base URL for the storage service (overrides subdomain/region)\n */\n storageUrl?: string;\n\n /**\n * Complete base URL for the GraphQL service (overrides subdomain/region)\n */\n graphqlUrl?: string;\n\n /**\n * Complete base URL for the functions service (overrides subdomain/region)\n */\n functionsUrl?: string;\n\n /**\n * Storage backend to use for session persistence. If not provided, the SDK will\n * default to localStorage in the browser or memory in other environments.\n */\n storage?: SessionStorageBackend;\n\n /**\n * Configuration functions to be applied to the client after initialization.\n * These functions receive all clients and can attach middleware or perform other setup.\n */\n configure?: ClientConfigurationFn[];\n}\n\n/**\n * Creates and configures a new Nhost client instance with custom configuration.\n *\n * This is the main factory function for creating Nhost clients. It instantiates\n * all service clients (auth, storage, graphql, functions) and applies the provided\n * configuration functions to set up middleware and other customizations.\n *\n * @param options - Configuration options for the client\n * @returns A configured Nhost client\n *\n * @example\n * ```ts\n * // Create a basic client with no middleware\n * const nhost = createNhostClient({\n * subdomain: 'abcdefgh',\n * region: 'eu-central-1',\n * configure: []\n * });\n *\n * // Create a client with custom configuration\n * const nhost = createNhostClient({\n * subdomain: 'abcdefgh',\n * region: 'eu-central-1',\n * configure: [\n * withClientSideSessionMiddleware,\n * withChainFunctions([customLoggingMiddleware])\n * ]\n * });\n *\n * // Create an admin client\n * const nhost = createNhostClient({\n * subdomain,\n * region,\n * configure: [\n * withAdminSession({\n * adminSecret: \"nhost-admin-secret\",\n * role: \"user\",\n * sessionVariables: {\n * \"user-id\": \"54058C42-51F7-4B37-8B69-C89A841D2221\",\n * },\n * }),\n * ],\n * });\n\n * ```\n */\nexport function createNhostClient(\n options: NhostClientOptions = {},\n): NhostClient {\n const {\n subdomain,\n region,\n authUrl,\n storageUrl,\n graphqlUrl,\n functionsUrl,\n storage = detectStorage(),\n configure = [],\n } = options;\n\n const sessionStorage = new SessionStorage(storage);\n\n // Determine base URLs for each service\n const authBaseUrl = generateServiceUrl(\"auth\", subdomain, region, authUrl);\n const storageBaseUrl = generateServiceUrl(\n \"storage\",\n subdomain,\n region,\n storageUrl,\n );\n const graphqlBaseUrl = generateServiceUrl(\n \"graphql\",\n subdomain,\n region,\n graphqlUrl,\n );\n const functionsBaseUrl = generateServiceUrl(\n \"functions\",\n subdomain,\n region,\n functionsUrl,\n );\n\n // Create all clients\n const auth = createAuthClient(authBaseUrl);\n const storageClient = createStorageClient(storageBaseUrl, []);\n const graphqlClient = createGraphQLClient(graphqlBaseUrl, []);\n const functionsClient = createFunctionsClient(functionsBaseUrl, []);\n\n // Apply configuration functions\n for (const configFn of configure) {\n configFn({\n auth,\n storage: storageClient,\n graphql: graphqlClient,\n functions: functionsClient,\n sessionStorage,\n });\n }\n\n // Return an initialized NhostClient\n return new NhostClient(\n auth,\n storageClient,\n graphqlClient,\n functionsClient,\n sessionStorage,\n );\n}\n\n/**\n * Creates and configures a new Nhost client instance optimized for client-side usage.\n *\n * This helper method instantiates a fully configured Nhost client by:\n * - Instantiating the various service clients (auth, storage, functions and graphql)\n * - Auto-detecting and configuring an appropriate session storage (localStorage in browsers, memory otherwise)\n * - Setting up a sophisticated middleware chain for seamless authentication management:\n * - Automatically refreshing tokens before they expire\n * - Attaching authorization tokens to all service requests\n * - Updating the session storage when new tokens are received\n *\n * This method includes automatic session refresh middleware, making it ideal for\n * client-side applications where long-lived sessions are expected.\n *\n * @param options - Configuration options for the client\n * @returns A configured Nhost client\n *\n * @example\n * ```ts\n * // Create client using Nhost cloud default URLs\n * const nhost = createClient({\n * subdomain: 'abcdefgh',\n * region: 'eu-central-1'\n * });\n *\n * // Create client with custom service URLs\n * const customNhost = createClient({\n * authUrl: 'https://auth.example.com',\n * storageUrl: 'https://storage.example.com',\n * graphqlUrl: 'https://graphql.example.com',\n * functionsUrl: 'https://functions.example.com'\n * });\n *\n * // Create client using cookies for storing the session\n * import { CookieStorage } from \"@nhost/nhost-js/session\";\n *\n * const nhost = createClient({\n * subdomain: 'abcdefgh',\n * region: 'eu-central-1',\n * storage: new CookieStorage({\n * secure: import.meta.env.ENVIRONMENT === 'production',\n * })\n * });\n *\n * // Create client with additional custom middleware\n * const nhost = createClient({\n * subdomain: 'abcdefgh',\n * region: 'eu-central-1',\n * configure: [customLoggingMiddleware]\n * });\n * ```\n */\nexport function createClient(options: NhostClientOptions = {}): NhostClient {\n const storage = options.storage ?? detectStorage();\n\n return createNhostClient({\n ...options,\n storage,\n configure: [withClientSideSessionMiddleware, ...(options.configure ?? [])],\n });\n}\n\nexport interface NhostServerClientOptions extends NhostClientOptions {\n /**\n * Storage backend to use for session persistence in server environments.\n * Unlike the base options, this field is required for server-side usage\n * as the SDK cannot auto-detect an appropriate storage mechanism.\n */\n storage: SessionStorageBackend;\n}\n\n/**\n * Creates and configures a new Nhost client instance optimized for server-side usage.\n *\n * This helper method instantiates a fully configured Nhost client specifically designed for:\n * - Server components (in frameworks like Next.js or Remix)\n * - API routes and middleware\n * - Backend services and server-side rendering contexts\n *\n * Key differences from the standard client:\n * - Requires explicit storage implementation (must be provided)\n * - Disables automatic session refresh middleware (to prevent race conditions in server contexts)\n * - Still attaches authorization tokens and updates session storage from responses\n *\n * The server client is ideal for short-lived request contexts where session tokens\n * are passed in (like cookie-based authentication flows) and automatic refresh\n * mechanisms could cause issues with concurrent requests.\n *\n * @param options - Configuration options for the server client (requires storage implementation)\n * @returns A configured Nhost client optimized for server-side usage\n *\n * @example\n * ```ts\n * // Example with cookie storage for Next.js API route or server component\n * import { cookies } from 'next/headers';\n *\n * const nhost = createServerClient({\n * region: process.env[\"NHOST_REGION\"] || \"local\",\n * subdomain: process.env[\"NHOST_SUBDOMAIN\"] || \"local\",\n * storage: {\n * // storage compatible with Next.js server components\n * get: (): Session | null => {\n * const s = cookieStore.get(key)?.value || null;\n * if (!s) {\n * return null;\n * }\n * const session = JSON.parse(s) as Session;\n * return session;\n * },\n * set: (value: Session) => {\n * cookieStore.set(key, JSON.stringify(value));\n * },\n * remove: () => {\n * cookieStore.delete(key);\n * },\n * },\n * });\n *\n * // Example with cookie storage for Next.js middleware\n * const nhost = createServerClient({\n * region: process.env[\"NHOST_REGION\"] || \"local\",\n * subdomain: process.env[\"NHOST_SUBDOMAIN\"] || \"local\",\n * storage: {\n * // storage compatible with Next.js middleware\n * get: (): Session | null => {\n * const raw = request.cookies.get(key)?.value || null;\n * if (!raw) {\n * return null;\n * }\n * const session = JSON.parse(raw) as Session;\n * return session;\n * },\n * set: (value: Session) => {\n * response.cookies.set({\n * name: key,\n * value: JSON.stringify(value),\n * path: \"/\",\n * httpOnly: false, //if set to true we can't access it in the client\n * secure: process.env.NODE_ENV === \"production\",\n * sameSite: \"lax\",\n * maxAge: 60 * 60 * 24 * 30, // 30 days in seconds\n * });\n * },\n * remove: () => {\n * response.cookies.delete(key);\n * },\n * },\n * });\n *\n * // Example for express reading session from a cookie\n *\n * import express, { Request, Response } from \"express\";\n * import cookieParser from \"cookie-parser\";\n *\n * app.use(cookieParser());\n *\n * const nhostClientFromCookies = (req: Request) => {\n * return createServerClient({\n * subdomain: \"local\",\n * region: \"local\",\n * storage: {\n * get: (): Session | null => {\n * const s = req.cookies.nhostSession || null;\n * if (!s) {\n * return null;\n * }\n * const session = JSON.parse(s) as Session;\n * return session;\n * },\n * set: (_value: Session) => {\n * throw new Error(\"It is easier to handle the session in the client\");\n * },\n * remove: () => {\n * throw new Error(\"It is easier to handle the session in the client\");\n * },\n * },\n * });\n * };\n *\n * // Example with additional custom middleware\n * const nhost = createServerClient({\n * region: process.env[\"NHOST_REGION\"] || \"local\",\n * subdomain: process.env[\"NHOST_SUBDOMAIN\"] || \"local\",\n * storage: myStorage,\n * configure: [customLoggingMiddleware]\n * });\n * ```\n */\nexport function createServerClient(\n options: NhostServerClientOptions,\n): NhostClient {\n return createNhostClient({\n ...options,\n configure: [withServerSideSessionMiddleware, ...(options.configure ?? [])],\n });\n}\n","/**\n * Main entry point for the Nhost JavaScript SDK.\n *\n * This package provides a unified client for interacting with Nhost services:\n * - Authentication\n * - Storage\n * - GraphQL\n * - Functions\n *\n * ## Import\n *\n * ```ts\n * import { createClient } from \"@nhost/nhost-js\";\n * ```\n *\n * ## Usage\n *\n * Create a client instance to interact with Nhost services:\n *\n * {@includeCode ./__tests__/docstrings.test.ts:15-119}\n *\n * ### Creating an admin client\n *\n * You can also create an admin client if needed. This client will have admin access to the database\n * and will bypass permissions. Additionally, it can impersonate users and set any role or session\n * variable.\n *\n * IMPORTANT!!! Keep your admin secret safe and never expose it in client-side code.\n *\n * {@includeCode ./__tests__/docstrings.test.ts:142-201}\n *\n * @packageDocumentation\n */\n\nexport {\n type ClientConfigurationFn,\n createClient,\n createNhostClient,\n createServerClient,\n type NhostClient,\n type NhostClientOptions,\n type NhostServerClientOptions,\n withAdminSession,\n withClientSideSessionMiddleware,\n withServerSideSessionMiddleware,\n} from \"./nhost\";\n\n/**\n * Generates a base URL for a Nhost service based on configuration\n *\n * @param serviceType - Type of service (auth, storage, graphql, functions)\n * @param subdomain - Nhost project subdomain\n * @param region - Nhost region\n * @param customUrl - Custom URL override if provided\n * @returns The base URL for the service\n */\nexport const generateServiceUrl = (\n serviceType: \"auth\" | \"storage\" | \"graphql\" | \"functions\",\n subdomain?: string,\n region?: string,\n customUrl?: string,\n): string => {\n if (customUrl) {\n return customUrl;\n } else if (subdomain && region) {\n return `https://${subdomain}.${serviceType}.${region}.nhost.run/v1`;\n } else {\n return `https://local.${serviceType}.local.nhost.run/v1`;\n }\n};\n"],"names":["withClientSideSessionMiddleware","auth","storage","graphql","functions","sessionStorage","mwChain","sessionRefreshMiddleware","updateSessionFromResponseMiddleware","attachAccessTokenMiddleware","mw","pushChainFunction","withServerSideSessionMiddleware","NhostClient","constructor","this","getUserSession","get","refreshSession","marginSeconds","clearSession","remove","createNhostClient","options","subdomain","region","authUrl","storageUrl","graphqlUrl","functionsUrl","detectStorage","configure","SessionStorage","authBaseUrl","generateServiceUrl","storageBaseUrl","graphqlBaseUrl","functionsBaseUrl","createAuthClient","storageClient","createStorageClient","graphqlClient","createGraphQLClient","functionsClient","createFunctionsClient","configFn","serviceType","customUrl","adminSession","adminMiddleware","withAdminSessionMiddleware"],"mappings":"2WAiDaA,EAAyD,EACpEC,OACAC,UACAC,UACAC,YACAC,qBAEA,MAAMC,EAA2B,CAC/BC,EAAAA,yBAAyBN,EAAMI,GAC/BG,EAAAA,oCAAoCH,GACpCI,EAAAA,4BAA4BJ,IAG9B,IAAA,MAAWK,KAAMJ,EACfL,EAAKU,kBAAkBD,GACvBR,EAAQS,kBAAkBD,GAC1BP,EAAQQ,kBAAkBD,GAC1BN,EAAUO,kBAAkBD,EAC9B,EAQWE,EAAyD,EACpEX,OACAC,UACAC,UACAC,YACAC,qBAEA,MAAMC,EAA2B,CAC/BE,EAAAA,oCAAoCH,GACpCI,EAAAA,4BAA4BJ,IAG9B,IAAA,MAAWK,KAAMJ,EACfL,EAAKU,kBAAkBD,GACvBR,EAAQS,kBAAkBD,GAC1BP,EAAQQ,kBAAkBD,GAC1BN,EAAUO,kBAAkBD,EAC9B,EAkDK,MAAMG,EAKXZ,KAMAC,QAMAC,QAMAC,UAMAC,eAYA,WAAAS,CACEb,EACAC,EACAC,EACAC,EACAC,GAEAU,KAAKd,KAAOA,EACZc,KAAKb,QAAUA,EACfa,KAAKZ,QAAUA,EACfY,KAAKX,UAAYA,EACjBW,KAAKV,eAAiBA,CACxB,CAkBA,cAAAW,GACE,OAAOD,KAAKV,eAAeY,KAC7B,CAsBA,oBAAMC,CAAeC,EAAgB,IACnC,OAAOD,EAAAA,eAAeH,KAAKd,KAAMc,KAAKV,eAAgBc,EACxD,CAiBA,YAAAC,GACEL,KAAKV,eAAegB,QACtB,EAgGK,SAASC,EACdC,EAA8B,IAE9B,MAAMC,UACJA,EAAAC,OACAA,EAAAC,QACAA,EAAAC,WACAA,EAAAC,WACAA,EAAAC,aACAA,EAAA3B,QACAA,EAAU4B,EAAAA,gBAAAC,UACVA,EAAY,IACVR,EAEElB,EAAiB,IAAI2B,EAAAA,eAAe9B,GAGpC+B,EAAcC,EAAmB,OAAQV,EAAWC,EAAQC,GAC5DS,EAAiBD,EACrB,UACAV,EACAC,EACAE,GAEIS,EAAiBF,EACrB,UACAV,EACAC,EACAG,GAEIS,EAAmBH,EACvB,YACAV,EACAC,EACAI,GAII5B,EAAOqC,EAAAA,gBAAiBL,GACxBM,EAAgBC,EAAAA,gBAAoBL,EAAgB,IACpDM,EAAgBC,EAAAA,gBAAoBN,EAAgB,IACpDO,EAAkBC,EAAAA,gBAAsBP,EAAkB,IAGhE,IAAA,MAAWQ,KAAYd,EACrBc,EAAS,CACP5C,OACAC,QAASqC,EACTpC,QAASsC,EACTrC,UAAWuC,EACXtC,mBAKJ,OAAO,IAAIQ,EACTZ,EACAsC,EACAE,EACAE,EACAtC,EAEJ,CCxWO,MAAM6B,EAAqB,CAChCY,EACAtB,EACAC,EACAsB,IAEIA,IAEOvB,GAAaC,EACf,WAAWD,KAAasB,KAAerB,iBAEvC,iBAAiBqB,6CDmZrB,SAAsBvB,EAA8B,IACzD,MAAMrB,EAAUqB,EAAQrB,SAAW4B,kBAEnC,OAAOR,EAAkB,IACpBC,EACHrB,UACA6B,UAAW,CAAC/B,KAAqCuB,EAAQQ,WAAa,KAE1E,yDAgIO,SACLR,GAEA,OAAOD,EAAkB,IACpBC,EACHQ,UAAW,CAACnB,KAAqCW,EAAQQ,WAAa,KAE1E,wDA5fO,SACLiB,GAEA,MAAO,EAAG9C,UAASC,UAASC,gBAC1B,MAAM6C,EAAkBC,EAAAA,2BAA2BF,GAEnD9C,EAAQS,kBAAkBsC,GAC1B9C,EAAQQ,kBAAkBsC,GAC1B7C,EAAUO,kBAAkBsC,EAAe,CAE/C"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { createAPIClient } from "./nhost-js/auth.
|
|
2
|
-
import { w as withAdminSessionMiddleware, s as sessionRefreshMiddleware, u as updateSessionFromResponseMiddleware, a as attachAccessTokenMiddleware } from "./middlewareWithAdminSession-
|
|
3
|
-
import { createAPIClient as createAPIClient$3 } from "./nhost-js/functions.
|
|
4
|
-
import { createAPIClient as createAPIClient$2 } from "./nhost-js/graphql.
|
|
5
|
-
import { r as refreshSession } from "./refreshSession-CG8GIEun.
|
|
6
|
-
import { detectStorage, SessionStorage } from "./nhost-js/session.
|
|
7
|
-
import { createAPIClient as createAPIClient$1 } from "./nhost-js/storage.
|
|
1
|
+
import { createAPIClient } from "./nhost-js/auth.js";
|
|
2
|
+
import { w as withAdminSessionMiddleware, s as sessionRefreshMiddleware, u as updateSessionFromResponseMiddleware, a as attachAccessTokenMiddleware } from "./middlewareWithAdminSession-DLqDQUbW.js";
|
|
3
|
+
import { createAPIClient as createAPIClient$3 } from "./nhost-js/functions.js";
|
|
4
|
+
import { createAPIClient as createAPIClient$2 } from "./nhost-js/graphql.js";
|
|
5
|
+
import { r as refreshSession } from "./refreshSession-CG8GIEun.js";
|
|
6
|
+
import { detectStorage, SessionStorage } from "./nhost-js/session.js";
|
|
7
|
+
import { createAPIClient as createAPIClient$1 } from "./nhost-js/storage.js";
|
|
8
8
|
const withClientSideSessionMiddleware = ({
|
|
9
9
|
auth,
|
|
10
10
|
storage,
|
|
@@ -238,4 +238,4 @@ export {
|
|
|
238
238
|
withClientSideSessionMiddleware,
|
|
239
239
|
withServerSideSessionMiddleware
|
|
240
240
|
};
|
|
241
|
-
//# sourceMappingURL=nhost-js.
|
|
241
|
+
//# sourceMappingURL=nhost-js.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nhost-js.js","sources":["../src/nhost.ts","../src/index.ts"],"sourcesContent":["import { generateServiceUrl } from \"./\";\nimport {\n type Client as AuthClient,\n createAPIClient as createAuthClient,\n} from \"./auth\";\nimport {\n type AdminSessionOptions,\n attachAccessTokenMiddleware,\n type ChainFunction,\n sessionRefreshMiddleware,\n updateSessionFromResponseMiddleware,\n withAdminSessionMiddleware,\n} from \"./fetch\";\nimport {\n createAPIClient as createFunctionsClient,\n type Client as FunctionsClient,\n} from \"./functions\";\nimport {\n createAPIClient as createGraphQLClient,\n type Client as GraphQLClient,\n} from \"./graphql\";\nimport {\n detectStorage,\n refreshSession,\n type Session,\n SessionStorage,\n type SessionStorageBackend,\n} from \"./session/\";\nimport {\n createAPIClient as createStorageClient,\n type Client as StorageClient,\n} from \"./storage\";\n\n/**\n * Configuration function that receives all clients and can configure them\n * (e.g., by attaching middleware, setting up interceptors, etc.)\n */\nexport type ClientConfigurationFn = (clients: {\n auth: AuthClient;\n storage: StorageClient;\n graphql: GraphQLClient;\n functions: FunctionsClient;\n sessionStorage: SessionStorage;\n}) => void;\n\n/**\n * Built-in configuration for client-side applications.\n * Includes automatic session refresh, token attachment, and session updates.\n */\nexport const withClientSideSessionMiddleware: ClientConfigurationFn = ({\n auth,\n storage,\n graphql,\n functions,\n sessionStorage,\n}) => {\n const mwChain: ChainFunction[] = [\n sessionRefreshMiddleware(auth, sessionStorage),\n updateSessionFromResponseMiddleware(sessionStorage),\n attachAccessTokenMiddleware(sessionStorage),\n ];\n\n for (const mw of mwChain) {\n auth.pushChainFunction(mw);\n storage.pushChainFunction(mw);\n graphql.pushChainFunction(mw);\n functions.pushChainFunction(mw);\n }\n};\n\n/**\n * Built-in configuration for server-side applications.\n * Includes token attachment and session updates, but NOT automatic session refresh\n * to prevent race conditions in server contexts.\n */\nexport const withServerSideSessionMiddleware: ClientConfigurationFn = ({\n auth,\n storage,\n graphql,\n functions,\n sessionStorage,\n}) => {\n const mwChain: ChainFunction[] = [\n updateSessionFromResponseMiddleware(sessionStorage),\n attachAccessTokenMiddleware(sessionStorage),\n ];\n\n for (const mw of mwChain) {\n auth.pushChainFunction(mw);\n storage.pushChainFunction(mw);\n graphql.pushChainFunction(mw);\n functions.pushChainFunction(mw);\n }\n};\n\n/**\n * Configuration for admin clients with elevated privileges.\n * Applies admin session middleware to storage, graphql, and functions clients only.\n *\n * **Security Warning**: Never use this in client-side code. Admin secrets grant\n * unrestricted access to your entire database.\n *\n * @param adminSession - Admin session options including admin secret, role, and session variables\n * @returns Configuration function that sets up admin middleware\n */\nexport function withAdminSession(\n adminSession: AdminSessionOptions,\n): ClientConfigurationFn {\n return ({ storage, graphql, functions }) => {\n const adminMiddleware = withAdminSessionMiddleware(adminSession);\n\n storage.pushChainFunction(adminMiddleware);\n graphql.pushChainFunction(adminMiddleware);\n functions.pushChainFunction(adminMiddleware);\n };\n}\n\n/**\n * Configuration for adding custom chain functions to all clients.\n * Useful for adding custom middleware like logging, caching, or custom headers.\n *\n * @param chainFunctions - Array of chain functions to apply to all clients\n * @returns Configuration function that sets up custom middleware\n */\nexport function withChainFunctions(\n chainFunctions: ChainFunction[],\n): ClientConfigurationFn {\n return ({ auth, storage, graphql, functions }) => {\n for (const mw of chainFunctions) {\n auth.pushChainFunction(mw);\n storage.pushChainFunction(mw);\n graphql.pushChainFunction(mw);\n functions.pushChainFunction(mw);\n }\n };\n}\n\n/**\n * Main client class that provides unified access to all Nhost services.\n * This class serves as the central interface for interacting with Nhost's\n * authentication, storage, GraphQL, and serverless functions capabilities.\n */\nexport class NhostClient {\n /**\n * Authentication client providing methods for user sign-in, sign-up, and session management.\n * Use this client to handle all authentication-related operations.\n */\n auth: AuthClient;\n\n /**\n * Storage client providing methods for file operations (upload, download, delete).\n * Use this client to manage files in your Nhost storage.\n */\n storage: StorageClient;\n\n /**\n * GraphQL client providing methods for executing GraphQL operations against your Hasura backend.\n * Use this client to query and mutate data in your database through GraphQL.\n */\n graphql: GraphQLClient;\n\n /**\n * Functions client providing methods for invoking serverless functions.\n * Use this client to call your custom serverless functions deployed to Nhost.\n */\n functions: FunctionsClient;\n\n /**\n * Storage implementation used for persisting session information.\n * This handles saving, retrieving, and managing authentication sessions across requests.\n */\n sessionStorage: SessionStorage;\n\n /**\n * Create a new Nhost client. This constructor is reserved for advanced use cases.\n * For typical usage, use [createClient](#createclient) or [createServerClient](#createserverclient) instead.\n *\n * @param auth - Authentication client instance\n * @param storage - Storage client instance\n * @param graphql - GraphQL client instance\n * @param functions - Functions client instance\n * @param sessionStorage - Storage implementation for session persistence\n */\n constructor(\n auth: AuthClient,\n storage: StorageClient,\n graphql: GraphQLClient,\n functions: FunctionsClient,\n sessionStorage: SessionStorage,\n ) {\n this.auth = auth;\n this.storage = storage;\n this.graphql = graphql;\n this.functions = functions;\n this.sessionStorage = sessionStorage;\n }\n\n /**\n * Get the current session from storage.\n * This method retrieves the authenticated user's session information if one exists.\n *\n * @returns The current session or null if no session exists\n *\n * @example\n * ```ts\n * const session = nhost.getUserSession();\n * if (session) {\n * console.log('User is authenticated:', session.user.id);\n * } else {\n * console.log('No active session');\n * }\n * ```\n */\n getUserSession(): Session | null {\n return this.sessionStorage.get();\n }\n\n /**\n * Refresh the session using the current refresh token\n * in the storage and update the storage with the new session.\n *\n * This method can be used to proactively refresh tokens before they expire\n * or to force a refresh when needed.\n *\n * @param marginSeconds - The number of seconds before the token expiration to refresh the session. If the token is still valid for this duration, it will not be refreshed. Set to 0 to force the refresh.\n *\n * @returns The new session or null if there is currently no session or if refresh fails\n *\n * @example\n * ```ts\n * // Refresh token if it's about to expire in the next 5 minutes\n * const refreshedSession = await nhost.refreshSession(300);\n *\n * // Force refresh regardless of current token expiration\n * const forcedRefresh = await nhost.refreshSession(0);\n * ```\n */\n async refreshSession(marginSeconds = 60): Promise<Session | null> {\n return refreshSession(this.auth, this.sessionStorage, marginSeconds);\n }\n\n /**\n * Clear the session from storage.\n *\n * This method removes the current authentication session, effectively logging out the user.\n * Note that this is a client-side operation and doesn't invalidate the refresh token on\n * the server, which can be done with `nhost.auth.signOut({refreshToken: session.refreshTokenId})`.\n * If the middle `updateSessionFromResponseMiddleware` is used, the session will be removed\n * from the storage automatically and calling this method is not necessary.\n *\n * @example\n * ```ts\n * // Log out the user\n * nhost.clearSession();\n * ```\n */\n clearSession(): void {\n this.sessionStorage.remove();\n }\n}\n\n/**\n * Configuration options for creating an Nhost client\n */\nexport interface NhostClientOptions {\n /**\n * Nhost project subdomain (e.g., 'abcdefgh'). Used to construct the base URL for services for the Nhost cloud.\n */\n subdomain?: string;\n\n /**\n * Nhost region (e.g., 'eu-central-1'). Used to construct the base URL for services for the Nhost cloud.\n */\n region?: string;\n\n /**\n * Complete base URL for the auth service (overrides subdomain/region)\n */\n authUrl?: string;\n\n /**\n * Complete base URL for the storage service (overrides subdomain/region)\n */\n storageUrl?: string;\n\n /**\n * Complete base URL for the GraphQL service (overrides subdomain/region)\n */\n graphqlUrl?: string;\n\n /**\n * Complete base URL for the functions service (overrides subdomain/region)\n */\n functionsUrl?: string;\n\n /**\n * Storage backend to use for session persistence. If not provided, the SDK will\n * default to localStorage in the browser or memory in other environments.\n */\n storage?: SessionStorageBackend;\n\n /**\n * Configuration functions to be applied to the client after initialization.\n * These functions receive all clients and can attach middleware or perform other setup.\n */\n configure?: ClientConfigurationFn[];\n}\n\n/**\n * Creates and configures a new Nhost client instance with custom configuration.\n *\n * This is the main factory function for creating Nhost clients. It instantiates\n * all service clients (auth, storage, graphql, functions) and applies the provided\n * configuration functions to set up middleware and other customizations.\n *\n * @param options - Configuration options for the client\n * @returns A configured Nhost client\n *\n * @example\n * ```ts\n * // Create a basic client with no middleware\n * const nhost = createNhostClient({\n * subdomain: 'abcdefgh',\n * region: 'eu-central-1',\n * configure: []\n * });\n *\n * // Create a client with custom configuration\n * const nhost = createNhostClient({\n * subdomain: 'abcdefgh',\n * region: 'eu-central-1',\n * configure: [\n * withClientSideSessionMiddleware,\n * withChainFunctions([customLoggingMiddleware])\n * ]\n * });\n *\n * // Create an admin client\n * const nhost = createNhostClient({\n * subdomain,\n * region,\n * configure: [\n * withAdminSession({\n * adminSecret: \"nhost-admin-secret\",\n * role: \"user\",\n * sessionVariables: {\n * \"user-id\": \"54058C42-51F7-4B37-8B69-C89A841D2221\",\n * },\n * }),\n * ],\n * });\n\n * ```\n */\nexport function createNhostClient(\n options: NhostClientOptions = {},\n): NhostClient {\n const {\n subdomain,\n region,\n authUrl,\n storageUrl,\n graphqlUrl,\n functionsUrl,\n storage = detectStorage(),\n configure = [],\n } = options;\n\n const sessionStorage = new SessionStorage(storage);\n\n // Determine base URLs for each service\n const authBaseUrl = generateServiceUrl(\"auth\", subdomain, region, authUrl);\n const storageBaseUrl = generateServiceUrl(\n \"storage\",\n subdomain,\n region,\n storageUrl,\n );\n const graphqlBaseUrl = generateServiceUrl(\n \"graphql\",\n subdomain,\n region,\n graphqlUrl,\n );\n const functionsBaseUrl = generateServiceUrl(\n \"functions\",\n subdomain,\n region,\n functionsUrl,\n );\n\n // Create all clients\n const auth = createAuthClient(authBaseUrl);\n const storageClient = createStorageClient(storageBaseUrl, []);\n const graphqlClient = createGraphQLClient(graphqlBaseUrl, []);\n const functionsClient = createFunctionsClient(functionsBaseUrl, []);\n\n // Apply configuration functions\n for (const configFn of configure) {\n configFn({\n auth,\n storage: storageClient,\n graphql: graphqlClient,\n functions: functionsClient,\n sessionStorage,\n });\n }\n\n // Return an initialized NhostClient\n return new NhostClient(\n auth,\n storageClient,\n graphqlClient,\n functionsClient,\n sessionStorage,\n );\n}\n\n/**\n * Creates and configures a new Nhost client instance optimized for client-side usage.\n *\n * This helper method instantiates a fully configured Nhost client by:\n * - Instantiating the various service clients (auth, storage, functions and graphql)\n * - Auto-detecting and configuring an appropriate session storage (localStorage in browsers, memory otherwise)\n * - Setting up a sophisticated middleware chain for seamless authentication management:\n * - Automatically refreshing tokens before they expire\n * - Attaching authorization tokens to all service requests\n * - Updating the session storage when new tokens are received\n *\n * This method includes automatic session refresh middleware, making it ideal for\n * client-side applications where long-lived sessions are expected.\n *\n * @param options - Configuration options for the client\n * @returns A configured Nhost client\n *\n * @example\n * ```ts\n * // Create client using Nhost cloud default URLs\n * const nhost = createClient({\n * subdomain: 'abcdefgh',\n * region: 'eu-central-1'\n * });\n *\n * // Create client with custom service URLs\n * const customNhost = createClient({\n * authUrl: 'https://auth.example.com',\n * storageUrl: 'https://storage.example.com',\n * graphqlUrl: 'https://graphql.example.com',\n * functionsUrl: 'https://functions.example.com'\n * });\n *\n * // Create client using cookies for storing the session\n * import { CookieStorage } from \"@nhost/nhost-js/session\";\n *\n * const nhost = createClient({\n * subdomain: 'abcdefgh',\n * region: 'eu-central-1',\n * storage: new CookieStorage({\n * secure: import.meta.env.ENVIRONMENT === 'production',\n * })\n * });\n *\n * // Create client with additional custom middleware\n * const nhost = createClient({\n * subdomain: 'abcdefgh',\n * region: 'eu-central-1',\n * configure: [customLoggingMiddleware]\n * });\n * ```\n */\nexport function createClient(options: NhostClientOptions = {}): NhostClient {\n const storage = options.storage ?? detectStorage();\n\n return createNhostClient({\n ...options,\n storage,\n configure: [withClientSideSessionMiddleware, ...(options.configure ?? [])],\n });\n}\n\nexport interface NhostServerClientOptions extends NhostClientOptions {\n /**\n * Storage backend to use for session persistence in server environments.\n * Unlike the base options, this field is required for server-side usage\n * as the SDK cannot auto-detect an appropriate storage mechanism.\n */\n storage: SessionStorageBackend;\n}\n\n/**\n * Creates and configures a new Nhost client instance optimized for server-side usage.\n *\n * This helper method instantiates a fully configured Nhost client specifically designed for:\n * - Server components (in frameworks like Next.js or Remix)\n * - API routes and middleware\n * - Backend services and server-side rendering contexts\n *\n * Key differences from the standard client:\n * - Requires explicit storage implementation (must be provided)\n * - Disables automatic session refresh middleware (to prevent race conditions in server contexts)\n * - Still attaches authorization tokens and updates session storage from responses\n *\n * The server client is ideal for short-lived request contexts where session tokens\n * are passed in (like cookie-based authentication flows) and automatic refresh\n * mechanisms could cause issues with concurrent requests.\n *\n * @param options - Configuration options for the server client (requires storage implementation)\n * @returns A configured Nhost client optimized for server-side usage\n *\n * @example\n * ```ts\n * // Example with cookie storage for Next.js API route or server component\n * import { cookies } from 'next/headers';\n *\n * const nhost = createServerClient({\n * region: process.env[\"NHOST_REGION\"] || \"local\",\n * subdomain: process.env[\"NHOST_SUBDOMAIN\"] || \"local\",\n * storage: {\n * // storage compatible with Next.js server components\n * get: (): Session | null => {\n * const s = cookieStore.get(key)?.value || null;\n * if (!s) {\n * return null;\n * }\n * const session = JSON.parse(s) as Session;\n * return session;\n * },\n * set: (value: Session) => {\n * cookieStore.set(key, JSON.stringify(value));\n * },\n * remove: () => {\n * cookieStore.delete(key);\n * },\n * },\n * });\n *\n * // Example with cookie storage for Next.js middleware\n * const nhost = createServerClient({\n * region: process.env[\"NHOST_REGION\"] || \"local\",\n * subdomain: process.env[\"NHOST_SUBDOMAIN\"] || \"local\",\n * storage: {\n * // storage compatible with Next.js middleware\n * get: (): Session | null => {\n * const raw = request.cookies.get(key)?.value || null;\n * if (!raw) {\n * return null;\n * }\n * const session = JSON.parse(raw) as Session;\n * return session;\n * },\n * set: (value: Session) => {\n * response.cookies.set({\n * name: key,\n * value: JSON.stringify(value),\n * path: \"/\",\n * httpOnly: false, //if set to true we can't access it in the client\n * secure: process.env.NODE_ENV === \"production\",\n * sameSite: \"lax\",\n * maxAge: 60 * 60 * 24 * 30, // 30 days in seconds\n * });\n * },\n * remove: () => {\n * response.cookies.delete(key);\n * },\n * },\n * });\n *\n * // Example for express reading session from a cookie\n *\n * import express, { Request, Response } from \"express\";\n * import cookieParser from \"cookie-parser\";\n *\n * app.use(cookieParser());\n *\n * const nhostClientFromCookies = (req: Request) => {\n * return createServerClient({\n * subdomain: \"local\",\n * region: \"local\",\n * storage: {\n * get: (): Session | null => {\n * const s = req.cookies.nhostSession || null;\n * if (!s) {\n * return null;\n * }\n * const session = JSON.parse(s) as Session;\n * return session;\n * },\n * set: (_value: Session) => {\n * throw new Error(\"It is easier to handle the session in the client\");\n * },\n * remove: () => {\n * throw new Error(\"It is easier to handle the session in the client\");\n * },\n * },\n * });\n * };\n *\n * // Example with additional custom middleware\n * const nhost = createServerClient({\n * region: process.env[\"NHOST_REGION\"] || \"local\",\n * subdomain: process.env[\"NHOST_SUBDOMAIN\"] || \"local\",\n * storage: myStorage,\n * configure: [customLoggingMiddleware]\n * });\n * ```\n */\nexport function createServerClient(\n options: NhostServerClientOptions,\n): NhostClient {\n return createNhostClient({\n ...options,\n configure: [withServerSideSessionMiddleware, ...(options.configure ?? [])],\n });\n}\n","/**\n * Main entry point for the Nhost JavaScript SDK.\n *\n * This package provides a unified client for interacting with Nhost services:\n * - Authentication\n * - Storage\n * - GraphQL\n * - Functions\n *\n * ## Import\n *\n * ```ts\n * import { createClient } from \"@nhost/nhost-js\";\n * ```\n *\n * ## Usage\n *\n * Create a client instance to interact with Nhost services:\n *\n * {@includeCode ./__tests__/docstrings.test.ts:15-119}\n *\n * ### Creating an admin client\n *\n * You can also create an admin client if needed. This client will have admin access to the database\n * and will bypass permissions. Additionally, it can impersonate users and set any role or session\n * variable.\n *\n * IMPORTANT!!! Keep your admin secret safe and never expose it in client-side code.\n *\n * {@includeCode ./__tests__/docstrings.test.ts:142-201}\n *\n * @packageDocumentation\n */\n\nexport {\n type ClientConfigurationFn,\n createClient,\n createNhostClient,\n createServerClient,\n type NhostClient,\n type NhostClientOptions,\n type NhostServerClientOptions,\n withAdminSession,\n withClientSideSessionMiddleware,\n withServerSideSessionMiddleware,\n} from \"./nhost\";\n\n/**\n * Generates a base URL for a Nhost service based on configuration\n *\n * @param serviceType - Type of service (auth, storage, graphql, functions)\n * @param subdomain - Nhost project subdomain\n * @param region - Nhost region\n * @param customUrl - Custom URL override if provided\n * @returns The base URL for the service\n */\nexport const generateServiceUrl = (\n serviceType: \"auth\" | \"storage\" | \"graphql\" | \"functions\",\n subdomain?: string,\n region?: string,\n customUrl?: string,\n): string => {\n if (customUrl) {\n return customUrl;\n } else if (subdomain && region) {\n return `https://${subdomain}.${serviceType}.${region}.nhost.run/v1`;\n } else {\n return `https://local.${serviceType}.local.nhost.run/v1`;\n }\n};\n"],"names":["createAuthClient","createStorageClient","createGraphQLClient","createFunctionsClient"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use strict";const e="undefined"!=typeof navigator&&navigator.locks?navigator.locks:new class{async request(e,s,r){return r()}},s=async(s,n,o=60)=>{const{session:t,needsRefresh:i}=await e.request("nhostSessionLock",{mode:"shared"},(async()=>r(n,o)));if(!t)return null;if(!i)return t;return await e.request("nhostSessionLock",{mode:"exclusive"},(async()=>{const{session:e,needsRefresh:t,sessionExpired:i}=r(n,o);if(!e)return null;if(!t)return e;try{const r=await s.refreshToken({refreshToken:e.refreshToken});return n.set(r.body),r.body}catch(d){if(!i)return e;throw d}}))},r=(e,s=60)=>{const r=e.get();if(!r)return{session:null,needsRefresh:!1,sessionExpired:!1};if(!r.decodedToken||!r.decodedToken.exp)return{session:r,needsRefresh:!0,sessionExpired:!0};if(0===s)return{session:r,needsRefresh:!0,sessionExpired:!1};const n=Date.now();return r.decodedToken.exp-n>1e3*s?{session:r,needsRefresh:!1,sessionExpired:!1}:{session:r,needsRefresh:!0,sessionExpired:r.decodedToken.exp<n}};exports.refreshSession=async(e,r,n=60)=>{try{return await s(e,r,n)}catch(o){try{return console.warn("error refreshing session, retrying:",o),await s(e,r,n)}catch(t){const e=t;return 401===e?.status&&(console.error("session probably expired"),r.remove()),null}}};
|
|
2
|
-
//# sourceMappingURL=refreshSession-Bw715ZmX.
|
|
2
|
+
//# sourceMappingURL=refreshSession-Bw715ZmX.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refreshSession-
|
|
1
|
+
{"version":3,"file":"refreshSession-Bw715ZmX.cjs","sources":["../src/session/refreshSession.ts"],"sourcesContent":["import type { Client as AuthClient, ErrorResponse } from \"../auth\";\nimport type { FetchResponse } from \"../fetch\";\nimport type { Session } from \"./session\";\nimport type { SessionStorage } from \"./storage\";\n\nclass DummyLock implements Lock {\n async request(\n _name: string,\n _options: { mode: \"exclusive\" | \"shared\" },\n // biome-ignore lint/suspicious/noExplicitAny: any\n callback: () => Promise<any>,\n ) {\n return callback();\n }\n}\n\ninterface Lock {\n request: (\n name: string,\n options: { mode: \"exclusive\" | \"shared\" },\n // biome-ignore lint/suspicious/noExplicitAny: blah\n callback: () => Promise<any>,\n // biome-ignore lint/suspicious/noExplicitAny: blah\n ) => Promise<any>;\n}\n\nconst lock: Lock =\n // biome-ignore lint/complexity/useOptionalChain: this check breaks non-browser environments\n typeof navigator !== \"undefined\" && navigator.locks\n ? navigator.locks\n : new DummyLock();\n\n/**\n * Refreshes the authentication session if needed\n *\n * This function checks if the current session needs to be refreshed based on\n * the access token expiration time. If a refresh is needed, it will attempt to\n * refresh the token using the provided auth client.\n *\n * @param auth - The authentication client to use for token refresh\n * @param storage - The session storage implementation\n * @param marginSeconds - The number of seconds before the token expiration to refresh the session. If the token is still valid for this duration, it will not be refreshed. Set to 0 to force the refresh.\n * @returns A promise that resolves to the current session (refreshed if needed) or null if no session exists\n */\nexport const refreshSession = async (\n auth: AuthClient,\n storage: SessionStorage,\n marginSeconds = 60,\n): Promise<Session | null> => {\n try {\n return await _refreshSession(auth, storage, marginSeconds);\n } catch (error) {\n try {\n // we retry the refresh token in case of transient error\n // or race conditions\n console.warn(\"error refreshing session, retrying:\", error);\n return await _refreshSession(auth, storage, marginSeconds);\n } catch (error) {\n const errResponse = error as FetchResponse<ErrorResponse>;\n if (errResponse?.status === 401) {\n // this probably means the refresh token is invalid\n console.error(\"session probably expired\");\n storage.remove();\n }\n return null;\n }\n }\n};\n\n/**\n * Internal implementation of the refresh session logic\n *\n * @param auth - The authentication client to use for token refresh\n * @param storage - The session storage implementation\n * @param marginSeconds - How many seconds before expiration to trigger a refresh\n * @returns A promise that resolves to the current session (refreshed if needed) or null if no session exists\n * @private\n */\nconst _refreshSession = async (\n auth: AuthClient,\n storage: SessionStorage,\n marginSeconds = 60,\n): Promise<Session | null> => {\n const {\n session,\n needsRefresh,\n }: { session: Session | null; needsRefresh: boolean } = await lock.request(\n \"nhostSessionLock\",\n { mode: \"shared\" },\n async () => {\n return _needsRefresh(storage, marginSeconds);\n },\n );\n\n if (!session) {\n return null; // No session found\n }\n\n if (!needsRefresh) {\n return session; // No need to refresh\n }\n\n const refreshedSession: Session | null = await lock.request(\n \"nhostSessionLock\",\n { mode: \"exclusive\" },\n async () => {\n const { session, needsRefresh, sessionExpired } = _needsRefresh(\n storage,\n marginSeconds,\n );\n\n if (!session) {\n return null; // No session found\n }\n\n if (!needsRefresh) {\n return session; // No need to refresh\n }\n\n try {\n const response = await auth.refreshToken({\n refreshToken: session.refreshToken,\n });\n storage.set(response.body);\n\n return response.body;\n } catch (error) {\n if (!sessionExpired) {\n return session;\n }\n\n throw error;\n }\n },\n );\n\n return refreshedSession;\n};\n\n/**\n * Checks if the current session needs to be refreshed based on token expiration\n *\n * @param storage - The session storage implementation\n * @param marginSeconds - How many seconds before expiration to trigger a refresh\n * @returns An object containing the session, whether it needs refreshing, and whether it has expired\n * @private\n */\nconst _needsRefresh = (storage: SessionStorage, marginSeconds = 60) => {\n const session = storage.get();\n if (!session) {\n return { session: null, needsRefresh: false, sessionExpired: false };\n }\n\n if (!session.decodedToken || !session.decodedToken.exp) {\n // if the session does not have a valid decoded token, treat it as expired\n // as we can't determine its validity\n return { session, needsRefresh: true, sessionExpired: true };\n }\n\n // Force refresh if marginSeconds is 0\n if (marginSeconds === 0) {\n return { session, needsRefresh: true, sessionExpired: false };\n }\n\n const currentTime = Date.now();\n if (session.decodedToken.exp - currentTime > marginSeconds * 1000) {\n return { session, needsRefresh: false, sessionExpired: false };\n }\n\n return {\n session,\n needsRefresh: true,\n sessionExpired: session.decodedToken.exp < currentTime,\n };\n};\n"],"names":["lock","navigator","locks","request","_name","_options","callback","_refreshSession","async","auth","storage","marginSeconds","session","needsRefresh","mode","_needsRefresh","sessionExpired","response","refreshToken","set","body","error","get","decodedToken","exp","currentTime","Date","now","console","warn","errResponse","status","remove"],"mappings":"aA0BA,MAAMA,EAEiB,oBAAdC,WAA6BA,UAAUC,MAC1CD,UAAUC,MACV,IAzBN,MACE,aAAMC,CACJC,EACAC,EAEAC,GAEA,OAAOA,GACT,GAiEIC,EAAkBC,MACtBC,EACAC,EACAC,EAAgB,MAEhB,MAAMC,QACJA,EAAAC,aACAA,SAC4Db,EAAKG,QACjE,mBACA,CAAEW,KAAM,WACRN,SACSO,EAAcL,EAASC,KAIlC,IAAKC,EACH,OAAO,KAGT,IAAKC,EACH,OAAOD,EAqCT,aAlC+CZ,EAAKG,QAClD,mBACA,CAAEW,KAAM,cACRN,UACE,MAAQI,QAAAA,EAASC,aAAAA,EAAAA,eAAcG,GAAmBD,EAChDL,EACAC,GAGF,IAAKC,EACH,OAAO,KAGT,IAAKC,EACH,OAAOD,EAGT,IACE,MAAMK,QAAiBR,EAAKS,aAAa,CACvCA,aAAcN,EAAQM,eAIxB,OAFAR,EAAQS,IAAIF,EAASG,MAEdH,EAASG,IAClB,OAASC,GACP,IAAKL,EACH,OAAOJ,EAGT,MAAMS,CACR,IAIG,EAWHN,EAAgB,CAACL,EAAyBC,EAAgB,MAC9D,MAAMC,EAAUF,EAAQY,MACxB,IAAKV,EACH,MAAO,CAAEA,QAAS,KAAMC,cAAc,EAAOG,gBAAgB,GAG/D,IAAKJ,EAAQW,eAAiBX,EAAQW,aAAaC,IAGjD,MAAO,CAAEZ,UAASC,cAAc,EAAMG,gBAAgB,GAIxD,GAAsB,IAAlBL,EACF,MAAO,CAAEC,UAASC,cAAc,EAAMG,gBAAgB,GAGxD,MAAMS,EAAcC,KAAKC,MACzB,OAAIf,EAAQW,aAAaC,IAAMC,EAA8B,IAAhBd,EACpC,CAAEC,UAASC,cAAc,EAAOG,gBAAgB,GAGlD,CACLJ,UACAC,cAAc,EACdG,eAAgBJ,EAAQW,aAAaC,IAAMC,EAAA,yBAhIjBjB,MAC5BC,EACAC,EACAC,EAAgB,MAEhB,IACE,aAAaJ,EAAgBE,EAAMC,EAASC,EAC9C,OAASU,GACP,IAIE,OADAO,QAAQC,KAAK,sCAAuCR,SACvCd,EAAgBE,EAAMC,EAASC,EAC9C,OAASU,GACP,MAAMS,EAAcT,EAMpB,OAL4B,MAAxBS,GAAaC,SAEfH,QAAQP,MAAM,4BACdX,EAAQsB,UAEH,IACT,CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refreshSession-
|
|
1
|
+
{"version":3,"file":"refreshSession-CG8GIEun.js","sources":["../src/session/refreshSession.ts"],"sourcesContent":["import type { Client as AuthClient, ErrorResponse } from \"../auth\";\nimport type { FetchResponse } from \"../fetch\";\nimport type { Session } from \"./session\";\nimport type { SessionStorage } from \"./storage\";\n\nclass DummyLock implements Lock {\n async request(\n _name: string,\n _options: { mode: \"exclusive\" | \"shared\" },\n // biome-ignore lint/suspicious/noExplicitAny: any\n callback: () => Promise<any>,\n ) {\n return callback();\n }\n}\n\ninterface Lock {\n request: (\n name: string,\n options: { mode: \"exclusive\" | \"shared\" },\n // biome-ignore lint/suspicious/noExplicitAny: blah\n callback: () => Promise<any>,\n // biome-ignore lint/suspicious/noExplicitAny: blah\n ) => Promise<any>;\n}\n\nconst lock: Lock =\n // biome-ignore lint/complexity/useOptionalChain: this check breaks non-browser environments\n typeof navigator !== \"undefined\" && navigator.locks\n ? navigator.locks\n : new DummyLock();\n\n/**\n * Refreshes the authentication session if needed\n *\n * This function checks if the current session needs to be refreshed based on\n * the access token expiration time. If a refresh is needed, it will attempt to\n * refresh the token using the provided auth client.\n *\n * @param auth - The authentication client to use for token refresh\n * @param storage - The session storage implementation\n * @param marginSeconds - The number of seconds before the token expiration to refresh the session. If the token is still valid for this duration, it will not be refreshed. Set to 0 to force the refresh.\n * @returns A promise that resolves to the current session (refreshed if needed) or null if no session exists\n */\nexport const refreshSession = async (\n auth: AuthClient,\n storage: SessionStorage,\n marginSeconds = 60,\n): Promise<Session | null> => {\n try {\n return await _refreshSession(auth, storage, marginSeconds);\n } catch (error) {\n try {\n // we retry the refresh token in case of transient error\n // or race conditions\n console.warn(\"error refreshing session, retrying:\", error);\n return await _refreshSession(auth, storage, marginSeconds);\n } catch (error) {\n const errResponse = error as FetchResponse<ErrorResponse>;\n if (errResponse?.status === 401) {\n // this probably means the refresh token is invalid\n console.error(\"session probably expired\");\n storage.remove();\n }\n return null;\n }\n }\n};\n\n/**\n * Internal implementation of the refresh session logic\n *\n * @param auth - The authentication client to use for token refresh\n * @param storage - The session storage implementation\n * @param marginSeconds - How many seconds before expiration to trigger a refresh\n * @returns A promise that resolves to the current session (refreshed if needed) or null if no session exists\n * @private\n */\nconst _refreshSession = async (\n auth: AuthClient,\n storage: SessionStorage,\n marginSeconds = 60,\n): Promise<Session | null> => {\n const {\n session,\n needsRefresh,\n }: { session: Session | null; needsRefresh: boolean } = await lock.request(\n \"nhostSessionLock\",\n { mode: \"shared\" },\n async () => {\n return _needsRefresh(storage, marginSeconds);\n },\n );\n\n if (!session) {\n return null; // No session found\n }\n\n if (!needsRefresh) {\n return session; // No need to refresh\n }\n\n const refreshedSession: Session | null = await lock.request(\n \"nhostSessionLock\",\n { mode: \"exclusive\" },\n async () => {\n const { session, needsRefresh, sessionExpired } = _needsRefresh(\n storage,\n marginSeconds,\n );\n\n if (!session) {\n return null; // No session found\n }\n\n if (!needsRefresh) {\n return session; // No need to refresh\n }\n\n try {\n const response = await auth.refreshToken({\n refreshToken: session.refreshToken,\n });\n storage.set(response.body);\n\n return response.body;\n } catch (error) {\n if (!sessionExpired) {\n return session;\n }\n\n throw error;\n }\n },\n );\n\n return refreshedSession;\n};\n\n/**\n * Checks if the current session needs to be refreshed based on token expiration\n *\n * @param storage - The session storage implementation\n * @param marginSeconds - How many seconds before expiration to trigger a refresh\n * @returns An object containing the session, whether it needs refreshing, and whether it has expired\n * @private\n */\nconst _needsRefresh = (storage: SessionStorage, marginSeconds = 60) => {\n const session = storage.get();\n if (!session) {\n return { session: null, needsRefresh: false, sessionExpired: false };\n }\n\n if (!session.decodedToken || !session.decodedToken.exp) {\n // if the session does not have a valid decoded token, treat it as expired\n // as we can't determine its validity\n return { session, needsRefresh: true, sessionExpired: true };\n }\n\n // Force refresh if marginSeconds is 0\n if (marginSeconds === 0) {\n return { session, needsRefresh: true, sessionExpired: false };\n }\n\n const currentTime = Date.now();\n if (session.decodedToken.exp - currentTime > marginSeconds * 1000) {\n return { session, needsRefresh: false, sessionExpired: false };\n }\n\n return {\n session,\n needsRefresh: true,\n sessionExpired: session.decodedToken.exp < currentTime,\n };\n};\n"],"names":["error","session","needsRefresh"],"mappings":"AAKA,MAAM,UAA0B;AAAA,EAC9B,MAAM,QACJ,OACA,UAEA,UACA;AACA,WAAO,SAAA;AAAA,EACT;AACF;AAYA,MAAM;AAAA;AAAA,EAEJ,OAAO,cAAc,eAAe,UAAU,QAC1C,UAAU,QACV,IAAI,UAAA;AAAA;AAcH,MAAM,iBAAiB,OAC5B,MACA,SACA,gBAAgB,OACY;AAC5B,MAAI;AACF,WAAO,MAAM,gBAAgB,MAAM,SAAS,aAAa;AAAA,EAC3D,SAAS,OAAO;AACd,QAAI;AAGF,cAAQ,KAAK,uCAAuC,KAAK;AACzD,aAAO,MAAM,gBAAgB,MAAM,SAAS,aAAa;AAAA,IAC3D,SAASA,QAAO;AACd,YAAM,cAAcA;AACpB,UAAI,aAAa,WAAW,KAAK;AAE/B,gBAAQ,MAAM,0BAA0B;AACxC,gBAAQ,OAAA;AAAA,MACV;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAWA,MAAM,kBAAkB,OACtB,MACA,SACA,gBAAgB,OACY;AAC5B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,EAAA,IACsD,MAAM,KAAK;AAAA,IACjE;AAAA,IACA,EAAE,MAAM,SAAA;AAAA,IACR,YAAY;AACV,aAAO,cAAc,SAAS,aAAa;AAAA,IAC7C;AAAA,EAAA;AAGF,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,cAAc;AACjB,WAAO;AAAA,EACT;AAEA,QAAM,mBAAmC,MAAM,KAAK;AAAA,IAClD;AAAA,IACA,EAAE,MAAM,YAAA;AAAA,IACR,YAAY;AACV,YAAM,EAAE,SAAAC,UAAS,cAAAC,eAAc,mBAAmB;AAAA,QAChD;AAAA,QACA;AAAA,MAAA;AAGF,UAAI,CAACD,UAAS;AACZ,eAAO;AAAA,MACT;AAEA,UAAI,CAACC,eAAc;AACjB,eAAOD;AAAAA,MACT;AAEA,UAAI;AACF,cAAM,WAAW,MAAM,KAAK,aAAa;AAAA,UACvC,cAAcA,SAAQ;AAAA,QAAA,CACvB;AACD,gBAAQ,IAAI,SAAS,IAAI;AAEzB,eAAO,SAAS;AAAA,MAClB,SAAS,OAAO;AACd,YAAI,CAAC,gBAAgB;AACnB,iBAAOA;AAAAA,QACT;AAEA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EAAA;AAGF,SAAO;AACT;AAUA,MAAM,gBAAgB,CAAC,SAAyB,gBAAgB,OAAO;AACrE,QAAM,UAAU,QAAQ,IAAA;AACxB,MAAI,CAAC,SAAS;AACZ,WAAO,EAAE,SAAS,MAAM,cAAc,OAAO,gBAAgB,MAAA;AAAA,EAC/D;AAEA,MAAI,CAAC,QAAQ,gBAAgB,CAAC,QAAQ,aAAa,KAAK;AAGtD,WAAO,EAAE,SAAS,cAAc,MAAM,gBAAgB,KAAA;AAAA,EACxD;AAGA,MAAI,kBAAkB,GAAG;AACvB,WAAO,EAAE,SAAS,cAAc,MAAM,gBAAgB,MAAA;AAAA,EACxD;AAEA,QAAM,cAAc,KAAK,IAAA;AACzB,MAAI,QAAQ,aAAa,MAAM,cAAc,gBAAgB,KAAM;AACjE,WAAO,EAAE,SAAS,cAAc,OAAO,gBAAgB,MAAA;AAAA,EACzD;AAEA,SAAO;AAAA,IACL;AAAA,IACA,cAAc;AAAA,IACd,gBAAgB,QAAQ,aAAa,MAAM;AAAA,EAAA;AAE/C;"}
|