{"version":3,"file":"pocketbase.es.mjs","sources":["../src/ClientResponseError.ts","../src/stores/utils/cookie.ts","../src/stores/utils/jwt.ts","../src/stores/BaseAuthStore.ts","../src/stores/LocalAuthStore.ts","../src/services/utils/BaseService.ts","../src/services/SettingsService.ts","../src/services/utils/CrudService.ts","../src/services/utils/legacy.ts","../src/services/utils/refresh.ts","../src/services/AdminService.ts","../src/services/RealtimeService.ts","../src/services/RecordService.ts","../src/services/CollectionService.ts","../src/services/LogService.ts","../src/services/HealthService.ts","../src/services/FileService.ts","../src/services/BackupService.ts","../src/Client.ts","../src/stores/AsyncAuthStore.ts"],"sourcesContent":["/**\n * ClientResponseError is a custom Error class that is intended to wrap\n * and normalize any error thrown by `Client.send()`.\n */\nexport class ClientResponseError extends Error {\n    url: string                    = '';\n    status: number                 = 0;\n    response: {[key: string]: any} = {};\n    isAbort:  boolean              = false;\n    originalError: any             = null;\n\n    constructor(errData?: any) {\n        super(\"ClientResponseError\");\n\n        // Set the prototype explicitly.\n        // https://github.com/Microsoft/TypeScript-wiki/blob/main/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n        Object.setPrototypeOf(this, ClientResponseError.prototype);\n\n        if (errData !== null && typeof errData === 'object') {\n            this.url           = typeof errData.url === 'string' ? errData.url : '';\n            this.status        = typeof errData.status === 'number' ? errData.status : 0;\n            this.isAbort       = !!errData.isAbort;\n            this.originalError = errData.originalError;\n\n            if (errData.response !== null && typeof errData.response === 'object')  {\n                this.response =  errData.response;\n            } else if (errData.data !== null && typeof errData.data === 'object')  {\n                this.response =  errData.data;\n            } else {\n                this.response =  {};\n            }\n        }\n\n        if (!this.originalError && !(errData instanceof ClientResponseError)) {\n            this.originalError = errData;\n        }\n\n        if (typeof DOMException !== 'undefined' && errData instanceof DOMException) {\n            this.isAbort = true;\n        }\n\n        this.name = \"ClientResponseError \" + this.status;\n        this.message = this.response?.message;\n        if (!this.message) {\n            if (this.isAbort) {\n                this.message = 'The request was autocancelled. You can find more info in https://github.com/pocketbase/js-sdk#auto-cancellation.';\n            } else if (this.originalError?.cause?.message?.includes(\"ECONNREFUSED ::1\")) {\n                this.message = 'Failed to connect to the PocketBase server. Try changing the SDK URL from localhost to 127.0.0.1 (https://github.com/pocketbase/js-sdk/issues/21).';\n            } else {\n                this.message = 'Something went wrong while processing your request.';\n            }\n        }\n    }\n\n    /**\n     * Alias for `this.response` to preserve the backward compatibility.\n     */\n    get data() {\n        return this.response;\n    }\n\n    /**\n     * Make a POJO's copy of the current error class instance.\n     * @see https://github.com/vuex-orm/vuex-orm/issues/255\n     */\n    toJSON() {\n        return { ...this };\n    }\n}\n","/**\n * -------------------------------------------------------------------\n * Simple cookie parse and serialize utilities mostly based on the\n * node module https://github.com/jshttp/cookie.\n * -------------------------------------------------------------------\n */\n\n/**\n * RegExp to match field-content in RFC 7230 sec 3.2\n *\n * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]\n * field-vchar   = VCHAR / obs-text\n * obs-text      = %x80-FF\n */\nconst fieldContentRegExp = /^[\\u0009\\u0020-\\u007e\\u0080-\\u00ff]+$/;\n\nexport interface ParseOptions{\n    decode?: (val: string) => string,\n}\n\n/**\n* Parses the given cookie header string into an object\n* The object has the various cookies as keys(names) => values\n*/\nexport function cookieParse(str: string, options?: ParseOptions): { [key: string]: any }  {\n    const result: { [key: string]: any } = {};\n\n    if (typeof str !== 'string') {\n        return result;\n    }\n\n    const opt    = Object.assign({}, options || {});\n    const decode = opt.decode || defaultDecode;\n\n    let index = 0;\n    while (index < str.length) {\n        const eqIdx = str.indexOf('=', index);\n\n        // no more cookie pairs\n        if (eqIdx === -1) {\n            break;\n        }\n\n        let endIdx = str.indexOf(';', index);\n\n        if (endIdx === -1) {\n            endIdx = str.length;\n        } else if (endIdx < eqIdx) {\n            // backtrack on prior semicolon\n            index = str.lastIndexOf(';', eqIdx - 1) + 1;\n            continue;\n        }\n\n        const key = str.slice(index, eqIdx).trim();\n\n        // only assign once\n        if (undefined === result[key]) {\n            let val = str.slice(eqIdx + 1, endIdx).trim();\n\n            // quoted values\n            if (val.charCodeAt(0) === 0x22) {\n                val = val.slice(1, -1);\n            }\n\n            try {\n                result[key] = decode(val);\n            } catch (_) {\n                result[key] = val; // no decoding\n            }\n        }\n\n        index = endIdx + 1;\n    }\n\n    return result;\n};\n\nexport interface SerializeOptions {\n    encode?:   (val: string | number | boolean) => string,\n    maxAge?:   number,\n    domain?:   string,\n    path?:     string,\n    expires?:  Date,\n    httpOnly?: boolean,\n    secure?:   boolean,\n    priority?: string,\n    sameSite?: boolean|string,\n}\n\n/**\n * Serialize data into a cookie header.\n *\n * Serialize the a name value pair into a cookie string suitable for\n * http headers. An optional options object specified cookie parameters.\n *\n * ```js\n * cookieSerialize('foo', 'bar', { httpOnly: true }) // \"foo=bar; httpOnly\"\n * ```\n */\nexport function cookieSerialize(name: string, val: string, options?: SerializeOptions): string {\n    const opt    = Object.assign({}, options || {});\n    const encode = opt.encode || defaultEncode;\n\n    if (!fieldContentRegExp.test(name)) {\n        throw new TypeError('argument name is invalid');\n    }\n\n    const value = encode(val);\n\n    if (value && !fieldContentRegExp.test(value)) {\n        throw new TypeError('argument val is invalid');\n    }\n\n    let result = name + '=' + value;\n\n    if (opt.maxAge != null) {\n        const maxAge = opt.maxAge - 0;\n\n        if (isNaN(maxAge) || !isFinite(maxAge)) {\n            throw new TypeError('option maxAge is invalid');\n        }\n\n        result += '; Max-Age=' + Math.floor(maxAge);\n    }\n\n    if (opt.domain) {\n        if (!fieldContentRegExp.test(opt.domain)) {\n            throw new TypeError('option domain is invalid');\n        }\n\n        result += '; Domain=' + opt.domain;\n    }\n\n    if (opt.path) {\n        if (!fieldContentRegExp.test(opt.path)) {\n            throw new TypeError('option path is invalid');\n        }\n\n        result += '; Path=' + opt.path;\n    }\n\n    if (opt.expires) {\n        if (!isDate(opt.expires) || isNaN(opt.expires.valueOf())) {\n            throw new TypeError('option expires is invalid');\n        }\n\n        result += '; Expires=' + opt.expires.toUTCString();\n    }\n\n    if (opt.httpOnly) {\n        result += '; HttpOnly';\n    }\n\n    if (opt.secure) {\n        result += '; Secure';\n    }\n\n    if (opt.priority) {\n        const priority = typeof opt.priority === 'string' ? opt.priority.toLowerCase() : opt.priority;\n\n        switch (priority) {\n            case 'low':\n                result += '; Priority=Low';\n                break;\n            case 'medium':\n                result += '; Priority=Medium';\n                break;\n            case 'high':\n                result += '; Priority=High';\n                break;\n            default:\n                throw new TypeError('option priority is invalid');\n        }\n    }\n\n    if (opt.sameSite) {\n        const sameSite = typeof opt.sameSite === 'string' ? opt.sameSite.toLowerCase() : opt.sameSite;\n\n        switch (sameSite) {\n            case true:\n                result += '; SameSite=Strict';\n                break;\n            case 'lax':\n                result += '; SameSite=Lax';\n                break;\n            case 'strict':\n                result += '; SameSite=Strict';\n                break;\n            case 'none':\n                result += '; SameSite=None';\n                break;\n            default:\n                throw new TypeError('option sameSite is invalid');\n        }\n    }\n\n    return result;\n};\n\n/**\n * Default URL-decode string value function.\n * Optimized to skip native call when no `%`.\n */\nfunction defaultDecode(val: string): string {\n    return val.indexOf('%') !== -1\n        ? decodeURIComponent(val)\n        : val;\n}\n\n/**\n * Default URL-encode value function.\n */\nfunction defaultEncode(val: string | number | boolean): string {\n    return encodeURIComponent(val);\n}\n\n/**\n * Determines if value is a Date.\n */\nfunction isDate(val: any): boolean {\n    return (\n        Object.prototype.toString.call(val) === '[object Date]' ||\n        val instanceof Date\n    );\n}\n","let atobPolyfill: Function;\nif (typeof atob === 'function') {\n    atobPolyfill = atob\n} else {\n    /**\n     * The code was extracted from:\n     * https://github.com/davidchambers/Base64.js\n     */\n    atobPolyfill = (input: any) => {\n        const chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\n\n        let str = String(input).replace(/=+$/, \"\");\n        if (str.length % 4 == 1) {\n            throw new Error(\"'atob' failed: The string to be decoded is not correctly encoded.\");\n        }\n\n        for (\n            // initialize result and counters\n            var bc = 0, bs, buffer, idx = 0, output = \"\";\n            // get next character\n            (buffer = str.charAt(idx++));\n            // character found in table? initialize bit storage and add its ascii value;\n            ~buffer &&\n            ((bs = bc % 4 ? (bs as any) * 64 + buffer : buffer),\n                // and if not first of each 4 characters,\n                // convert the first 8 bits to one ascii character\n                bc++ % 4) ?\n            (output += String.fromCharCode(255 & (bs >> ((-2 * bc) & 6)))) :\n            0\n        ) {\n            // try to find character in table (0-63, not found => -1)\n            buffer = chars.indexOf(buffer);\n        }\n\n        return output;\n    };\n}\n\n/**\n * Returns JWT token's payload data.\n */\nexport function getTokenPayload(token: string): { [key: string]: any } {\n    if (token) {\n        try {\n            const encodedPayload = decodeURIComponent(atobPolyfill(token.split('.')[1]).split('').map(function (c: string) {\n                return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);\n            }).join(''));\n\n            return JSON.parse(encodedPayload) || {};\n        } catch (e) {\n        }\n    }\n\n    return {};\n}\n\n/**\n * Checks whether a JWT token is expired or not.\n * Tokens without `exp` payload key are considered valid.\n * Tokens with empty payload (eg. invalid token strings) are considered expired.\n *\n * @param token The token to check.\n * @param [expirationThreshold] Time in seconds that will be subtracted from the token `exp` property.\n */\nexport function isTokenExpired(token: string, expirationThreshold = 0): boolean {\n    let payload = getTokenPayload(token);\n\n    if (\n        Object.keys(payload).length > 0 &&\n        (!payload.exp || (payload.exp - expirationThreshold) > (Date.now() / 1000))\n    ) {\n        return false;\n    }\n\n    return true;\n}\n","import { cookieParse, cookieSerialize, SerializeOptions } from '@/stores/utils/cookie';\nimport { isTokenExpired, getTokenPayload } from '@/stores/utils/jwt';\n\nexport type AuthModel = { [key: string]: any }|null;\n\nexport type OnStoreChangeFunc = (token: string, model: AuthModel) => void;\n\nconst defaultCookieKey = 'pb_auth';\n\n/**\n * Base AuthStore class that is intended to be extended by all other\n * PocketBase AuthStore implementations.\n */\nexport abstract class BaseAuthStore {\n    protected baseToken: string = '';\n    protected baseModel: AuthModel = null;\n\n    private _onChangeCallbacks: Array<OnStoreChangeFunc> = [];\n\n    /**\n     * Retrieves the stored token (if any).\n     */\n    get token(): string {\n        return this.baseToken;\n    }\n\n    /**\n     * Retrieves the stored model data (if any).\n     */\n    get model(): AuthModel {\n        return this.baseModel;\n    }\n\n    /**\n     * Loosely checks if the store has valid token (aka. existing and unexpired exp claim).\n     */\n    get isValid(): boolean {\n        return !isTokenExpired(this.token);\n    }\n\n    /**\n     * Checks whether the current store state is for admin authentication.\n     */\n    get isAdmin(): boolean {\n        return getTokenPayload(this.token).type === \"admin\";\n    }\n\n    /**\n     * Checks whether the current store state is for auth record authentication.\n     */\n    get isAuthRecord(): boolean {\n        return getTokenPayload(this.token).type === \"authRecord\";\n    }\n\n    /**\n     * Saves the provided new token and model data in the auth store.\n     */\n    save(token: string, model?: AuthModel): void {\n        this.baseToken = token || '';\n        this.baseModel = model || null;\n\n        this.triggerChange();\n    }\n\n    /**\n     * Removes the stored token and model data form the auth store.\n     */\n    clear(): void {\n        this.baseToken = '';\n        this.baseModel = null;\n        this.triggerChange();\n    }\n\n    /**\n     * Parses the provided cookie string and updates the store state\n     * with the cookie's token and model data.\n     *\n     * NB! This function doesn't validate the token or its data.\n     * Usually this isn't a concern if you are interacting only with the\n     * PocketBase API because it has the proper server-side security checks in place,\n     * but if you are using the store `isValid` state for permission controls\n     * in a node server (eg. SSR), then it is recommended to call `authRefresh()`\n     * after loading the cookie to ensure an up-to-date token and model state.\n     * For example:\n     *\n     * ```js\n     * pb.authStore.loadFromCookie(\"cookie string...\");\n     *\n     * try {\n     *     // get an up-to-date auth store state by veryfing and refreshing the loaded auth model (if any)\n     *     pb.authStore.isValid && await pb.collection('users').authRefresh();\n     * } catch (_) {\n     *     // clear the auth store on failed refresh\n     *     pb.authStore.clear();\n     * }\n     * ```\n     */\n    loadFromCookie(cookie: string, key = defaultCookieKey): void {\n        const rawData = cookieParse(cookie || '')[key] || '';\n\n        let data: { [key: string]: any } = {};\n        try {\n            data = JSON.parse(rawData);\n            // normalize\n            if (typeof data === null || typeof data !== 'object' || Array.isArray(data)) {\n                data = {};\n            }\n        } catch (_) {}\n\n        this.save(data.token || '', data.model || null);\n    }\n\n    /**\n     * Exports the current store state as cookie string.\n     *\n     * By default the following optional attributes are added:\n     * - Secure\n     * - HttpOnly\n     * - SameSite=Strict\n     * - Path=/\n     * - Expires={the token expiration date}\n     *\n     * NB! If the generated cookie exceeds 4096 bytes, this method will\n     * strip the model data to the bare minimum to try to fit within the\n     * recommended size in https://www.rfc-editor.org/rfc/rfc6265#section-6.1.\n     */\n    exportToCookie(options?: SerializeOptions, key = defaultCookieKey): string {\n        const defaultOptions: SerializeOptions = {\n            secure:   true,\n            sameSite: true,\n            httpOnly: true,\n            path:     \"/\",\n        };\n\n        // extract the token expiration date\n        const payload = getTokenPayload(this.token);\n        if (payload?.exp) {\n            defaultOptions.expires = new Date(payload.exp * 1000);\n        } else {\n            defaultOptions.expires = new Date('1970-01-01');\n        }\n\n        // merge with the user defined options\n        options = Object.assign({}, defaultOptions, options);\n\n        const rawData = {\n            token: this.token,\n            model: this.model ? JSON.parse(JSON.stringify(this.model)) : null,\n        };\n\n        let result = cookieSerialize(key, JSON.stringify(rawData), options);\n\n        const resultLength = typeof Blob !== 'undefined' ?\n            (new Blob([result])).size : result.length;\n\n        // strip down the model data to the bare minimum\n        if (rawData.model && resultLength > 4096) {\n            rawData.model = {id: rawData?.model?.id, email: rawData?.model?.email};\n            const extraProps = [\"collectionId\", \"username\", \"verified\"];\n            for (const prop in this.model) {\n                if (extraProps.includes(prop)) {\n                    rawData.model[prop] = this.model[prop];\n                }\n            }\n            result = cookieSerialize(key, JSON.stringify(rawData), options);\n        }\n\n        return result;\n    }\n\n    /**\n     * Register a callback function that will be called on store change.\n     *\n     * You can set the `fireImmediately` argument to true in order to invoke\n     * the provided callback right after registration.\n     *\n     * Returns a removal function that you could call to \"unsubscribe\" from the changes.\n     */\n    onChange(callback: OnStoreChangeFunc, fireImmediately = false): () => void {\n        this._onChangeCallbacks.push(callback);\n\n        if (fireImmediately) {\n            callback(this.token, this.model);\n        }\n\n        return () => {\n            for (let i = this._onChangeCallbacks.length - 1; i >= 0; i--) {\n                if (this._onChangeCallbacks[i] == callback) {\n                    delete this._onChangeCallbacks[i];    // removes the function reference\n                    this._onChangeCallbacks.splice(i, 1); // reindex the array\n                    return;\n                }\n            }\n        }\n    }\n\n    protected triggerChange(): void {\n        for (const callback of this._onChangeCallbacks) {\n            callback && callback(this.token, this.model);\n        }\n    }\n}\n","import { BaseAuthStore, AuthModel } from '@/stores/BaseAuthStore';\n\n/**\n * The default token store for browsers with auto fallback\n * to runtime/memory if local storage is undefined (eg. in node env).\n */\nexport class LocalAuthStore extends BaseAuthStore {\n    private storageFallback: { [key: string]: any } = {};\n    private storageKey: string\n\n    constructor(storageKey = \"pocketbase_auth\") {\n        super();\n\n        this.storageKey = storageKey;\n\n        this._bindStorageEvent();\n    }\n\n    /**\n     * @inheritdoc\n     */\n    get token(): string {\n        const data = this._storageGet(this.storageKey) || {};\n\n        return data.token || '';\n    }\n\n    /**\n     * @inheritdoc\n     */\n    get model(): AuthModel {\n        const data = this._storageGet(this.storageKey) || {};\n\n        return data.model || null;\n    }\n\n    /**\n     * @inheritdoc\n     */\n    save(token: string, model?: AuthModel) {\n        this._storageSet(this.storageKey, {\n            'token': token,\n            'model': model,\n        });\n\n        super.save(token, model);\n    }\n\n    /**\n     * @inheritdoc\n     */\n    clear() {\n        this._storageRemove(this.storageKey);\n\n        super.clear();\n    }\n\n    // ---------------------------------------------------------------\n    // Internal helpers:\n    // ---------------------------------------------------------------\n\n    /**\n     * Retrieves `key` from the browser's local storage\n     * (or runtime/memory if local storage is undefined).\n     */\n    private _storageGet(key: string): any {\n        if (typeof window !== 'undefined' && window?.localStorage) {\n            const rawValue = window.localStorage.getItem(key) || '';\n            try {\n                return JSON.parse(rawValue);\n            } catch (e) { // not a json\n                return rawValue;\n            }\n        }\n\n        // fallback\n        return this.storageFallback[key];\n    }\n\n    /**\n     * Stores a new data in the browser's local storage\n     * (or runtime/memory if local storage is undefined).\n     */\n    private _storageSet(key: string, value: any) {\n        if (typeof window !== 'undefined' && window?.localStorage) {\n            // store in local storage\n            let normalizedVal = value;\n            if (typeof value !== 'string') {\n                normalizedVal = JSON.stringify(value);\n            }\n            window.localStorage.setItem(key, normalizedVal);\n        } else {\n            // store in fallback\n            this.storageFallback[key] = value;\n        }\n    }\n\n    /**\n     * Removes `key` from the browser's local storage and the runtime/memory.\n     */\n    private _storageRemove(key: string) {\n        // delete from local storage\n        if (typeof window !== 'undefined' && window?.localStorage) {\n            window.localStorage?.removeItem(key);\n        }\n\n        // delete from fallback\n        delete this.storageFallback[key];\n    }\n\n    /**\n     * Updates the current store state on localStorage change.\n     */\n    private _bindStorageEvent() {\n        if (typeof window === 'undefined' || !window?.localStorage || !window.addEventListener) {\n            return;\n        }\n\n        window.addEventListener('storage', (e) => {\n            if (e.key != this.storageKey) {\n                return;\n            }\n\n            const data = this._storageGet(this.storageKey) || {};\n\n            super.save(data.token || '', data.model || null);\n        });\n    }\n}\n","import Client from '@/Client';\n\n/**\n * BaseService class that should be inherited from all API services.\n */\nexport abstract class BaseService {\n    readonly client: Client\n\n    constructor(client: Client) {\n        this.client = client;\n    }\n}\n","import { BaseService }   from '@/services/utils/BaseService';\nimport { CommonOptions } from '@/services/utils/options';\n\ninterface appleClientSecret {\n    secret: string;\n}\n\nexport class SettingsService extends BaseService {\n    /**\n     * Fetch all available app settings.\n     */\n    getAll(options?: CommonOptions): Promise<{[key: string]:any}> {\n        options = Object.assign({\n            'method': 'GET',\n        }, options);\n\n        return this.client.send('/api/settings', options);\n    }\n\n    /**\n     * Bulk updates app settings.\n     */\n    update(\n        bodyParams?: {[key:string]:any}|FormData,\n        options?: CommonOptions,\n    ): Promise<{[key: string]:any}> {\n        options = Object.assign({\n            'method': 'PATCH',\n            'body':   bodyParams,\n        }, options);\n\n        return this.client.send('/api/settings', options);\n    }\n\n    /**\n     * Performs a S3 filesystem connection test.\n     *\n     * The currently supported `filesystem` are \"storage\" and \"backups\".\n     */\n    testS3(filesystem: string = \"storage\", options?: CommonOptions): Promise<boolean> {\n        options = Object.assign({\n            'method': 'POST',\n            'body': {\n                'filesystem': filesystem,\n            },\n        }, options);\n\n        return this.client.send('/api/settings/test/s3', options)\n            .then(() => true);\n    }\n\n    /**\n     * Sends a test email.\n     *\n     * The possible `emailTemplate` values are:\n     * - verification\n     * - password-reset\n     * - email-change\n     */\n    testEmail(toEmail: string, emailTemplate: string, options?: CommonOptions): Promise<boolean> {\n        options = Object.assign({\n            'method': 'POST',\n            'body': {\n                'email':    toEmail,\n                'template': emailTemplate,\n            },\n        }, options);\n\n        return this.client.send('/api/settings/test/email', options)\n            .then(() => true);\n    }\n\n    /**\n     * Generates a new Apple OAuth2 client secret.\n     */\n    generateAppleClientSecret(\n        clientId: string,\n        teamId: string,\n        keyId: string,\n        privateKey: string,\n        duration: number,\n        options?: CommonOptions,\n    ): Promise<appleClientSecret> {\n        options = Object.assign({\n            'method': 'POST',\n            'body': {\n                clientId,\n                teamId,\n                keyId,\n                privateKey,\n                duration,\n            },\n        }, options);\n\n        return this.client.send('/api/settings/apple/generate-client-secret', options);\n    }\n}\n","import { BaseService }         from '@/services/utils/BaseService';\nimport { ClientResponseError } from '@/ClientResponseError';\nimport { ListResult }          from '@/services/utils/dtos';\nimport {\n    CommonOptions,\n    ListOptions,\n    FullListOptions\n} from '@/services/utils/options';\n\nexport abstract class CrudService<M> extends BaseService   {\n    /**\n     * Base path for the crud actions (without trailing slash, eg. '/admins').\n     */\n    abstract get baseCrudPath(): string\n\n    /**\n     * Response data decoder.\n     */\n    decode<T = M>(data: { [key: string]: any }): T {\n        return data as T;\n    }\n\n    /**\n     * Returns a promise with all list items batch fetched at once\n     * (by default 500 items per request; to change it set the `batch` query param).\n     *\n     * You can use the generic T to supply a wrapper type of the crud model.\n     */\n    getFullList<T = M>(options?: FullListOptions): Promise<Array<T>>\n\n    /**\n     * Legacy version of getFullList with explicitly specified batch size.\n     */\n    getFullList<T = M>(batch?: number, options?: ListOptions): Promise<Array<T>>\n\n    getFullList<T = M>(batchOrqueryParams?: number|FullListOptions, options?: ListOptions): Promise<Array<T>> {\n        if (typeof batchOrqueryParams == \"number\") {\n            return this._getFullList<T>(batchOrqueryParams, options);\n        }\n\n        options = Object.assign({}, batchOrqueryParams, options);\n\n        let batch = 500;\n        if (options.batch) {\n            batch = options.batch;\n            delete options.batch;\n        }\n\n        return this._getFullList<T>(batch, options);\n    }\n\n    /**\n     * Returns paginated items list.\n     *\n     * You can use the generic T to supply a wrapper type of the crud model.\n     */\n    getList<T = M>(page = 1, perPage = 30, options?: ListOptions): Promise<ListResult<T>> {\n        options = Object.assign({\n            method: 'GET'\n        }, options);\n\n        options.query = Object.assign({\n            'page':    page,\n            'perPage': perPage,\n        }, options.query);\n\n        return this.client.send(this.baseCrudPath, options)\n            .then((responseData: any) => {\n                responseData.items = responseData.items?.map((item: any) => {\n                    return this.decode<T>(item);\n                }) || [];\n\n                return responseData;\n            });\n    }\n\n    /**\n     * Returns the first found item by the specified filter.\n     *\n     * Internally it calls `getList(1, 1, { filter, skipTotal })` and\n     * returns the first found item.\n     *\n     * You can use the generic T to supply a wrapper type of the crud model.\n     *\n     * For consistency with `getOne`, this method will throw a 404\n     * ClientResponseError if no item was found.\n     */\n    getFirstListItem<T = M>(filter: string, options?: CommonOptions): Promise<T> {\n        options = Object.assign({\n            'requestKey': 'one_by_filter_' + this.baseCrudPath + \"_\" + filter,\n        }, options);\n\n        options.query = Object.assign({\n            'filter':     filter,\n            'skipTotal':  1,\n        }, options.query);\n\n        return this.getList<T>(1, 1, options)\n            .then((result) => {\n                if (!result?.items?.length) {\n                    throw new ClientResponseError({\n                        status: 404,\n                        data: {\n                            code: 404,\n                            message: \"The requested resource wasn't found.\",\n                            data: {},\n                        },\n                    });\n                }\n\n                return result.items[0];\n            });\n    }\n\n    /**\n     * Returns single item by its id.\n     *\n     * You can use the generic T to supply a wrapper type of the crud model.\n     */\n    getOne<T = M>(id: string, options?: CommonOptions): Promise<T> {\n        options = Object.assign({\n            'method': 'GET',\n        }, options);\n\n        return this.client.send(this.baseCrudPath + '/' + encodeURIComponent(id), options)\n            .then((responseData: any) => this.decode<T>(responseData));\n    }\n\n    /**\n     * Creates a new item.\n     *\n     * You can use the generic T to supply a wrapper type of the crud model.\n     */\n    create<T = M>(\n        bodyParams?: {[key:string]:any}|FormData,\n        options?: CommonOptions,\n    ): Promise<T> {\n        options = Object.assign({\n            'method': 'POST',\n            'body':   bodyParams,\n        }, options);\n\n        return this.client.send(this.baseCrudPath, options)\n            .then((responseData: any) => this.decode<T>(responseData));\n    }\n\n    /**\n     * Updates an existing item by its id.\n     *\n     * You can use the generic T to supply a wrapper type of the crud model.\n     */\n    update<T = M>(\n        id: string,\n        bodyParams?: {[key:string]:any}|FormData,\n        options?: CommonOptions,\n    ): Promise<T> {\n        options = Object.assign({\n            'method': 'PATCH',\n            'body':   bodyParams,\n        }, options);\n\n        return this.client.send(this.baseCrudPath + '/' + encodeURIComponent(id), options)\n            .then((responseData: any) => this.decode<T>(responseData));\n    }\n\n    /**\n     * Deletes an existing item by its id.\n     */\n    delete(id: string, options?: CommonOptions): Promise<boolean> {\n        options = Object.assign({\n            'method': 'DELETE',\n        }, options);\n\n        return this.client.send(this.baseCrudPath + '/' + encodeURIComponent(id), options)\n            .then(() => true);\n    }\n\n    /**\n     * Returns a promise with all list items batch fetched at once.\n     */\n    protected _getFullList<T = M>(batchSize = 500, options?: ListOptions): Promise<Array<T>> {\n        options = options || {};\n        options.query = Object.assign({\n            'skipTotal': 1,\n        }, options.query);\n\n        let result: Array<T> = [];\n\n        let request = async (page: number): Promise<Array<any>> => {\n            return this.getList(page, batchSize || 500, options).then((list) => {\n                const castedList = (list as any as ListResult<T>);\n                const items      = castedList.items;\n\n                result = result.concat(items);\n\n                if (items.length == list.perPage) {\n                    return request(page + 1);\n                }\n\n                return result;\n            });\n        }\n\n        return request(1);\n    }\n}\n","import { SendOptions } from '@/services/utils/options';\n\nexport function normalizeLegacyOptionsArgs(legacyWarn: string, baseOptions: SendOptions, bodyOrOptions?: any, query?: any): SendOptions {\n    const hasBodyOrOptions = typeof bodyOrOptions !== 'undefined';\n    const hasQuery = typeof query !== 'undefined';\n\n    if (!hasQuery && !hasBodyOrOptions) {\n        return baseOptions;\n    }\n\n    if (hasQuery) {\n        console.warn(legacyWarn);\n        baseOptions.body = Object.assign({}, baseOptions.body, bodyOrOptions);\n        baseOptions.query = Object.assign({}, baseOptions.query, query);\n\n        return baseOptions;\n    }\n\n    return Object.assign(baseOptions, bodyOrOptions);\n}\n","import Client             from '@/Client';\nimport { isTokenExpired } from '@/stores/utils/jwt';\n\n// reset previous auto refresh registrations\nexport function resetAutoRefresh(client: Client) {\n    (client as any)._resetAutoRefresh?.();\n}\n\nexport function registerAutoRefresh(\n  client: Client,\n  threshold: number,\n  refreshFunc: () => Promise<any>,\n  reauthenticateFunc: () => Promise<any>,\n) {\n    resetAutoRefresh(client);\n\n    const oldBeforeSend = client.beforeSend;\n    const oldModel = client.authStore.model;\n\n    // unset the auto refresh in case the auth store was cleared\n    // OR a new model was authenticated\n    const unsubStoreChange = client.authStore.onChange((newToken, model) => {\n        if (\n            !newToken ||\n            model?.id != oldModel?.id ||\n            // check the collection id in case an admin and auth record share the same id\n            ((model?.collectionId || oldModel?.collectionId) && model?.collectionId != oldModel?.collectionId)\n        ) {\n            resetAutoRefresh(client);\n        }\n    });\n\n    // initialize a reset function and attach it dynamically to the client\n    (client as any)._resetAutoRefresh = function() {\n        unsubStoreChange();\n        client.beforeSend = oldBeforeSend;\n        delete (client as any)._resetAutoRefresh;\n    };\n\n    client.beforeSend = async (url, sendOptions) => {\n        const oldToken = client.authStore.token;\n\n        if (sendOptions.query?.autoRefresh) {\n            return oldBeforeSend ? oldBeforeSend(url, sendOptions) : { url, sendOptions };\n        }\n\n        let isValid = client.authStore.isValid;\n        if (\n            // is loosely valid\n            isValid &&\n            // but it is going to expire in the next \"threshold\" seconds\n            isTokenExpired(client.authStore.token, threshold)\n        ) {\n            try {\n                await refreshFunc();\n            } catch (_) {\n                isValid = false;\n            }\n        }\n\n        // still invalid -> reauthenticate\n        if (!isValid) {\n            await reauthenticateFunc();\n        }\n\n        // the request wasn't sent with a custom token\n        const headers = sendOptions.headers || {};\n        for (let key in headers) {\n            if (\n                key.toLowerCase() == \"authorization\" &&\n                // the request wasn't sent with a custom token\n                oldToken == headers[key] &&\n                client.authStore.token\n            ) {\n                // set the latest store token\n                headers[key] = client.authStore.token;\n                break;\n            }\n        }\n        sendOptions.headers = headers;\n\n        return oldBeforeSend ? oldBeforeSend(url, sendOptions) : { url, sendOptions };\n    }\n}\n","import { CrudService }                           from '@/services/utils/CrudService';\nimport { AdminModel }                            from '@/services/utils/dtos';\nimport { AuthOptions, CommonOptions }            from '@/services/utils/options';\nimport { normalizeLegacyOptionsArgs }            from '@/services/utils/legacy';\nimport { registerAutoRefresh, resetAutoRefresh } from '@/services/utils/refresh';\n\nexport interface AdminAuthResponse {\n    [key: string]: any;\n\n    token: string;\n    admin: AdminModel;\n}\n\nexport class AdminService extends CrudService<AdminModel> {\n    /**\n     * @inheritdoc\n     */\n    get baseCrudPath(): string {\n        return '/api/admins';\n    }\n\n    // ---------------------------------------------------------------\n    // Post update/delete AuthStore sync\n    // ---------------------------------------------------------------\n\n    /**\n     * @inheritdoc\n     *\n     * If the current `client.authStore.model` matches with the updated id, then\n     * on success the `client.authStore.model` will be updated with the result.\n     */\n    update<T = AdminModel>(\n        id: string,\n        bodyParams?: {[key:string]:any}|FormData,\n        options?: CommonOptions,\n    ): Promise<T> {\n        return super.update(id, bodyParams, options).then((item) => {\n            // update the store state if the updated item id matches with the stored model\n            if (\n                this.client.authStore.model?.id === item.id &&\n                typeof this.client.authStore.model?.collectionId === 'undefined' // is not record auth\n            ) {\n                this.client.authStore.save(this.client.authStore.token, item);\n            }\n\n            return item as any as T;\n        });\n    }\n\n    /**\n     * @inheritdoc\n     *\n     * If the current `client.authStore.model` matches with the deleted id,\n     * then on success the `client.authStore` will be cleared.\n     */\n    delete(id: string, options?: CommonOptions): Promise<boolean> {\n        return super.delete(id, options).then((success) => {\n            // clear the store state if the deleted item id matches with the stored model\n            if (\n                success &&\n                this.client.authStore.model?.id === id &&\n                typeof this.client.authStore.model?.collectionId === 'undefined' // is not record auth\n            ) {\n                this.client.authStore.clear();\n            }\n\n            return success;\n        });\n    }\n\n    // ---------------------------------------------------------------\n    // Auth handlers\n    // ---------------------------------------------------------------\n\n    /**\n     * Prepare successful authorize response.\n     */\n    protected authResponse(responseData: any): AdminAuthResponse {\n        const admin = this.decode(responseData?.admin || {});\n\n        if (responseData?.token && responseData?.admin) {\n            this.client.authStore.save(responseData.token, admin);\n        }\n\n        return Object.assign({}, responseData, {\n            // normalize common fields\n            'token': responseData?.token || '',\n            'admin': admin,\n        });\n    }\n\n    /**\n     * Authenticate an admin account with its email and password\n     * and returns a new admin token and data.\n     *\n     * On success this method automatically updates the client's AuthStore data.\n     */\n    authWithPassword(email: string, password: string, options?: AuthOptions): Promise<AdminAuthResponse>\n\n    /**\n     * @deprecated\n     * Consider using authWithPassword(email, password, options?).\n     */\n    authWithPassword(email: string, password: string, body?: any, query?: any): Promise<AdminAuthResponse>\n\n    async authWithPassword(\n        email: string,\n        password: string,\n        bodyOrOptions?: any,\n        query?: any,\n    ): Promise<AdminAuthResponse> {\n        let options: any = {\n            'method': 'POST',\n            'body': {\n                'identity': email,\n                'password': password,\n            },\n        };\n\n        options = normalizeLegacyOptionsArgs(\n            'This form of authWithPassword(email, pass, body?, query?) is deprecated. Consider replacing it with authWithPassword(email, pass, options?).',\n            options,\n            bodyOrOptions,\n            query\n        );\n\n        const autoRefreshThreshold = options.autoRefreshThreshold;\n        delete options.autoRefreshThreshold;\n\n        // not from auto refresh reauthentication\n        if (!options.autoRefresh) {\n            resetAutoRefresh(this.client);\n        }\n\n        let authData = await this.client.send(this.baseCrudPath + '/auth-with-password', options);\n\n        authData = this.authResponse(authData);\n\n        if (autoRefreshThreshold) {\n            registerAutoRefresh(\n                this.client,\n                autoRefreshThreshold,\n                () => this.authRefresh({autoRefresh: true}),\n                () => this.authWithPassword(email, password, Object.assign({autoRefresh: true}, options)),\n            );\n        }\n\n        return authData;\n    }\n\n    /**\n     * Refreshes the current admin authenticated instance and\n     * returns a new token and admin data.\n     *\n     * On success this method automatically updates the client's AuthStore data.\n     */\n    authRefresh(options?: CommonOptions): Promise<AdminAuthResponse>\n\n    /**\n     * @deprecated\n     * Consider using authRefresh(options?).\n     */\n    authRefresh(body?: any, query?: any): Promise<AdminAuthResponse>\n\n    authRefresh(bodyOrOptions?: any, query?: any): Promise<AdminAuthResponse> {\n        let options: any = {\n            'method': 'POST',\n        };\n\n        options = normalizeLegacyOptionsArgs(\n            'This form of authRefresh(body?, query?) is deprecated. Consider replacing it with authRefresh(options?).',\n            options,\n            bodyOrOptions,\n            query\n        );\n\n        return this.client.send(this.baseCrudPath + '/auth-refresh', options)\n            .then(this.authResponse.bind(this));\n    }\n\n    /**\n     * Sends admin password reset request.\n     */\n    requestPasswordReset(email: string, options?: CommonOptions): Promise<boolean>\n\n    /**\n     * @deprecated\n     * Consider using requestPasswordReset(email, options?).\n     */\n    requestPasswordReset(email: string, body?: any, query?: any): Promise<boolean>\n\n    requestPasswordReset(email: string, bodyOrOptions?: any, query?: any): Promise<boolean> {\n        let options: any = {\n            'method': 'POST',\n            'body': {\n                'email': email,\n            },\n        };\n\n        options = normalizeLegacyOptionsArgs(\n            'This form of requestPasswordReset(email, body?, query?) is deprecated. Consider replacing it with requestPasswordReset(email, options?).',\n            options,\n            bodyOrOptions,\n            query\n        );\n\n        return this.client.send(this.baseCrudPath + '/request-password-reset', options)\n            .then(() => true);\n    }\n\n    /**\n     * Confirms admin password reset request.\n     */\n    confirmPasswordReset(resetToken: string, password: string, passwordConfirm: string, options?: CommonOptions): Promise<boolean>\n\n    /**\n     * @deprecated\n     * Consider using confirmPasswordReset(resetToken, password, passwordConfirm, options?).\n     */\n    confirmPasswordReset(resetToken: string, password: string, passwordConfirm: string, body?: any, query?: any): Promise<boolean>\n\n    confirmPasswordReset(resetToken: string, password: string, passwordConfirm: string, bodyOrOptions?: any, query?: any): Promise<boolean>{\n        let options: any = {\n            'method': 'POST',\n            'body': {\n                'token':           resetToken,\n                'password':        password,\n                'passwordConfirm': passwordConfirm,\n            },\n        };\n\n        options = normalizeLegacyOptionsArgs(\n            'This form of confirmPasswordReset(resetToken, password, passwordConfirm, body?, query?) is deprecated. Consider replacing it with confirmPasswordReset(resetToken, password, passwordConfirm, options?).',\n            options,\n            bodyOrOptions,\n            query\n        );\n\n        return this.client.send(this.baseCrudPath + '/confirm-password-reset', options)\n            .then(() => true);\n    }\n}\n","import { BaseService }         from '@/services/utils/BaseService';\nimport { ClientResponseError } from '@/ClientResponseError';\n\ninterface promiseCallbacks {\n    resolve: Function\n    reject: Function\n}\n\nexport type UnsubscribeFunc = () => Promise<void>;\n\nexport class RealtimeService extends BaseService {\n    clientId: string = \"\";\n\n    private eventSource: EventSource | null = null;\n    private subscriptions: { [key: string]: Array<EventListener> } = {};\n    private lastSentTopics: Array<string> = [];\n    private connectTimeoutId: any;\n    private maxConnectTimeout: number = 15000;\n    private reconnectTimeoutId: any;\n    private reconnectAttempts: number = 0;\n    private maxReconnectAttempts: number = Infinity;\n    private predefinedReconnectIntervals: Array<number> = [\n        200, 300, 500, 1000, 1200, 1500, 2000,\n    ];\n    private pendingConnects: Array<promiseCallbacks> = [];\n\n    /**\n     * Returns whether the realtime connection has been established.\n     */\n    get isConnected(): boolean {\n        return !!this.eventSource && !!this.clientId && !this.pendingConnects.length;\n    }\n\n    /**\n     * Register the subscription listener.\n     *\n     * You can subscribe multiple times to the same topic.\n     *\n     * If the SSE connection is not started yet,\n     * this method will also initialize it.\n     */\n    async subscribe(topic: string, callback: (data: any) => void): Promise<UnsubscribeFunc> {\n        if (!topic) {\n            throw new Error('topic must be set.')\n        }\n\n        const listener = function (e: Event) {\n            const msgEvent = (e as MessageEvent);\n\n            let data;\n            try {\n                data = JSON.parse(msgEvent?.data);\n            } catch {}\n\n            callback(data || {});\n        };\n\n        // store the listener\n        if (!this.subscriptions[topic]) {\n            this.subscriptions[topic] = [];\n        }\n        this.subscriptions[topic].push(listener);\n\n        if (!this.isConnected) {\n            // initialize sse connection\n            await this.connect();\n        } else if (this.subscriptions[topic].length === 1) {\n            // send the updated subscriptions (if it is the first for the topic)\n            await this.submitSubscriptions();\n        } else {\n            // only register the listener\n            this.eventSource?.addEventListener(topic, listener);\n        }\n\n        return async (): Promise<void> => {\n            return this.unsubscribeByTopicAndListener(topic, listener);\n        };\n    }\n\n    /**\n     * Unsubscribe from all subscription listeners with the specified topic.\n     *\n     * If `topic` is not provided, then this method will unsubscribe\n     * from all active subscriptions.\n     *\n     * This method is no-op if there are no active subscriptions.\n     *\n     * The related sse connection will be autoclosed if after the\n     * unsubscribe operation there are no active subscriptions left.\n     */\n    async unsubscribe(topic?: string): Promise<void> {\n        if (!this.hasSubscriptionListeners(topic)) {\n            return; // already unsubscribed\n        }\n\n        if (!topic) {\n            // remove all subscriptions\n            this.subscriptions = {};\n        } else {\n            // remove all topic listeners\n            for (let listener of this.subscriptions[topic]) {\n                this.eventSource?.removeEventListener(topic, listener);\n            }\n            delete this.subscriptions[topic];\n        }\n\n        if (!this.hasSubscriptionListeners()) {\n            // no other active subscriptions -> close the sse connection\n            this.disconnect();\n        } else if (!this.hasSubscriptionListeners(topic)) {\n            // submit subscriptions change if there are no other active subscriptions related to the topic\n            await this.submitSubscriptions();\n        }\n    }\n\n    /**\n     * Unsubscribe from all subscription listeners starting with the specified topic prefix.\n     *\n     * This method is no-op if there are no active subscriptions with the specified topic prefix.\n     *\n     * The related sse connection will be autoclosed if after the\n     * unsubscribe operation there are no active subscriptions left.\n     */\n    async unsubscribeByPrefix(topicPrefix: string): Promise<void> {\n        let hasAtleastOneTopic = false;\n        for (let topic in this.subscriptions) {\n            if (!topic.startsWith(topicPrefix)) {\n                continue;\n            }\n\n            hasAtleastOneTopic = true;\n            for (let listener of this.subscriptions[topic]) {\n                this.eventSource?.removeEventListener(topic, listener);\n            }\n            delete this.subscriptions[topic];\n        }\n\n        if (!hasAtleastOneTopic) {\n            return; // nothing to unsubscribe from\n        }\n\n        if (this.hasSubscriptionListeners()) {\n            // submit the deleted subscriptions\n            await this.submitSubscriptions();\n        } else {\n            // no other active subscriptions -> close the sse connection\n            this.disconnect();\n        }\n    }\n\n    /**\n     * Unsubscribe from all subscriptions matching the specified topic and listener function.\n     *\n     * This method is no-op if there are no active subscription with\n     * the specified topic and listener.\n     *\n     * The related sse connection will be autoclosed if after the\n     * unsubscribe operation there are no active subscriptions left.\n     */\n    async unsubscribeByTopicAndListener(topic: string, listener: EventListener): Promise<void> {\n        if (!Array.isArray(this.subscriptions[topic]) || !this.subscriptions[topic].length) {\n            return; // already unsubscribed\n        }\n\n        let exist = false;\n        for (let i = this.subscriptions[topic].length - 1; i >= 0; i--) {\n            if (this.subscriptions[topic][i] !== listener) {\n                continue;\n            }\n\n            exist = true;                           // has at least one matching listener\n            delete this.subscriptions[topic][i];    // removes the function reference\n            this.subscriptions[topic].splice(i, 1); // reindex the array\n            this.eventSource?.removeEventListener(topic, listener);\n        }\n        if (!exist) {\n            return;\n        }\n\n        // remove the topic from the subscriptions list if there are no other listeners\n        if (!this.subscriptions[topic].length) {\n            delete this.subscriptions[topic];\n        }\n\n        if (!this.hasSubscriptionListeners()) {\n            // no other active subscriptions -> close the sse connection\n            this.disconnect();\n        } else if (!this.hasSubscriptionListeners(topic)) {\n            // submit subscriptions change if there are no other active subscriptions related to the topic\n            await this.submitSubscriptions();\n        }\n    }\n\n    private hasSubscriptionListeners(topicToCheck?: string): boolean {\n        this.subscriptions = this.subscriptions || {};\n\n        // check the specified topic\n        if (topicToCheck) {\n            return !!this.subscriptions[topicToCheck]?.length;\n        }\n\n        // check for at least one non-empty topic\n        for (let topic in this.subscriptions) {\n            if (!!this.subscriptions[topic]?.length) {\n                return true\n            }\n        }\n\n        return false;\n    }\n\n    private async submitSubscriptions(): Promise<void> {\n        if (!this.clientId) {\n            return; // no client/subscriber\n        }\n\n        // optimistic update\n        this.addAllSubscriptionListeners();\n\n        this.lastSentTopics = this.getNonEmptySubscriptionTopics();\n\n        return this.client.send('/api/realtime', {\n            'method': 'POST',\n            'body': {\n                'clientId': this.clientId,\n                'subscriptions': this.lastSentTopics,\n            },\n            'query': {\n                'requestKey': this.getSubscriptionsCancelKey(),\n            },\n        }).catch((err) => {\n            if (err?.isAbort) {\n                return; // silently ignore aborted pending requests\n            }\n            throw err;\n        });\n    }\n\n    private getSubscriptionsCancelKey(): string {\n        return \"realtime_\" + this.clientId;\n    }\n\n    private getNonEmptySubscriptionTopics(): Array<string> {\n        const result : Array<string> = [];\n\n        for (let topic in this.subscriptions) {\n            if (this.subscriptions[topic].length) {\n                result.push(topic);\n            }\n        }\n\n        return result;\n    }\n\n    private addAllSubscriptionListeners(): void {\n        if (!this.eventSource) {\n            return;\n        }\n\n        this.removeAllSubscriptionListeners();\n\n        for (let topic in this.subscriptions) {\n            for (let listener of this.subscriptions[topic]) {\n                this.eventSource.addEventListener(topic, listener);\n            }\n        }\n    }\n\n    private removeAllSubscriptionListeners(): void {\n        if (!this.eventSource) {\n            return;\n        }\n\n        for (let topic in this.subscriptions) {\n            for (let listener of this.subscriptions[topic]) {\n                this.eventSource.removeEventListener(topic, listener);\n            }\n        }\n    }\n\n    private async connect(): Promise<void> {\n        if (this.reconnectAttempts > 0)  {\n            // immediately resolve the promise to avoid indefinitely\n            // blocking the client during reconnection\n            return;\n        }\n\n        return new Promise((resolve, reject) => {\n            this.pendingConnects.push({ resolve, reject });\n\n            if (this.pendingConnects.length > 1) {\n                // all promises will be resolved once the connection is established\n                return;\n            }\n\n            this.initConnect();\n        })\n    }\n\n    private initConnect() {\n        this.disconnect(true);\n\n        // wait up to 15s for connect\n        clearTimeout(this.connectTimeoutId);\n        this.connectTimeoutId = setTimeout(() => {\n            this.connectErrorHandler(new Error(\"EventSource connect took too long.\"));\n        }, this.maxConnectTimeout);\n\n        this.eventSource = new EventSource(this.client.buildUrl('/api/realtime'))\n\n        this.eventSource.onerror = (_) => {\n            this.connectErrorHandler(new Error(\"Failed to establish realtime connection.\"));\n        };\n\n        this.eventSource.addEventListener('PB_CONNECT', (e) => {\n            const msgEvent = (e as MessageEvent);\n            this.clientId = msgEvent?.lastEventId;\n\n            this.submitSubscriptions()\n            .then(async () => {\n                let retries = 3;\n                while (this.hasUnsentSubscriptions() && retries > 0) {\n                    retries--;\n                    // resubscribe to ensure that the latest topics are submitted\n                    //\n                    // This is needed because missed topics could happen on reconnect\n                    // if after the pending sent `submitSubscriptions()` call another `subscribe()`\n                    // was made before the submit was able to complete.\n                    await this.submitSubscriptions();\n                }\n            }).then(() => {\n                for (let p of this.pendingConnects) {\n                    p.resolve();\n                }\n\n                // reset connect meta\n                this.pendingConnects = [];\n                this.reconnectAttempts = 0;\n                clearTimeout(this.reconnectTimeoutId);\n                clearTimeout(this.connectTimeoutId);\n            }).catch((err) => {\n                this.clientId = \"\";\n                this.connectErrorHandler(err);\n            });\n        });\n    }\n\n    private hasUnsentSubscriptions(): boolean {\n        const latestTopics = this.getNonEmptySubscriptionTopics();\n        if (latestTopics.length != this.lastSentTopics.length) {\n            return true;\n        }\n\n        for (const t of latestTopics) {\n            if (!this.lastSentTopics.includes(t)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    private connectErrorHandler(err: any) {\n        clearTimeout(this.connectTimeoutId);\n        clearTimeout(this.reconnectTimeoutId);\n\n        if (\n            // wasn't previously connected -> direct reject\n            (!this.clientId && !this.reconnectAttempts) ||\n            // was previously connected but the max reconnection limit has been reached\n            this.reconnectAttempts > this.maxReconnectAttempts\n        ) {\n            for (let p of this.pendingConnects) {\n                p.reject(new ClientResponseError(err));\n            }\n            this.pendingConnects = [];\n            this.disconnect();\n            return;\n        }\n\n        // otherwise -> reconnect in the background\n        this.disconnect(true);\n        const timeout = this.predefinedReconnectIntervals[this.reconnectAttempts] || this.predefinedReconnectIntervals[this.predefinedReconnectIntervals.length - 1];\n        this.reconnectAttempts++;\n        this.reconnectTimeoutId = setTimeout(() => {\n            this.initConnect();\n        }, timeout);\n    }\n\n    private disconnect(fromReconnect = false): void {\n        clearTimeout(this.connectTimeoutId);\n        clearTimeout(this.reconnectTimeoutId);\n        this.removeAllSubscriptionListeners();\n        this.client.cancelRequest(this.getSubscriptionsCancelKey());\n        this.eventSource?.close();\n        this.eventSource = null;\n        this.clientId = \"\";\n\n        if (!fromReconnect) {\n            this.reconnectAttempts = 0;\n\n            // resolve any remaining connect promises\n            //\n            // this is done to avoid unnecessary throwing errors in case\n            // unsubscribe is called before the pending connect promises complete\n            // (see https://github.com/pocketbase/pocketbase/discussions/2897#discussioncomment-6423818)\n            for (let p of this.pendingConnects) {\n                p.resolve();\n            }\n            this.pendingConnects = [];\n        }\n    }\n}\n","import Client from '@/Client';\nimport { CrudService } from '@/services/utils/CrudService';\nimport { RealtimeService, UnsubscribeFunc } from '@/services/RealtimeService';\nimport { ClientResponseError } from '@/ClientResponseError';\nimport { ListResult, RecordModel, ExternalAuthModel } from '@/services/utils/dtos';\nimport {\n    SendOptions,\n    CommonOptions,\n    RecordOptions,\n    RecordListOptions,\n    RecordFullListOptions,\n} from '@/services/utils/options';\nimport { normalizeLegacyOptionsArgs } from '@/services/utils/legacy';\n\nexport interface RecordAuthResponse<T = RecordModel> {\n    /**\n     * The signed PocketBase auth record.\n     */\n    record: T;\n\n    /**\n     * The PocketBase record auth token.\n     *\n     * If you are looking for the OAuth2 access and refresh tokens\n     * they are available under the `meta.accessToken` and `meta.refreshToken` props.\n     */\n    token: string;\n\n    /**\n     * Auth meta data usually filled when OAuth2 is used.\n     */\n    meta?: {[key: string]: any};\n}\n\nexport interface AuthProviderInfo {\n    name:                string;\n    state:               string;\n    codeVerifier:        string;\n    codeChallenge:       string;\n    codeChallengeMethod: string;\n    authUrl:             string;\n}\n\nexport interface AuthMethodsList {\n    usernamePassword: boolean;\n    emailPassword:    boolean;\n    authProviders:    Array<AuthProviderInfo>;\n}\n\nexport interface RecordSubscription<T = RecordModel> {\n    action: string; // eg. create, update, delete\n    record: T;\n}\n\nexport type OAuth2UrlCallback = (url: string) => void|Promise<void>;\n\nexport interface OAuth2AuthConfig extends SendOptions {\n    // the name of the OAuth2 provider (eg. \"google\")\n    provider: string;\n\n    // custom scopes to overwrite the default ones\n    scopes?: Array<string>;\n\n    // optional record create data\n    createData?: {[key: string]: any};\n\n    // optional callback that is triggered after the OAuth2 sign-in/sign-up url generation\n    urlCallback?: OAuth2UrlCallback;\n\n    // optional query params to send with the PocketBase auth request (eg. fields, expand, etc.)\n    query?: RecordOptions;\n}\n\nexport class RecordService extends CrudService<RecordModel> {\n    readonly collectionIdOrName: string;\n\n    constructor(client: Client, collectionIdOrName: string) {\n        super(client);\n\n        this.collectionIdOrName = collectionIdOrName;\n    }\n\n    /**\n     * @inheritdoc\n     */\n    get baseCrudPath(): string {\n        return this.baseCollectionPath + '/records';\n    }\n\n    /**\n     * Returns the current collection service base path.\n     */\n    get baseCollectionPath(): string {\n        return '/api/collections/' + encodeURIComponent(this.collectionIdOrName);\n    }\n\n    // ---------------------------------------------------------------\n    // Realtime handlers\n    // ---------------------------------------------------------------\n\n    /**\n     * @deprecated Use subscribe(recordId, callback) instead.\n     *\n     * Subscribe to the realtime changes of a single record in the collection.\n     */\n    async subscribeOne<T = RecordModel>(recordId: string, callback: (data: RecordSubscription<T>) => void): Promise<UnsubscribeFunc> {\n        console.warn(\"PocketBase: subscribeOne(recordId, callback) is deprecated. Please replace it with subscribe(recordId, callback).\");\n        return this.client.realtime.subscribe(this.collectionIdOrName + \"/\" + recordId, callback);\n    }\n\n    /**\n     * @deprecated This form of subscribe is deprecated. Please use `subscribe(\"*\", callback)`.\n     */\n    async subscribe<T = RecordModel>(callback: (data: RecordSubscription<T>) => void): Promise<UnsubscribeFunc>\n\n    /**\n     * Subscribe to realtime changes to the specified topic (\"*\" or record id).\n     *\n     * If `topic` is the wildcard \"*\", then this method will subscribe to\n     * any record changes in the collection.\n     *\n     * If `topic` is a record id, then this method will subscribe only\n     * to changes of the specified record id.\n     *\n     * It's OK to subscribe multiple times to the same topic.\n     * You can use the returned `UnsubscribeFunc` to remove only a single subscription.\n     * Or use `unsubscribe(topic)` if you want to remove all subscriptions attached to the topic.\n     */\n    async subscribe<T = RecordModel>(topic: string, callback: (data: RecordSubscription<T>) => void): Promise<UnsubscribeFunc>\n\n    async subscribe<T = RecordModel>(\n        topicOrCallback: string|((data: RecordSubscription<T>) => void),\n        callback?: (data: RecordSubscription<T>) => void\n    ): Promise<UnsubscribeFunc> {\n        if (typeof topicOrCallback === 'function') {\n            console.warn(\"PocketBase: subscribe(callback) is deprecated. Please replace it with subscribe('*', callback).\");\n            return this.client.realtime.subscribe(this.collectionIdOrName, topicOrCallback);\n        }\n\n        if (!callback) {\n            throw new Error(\"Missing subscription callback.\");\n        }\n\n        if (topicOrCallback === \"\") {\n            throw new Error(\"Missing topic.\");\n        }\n\n        let topic = this.collectionIdOrName;\n        if (topicOrCallback !== \"*\") {\n            topic += ('/' + topicOrCallback);\n        }\n\n        return this.client.realtime.subscribe(topic, callback)\n    }\n\n    /**\n     * Unsubscribe from all subscriptions of the specified topic\n     * (\"*\" or record id).\n     *\n     * If `topic` is not set, then this method will unsubscribe from\n     * all subscriptions associated to the current collection.\n     */\n    async unsubscribe(topic?: string): Promise<void> {\n        // unsubscribe wildcard topic\n        if (topic === \"*\") {\n            return this.client.realtime.unsubscribe(this.collectionIdOrName);\n        }\n\n        // unsubscribe recordId topic\n        if (topic) {\n            return this.client.realtime.unsubscribe(this.collectionIdOrName + \"/\" + topic);\n        }\n\n        // unsubscribe from everything related to the collection\n        return this.client.realtime.unsubscribeByPrefix(this.collectionIdOrName);\n    }\n\n    // ---------------------------------------------------------------\n    // Crud handers\n    // ---------------------------------------------------------------\n    /**\n     * @inheritdoc\n     */\n    getFullList<T = RecordModel>(options?: RecordFullListOptions): Promise<Array<T>>\n\n    /**\n     * @inheritdoc\n     */\n    getFullList<T = RecordModel>(batch?: number, options?: RecordListOptions): Promise<Array<T>>\n\n    /**\n     * @inheritdoc\n     */\n    getFullList<T = RecordModel>(batchOrOptions?: number|RecordFullListOptions, options?: RecordListOptions): Promise<Array<T>> {\n        if (typeof batchOrOptions == \"number\") {\n            return super.getFullList<T>(batchOrOptions, options);\n        }\n\n        const params = Object.assign({}, batchOrOptions, options);\n\n        return super.getFullList<T>(params);\n    }\n\n    /**\n     * @inheritdoc\n     */\n    getList<T = RecordModel>(page = 1, perPage = 30, options?: RecordListOptions): Promise<ListResult<T>> {\n        return super.getList<T>(page, perPage, options);\n    }\n\n    /**\n     * @inheritdoc\n     */\n    getFirstListItem<T = RecordModel>(filter: string, options?: RecordListOptions): Promise<T> {\n        return super.getFirstListItem<T>(filter, options);\n    }\n\n    /**\n     * @inheritdoc\n     */\n    getOne<T = RecordModel>(id: string, options?: RecordOptions): Promise<T> {\n        return super.getOne<T>(id, options);\n    }\n\n    /**\n     * @inheritdoc\n     */\n    create<T = RecordModel>(bodyParams?: {[key:string]:any}|FormData, options?: RecordOptions): Promise<T> {\n        return super.create<T>(bodyParams, options);\n    }\n\n    /**\n     * @inheritdoc\n     *\n     * If the current `client.authStore.model` matches with the updated id, then\n     * on success the `client.authStore.model` will be updated with the result.\n     */\n    update<T = RecordModel>(id: string, bodyParams?: {[key:string]:any}|FormData, options?: RecordOptions): Promise<T> {\n        return super.update<RecordModel>(id, bodyParams, options).then((item) => {\n            if (\n                // is record auth\n                this.client.authStore.model?.id === item?.id &&\n                (\n                    this.client.authStore.model?.collectionId === this.collectionIdOrName ||\n                    this.client.authStore.model?.collectionName === this.collectionIdOrName\n                )\n            ) {\n                this.client.authStore.save(this.client.authStore.token, item);\n            }\n\n            return item as any as T;\n        });\n    }\n\n    /**\n     * @inheritdoc\n     *\n     * If the current `client.authStore.model` matches with the deleted id,\n     * then on success the `client.authStore` will be cleared.\n     */\n    delete(id: string, options?: CommonOptions): Promise<boolean> {\n        return super.delete(id, options).then((success) => {\n            if (\n                success &&\n                // is record auth\n                this.client.authStore.model?.id === id &&\n                (\n                    this.client.authStore.model?.collectionId === this.collectionIdOrName ||\n                    this.client.authStore.model?.collectionName === this.collectionIdOrName\n                )\n            ) {\n                this.client.authStore.clear();\n            }\n\n            return success;\n        });\n    }\n\n    // ---------------------------------------------------------------\n    // Auth handlers\n    // ---------------------------------------------------------------\n\n    /**\n     * Prepare successful collection authorization response.\n     */\n    protected authResponse<T = RecordModel>(responseData: any): RecordAuthResponse<T> {\n        const record = this.decode(responseData?.record || {});\n\n        this.client.authStore.save(responseData?.token, record);\n\n        return Object.assign({}, responseData, {\n            // normalize common fields\n            'token':  responseData?.token || '',\n            'record': record as any as T,\n        });\n    }\n\n    /**\n     * Returns all available collection auth methods.\n     */\n    listAuthMethods(options?: CommonOptions): Promise<AuthMethodsList> {\n        options = Object.assign({\n            'method': 'GET',\n        }, options);\n\n        return this.client.send(this.baseCollectionPath + '/auth-methods', options)\n            .then((responseData: any) => {\n                return Object.assign({}, responseData, {\n                    // normalize common fields\n                    'usernamePassword': !!responseData?.usernamePassword,\n                    'emailPassword':    !!responseData?.emailPassword,\n                    'authProviders':    Array.isArray(responseData?.authProviders) ? responseData?.authProviders : [],\n                });\n            });\n    }\n\n    /**\n     * Authenticate a single auth collection record via its username/email and password.\n     *\n     * On success, this method also automatically updates\n     * the client's AuthStore data and returns:\n     * - the authentication token\n     * - the authenticated record model\n     */\n    authWithPassword<T = RecordModel>(usernameOrEmail: string, password: string, options?: RecordOptions): Promise<RecordAuthResponse<T>>\n\n    /**\n     * @deprecated\n     * Consider using authWithPassword(usernameOrEmail, password, options?).\n     */\n    authWithPassword<T = RecordModel>(usernameOrEmail: string, password: string, body?: any, query?: any): Promise<RecordAuthResponse<T>>\n\n    authWithPassword<T = RecordModel>(usernameOrEmail: string, password: string, bodyOrOptions?: any, query?: any): Promise<RecordAuthResponse<T>> {\n        let options: any = {\n            'method': 'POST',\n            'body': {\n                'identity': usernameOrEmail,\n                'password': password,\n            },\n        };\n\n        options = normalizeLegacyOptionsArgs(\n            'This form of authWithPassword(usernameOrEmail, pass, body?, query?) is deprecated. Consider replacing it with authWithPassword(usernameOrEmail, pass, options?).',\n            options,\n            bodyOrOptions,\n            query\n        );\n\n        return this.client.send(this.baseCollectionPath + '/auth-with-password', options)\n            .then((data) => this.authResponse<T>(data));\n    }\n\n    /**\n     * Authenticate a single auth collection record with OAuth2 code.\n     *\n     * If you don't have an OAuth2 code you may also want to check `authWithOAuth2` method.\n     *\n     * On success, this method also automatically updates\n     * the client's AuthStore data and returns:\n     * - the authentication token\n     * - the authenticated record model\n     * - the OAuth2 account data (eg. name, email, avatar, etc.)\n     */\n    authWithOAuth2Code<T = RecordModel>(\n        provider: string,\n        code: string,\n        codeVerifier: string,\n        redirectUrl: string,\n        createData?: {[key:string]:any},\n        options?: RecordOptions,\n    ): Promise<RecordAuthResponse<T>>\n\n    /**\n     * @deprecated\n     * Consider using authWithOAuth2Code(provider, code, codeVerifier, redirectUrl, createdData, options?).\n     */\n    authWithOAuth2Code<T = RecordModel>(\n        provider: string,\n        code: string,\n        codeVerifier: string,\n        redirectUrl: string,\n        createData?: {[key:string]:any},\n        body?: any,\n        query?: any\n    ): Promise<RecordAuthResponse<T>>\n\n    authWithOAuth2Code<T = RecordModel>(\n        provider: string,\n        code: string,\n        codeVerifier: string,\n        redirectUrl: string,\n        createData?: {[key:string]:any},\n        bodyOrOptions?: any,\n        query?: any\n    ): Promise<RecordAuthResponse<T>> {\n        let options: any = {\n            'method': 'POST',\n            'body': {\n                'provider':     provider,\n                'code':         code,\n                'codeVerifier': codeVerifier,\n                'redirectUrl':  redirectUrl,\n                'createData':   createData,\n            },\n        };\n\n        options = normalizeLegacyOptionsArgs(\n            'This form of authWithOAuth2Code(provider, code, codeVerifier, redirectUrl, createData?, body?, query?) is deprecated. Consider replacing it with authWithOAuth2Code(provider, code, codeVerifier, redirectUrl, createData?, options?).',\n            options,\n            bodyOrOptions,\n            query\n        );\n\n        return this.client.send(this.baseCollectionPath + '/auth-with-oauth2', options)\n            .then((data) => this.authResponse<T>(data));\n    }\n\n    /**\n     * @deprecated This form of authWithOAuth2 is deprecated.\n     *\n     * Please use `authWithOAuth2Code()` OR its simplified realtime version\n     * as shown in https://pocketbase.io/docs/authentication/#oauth2-integration.\n     */\n    async authWithOAuth2<T = RecordModel>(\n        provider: string,\n        code: string,\n        codeVerifier: string,\n        redirectUrl: string,\n        createData?: {[key: string]: any},\n        bodyParams?: {[key: string]: any},\n        queryParams?: RecordOptions,\n    ): Promise<RecordAuthResponse<T>>\n\n    /**\n     * Authenticate a single auth collection record with OAuth2\n     * **without custom redirects, deeplinks or even page reload**.\n     *\n     * This method initializes a one-off realtime subscription and will\n     * open a popup window with the OAuth2 vendor page to authenticate.\n     * Once the external OAuth2 sign-in/sign-up flow is completed, the popup\n     * window will be automatically closed and the OAuth2 data sent back\n     * to the user through the previously established realtime connection.\n     *\n     * You can specify an optional `urlCallback` prop to customize\n     * the default url `window.open` behavior.\n     *\n     * On success, this method also automatically updates\n     * the client's AuthStore data and returns:\n     * - the authentication token\n     * - the authenticated record model\n     * - the OAuth2 account data (eg. name, email, avatar, etc.)\n     *\n     * Example:\n     *\n     * ```js\n     * const authData = await pb.collection(\"users\").authWithOAuth2({\n     *     provider: \"google\",\n     * })\n     * ```\n     *\n     * _Site-note_: when creating the OAuth2 app in the provider dashboard\n     * you have to configure `https://yourdomain.com/api/oauth2-redirect`\n     * as redirect URL.\n     */\n    async authWithOAuth2<T = RecordModel>(options: OAuth2AuthConfig): Promise<RecordAuthResponse<T>>\n\n    async authWithOAuth2<T = RecordModel>(...args: any): Promise<RecordAuthResponse<T>> {\n        // fallback to legacy format\n        if (args.length > 1 || typeof args?.[0] === 'string') {\n            console.warn(\"PocketBase: This form of authWithOAuth2() is deprecated and may get removed in the future. Please replace with authWithOAuth2Code() OR use the authWithOAuth2() realtime form as shown in https://pocketbase.io/docs/authentication/#oauth2-integration.\");\n            return this.authWithOAuth2Code<T>(\n                args?.[0] || '',\n                args?.[1] || '',\n                args?.[2] || '',\n                args?.[3] || '',\n                args?.[4] || {},\n                args?.[5] || {},\n                args?.[6] || {},\n            );\n        }\n\n        const config = args?.[0] || {};\n\n        const authMethods = await this.listAuthMethods();\n\n        const provider = authMethods.authProviders.find((p) => p.name === config.provider);\n        if (!provider) {\n            throw new ClientResponseError(new Error(`Missing or invalid provider \"${config.provider}\".`));\n        }\n\n        const redirectUrl = this.client.buildUrl('/api/oauth2-redirect');\n\n        // initialize a one-off realtime service\n        const realtime = new RealtimeService(this.client);\n\n        // open a new popup window in case config.urlCallback is not set\n        //\n        // note: it is opened before the async call due to Safari restrictions\n        // (see https://github.com/pocketbase/pocketbase/discussions/2429#discussioncomment-5943061)\n        let eagerDefaultPopup: Window|null = null;\n        if (!config.urlCallback) {\n            eagerDefaultPopup = openBrowserPopup(undefined);\n        }\n\n        function cleanup() {\n            eagerDefaultPopup?.close();\n            realtime.unsubscribe();\n        }\n\n        return new Promise(async (resolve, reject) => {\n            try {\n                await realtime.subscribe('@oauth2', async (e) => {\n                    const oldState = realtime.clientId;\n\n                    try {\n                        if (!e.state || oldState !== e.state) {\n                            throw new Error(\"State parameters don't match.\");\n                        }\n\n                        // clear the non SendOptions props\n                        const options = Object.assign({}, config);\n                        delete options.provider;\n                        delete options.scopes;\n                        delete options.createData;\n                        delete options.urlCallback;\n\n                        const authData = await this.authWithOAuth2Code<T>(\n                            provider.name,\n                            e.code,\n                            provider.codeVerifier,\n                            redirectUrl,\n                            config.createData,\n                            options,\n                        );\n\n                        resolve(authData);\n                    } catch (err) {\n                        reject(new ClientResponseError(err));\n                    }\n\n                    cleanup();\n                });\n\n                const replacements: {[key: string]: any} = {\n                    \"state\": realtime.clientId,\n                }\n                if (config.scopes?.length) {\n                    replacements[\"scope\"] = config.scopes.join(\" \");\n                }\n\n                const url = this._replaceQueryParams(provider.authUrl + redirectUrl, replacements);\n\n                let urlCallback = config.urlCallback || function (url: string) {\n                    if (eagerDefaultPopup) {\n                       eagerDefaultPopup.location.href = url;\n                    } else {\n                        // it could have been blocked due to its empty initial url,\n                        // try again...\n                        eagerDefaultPopup = openBrowserPopup(url);\n                    }\n                }\n\n                await urlCallback(url);\n            } catch (err) {\n                cleanup();\n                reject(new ClientResponseError(err));\n            }\n        });\n    }\n\n    /**\n     * Refreshes the current authenticated record instance and\n     * returns a new token and record data.\n     *\n     * On success this method also automatically updates the client's AuthStore.\n     */\n    authRefresh<T = RecordModel>(options?: RecordOptions): Promise<RecordAuthResponse<T>>\n\n    /**\n     * @deprecated\n     * Consider using authRefresh(options?).\n     */\n    authRefresh<T = RecordModel>(body?: any, query?: any): Promise<RecordAuthResponse<T>>\n\n    authRefresh<T = RecordModel>(bodyOrOptions?: any, query?: any): Promise<RecordAuthResponse<T>> {\n        let options: any = {\n            'method': 'POST',\n        };\n\n        options = normalizeLegacyOptionsArgs(\n            'This form of authRefresh(body?, query?) is deprecated. Consider replacing it with authRefresh(options?).',\n            options,\n            bodyOrOptions,\n            query\n        );\n\n        return this.client.send(this.baseCollectionPath + '/auth-refresh', options)\n            .then((data) => this.authResponse<T>(data));\n    }\n\n    /**\n     * Sends auth record password reset request.\n     */\n    requestPasswordReset(email: string, options?: CommonOptions): Promise<boolean>\n\n    /**\n     * @deprecated\n     * Consider using requestPasswordReset(email, options?).\n     */\n    requestPasswordReset(email: string, body?: any, query?: any): Promise<boolean>\n\n    requestPasswordReset(email: string, bodyOrOptions?: any, query?: any): Promise<boolean> {\n        let options: any = {\n            'method': 'POST',\n            'body': {\n                'email': email,\n            }\n        };\n\n        options = normalizeLegacyOptionsArgs(\n            'This form of requestPasswordReset(email, body?, query?) is deprecated. Consider replacing it with requestPasswordReset(email, options?).',\n            options,\n            bodyOrOptions,\n            query\n        );\n\n        return this.client.send(this.baseCollectionPath + '/request-password-reset', options).then(() => true);\n    }\n\n    /**\n     * Confirms auth record password reset request.\n     */\n    confirmPasswordReset(\n        passwordResetToken: string,\n        password: string,\n        passwordConfirm: string,\n        options?: CommonOptions,\n    ): Promise<boolean>\n\n    /**\n     * @deprecated\n     * Consider using confirmPasswordReset(passwordResetToken, password, passwordConfirm, options?).\n     */\n    confirmPasswordReset(\n        passwordResetToken: string,\n        password: string,\n        passwordConfirm: string,\n        body?: any,\n        query?: any,\n    ): Promise<boolean>\n\n    confirmPasswordReset(\n        passwordResetToken: string,\n        password: string,\n        passwordConfirm: string,\n        bodyOrOptions?: any,\n        query?: any,\n    ): Promise<boolean> {\n        let options: any = {\n            'method': 'POST',\n            'body': {\n                'token':           passwordResetToken,\n                'password':        password,\n                'passwordConfirm': passwordConfirm,\n            }\n        };\n\n        options = normalizeLegacyOptionsArgs(\n            'This form of confirmPasswordReset(token, password, passwordConfirm, body?, query?) is deprecated. Consider replacing it with confirmPasswordReset(token, password, passwordConfirm, options?).',\n            options,\n            bodyOrOptions,\n            query\n        );\n\n        return this.client.send(this.baseCollectionPath + '/confirm-password-reset', options)\n            .then(() => true);\n    }\n\n    /**\n     * Sends auth record verification email request.\n     */\n    requestVerification(email: string, options?: CommonOptions): Promise<boolean>\n\n    /**\n     * @deprecated\n     * Consider using requestVerification(email, options?).\n     */\n    requestVerification(email: string, body?: any, query?: any): Promise<boolean>\n\n    requestVerification(email: string, bodyOrOptions?: any, query?: any): Promise<boolean> {\n        let options: any = {\n            'method': 'POST',\n            'body': {\n                'email': email,\n            }\n        };\n\n        options = normalizeLegacyOptionsArgs(\n            'This form of requestVerification(email, body?, query?) is deprecated. Consider replacing it with requestVerification(email, options?).',\n            options,\n            bodyOrOptions,\n            query\n        );\n\n        return this.client.send(this.baseCollectionPath + '/request-verification', options)\n            .then(() => true);\n    }\n\n    /**\n     * Confirms auth record email verification request.\n     */\n    confirmVerification(verificationToken: string, options?: CommonOptions): Promise<boolean>\n\n    /**\n     * @deprecated\n     * Consider using confirmVerification(verificationToken, options?).\n     */\n    confirmVerification(verificationToken: string, body?: any, query?: any): Promise<boolean>\n\n    confirmVerification(verificationToken: string, bodyOrOptions?: any, query?: any): Promise<boolean> {\n        let options: any = {\n            'method': 'POST',\n            'body': {\n                'token': verificationToken,\n            }\n        };\n\n        options = normalizeLegacyOptionsArgs(\n            'This form of confirmVerification(token, body?, query?) is deprecated. Consider replacing it with confirmVerification(token, options?).',\n            options,\n            bodyOrOptions,\n            query\n        );\n\n        return this.client.send(this.baseCollectionPath + '/confirm-verification', options)\n            .then(() => true);\n    }\n\n    /**\n     * Sends an email change request to the authenticated record model.\n     */\n    requestEmailChange(newEmail: string, options?: CommonOptions): Promise<boolean>\n\n    /**\n     * @deprecated\n     * Consider using requestEmailChange(newEmail, options?).\n     */\n    requestEmailChange(newEmail: string, body?: any, query?: any): Promise<boolean>\n\n    requestEmailChange(newEmail: string, bodyOrOptions?: any, query?: any): Promise<boolean> {\n        let options: any = {\n            'method': 'POST',\n            'body': {\n                'newEmail': newEmail,\n            }\n        };\n\n        options = normalizeLegacyOptionsArgs(\n            'This form of requestEmailChange(newEmail, body?, query?) is deprecated. Consider replacing it with requestEmailChange(newEmail, options?).',\n            options,\n            bodyOrOptions,\n            query\n        );\n\n        return this.client.send(this.baseCollectionPath + '/request-email-change', options)\n            .then(() => true);\n    }\n\n    /**\n     * Confirms auth record's new email address.\n     */\n    confirmEmailChange(emailChangeToken: string, password: string, options?: CommonOptions): Promise<boolean>\n\n\n    /**\n     * @deprecated\n     * Consider using confirmEmailChange(emailChangeToken, password, options?).\n     */\n    confirmEmailChange(emailChangeToken: string, password: string, body?: any, query?: any): Promise<boolean>\n\n    confirmEmailChange(emailChangeToken: string, password: string, bodyOrOptions?: any, query?: any): Promise<boolean> {\n        let options: any = {\n            'method': 'POST',\n            'body': {\n                'token':    emailChangeToken,\n                'password': password,\n            }\n        };\n\n        options = normalizeLegacyOptionsArgs(\n            'This form of confirmEmailChange(token, password, body?, query?) is deprecated. Consider replacing it with confirmEmailChange(token, password, options?).',\n            options,\n            bodyOrOptions,\n            query\n        );\n\n        return this.client.send(this.baseCollectionPath + '/confirm-email-change', options)\n            .then(() => true);\n    }\n\n    /**\n     * Lists all linked external auth providers for the specified auth record.\n     */\n    listExternalAuths(recordId: string, options?: CommonOptions): Promise<Array<ExternalAuthModel>> {\n        options = Object.assign({\n            'method': 'GET',\n        }, options);\n\n        return this.client.send(this.baseCrudPath + '/' + encodeURIComponent(recordId) + '/external-auths', options);\n    }\n\n    /**\n     * Unlink a single external auth provider from the specified auth record.\n     */\n    unlinkExternalAuth(recordId: string, provider: string, options?: CommonOptions): Promise<boolean> {\n        options = Object.assign({\n            'method': 'DELETE',\n        }, options);\n\n        return this.client.send(this.baseCrudPath + '/' + encodeURIComponent(recordId) + '/external-auths/' + encodeURIComponent(provider), options)\n            .then(() => true);\n    }\n\n    // ---------------------------------------------------------------\n\n    // very rudimentary url query params replacement because at the moment\n    // URL (and URLSearchParams) doesn't seem to be fully supported in React Native\n    //\n    // note: for details behind some of the decode/encode parsing check https://unixpapa.com/js/querystring.html\n    private _replaceQueryParams(url: string, replacements: {[key: string]: any} = {}): string {\n        let urlPath = url\n        let query = \"\";\n\n        const queryIndex = url.indexOf(\"?\");\n        if (queryIndex >= 0) {\n            urlPath = url.substring(0, url.indexOf(\"?\"));\n            query = url.substring(url.indexOf(\"?\") + 1);\n        }\n\n        const parsedParams: {[key: string]: string} = {};\n\n        // parse the query parameters\n        const rawParams = query.split(\"&\");\n        for (const param of rawParams) {\n            if (param == \"\") {\n                continue\n            }\n\n            const pair = param.split(\"=\");\n            parsedParams[decodeURIComponent(pair[0].replace(/\\+/g,' '))] = decodeURIComponent((pair[1] || \"\").replace(/\\+/g,' '));\n        }\n\n        // apply the replacements\n        for (let key in replacements) {\n            if (!replacements.hasOwnProperty(key)) {\n                continue;\n            }\n\n            if (replacements[key] == null) {\n                delete parsedParams[key];\n            } else {\n                parsedParams[key] = replacements[key];\n            }\n        }\n\n        // construct back the full query string\n        query = \"\";\n        for (let key in parsedParams) {\n            if (!parsedParams.hasOwnProperty(key)) {\n                continue;\n            }\n\n            if (query != \"\") {\n                query += \"&\";\n            }\n\n            query += encodeURIComponent(key.replace(/%20/g,'+')) + \"=\" + encodeURIComponent(parsedParams[key].replace(/%20/g,'+'));\n        }\n\n        return query != \"\" ? (urlPath + \"?\" + query) : urlPath;\n    }\n}\n\nfunction openBrowserPopup(url?: string): Window|null {\n    if (typeof window === \"undefined\" || !window?.open) {\n        throw new ClientResponseError(new Error(`Not in a browser context - please pass a custom urlCallback function.`));\n    }\n\n    let width  = 1024;\n    let height = 768;\n\n    let windowWidth  = window.innerWidth;\n    let windowHeight = window.innerHeight;\n\n    // normalize window size\n    width  = width > windowWidth ? windowWidth : width;\n    height = height > windowHeight ? windowHeight : height;\n\n    let left = (windowWidth / 2) - (width / 2);\n    let top  = (windowHeight / 2) - (height / 2);\n\n    // note: we don't use the noopener and noreferrer attributes since\n    // for some reason browser blocks such windows then url is undefined/blank\n    return window.open(\n        url,\n        'popup_window',\n        'width='+width+',height='+height+',top='+top+',left='+left+',resizable,menubar=no'\n    );\n}\n","import { CrudService }     from '@/services/utils/CrudService';\nimport { CollectionModel } from '@/services/utils/dtos';\nimport { CommonOptions }   from '@/services/utils/options';\n\nexport class CollectionService extends CrudService<CollectionModel> {\n    /**\n     * @inheritdoc\n     */\n    get baseCrudPath(): string {\n        return '/api/collections';\n    }\n\n    /**\n     * Imports the provided collections.\n     *\n     * If `deleteMissing` is `true`, all local collections and schema fields,\n     * that are not present in the imported configuration, WILL BE DELETED\n     * (including their related records data)!\n     */\n    async import(\n        collections: Array<CollectionModel>,\n        deleteMissing: boolean = false,\n        options?: CommonOptions,\n    ): Promise<true> {\n        options = Object.assign({\n            'method': 'PUT',\n            'body': {\n                'collections':   collections,\n                'deleteMissing': deleteMissing,\n            }\n        }, options);\n\n        return this.client.send(this.baseCrudPath + '/import', options)\n            .then(() => true);\n    }\n}\n","import { BaseService } from '@/services/utils/BaseService';\nimport { ListResult, LogRequestModel }  from '@/services/utils/dtos';\nimport {\n    CommonOptions,\n    ListOptions,\n    LogStatsOptions,\n} from '@/services/utils/options';\n\nexport interface HourlyStats {\n    total: number;\n    date:  string;\n}\n\nexport class LogService extends BaseService {\n    /**\n     * Returns paginated logged requests list.\n     */\n    getRequestsList(page = 1, perPage = 30, options?: ListOptions): Promise<ListResult<LogRequestModel>> {\n        options = Object.assign({'method': 'GET'}, options);\n\n        options.query = Object.assign({\n            'page':    page,\n            'perPage': perPage,\n        }, options.query);\n\n        return this.client.send('/api/logs/requests', options);\n    }\n\n    /**\n     * Returns a single logged request by its id.\n     */\n    getRequest(id: string, options?: CommonOptions): Promise<LogRequestModel> {\n        options = Object.assign({\n            'method': 'GET',\n        }, options);\n\n        return this.client.send('/api/logs/requests/' + encodeURIComponent(id), options);\n    }\n\n    /**\n     * Returns request logs statistics.\n     */\n    getRequestsStats(options?: LogStatsOptions): Promise<Array<HourlyStats>> {\n        options = Object.assign({\n            'method': 'GET',\n        }, options);\n\n        return this.client.send('/api/logs/requests/stats', options);\n    }\n}\n","import { BaseService }   from '@/services/utils/BaseService';\nimport { CommonOptions } from '@/services/utils/options';\n\nexport interface HealthCheckResponse {\n    code:    number;\n    message: string;\n    data:    {[key: string]: any};\n}\n\nexport class HealthService extends BaseService {\n    /**\n     * Checks the health status of the api.\n     */\n    check(options?: CommonOptions): Promise<HealthCheckResponse> {\n        options = Object.assign({\n            'method': 'GET',\n        }, options);\n\n        return this.client.send('/api/health', options);\n    }\n}\n","import { BaseService } from '@/services/utils/BaseService';\nimport { CommonOptions, FileOptions } from '@/services/utils/options';\n\nexport class FileService extends BaseService {\n    /**\n     * Builds and returns an absolute record file url for the provided filename.\n     */\n    getUrl(\n        record: {[key:string]:any},\n        filename: string,\n        queryParams: FileOptions = {}\n    ): string {\n        if (\n            !filename ||\n            !record?.id ||\n            !(record?.collectionId || record?.collectionName)\n        ) {\n            return '';\n        }\n\n        const parts = [];\n        parts.push('api')\n        parts.push('files')\n        parts.push(encodeURIComponent(record.collectionId || record.collectionName))\n        parts.push(encodeURIComponent(record.id))\n        parts.push(encodeURIComponent(filename))\n\n        let result = this.client.buildUrl(parts.join('/'));\n\n        if (Object.keys(queryParams).length) {\n            // normalize the download query param for consistency with the Dart sdk\n            if (queryParams.download === false) {\n                delete(queryParams.download);\n            }\n\n            const params = new URLSearchParams(queryParams);\n\n            result += (result.includes('?') ? '&' : '?') + params;\n        }\n\n        return result\n    }\n\n    /**\n     * Requests a new private file access token for the current auth model (admin or record).\n     */\n    getToken(options?: CommonOptions): Promise<string> {\n        options = Object.assign({\n            'method': 'POST',\n        }, options);\n\n        return this.client.send('/api/files/token', options)\n            .then((data) => data?.token || '');\n    }\n}\n","import { BaseService }   from '@/services/utils/BaseService';\nimport { CommonOptions } from '@/services/utils/options';\n\nexport interface BackupFileInfo {\n    key:      string;\n    size:     number;\n    modified: string;\n}\n\nexport class BackupService extends BaseService {\n    /**\n     * Returns list with all available backup files.\n     */\n    getFullList(options?: CommonOptions): Promise<Array<BackupFileInfo>> {\n        options = Object.assign({\n            'method': 'GET',\n        }, options);\n\n        return this.client.send('/api/backups', options);\n    }\n\n    /**\n     * Initializes a new backup.\n     */\n    create(basename: string, options?: CommonOptions): Promise<boolean> {\n        options = Object.assign({\n            'method': 'POST',\n            'body':   {\n                'name': basename,\n            },\n        }, options);\n\n        return this.client.send('/api/backups', options)\n            .then(() => true);\n    }\n\n    /**\n     * Uploads an existing backup file.\n     *\n     * Example:\n     *\n     * ```js\n     * await pb.backups.upload({\n     *     file: new Blob([...]),\n     * });\n     * ```\n     */\n    upload(bodyParams: {[key:string]:any}|FormData, options?: CommonOptions): Promise<boolean> {\n        options = Object.assign({\n            'method': 'POST',\n            'body':   bodyParams,\n        }, options);\n\n        return this.client.send('/api/backups/upload', options)\n            .then(() => true);\n    }\n\n    /**\n     * Deletes a single backup file.\n     */\n    delete(key: string, options?: CommonOptions): Promise<boolean> {\n        options = Object.assign({\n            'method': 'DELETE',\n        }, options);\n\n        return this.client.send(`/api/backups/${encodeURIComponent(key)}`, options)\n            .then(() => true);\n    }\n\n    /**\n     * Initializes an app data restore from an existing backup.\n     */\n    restore(key: string, options?: CommonOptions): Promise<boolean> {\n        options = Object.assign({\n            'method': 'POST',\n        }, options);\n\n        return this.client.send(`/api/backups/${encodeURIComponent(key)}/restore`, options)\n            .then(() => true);\n    }\n\n    /**\n     * Builds a download url for a single existing backup using an\n     * admin file token and the backup file key.\n     *\n     * The file token can be generated via `pb.files.getToken()`.\n     */\n    getDownloadUrl(token: string, key: string): string {\n        return this.client.buildUrl(`/api/backups/${encodeURIComponent(key)}?token=${encodeURIComponent(token)}`);\n    }\n}\n","import { ClientResponseError }      from '@/ClientResponseError';\nimport { BaseAuthStore }            from '@/stores/BaseAuthStore';\nimport { LocalAuthStore }           from '@/stores/LocalAuthStore';\nimport { SettingsService }          from '@/services/SettingsService';\nimport { AdminService }             from '@/services/AdminService';\nimport { RecordService }            from '@/services/RecordService';\nimport { CollectionService }        from '@/services/CollectionService';\nimport { LogService }               from '@/services/LogService';\nimport { RealtimeService }          from '@/services/RealtimeService';\nimport { HealthService }            from '@/services/HealthService';\nimport { FileService }              from '@/services/FileService';\nimport { BackupService }            from '@/services/BackupService';\nimport { SendOptions, FileOptions } from '@/services/utils/options';\n\n// list of known SendOptions keys (everything else is treated as query param)\nconst knownSendOptionsKeys = [\n    'requestKey',\n    '$cancelKey',\n    '$autoCancel',\n    'fetch',\n    'headers',\n    'body',\n    'query',\n    'params',\n    // ---,\n    'cache',\n    'credentials',\n    'headers',\n    'integrity',\n    'keepalive',\n    'method',\n    'mode',\n    'redirect',\n    'referrer',\n    'referrerPolicy',\n    'signal',\n    'window',\n];\n\nexport interface BeforeSendResult {\n    [key:     string]: any, // for backward compatibility\n    url?:     string,\n    options?: {[key: string]: any}\n}\n\ntype Fetch = typeof fetch;\n\n/**\n * PocketBase JS Client.\n */\nexport default class Client {\n    /**\n     * The base PocketBase backend url address (eg. 'http://127.0.0.1.8090').\n     */\n    baseUrl: string;\n\n    fetch: Fetch;\n\n    /**\n     * Hook that get triggered right before sending the fetch request,\n     * allowing you to inspect and modify the url and request options.\n     *\n     * For list of the possible options check https://developer.mozilla.org/en-US/docs/Web/API/fetch#options\n     *\n     * You can return a non-empty result object `{ url, options }` to replace the url and request options entirely.\n     *\n     * Example:\n     * ```js\n     * client.beforeSend = function (url, options) {\n     *     options.headers = Object.assign({}, options.headers, {\n     *         'X-Custom-Header': 'example',\n     *     });\n     *\n     *     return { url, options }\n     * };\n     * ```\n     */\n    beforeSend?: (url: string, options: SendOptions) => BeforeSendResult|Promise<BeforeSendResult>;\n\n    /**\n     * Hook that get triggered after successfully sending the fetch request,\n     * allowing you to inspect/modify the response object and its parsed data.\n     *\n     * Returns the new Promise resolved `data` that will be returned to the client.\n     *\n     * Example:\n     * ```js\n     * client.afterSend = function (response, data) {\n     *     if (response.status != 200) {\n     *         throw new ClientResponseError({\n     *             url:      response.url,\n     *             status:   response.status,\n     *             data:     data,\n     *         });\n     *     }\n     *\n     *     return data;\n     * };\n     * ```\n     */\n    afterSend?: (response: Response, data: any) => any;\n\n    /**\n     * Optional language code (default to `en-US`) that will be sent\n     * with the requests to the server as `Accept-Language` header.\n     */\n    lang: string;\n\n    /**\n     * A replaceable instance of the local auth store service.\n     */\n    authStore: BaseAuthStore;\n\n    /**\n     * An instance of the service that handles the **Settings APIs**.\n     */\n    readonly settings: SettingsService;\n\n    /**\n     * An instance of the service that handles the **Admin APIs**.\n     */\n    readonly admins: AdminService;\n\n    /**\n     * An instance of the service that handles the **Collection APIs**.\n     */\n    readonly collections: CollectionService;\n\n    /**\n     * An instance of the service that handles the **File APIs**.\n     */\n    readonly files: FileService;\n\n    /**\n     * An instance of the service that handles the **Log APIs**.\n     */\n    readonly logs: LogService;\n\n    /**\n     * An instance of the service that handles the **Realtime APIs**.\n     */\n    readonly realtime: RealtimeService;\n\n    /**\n     * An instance of the service that handles the **Health APIs**.\n     */\n    readonly health: HealthService;\n\n    /**\n     * An instance of the service that handles the **Backup APIs**.\n     */\n    readonly backups: BackupService;\n\n    private cancelControllers: { [key: string]: AbortController } = {};\n    private recordServices: { [key: string]: RecordService } = {};\n    private enableAutoCancellation: boolean = true;\n\n    constructor(\n        baseUrl = '/',\n        authStore?: BaseAuthStore | null,\n        lang = 'en-US',\n        customFetch: Fetch = fetch\n    ) {\n        this.baseUrl   = baseUrl;\n        this.lang      = lang;\n        this.authStore = authStore || new LocalAuthStore();\n        this.fetch = customFetch;\n\n        // services\n        this.admins      = new AdminService(this);\n        this.collections = new CollectionService(this);\n        this.files       = new FileService(this);\n        this.logs        = new LogService(this);\n        this.settings    = new SettingsService(this);\n        this.realtime    = new RealtimeService(this);\n        this.health      = new HealthService(this);\n        this.backups     = new BackupService(this);\n    }\n\n    /**\n     * Returns the RecordService associated to the specified collection.\n     *\n     * @param  {string} idOrName\n     * @return {RecordService}\n     */\n    collection(idOrName: string): RecordService {\n        if (!this.recordServices[idOrName]) {\n            this.recordServices[idOrName] = new RecordService(this, idOrName);\n        }\n\n        return this.recordServices[idOrName];\n    }\n\n    /**\n     * Globally enable or disable auto cancellation for pending duplicated requests.\n     */\n    autoCancellation(enable: boolean): Client {\n        this.enableAutoCancellation = !!enable;\n\n        return this;\n    }\n\n    /**\n     * Cancels single request by its cancellation key.\n     */\n    cancelRequest(requestKey: string): Client {\n        if (this.cancelControllers[requestKey]) {\n            this.cancelControllers[requestKey].abort();\n            delete this.cancelControllers[requestKey];\n        }\n\n        return this;\n    }\n\n    /**\n     * Cancels all pending requests.\n     */\n    cancelAllRequests(): Client {\n        for (let k in this.cancelControllers) {\n            this.cancelControllers[k].abort();\n        }\n\n        this.cancelControllers = {};\n\n        return this;\n    }\n\n    /**\n     * Legacy alias of `pb.files.getUrl()`.\n     */\n    getFileUrl(\n        record: {[key:string]:any},\n        filename: string,\n        queryParams: FileOptions = {}\n    ): string {\n        return this.files.getUrl(record, filename, queryParams);\n    }\n\n    /**\n     * Builds a full client url by safely concatenating the provided path.\n     */\n    buildUrl(path: string): string {\n        let url = this.baseUrl;\n\n        // construct an absolute base url if in a browser environment\n        if (\n            typeof window !== 'undefined' &&\n            !!window.location &&\n            !url.startsWith('https://') &&\n            !url.startsWith('http://')\n        ) {\n            url = window.location.origin?.endsWith('/') ?\n                window.location.origin.substring(0, window.location.origin.length - 1) :\n                (window.location.origin || '');\n\n            if (!this.baseUrl.startsWith('/')) {\n                url += window.location.pathname || '/';\n                url += url.endsWith('/') ? '' : '/';\n            }\n\n            url += this.baseUrl;\n        }\n\n        // concatenate the path\n        if (path) {\n            url += url.endsWith('/') ? '' : '/'; // append trailing slash if missing\n            url += path.startsWith('/') ? path.substring(1) : path;\n        }\n\n        return url;\n    }\n\n    /**\n     * Sends an api http request.\n     */\n    async send<T = any>(path: string, options: SendOptions): Promise<T> {\n        options = this.initSendOptions(path, options);\n\n        // build url + path\n        let url = this.buildUrl(path);\n\n        if (this.beforeSend) {\n            const result = Object.assign({}, await this.beforeSend(url, options));\n            if (typeof result.url !== 'undefined' || typeof result.options !== 'undefined') {\n                url = result.url || url;\n                options = result.options || options;\n            } else if (Object.keys(result).length) {\n                // legacy behavior\n                options = result as SendOptions;\n                console?.warn && console.warn('Deprecated format of beforeSend return: please use `return { url, options }`, instead of `return options`.');\n            }\n        }\n\n        // serialize the query parameters\n        if (typeof options.query !== 'undefined') {\n            const query = this.serializeQueryParams(options.query)\n            if (query) {\n                url += (url.includes('?') ? '&' : '?') + query;\n            }\n            delete options.query;\n        }\n\n        // ensures that the json body is serialized\n        if (\n            this.getHeader(options.headers, 'Content-Type') == 'application/json' &&\n            options.body && typeof options.body !== 'string'\n        ) {\n            options.body = JSON.stringify(options.body);\n        }\n\n        const fetchFunc = options.fetch || this.fetch;\n\n        // send the request\n        return fetchFunc(url, options)\n            .then(async (response) => {\n                let data : any = {};\n\n                try {\n                    data = await response.json();\n                } catch (_) {\n                    // all api responses are expected to return json\n                    // with the exception of the realtime event and 204\n                }\n\n                if (this.afterSend) {\n                    data = await this.afterSend(response, data);\n                }\n\n                if (response.status >= 400) {\n                    throw new ClientResponseError({\n                        url:      response.url,\n                        status:   response.status,\n                        data:     data,\n                    });\n                }\n\n                return data as T;\n            }).catch((err) => {\n                // wrap to normalize all errors\n                throw new ClientResponseError(err);\n            });\n    }\n\n    /**\n     * Shallow copy the provided object and takes care to initialize\n     * any options required to preserve the backward compatability.\n     *\n     * @param  {SendOptions} options\n     * @return {SendOptions}\n     */\n    private initSendOptions(path: string, options: SendOptions): SendOptions {\n        options = Object.assign({ method: 'GET' } as SendOptions, options)\n        options.query = options.query || {};\n\n        // auto convert the body to FormData, if needed\n        options.body = this.convertToFormDataIfNeeded(options.body);\n\n        // move unknown send options as query parameters\n        for (let key in options) {\n            if (knownSendOptionsKeys.includes(key)) {\n                continue\n            }\n\n            options.query[key] = options[key];\n            delete (options[key]);\n        }\n\n        // requestKey normalizations for backward-compatibility\n        // ---\n        options.query = Object.assign({}, options.params, options.query);\n        if (typeof options.requestKey === 'undefined') {\n            if (options.$autoCancel === false || options.query.$autoCancel === false) {\n                options.requestKey = null;\n            } else if (options.$cancelKey || options.query.$cancelKey) {\n                options.requestKey = options.$cancelKey || options.query.$cancelKey;\n            }\n        }\n        // remove the deprecated special cancellation params from the other query params\n        delete options.$autoCancel;\n        delete options.query.$autoCancel;\n        delete options.$cancelKey;\n        delete options.query.$cancelKey;\n        // ---\n\n        // add the json header, if not explicitly set\n        // (for FormData body the Content-Type header should be skipped since the boundary is autogenerated)\n        if (\n            this.getHeader(options.headers, 'Content-Type') === null &&\n            !this.isFormData(options.body)\n        ) {\n            options.headers = Object.assign({}, options.headers, {\n                'Content-Type': 'application/json',\n            });\n        }\n\n        // add Accept-Language header, if not explicitly set\n        if (this.getHeader(options.headers, 'Accept-Language') === null) {\n            options.headers = Object.assign({}, options.headers, {\n                'Accept-Language': this.lang,\n            });\n        }\n\n        // check if Authorization header can be added\n        if (\n            // has valid token\n            this.authStore.token &&\n            // auth header is not explicitly set\n            (this.getHeader(options.headers, 'Authorization') === null)\n        ) {\n            options.headers = Object.assign({}, options.headers, {\n                'Authorization': this.authStore.token,\n            });\n        }\n\n        // handle auto cancelation for duplicated pending request\n        if (this.enableAutoCancellation && options.requestKey !== null) {\n            const requestKey = options.requestKey || ((options.method || 'GET') + path);\n\n            delete options.requestKey;\n\n            // cancel previous pending requests\n            this.cancelRequest(requestKey);\n\n            const controller = new AbortController();\n            this.cancelControllers[requestKey] = controller;\n            options.signal = controller.signal;\n        }\n\n        return options\n    }\n\n    /**\n     * Converts analyzes the provided body and converts it to FormData\n     * in case a plain object with File/Blob values is used.\n     */\n    private convertToFormDataIfNeeded(body: any): any {\n        if (\n            typeof FormData === 'undefined' ||\n            typeof body === \"undefined\" ||\n            typeof body !== \"object\" ||\n            body === null ||\n            this.isFormData(body) ||\n            !this.hasBlobField(body)\n        ) {\n            return body;\n        }\n\n        const form = new FormData();\n\n        for (let key in body) {\n            const values = Array.isArray(body[key]) ? body[key] : [body[key]];\n            for (let val of values) {\n                form.append(key, val);\n            }\n        }\n\n        return form;\n    }\n\n    /**\n     * Checks if the submitted body object has at least one Blob/File field.\n     */\n    private hasBlobField(body: {[key:string]: any}): boolean {\n        for (let key in body) {\n            const values = Array.isArray(body[key]) ? body[key] : [body[key]];\n            for (let v of values) {\n                if (\n                    (typeof Blob !== 'undefined' && v instanceof Blob) ||\n                    (typeof File !== 'undefined' && v instanceof File)\n                ) {\n                    return true;\n                }\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Extracts the header with the provided name in case-insensitive manner.\n     * Returns `null` if no header matching the name is found.\n     */\n    private getHeader(headers: {[key:string]:string}|undefined, name: string): string|null {\n        headers = headers || {};\n        name = name.toLowerCase();\n\n        for (let key in headers) {\n            if (key.toLowerCase() == name) {\n                return headers[key];\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * Loosely checks if the specified body is a FormData instance.\n     */\n    private isFormData(body: any): boolean {\n        return body && (\n            // we are checking the constructor name because FormData\n            // is not available natively in some environments and the\n            // polyfill(s) may not be globally accessible\n            body.constructor.name === 'FormData' ||\n            // fallback to global FormData instance check\n            // note: this is needed because the constructor.name could be different in case of\n            //       custom global FormData implementation, eg. React Native on Android/iOS\n            (typeof FormData !== 'undefined' && body instanceof FormData)\n        )\n    }\n\n    /**\n     * Serializes the provided query parameters into a query string.\n     */\n    private serializeQueryParams(params: {[key: string]: any}): string {\n        const result: Array<string> = [];\n        for (const key in params) {\n            if (params[key] === null) {\n                // skip null query params\n                continue;\n            }\n\n            const value = params[key];\n            const encodedKey = encodeURIComponent(key);\n\n            if (Array.isArray(value)) {\n                // repeat array params\n                for (const v of value) {\n                    result.push(encodedKey + '=' + encodeURIComponent(v));\n                }\n            } else if (value instanceof Date) {\n                result.push(encodedKey + '=' + encodeURIComponent(value.toISOString()));\n            } else if (typeof value !== null && typeof value === 'object') {\n                result.push(encodedKey + '=' + encodeURIComponent(JSON.stringify(value)));\n            } else {\n                result.push(encodedKey + '=' + encodeURIComponent(value));\n            }\n        }\n\n        return result.join('&');\n    }\n}\n","import { BaseAuthStore, AuthModel } from '@/stores/BaseAuthStore';\n\nexport type AsyncSaveFunc = (serializedPayload: string) => Promise<void>;\n\nexport type AsyncClearFunc = () => Promise<void>;\n\ntype queueFunc = () => Promise<void>;\n\n/**\n * AsyncAuthStore is a helper auth store implementation\n * that could be used with any external async persistent layer\n * (key-value db, local file, etc.).\n *\n * Here is an example with the React Native AsyncStorage package:\n *\n * ```\n * import AsyncStorage from \"@react-native-async-storage/async-storage\";\n * import PocketBase, { AsyncAuthStore } from \"pocketbase\";\n *\n * const store = new AsyncAuthStore({\n *     save:    async (serialized) => AsyncStorage.setItem(\"pb_auth\", serialized),\n *     initial: await AsyncStorage.getItem(\"pb_auth\"),\n * });\n *\n * const pb = new PocketBase(\"https://example.com\", store)\n * ```\n */\nexport class AsyncAuthStore extends BaseAuthStore {\n    private saveFunc: AsyncSaveFunc;\n    private clearFunc?: AsyncClearFunc;\n    private queue: Array<queueFunc> = [];\n\n    constructor(config: {\n        // The async function that is called every time\n        // when the auth store state needs to be persisted.\n        save: AsyncSaveFunc,\n\n        /// An *optional* async function that is called every time\n        /// when the auth store needs to be cleared.\n        ///\n        /// If not explicitly set, `saveFunc` with empty data will be used.\n        clear?: AsyncClearFunc,\n\n        // initial data to load into the store\n        initial?: string,\n    }) {\n        super();\n\n        this.saveFunc = config.save;\n        this.clearFunc = config.clear;\n\n        this._loadInitial(config.initial);\n    }\n\n    /**\n     * @inheritdoc\n     */\n    save(token: string, model?: AuthModel): void {\n        super.save(token, model);\n\n        let value = '';\n        try {\n            value = JSON.stringify({token, model})\n        } catch (err) {\n            console.warn('AsyncAuthStore: failed to stringify the new state');\n        }\n\n        this._enqueue(() => this.saveFunc(value));\n    }\n\n    /**\n     * @inheritdoc\n     */\n    clear(): void {\n        super.clear();\n\n        if (this.clearFunc) {\n            this._enqueue(() => this.clearFunc!());\n        } else {\n            this._enqueue(() => this.saveFunc(\"\"));\n        }\n    }\n\n\n    /**\n     * Initializes the auth store state.\n     */\n    private _loadInitial(payload?: string) {\n        if (!payload) {\n            return; // nothing to load\n        }\n\n        try {\n            const parsed = JSON.parse(payload) || {};\n\n            this.save(parsed.token || \"\", parsed.model || null);\n        } catch (_) {}\n    }\n\n    /**\n     * Appends an async function to the queue.\n     */\n    private _enqueue(asyncCallback: () => Promise<void>) {\n        this.queue.push(asyncCallback);\n\n        if (this.queue.length == 1) {\n            this._dequeue();\n        }\n    }\n\n    /**\n     * Starts the queue processing.\n     */\n    private _dequeue() {\n        if (!this.queue.length) {\n            return;\n        }\n\n        this.queue[0]().finally(() => {\n            this.queue.shift();\n\n            if (!this.queue.length) {\n                return;\n            }\n\n            this._dequeue();\n        });\n    }\n}\n"],"names":["ClientResponseError","Error","constructor","errData","super","this","url","status","response","isAbort","originalError","Object","setPrototypeOf","prototype","data","DOMException","name","message","_a","_d","_c","_b","cause","includes","toJSON","assign","fieldContentRegExp","cookieParse","str","options","result","decode","defaultDecode","index","length","eqIdx","indexOf","endIdx","lastIndexOf","key","slice","trim","undefined","val","charCodeAt","_","cookieSerialize","opt","encode","defaultEncode","test","TypeError","value","maxAge","isNaN","isFinite","Math","floor","domain","path","expires","isDate","toString","call","Date","valueOf","toUTCString","httpOnly","secure","priority","toLowerCase","sameSite","decodeURIComponent","encodeURIComponent","atobPolyfill","getTokenPayload","token","encodedPayload","split","map","c","join","JSON","parse","e","isTokenExpired","expirationThreshold","payload","keys","exp","now","atob","input","String","replace","bs","buffer","bc","idx","output","charAt","fromCharCode","defaultCookieKey","BaseAuthStore","baseToken","baseModel","_onChangeCallbacks","model","isValid","isAdmin","type","isAuthRecord","save","triggerChange","clear","loadFromCookie","cookie","rawData","Array","isArray","exportToCookie","defaultOptions","stringify","resultLength","Blob","size","id","email","extraProps","prop","onChange","callback","fireImmediately","push","i","splice","LocalAuthStore","storageKey","storageFallback","_bindStorageEvent","_storageGet","_storageSet","_storageRemove","window","localStorage","rawValue","getItem","normalizedVal","setItem","removeItem","addEventListener","BaseService","client","SettingsService","getAll","method","send","update","bodyParams","body","testS3","filesystem","then","testEmail","toEmail","emailTemplate","template","generateAppleClientSecret","clientId","teamId","keyId","privateKey","duration","CrudService","getFullList","batchOrqueryParams","_getFullList","batch","getList","page","perPage","query","baseCrudPath","responseData","items","item","getFirstListItem","filter","requestKey","skipTotal","code","getOne","create","batchSize","request","__awaiter","list","concat","normalizeLegacyOptionsArgs","legacyWarn","baseOptions","bodyOrOptions","hasQuery","console","warn","resetAutoRefresh","_resetAutoRefresh","AdminService","authStore","collectionId","delete","success","authResponse","admin","authWithPassword","password","identity","autoRefreshThreshold","autoRefresh","authData","registerAutoRefresh","threshold","refreshFunc","reauthenticateFunc","oldBeforeSend","beforeSend","oldModel","unsubStoreChange","newToken","sendOptions","oldToken","headers","authRefresh","bind","requestPasswordReset","confirmPasswordReset","resetToken","passwordConfirm","RealtimeService","eventSource","subscriptions","lastSentTopics","maxConnectTimeout","reconnectAttempts","maxReconnectAttempts","Infinity","predefinedReconnectIntervals","pendingConnects","isConnected","subscribe","topic","listener","msgEvent","submitSubscriptions","connect","unsubscribeByTopicAndListener","unsubscribe","hasSubscriptionListeners","removeEventListener","disconnect","unsubscribeByPrefix","topicPrefix","hasAtleastOneTopic","startsWith","exist","topicToCheck","addAllSubscriptionListeners","getNonEmptySubscriptionTopics","getSubscriptionsCancelKey","catch","err","removeAllSubscriptionListeners","Promise","resolve","reject","initConnect","clearTimeout","connectTimeoutId","setTimeout","connectErrorHandler","EventSource","buildUrl","onerror","lastEventId","retries","hasUnsentSubscriptions","p","reconnectTimeoutId","latestTopics","t","timeout","fromReconnect","cancelRequest","close","RecordService","collectionIdOrName","baseCollectionPath","subscribeOne","recordId","realtime","topicOrCallback","batchOrOptions","params","collectionName","record","listAuthMethods","usernamePassword","emailPassword","authProviders","usernameOrEmail","authWithOAuth2Code","provider","codeVerifier","redirectUrl","createData","authWithOAuth2","args","config","find","eagerDefaultPopup","cleanup","urlCallback","openBrowserPopup","oldState","state","scopes","replacements","_replaceQueryParams","authUrl","location","href","passwordResetToken","requestVerification","confirmVerification","verificationToken","requestEmailChange","newEmail","confirmEmailChange","emailChangeToken","listExternalAuths","unlinkExternalAuth","urlPath","substring","parsedParams","rawParams","param","pair","hasOwnProperty","open","width","height","windowWidth","innerWidth","windowHeight","innerHeight","left","top","CollectionService","import","collections","deleteMissing","LogService","getRequestsList","getRequest","getRequestsStats","HealthService","check","FileService","getUrl","filename","queryParams","parts","download","URLSearchParams","getToken","BackupService","basename","upload","restore","getDownloadUrl","knownSendOptionsKeys","Client","baseUrl","lang","customFetch","fetch","cancelControllers","recordServices","enableAutoCancellation","admins","files","logs","settings","health","backups","collection","idOrName","autoCancellation","enable","abort","cancelAllRequests","k","getFileUrl","origin","endsWith","pathname","initSendOptions","serializeQueryParams","getHeader","json","afterSend","convertToFormDataIfNeeded","$autoCancel","$cancelKey","isFormData","Authorization","controller","AbortController","signal","FormData","hasBlobField","form","values","append","v","File","encodedKey","toISOString","AsyncAuthStore","queue","saveFunc","clearFunc","_loadInitial","initial","_enqueue","parsed","asyncCallback","_dequeue","finally","shift"],"mappings":"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"}