{"version":3,"file":"pocketbase.es.mjs","sources":["../src/ClientResponseError.ts","../src/tools/cookie.ts","../src/tools/jwt.ts","../src/stores/BaseAuthStore.ts","../src/stores/LocalAuthStore.ts","../src/services/BaseService.ts","../src/services/SettingsService.ts","../src/services/CrudService.ts","../src/tools/legacy.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/services/CronService.ts","../src/tools/formdata.ts","../src/tools/options.ts","../src/services/BatchService.ts","../src/Client.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.originalError?.cause?.message?.includes(\"ECONNREFUSED ::1\")) {\n                this.message =\n                    \"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` for 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(\n    name: string,\n    val: string,\n    options?: SerializeOptions,\n): 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 =\n            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 =\n            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 ? decodeURIComponent(val) : 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 Object.prototype.toString.call(val) === \"[object Date]\" || val instanceof Date;\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(\n                \"'atob' failed: The string to be decoded is not correctly encoded.\",\n            );\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(\n                atobPolyfill(token.split(\".\")[1])\n                    .split(\"\")\n                    .map(function (c: string) {\n                        return \"%\" + (\"00\" + c.charCodeAt(0).toString(16)).slice(-2);\n                    })\n                    .join(\"\"),\n            );\n\n            return JSON.parse(encodedPayload) || {};\n        } catch (e) {}\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 \"@/tools/cookie\";\nimport { isTokenExpired, getTokenPayload } from \"@/tools/jwt\";\nimport { RecordModel } from \"@/tools/dtos\";\n\nexport type AuthRecord = RecordModel | null;\n\nexport type AuthModel = AuthRecord; // for backward compatibility\n\nexport type OnStoreChangeFunc = (token: string, record: AuthRecord) => void;\n\nconst defaultCookieKey = \"pb_auth\";\n\n/**\n * Base AuthStore class that stores the auth state in runtime memory (aka. only for the duration of the store instane).\n *\n * Usually you wouldn't use it directly and instead use the builtin LocalAuthStore, AsyncAuthStore\n * or extend it with your own custom implementation.\n */\nexport class BaseAuthStore {\n    protected baseToken: string = \"\";\n    protected baseModel: AuthRecord = 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 record(): AuthRecord {\n        return this.baseModel;\n    }\n\n    /**\n     * @deprecated use `record` instead.\n     */\n    get model(): AuthRecord {\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     * Loosely checks whether the currently loaded store state is for superuser.\n     *\n     * Alternatively you can also compare directly `pb.authStore.record?.collectionName`.\n     */\n    get isSuperuser(): boolean {\n        let payload = getTokenPayload(this.token);\n\n        return (\n            payload.type == \"auth\" &&\n            (this.record?.collectionName == \"_superusers\" ||\n                // fallback in case the record field is not populated and assuming\n                // that the collection crc32 checksum id wasn't manually changed\n                (!this.record?.collectionName &&\n                    payload.collectionId == \"pbc_3142635823\"))\n        );\n    }\n\n    /**\n     * @deprecated use `isSuperuser` instead or simply check the record.collectionName property.\n     */\n    get isAdmin(): boolean {\n        console.warn(\n            \"Please replace pb.authStore.isAdmin with pb.authStore.isSuperuser OR simply check the value of pb.authStore.record?.collectionName\",\n        );\n        return this.isSuperuser;\n    }\n\n    /**\n     * @deprecated use `!isSuperuser` instead or simply check the record.collectionName property.\n     */\n    get isAuthRecord(): boolean {\n        console.warn(\n            \"Please replace pb.authStore.isAuthRecord with !pb.authStore.isSuperuser OR simply check the value of pb.authStore.record?.collectionName\",\n        );\n        return getTokenPayload(this.token).type == \"auth\" && !this.isSuperuser;\n    }\n\n    /**\n     * Saves the provided new token and model data in the auth store.\n     */\n    save(token: string, record?: AuthRecord): void {\n        this.baseToken = token || \"\";\n        this.baseModel = record || 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.record || 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            record: this.record ? JSON.parse(JSON.stringify(this.record)) : null,\n        };\n\n        let result = cookieSerialize(key, JSON.stringify(rawData), options);\n\n        const resultLength =\n            typeof Blob !== \"undefined\" ? new Blob([result]).size : result.length;\n\n        // strip down the model data to the bare minimum\n        if (rawData.record && resultLength > 4096) {\n            rawData.record = { id: rawData.record?.id, email: rawData.record?.email };\n            const extraProps = [\"collectionId\", \"collectionName\", \"verified\"];\n            for (const prop in this.record) {\n                if (extraProps.includes(prop)) {\n                    rawData.record[prop] = this.record[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.record);\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.record);\n        }\n    }\n}\n","import { BaseAuthStore, AuthRecord } from \"@/stores/BaseAuthStore\";\n\n/**\n * The default token store for browsers with auto fallback\n * to runtime/memory if local storage is undefined (e.g. 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 record(): AuthRecord {\n        const data = this._storageGet(this.storageKey) || {};\n\n        return data.record || data.model || null;\n    }\n\n    /**\n     * @deprecated use `record` instead.\n     */\n    get model(): AuthRecord {\n        return this.record;\n    }\n\n    /**\n     * @inheritdoc\n     */\n    save(token: string, record?: AuthRecord) {\n        this._storageSet(this.storageKey, {\n            token: token,\n            record: record,\n        });\n\n        super.save(token, record);\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) {\n                // 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 (\n            typeof window === \"undefined\" ||\n            !window?.localStorage ||\n            !window.addEventListener\n        ) {\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.record || 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/BaseService\";\nimport { CommonOptions } from \"@/tools/options\";\n\ninterface appleClientSecret {\n    secret: string;\n}\n\nexport class SettingsService extends BaseService {\n    /**\n     * Fetch all available app settings.\n     *\n     * @throws {ClientResponseError}\n     */\n    getAll(options?: CommonOptions): { [key: string]: any } {\n        options = Object.assign(\n            {\n                method: \"GET\",\n            },\n            options,\n        );\n\n        return this.client.send(\"/api/settings\", options);\n    }\n\n    /**\n     * Bulk updates app settings.\n     *\n     * @throws {ClientResponseError}\n     */\n    update(\n        bodyParams?: { [key: string]: any } | FormData,\n        options?: CommonOptions,\n    ): { [key: string]: any } {\n        options = Object.assign(\n            {\n                method: \"PATCH\",\n                body: bodyParams,\n            },\n            options,\n        );\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     * @throws {ClientResponseError}\n     */\n    testS3(filesystem: string = \"storage\", options?: CommonOptions): boolean {\n        options = Object.assign(\n            {\n                method: \"POST\",\n                body: {\n                    filesystem: filesystem,\n                },\n            },\n            options,\n        );\n\n        this.client.send(\"/api/settings/test/s3\", options);\n        return 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     * @throws {ClientResponseError}\n     */\n    testEmail(\n        collectionIdOrName: string,\n        toEmail: string,\n        emailTemplate: string,\n        options?: CommonOptions,\n    ): boolean {\n        options = Object.assign(\n            {\n                method: \"POST\",\n                body: {\n                    email: toEmail,\n                    template: emailTemplate,\n                    collection: collectionIdOrName,\n                },\n            },\n            options,\n        );\n\n        this.client.send(\"/api/settings/test/email\", options);\n        return true;\n    }\n\n    /**\n     * Generates a new Apple OAuth2 client secret.\n     *\n     * @throws {ClientResponseError}\n     */\n    generateAppleClientSecret(\n        clientId: string,\n        teamId: string,\n        keyId: string,\n        privateKey: string,\n        duration: number,\n        options?: CommonOptions,\n    ): appleClientSecret {\n        options = Object.assign(\n            {\n                method: \"POST\",\n                body: {\n                    clientId,\n                    teamId,\n                    keyId,\n                    privateKey,\n                    duration,\n                },\n            },\n            options,\n        );\n\n        return this.client.send(\"/api/settings/apple/generate-client-secret\", options);\n    }\n}\n","import { BaseService } from \"@/services/BaseService\";\nimport { ClientResponseError } from \"@/ClientResponseError\";\nimport { ListResult } from \"@/tools/dtos\";\nimport { CommonOptions, ListOptions, FullListOptions } from \"@/tools/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     * @throws {ClientResponseError}\n     */\n    getFullList<T = M>(options?: FullListOptions): Array<T>;\n\n    /**\n     * Legacy version of getFullList with explicitly specified batch size.\n     */\n    getFullList<T = M>(batch?: number, options?: ListOptions): Array<T>;\n\n    getFullList<T = M>(\n        batchOrqueryParams?: number | FullListOptions,\n        options?: ListOptions,\n    ): 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     * @throws {ClientResponseError}\n     */\n    getList<T = M>(page = 1, perPage = 30, options?: ListOptions): ListResult<T> {\n        options = Object.assign(\n            {\n                method: \"GET\",\n            },\n            options,\n        );\n\n        options.query = Object.assign(\n            {\n                page: page,\n                perPage: perPage,\n            },\n            options.query,\n        );\n\n        const responseData = this.client.send(this.baseCrudPath, options);\n        responseData.items =\n            responseData.items?.map((item: any) => {\n                return this.decode<T>(item);\n            }) || [];\n\n        return responseData;\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     * @throws {ClientResponseError}\n     */\n    getFirstListItem<T = M>(filter: string, options?: CommonOptions): T {\n        options = Object.assign(\n            {\n                requestKey: \"one_by_filter_\" + this.baseCrudPath + \"_\" + filter,\n            },\n            options,\n        );\n\n        options.query = Object.assign(\n            {\n                filter: filter,\n                skipTotal: 1,\n            },\n            options.query,\n        );\n\n        const result = this.getList<T>(1, 1, options);\n        if (!result?.items?.length) {\n            throw new ClientResponseError({\n                status: 404,\n                response: {\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     * 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     * If `id` is empty it will throw a 404 error.\n     *\n     * @throws {ClientResponseError}\n     */\n    getOne<T = M>(id: string, options?: CommonOptions): T {\n        if (!id) {\n            throw new ClientResponseError({\n                url: this.client.buildURL(this.baseCrudPath + \"/\"),\n                status: 404,\n                response: {\n                    code: 404,\n                    message: \"Missing required record id.\",\n                    data: {},\n                },\n            });\n        }\n\n        options = Object.assign(\n            {\n                method: \"GET\",\n            },\n            options,\n        );\n\n        const responseData = this.client.send(\n            this.baseCrudPath + \"/\" + encodeURIComponent(id),\n            options,\n        );\n        return 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     * @throws {ClientResponseError}\n     */\n    create<T = M>(\n        bodyParams?: { [key: string]: any } | FormData,\n        options?: CommonOptions,\n    ): T {\n        options = Object.assign(\n            {\n                method: \"POST\",\n                body: bodyParams,\n            },\n            options,\n        );\n\n        const responseData = this.client.send(this.baseCrudPath, options);\n        return 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     * @throws {ClientResponseError}\n     */\n    update<T = M>(\n        id: string,\n        bodyParams?: { [key: string]: any } | FormData,\n        options?: CommonOptions,\n    ): T {\n        options = Object.assign(\n            {\n                method: \"PATCH\",\n                body: bodyParams,\n            },\n            options,\n        );\n\n        const responseData = this.client.send(\n            this.baseCrudPath + \"/\" + encodeURIComponent(id),\n            options,\n        );\n        return this.decode<T>(responseData);\n    }\n\n    /**\n     * Deletes an existing item by its id.\n     *\n     * @throws {ClientResponseError}\n     */\n    delete(id: string, options?: CommonOptions): boolean {\n        options = Object.assign(\n            {\n                method: \"DELETE\",\n            },\n            options,\n        );\n\n        const responseData = this.client.send(\n            this.baseCrudPath + \"/\" + encodeURIComponent(id),\n            options,\n        );\n        return responseData;\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): Array<T> {\n        options = options || {};\n        options.query = Object.assign(\n            {\n                skipTotal: 1,\n            },\n            options.query,\n        );\n\n        let result: Array<T> = [];\n\n        let request = (page: number): Array<any> => {\n            const list = this.getList(page, batchSize || 500, options);\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        return request(1);\n    }\n}\n","import { SendOptions } from \"@/tools/options\";\n\nexport function normalizeLegacyOptionsArgs(\n    legacyWarn: string,\n    baseOptions: SendOptions,\n    bodyOrOptions?: any,\n    query?: any,\n): 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 { BaseAuthStore } from \"@/stores/BaseAuthStore\";\nimport { CrudService } from \"@/services/CrudService\";\nimport { ListResult, RecordModel } from \"@/tools/dtos\";\nimport { normalizeLegacyOptionsArgs } from \"@/tools/legacy\";\nimport {\n    CommonOptions,\n    RecordFullListOptions,\n    RecordListOptions,\n    RecordOptions,\n} from \"@/tools/options\";\nimport { getTokenPayload } from \"@/tools/jwt\";\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    displayName: string;\n    state: string;\n    authURL: string;\n    codeVerifier: string;\n    codeChallenge: string;\n    codeChallengeMethod: string;\n}\n\nexport interface AuthMethodsList {\n    mfa: {\n        enabled: boolean;\n        duration: number;\n    };\n    otp: {\n        enabled: boolean;\n        duration: number;\n    };\n    password: {\n        enabled: boolean;\n        identityFields: Array<string>;\n    };\n    oauth2: {\n        enabled: boolean;\n        providers: Array<AuthProviderInfo>;\n    };\n}\n\nexport interface RecordSubscription<T = RecordModel> {\n    action: string; // eg. create, update, delete\n    record: T;\n}\n\nexport interface OTPResponse {\n    otpId: string;\n}\n\nexport class RecordService<M = RecordModel> extends CrudService<M> {\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     * Returns whether the current service collection is superusers.\n     */\n    get isSuperusers(): boolean {\n        return (\n            this.collectionIdOrName == \"_superusers\" ||\n            this.collectionIdOrName == \"_pbc_2773867675\"\n        );\n    }\n\n    // ---------------------------------------------------------------\n    // Crud handlers\n    // ---------------------------------------------------------------\n    /**\n     * @inheritdoc\n     */\n    getFullList<T = M>(options?: RecordFullListOptions): Array<T>;\n\n    /**\n     * @inheritdoc\n     */\n    getFullList<T = M>(batch?: number, options?: RecordListOptions): Array<T>;\n\n    /**\n     * @inheritdoc\n     */\n    getFullList<T = M>(\n        batchOrOptions?: number | RecordFullListOptions,\n        options?: RecordListOptions,\n    ): 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 = M>(page = 1, perPage = 30, options?: RecordListOptions): ListResult<T> {\n        return super.getList<T>(page, perPage, options);\n    }\n\n    /**\n     * @inheritdoc\n     */\n    getFirstListItem<T = M>(filter: string, options?: RecordListOptions): T {\n        return super.getFirstListItem<T>(filter, options);\n    }\n\n    /**\n     * @inheritdoc\n     */\n    getOne<T = M>(id: string, options?: RecordOptions): T {\n        return super.getOne<T>(id, options);\n    }\n\n    /**\n     * @inheritdoc\n     */\n    create<T = M>(\n        bodyParams?: { [key: string]: any } | FormData,\n        options?: RecordOptions,\n    ): T {\n        return super.create<T>(bodyParams, options);\n    }\n\n    /**\n     * @inheritdoc\n     *\n     * If the current `client.authStore.record` matches with the updated id, then\n     * on success the `client.authStore.record` will be updated with the new response record fields.\n     */\n    update<T = M>(\n        id: string,\n        bodyParams?: { [key: string]: any } | FormData,\n        options?: RecordOptions,\n    ): T {\n        const item = super.update<RecordModel>(id, bodyParams, options);\n        if (\n            // is record auth\n            this.client.authStore.record?.id === item?.id &&\n            (this.client.authStore.record?.collectionId === this.collectionIdOrName ||\n                this.client.authStore.record?.collectionName === this.collectionIdOrName)\n        ) {\n            let authExpand = Object.assign({}, this.client.authStore.record.expand);\n            let authRecord = Object.assign({}, this.client.authStore.record, item);\n            if (authExpand) {\n                // for now \"merge\" only top-level expand\n                authRecord.expand = Object.assign(authExpand, item.expand);\n            }\n\n            this.client.authStore.save(this.client.authStore.token, authRecord);\n        }\n\n        return item as any as T;\n    }\n\n    /**\n     * @inheritdoc\n     *\n     * If the current `client.authStore.record` matches with the deleted id,\n     * then on success the `client.authStore` will be cleared.\n     */\n    delete(id: string, options?: CommonOptions): boolean {\n        const success = super.delete(id, options);\n        if (\n            success &&\n            // is record auth\n            this.client.authStore.record?.id === id &&\n            (this.client.authStore.record?.collectionId === this.collectionIdOrName ||\n                this.client.authStore.record?.collectionName === this.collectionIdOrName)\n        ) {\n            this.client.authStore.clear();\n        }\n\n        return success;\n    }\n\n    // ---------------------------------------------------------------\n    // Auth handlers\n    // ---------------------------------------------------------------\n\n    /**\n     * Prepare successful collection authorization response.\n     */\n    protected authResponse<T = M>(responseData: any): RecordAuthResponse<T> {\n        const record = this.decode(responseData?.record || {});\n\n        this.client.authStore.save(responseData?.token, record as any);\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     * @throws {ClientResponseError}\n     */\n    listAuthMethods(options?: CommonOptions): AuthMethodsList {\n        options = Object.assign(\n            {\n                method: \"GET\",\n                // @todo remove after deleting the pre v0.23 API response fields\n                fields: \"mfa,otp,password,oauth2\",\n            },\n            options,\n        );\n\n        return this.client.send(this.baseCollectionPath + \"/auth-methods\", options);\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     * @throws {ClientResponseError}\n     */\n    authWithPassword<T = M>(\n        usernameOrEmail: string,\n        password: string,\n        options?: RecordOptions,\n    ): RecordAuthResponse<T> {\n        options = Object.assign(\n            {\n                method: \"POST\",\n                body: {\n                    identity: usernameOrEmail,\n                    password: password,\n                },\n            },\n            options,\n        );\n\n        let authData = this.client.send(\n            this.baseCollectionPath + \"/auth-with-password\",\n            options,\n        );\n\n        authData = this.authResponse<T>(authData);\n\n        return authData;\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     * @throws {ClientResponseError}\n     */\n    authWithOAuth2Code<T = M>(\n        provider: string,\n        code: string,\n        codeVerifier: string,\n        redirectURL: string,\n        createData?: { [key: string]: any },\n        options?: RecordOptions,\n    ): RecordAuthResponse<T>;\n\n    authWithOAuth2Code<T = M>(\n        provider: string,\n        code: string,\n        codeVerifier: string,\n        redirectURL: string,\n        createData?: { [key: string]: any },\n        bodyOrOptions?: any,\n        query?: any,\n    ): 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        const data = this.client.send(\n            this.baseCollectionPath + \"/auth-with-oauth2\",\n            options,\n        );\n        return this.authResponse<T>(data);\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     * @throws {ClientResponseError}\n     */\n    authRefresh<T = M>(options?: RecordOptions): RecordAuthResponse<T>;\n\n    authRefresh<T = M>(bodyOrOptions?: any, query?: any): 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        const data = this.client.send(this.baseCollectionPath + \"/auth-refresh\", options);\n        return this.authResponse<T>(data);\n    }\n\n    /**\n     * Sends auth record password reset request.\n     *\n     * @throws {ClientResponseError}\n     */\n    requestPasswordReset(email: string, options?: CommonOptions): boolean;\n\n    requestPasswordReset(email: string, bodyOrOptions?: any, query?: any): 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        this.client.send(this.baseCollectionPath + \"/request-password-reset\", options);\n        return true;\n    }\n\n    /**\n     * Confirms auth record password reset request.\n     *\n     * @throws {ClientResponseError}\n     */\n    confirmPasswordReset(\n        passwordResetToken: string,\n        password: string,\n        passwordConfirm: string,\n        options?: CommonOptions,\n    ): boolean;\n\n    confirmPasswordReset(\n        passwordResetToken: string,\n        password: string,\n        passwordConfirm: string,\n        bodyOrOptions?: any,\n        query?: any,\n    ): 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        this.client.send(this.baseCollectionPath + \"/confirm-password-reset\", options);\n        return true;\n    }\n\n    /**\n     * Sends auth record verification email request.\n     *\n     * @throws {ClientResponseError}\n     */\n    requestVerification(email: string, options?: CommonOptions): boolean;\n\n    requestVerification(email: string, bodyOrOptions?: any, query?: any): 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        this.client.send(this.baseCollectionPath + \"/request-verification\", options);\n        return true;\n    }\n\n    /**\n     * Confirms auth record email verification request.\n     *\n     * If the current `client.authStore.record` matches with the auth record from the token,\n     * then on success the `client.authStore.record.verified` will be updated to `true`.\n     *\n     * @throws {ClientResponseError}\n     */\n    confirmVerification(verificationToken: string, options?: CommonOptions): boolean;\n\n    confirmVerification(\n        verificationToken: string,\n        bodyOrOptions?: any,\n        query?: any,\n    ): 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        this.client.send(this.baseCollectionPath + \"/confirm-verification\", options);\n        // on success manually update the current auth record verified state\n        const payload = getTokenPayload(verificationToken);\n        const model = this.client.authStore.record;\n        if (\n            model &&\n            !model.verified &&\n            model.id === payload.id &&\n            model.collectionId === payload.collectionId\n        ) {\n            model.verified = true;\n            this.client.authStore.save(this.client.authStore.token, model);\n        }\n\n        return true;\n    }\n\n    /**\n     * Sends an email change request to the authenticated record model.\n     *\n     * @throws {ClientResponseError}\n     */\n    requestEmailChange(newEmail: string, options?: CommonOptions): boolean;\n\n    requestEmailChange(newEmail: string, bodyOrOptions?: any, query?: any): 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        this.client.send(this.baseCollectionPath + \"/request-email-change\", options);\n        return true;\n    }\n\n    /**\n     * Confirms auth record's new email address.\n     *\n     * If the current `client.authStore.record` matches with the auth record from the token,\n     * then on success the `client.authStore` will be cleared.\n     *\n     * @throws {ClientResponseError}\n     */\n    confirmEmailChange(\n        emailChangeToken: string,\n        password: string,\n        options?: CommonOptions,\n    ): boolean;\n\n    confirmEmailChange(\n        emailChangeToken: string,\n        password: string,\n        bodyOrOptions?: any,\n        query?: any,\n    ): 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        this.client.send(this.baseCollectionPath + \"/confirm-email-change\", options);\n        // on success manually update the current auth record verified state\n        const payload = getTokenPayload(emailChangeToken);\n        const model = this.client.authStore.record;\n        if (\n            model &&\n            model.id === payload.id &&\n            model.collectionId === payload.collectionId\n        ) {\n            this.client.authStore.clear();\n        }\n\n        return true;\n    }\n\n    /**\n     * Sends auth record OTP to the provided email.\n     *\n     * @throws {ClientResponseError}\n     */\n    requestOTP(email: string, options?: CommonOptions): OTPResponse {\n        options = Object.assign(\n            {\n                method: \"POST\",\n                body: { email: email },\n            },\n            options,\n        );\n\n        return this.client.send(this.baseCollectionPath + \"/request-otp\", options);\n    }\n\n    /**\n     * Authenticate a single auth collection record via OTP.\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     * @throws {ClientResponseError}\n     */\n    authWithOTP<T = M>(\n        otpId: string,\n        password: string,\n        options?: CommonOptions,\n    ): RecordAuthResponse<T> {\n        options = Object.assign(\n            {\n                method: \"POST\",\n                body: { otpId, password },\n            },\n            options,\n        );\n\n        const data = this.client.send(\n            this.baseCollectionPath + \"/auth-with-otp\",\n            options,\n        );\n        return this.authResponse<T>(data);\n    }\n\n    /**\n     * Impersonate authenticates with the specified recordId and\n     * returns a new client with the received auth token in a memory store.\n     *\n     * If `duration` is 0 the generated auth token will fallback\n     * to the default collection auth token duration.\n     *\n     * This action currently requires superusers privileges.\n     *\n     * @throws {ClientResponseError}\n     */\n    impersonate(recordId: string, duration: number, options?: CommonOptions): Client {\n        options = Object.assign(\n            {\n                method: \"POST\",\n                body: { duration: duration },\n            },\n            options,\n        );\n        options.headers = options.headers || {};\n        if (!options.headers.Authorization) {\n            options.headers.Authorization = this.client.authStore.token;\n        }\n\n        // create a new client loaded with the impersonated auth state\n        // ---\n        const client = new Client(\n            this.client.baseURL,\n            new BaseAuthStore(),\n            this.client.lang,\n        );\n\n        const authData = client.send(\n            this.baseCollectionPath + \"/impersonate/\" + encodeURIComponent(recordId),\n            options,\n        );\n\n        client.authStore.save(authData?.token, this.decode(authData?.record || {}));\n        // ---\n\n        return client;\n    }\n}\n","import { CrudService } from \"@/services/CrudService\";\nimport { CollectionModel } from \"@/tools/dtos\";\nimport { CommonOptions } from \"@/tools/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 their fields,\n     * that are not present in the imported configuration, WILL BE DELETED\n     * (including their related records data)!\n     *\n     * @throws {ClientResponseError}\n     */\n    import(\n        collections: Array<CollectionModel>,\n        deleteMissing: boolean = false,\n        options?: CommonOptions,\n    ): boolean {\n        options = Object.assign(\n            {\n                method: \"PUT\",\n                body: {\n                    collections: collections,\n                    deleteMissing: deleteMissing,\n                },\n            },\n            options,\n        );\n\n        this.client.send(this.baseCrudPath + \"/import\", options);\n        return true;\n    }\n\n    /**\n     * Returns type indexed map with scaffolded collection models\n     * populated with their default field values.\n     *\n     * @throws {ClientResponseError}\n     */\n    getScaffolds(options?: CommonOptions): { [key: string]: CollectionModel } {\n        options = Object.assign(\n            {\n                method: \"GET\",\n            },\n            options,\n        );\n\n        return this.client.send(this.baseCrudPath + \"/meta/scaffolds\", options);\n    }\n\n    /**\n     * Deletes all records associated with the specified collection.\n     *\n     * @throws {ClientResponseError}\n     */\n    truncate(collectionIdOrName: string, options?: CommonOptions): boolean {\n        options = Object.assign(\n            {\n                method: \"DELETE\",\n            },\n            options,\n        );\n\n        this.client.send(\n            this.baseCrudPath +\n                \"/\" +\n                encodeURIComponent(collectionIdOrName) +\n                \"/truncate\",\n            options,\n        );\n        return true;\n    }\n}\n","import { ClientResponseError } from \"@/ClientResponseError\";\nimport { BaseService } from \"@/services/BaseService\";\nimport { ListResult, LogModel } from \"@/tools/dtos\";\nimport { CommonOptions, ListOptions, LogStatsOptions } from \"@/tools/options\";\n\nexport interface HourlyStats {\n    total: number;\n    date: string;\n}\n\nexport class LogService extends BaseService {\n    /**\n     * Returns paginated logs list.\n     *\n     * @throws {ClientResponseError}\n     */\n    getList(page = 1, perPage = 30, options?: ListOptions): ListResult<LogModel> {\n        options = Object.assign({ method: \"GET\" }, options);\n\n        options.query = Object.assign(\n            {\n                page: page,\n                perPage: perPage,\n            },\n            options.query,\n        );\n\n        return this.client.send(\"/api/logs\", options);\n    }\n\n    /**\n     * Returns a single log by its id.\n     *\n     * If `id` is empty it will throw a 404 error.\n     *\n     * @throws {ClientResponseError}\n     */\n    getOne(id: string, options?: CommonOptions): LogModel {\n        if (!id) {\n            throw new ClientResponseError({\n                url: this.client.buildURL(\"/api/logs/\"),\n                status: 404,\n                response: {\n                    code: 404,\n                    message: \"Missing required log id.\",\n                    data: {},\n                },\n            });\n        }\n\n        options = Object.assign(\n            {\n                method: \"GET\",\n            },\n            options,\n        );\n\n        return this.client.send(\"/api/logs/\" + encodeURIComponent(id), options);\n    }\n\n    /**\n     * Returns logs statistics.\n     *\n     * @throws {ClientResponseError}\n     */\n    getStats(options?: LogStatsOptions): Array<HourlyStats> {\n        options = Object.assign(\n            {\n                method: \"GET\",\n            },\n            options,\n        );\n\n        return this.client.send(\"/api/logs/stats\", options);\n    }\n}\n","import { BaseService } from \"@/services/BaseService\";\nimport { CommonOptions } from \"@/tools/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     * @throws {ClientResponseError}\n     */\n    check(options?: CommonOptions): HealthCheckResponse {\n        options = Object.assign(\n            {\n                method: \"GET\",\n            },\n            options,\n        );\n\n        return this.client.send(\"/api/health\", options);\n    }\n}\n","import { BaseService } from \"@/services/BaseService\";\nimport { CommonOptions, FileOptions } from \"@/tools/options\";\n\nexport class FileService extends BaseService {\n    /**\n     * @deprecated Please replace with `pb.files.getURL()`.\n     */\n    getUrl(\n        record: { [key: string]: any },\n        filename: string,\n        queryParams: FileOptions = {},\n    ): string {\n        console.warn(\"Please replace pb.files.getUrl() with pb.files.getURL()\");\n        return this.getURL(record, filename, queryParams);\n    }\n\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.\n     *\n     * @throws {ClientResponseError}\n     */\n    getToken(options?: CommonOptions): string {\n        options = Object.assign(\n            {\n                method: \"POST\",\n            },\n            options,\n        );\n\n        const data = this.client.send(\"/api/files/token\", options);\n        return data?.token || \"\";\n    }\n}\n","import { BaseService } from \"@/services/BaseService\";\nimport { CommonOptions } from \"@/tools/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     * @throws {ClientResponseError}\n     */\n    getFullList(options?: CommonOptions): Array<BackupFileInfo> {\n        options = Object.assign(\n            {\n                method: \"GET\",\n            },\n            options,\n        );\n\n        return this.client.send(\"/api/backups\", options);\n    }\n\n    /**\n     * Initializes a new backup.\n     *\n     * @throws {ClientResponseError}\n     */\n    create(basename: string, options?: CommonOptions): boolean {\n        options = Object.assign(\n            {\n                method: \"POST\",\n                body: {\n                    name: basename,\n                },\n            },\n            options,\n        );\n\n        this.client.send(\"/api/backups\", options);\n        return 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     * @throws {ClientResponseError}\n     */\n    upload(\n        bodyParams: { [key: string]: any } | FormData,\n        options?: CommonOptions,\n    ): boolean {\n        options = Object.assign(\n            {\n                method: \"POST\",\n                body: bodyParams,\n            },\n            options,\n        );\n\n        this.client.send(\"/api/backups/upload\", options);\n        return true;\n    }\n\n    /**\n     * Deletes a single backup file.\n     *\n     * @throws {ClientResponseError}\n     */\n    delete(key: string, options?: CommonOptions): boolean {\n        options = Object.assign(\n            {\n                method: \"DELETE\",\n            },\n            options,\n        );\n\n        this.client.send(`/api/backups/${encodeURIComponent(key)}`, options);\n        return true;\n    }\n\n    /**\n     * Initializes an app data restore from an existing backup.\n     *\n     * @throws {ClientResponseError}\n     */\n    restore(key: string, options?: CommonOptions): boolean {\n        options = Object.assign(\n            {\n                method: \"POST\",\n            },\n            options,\n        );\n\n        this.client.send(`/api/backups/${encodeURIComponent(key)}/restore`, options);\n        return true;\n    }\n\n    /**\n     * Builds a download url for a single existing backup using a\n     * superuser 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(\n            `/api/backups/${encodeURIComponent(key)}?token=${encodeURIComponent(token)}`,\n        );\n    }\n}\n","import { BaseService } from \"@/services/BaseService\";\nimport { CommonOptions } from \"@/tools/options\";\n\nexport interface CronJob {\n    id: string;\n    expression: string;\n}\n\nexport class CronService extends BaseService {\n    /**\n     * Returns list with all registered cron jobs.\n     *\n     * @throws {ClientResponseError}\n     */\n    getFullList(options?: CommonOptions): Array<CronJob> {\n        options = Object.assign(\n            {\n                method: \"GET\",\n            },\n            options,\n        );\n\n        return this.client.send(\"/api/crons\", options);\n    }\n\n    /**\n     * Runs the specified cron job.\n     *\n     * @throws {ClientResponseError}\n     */\n    run(jobId: string, options?: CommonOptions): boolean {\n        options = Object.assign(\n            {\n                method: \"POST\",\n            },\n            options,\n        );\n\n        this.client.send(`/api/crons/${encodeURIComponent(jobId)}`, options);\n        return true;\n    }\n}\n","/**\n * Checks if the specified value is a file (aka. File, Blob, RN file object).\n */\nexport function isFile(val: any): boolean {\n    return (\n        (typeof Blob !== \"undefined\" && val instanceof Blob) ||\n        (typeof File !== \"undefined\" && val instanceof File)\n    );\n}\n\n/**\n * Loosely checks if the specified body is a FormData instance.\n */\nexport function isFormData(body: any): boolean {\n    return (\n        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 * Checks if the submitted body object has at least one Blob/File field value.\n */\nexport function hasFileField(body: { [key: string]: any }): boolean {\n    for (const key in body) {\n        const values = Array.isArray(body[key]) ? body[key] : [body[key]];\n        for (const v of values) {\n            if (isFile(v)) {\n                return true;\n            }\n        }\n    }\n\n    return false;\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 */\nexport function convertToFormDataIfNeeded(body: any): any {\n    if (\n        typeof FormData === \"undefined\" ||\n        typeof body === \"undefined\" ||\n        typeof body !== \"object\" ||\n        body === null ||\n        isFormData(body) ||\n        !hasFileField(body)\n    ) {\n        return body;\n    }\n\n    const form = new FormData();\n\n    for (const key in body) {\n        const val = body[key];\n\n        if (typeof val === \"object\" && !hasFileField({ data: val })) {\n            // send json-like values as jsonPayload to avoid the implicit string value normalization\n            let payload: { [key: string]: any } = {};\n            payload[key] = val;\n            form.append(\"@jsonPayload\", JSON.stringify(payload));\n        } else {\n            // in case of mixed string and file/blob\n            const normalizedVal = Array.isArray(val) ? val : [val];\n            for (let v of normalizedVal) {\n                form.append(key, v);\n            }\n        }\n    }\n\n    return form;\n}\n\n/**\n * Converts the provided FormData instance into a plain object.\n *\n * For consistency with the server multipart/form-data inferring,\n * the following normalization rules are applied for plain multipart string values:\n *   - \"true\" is converted to the json \"true\"\n *   - \"false\" is converted to the json \"false\"\n *   - numeric strings are converted to json number ONLY if the resulted\n *     minimal number string representation is the same as the provided raw string\n *     (aka. scientific notations, \"Infinity\", \"0.0\", \"0001\", etc. are kept as string)\n *   - any other string (empty string too) is left as it is\n */\nexport function convertFormDataToObject(formData: FormData): { [key: string]: any } {\n    let result: { [key: string]: any } = {};\n\n    formData.forEach((v, k) => {\n        if (k === \"@jsonPayload\" && typeof v == \"string\") {\n            try {\n                let parsed = JSON.parse(v);\n                Object.assign(result, parsed);\n            } catch (err) {\n                console.warn(\"@jsonPayload error:\", err);\n            }\n        } else {\n            if (typeof result[k] !== \"undefined\") {\n                if (!Array.isArray(result[k])) {\n                    result[k] = [result[k]];\n                }\n                result[k].push(inferFormDataValue(v));\n            } else {\n                result[k] = inferFormDataValue(v);\n            }\n        }\n    });\n\n    return result;\n}\n\nconst inferNumberCharsRegex = /^[\\-\\.\\d]+$/;\n\nfunction inferFormDataValue(value: any): any {\n    if (typeof value != \"string\") {\n        return value;\n    }\n\n    if (value == \"true\") {\n        return true;\n    }\n\n    if (value == \"false\") {\n        return false;\n    }\n\n    // note: expects the provided raw string to match exactly with the minimal string representation of the parsed number\n    if (\n        (value[0] === \"-\" || (value[0] >= \"0\" && value[0] <= \"9\")) &&\n        inferNumberCharsRegex.test(value)\n    ) {\n        let num = +value;\n        if (\"\" + num === value) {\n            return num;\n        }\n    }\n\n    return value;\n}\n","export type FetchFunction = (url: string | URL, config?: RequestInit) => Response;\n\nexport interface SendOptions extends RequestInit {\n    // for backward compatibility and to minimize the verbosity,\n    // any top-level field that doesn't exist in RequestInit or the\n    // fields below will be treated as query parameter.\n    [key: string]: any;\n\n    /**\n     * Optional custom fetch function to use for sending the request.\n     */\n    fetch?: typeof $http.send;\n\n    /**\n     * Custom headers to send with the requests.\n     */\n    headers?: { [key: string]: string };\n\n    /**\n     * The body of the request (serialized automatically for json requests).\n     */\n    body?: any;\n\n    /**\n     * Query parameters that will be appended to the request url.\n     */\n    query?: { [key: string]: any };\n}\n\nexport interface CommonOptions extends SendOptions {\n    fields?: string;\n}\n\nexport interface ListOptions extends CommonOptions {\n    page?: number;\n    perPage?: number;\n    sort?: string;\n    filter?: string;\n    skipTotal?: boolean;\n}\n\nexport interface FullListOptions extends ListOptions {\n    batch?: number;\n}\n\nexport interface RecordOptions extends CommonOptions {\n    expand?: string;\n}\n\nexport interface RecordListOptions extends ListOptions, RecordOptions {}\n\nexport interface RecordFullListOptions extends FullListOptions, RecordOptions {}\n\nexport interface RecordSubscribeOptions extends SendOptions {\n    fields?: string;\n    filter?: string;\n    expand?: string;\n}\n\nexport interface LogStatsOptions extends CommonOptions {\n    filter?: string;\n}\n\nexport interface FileOptions extends CommonOptions {\n    thumb?: string;\n    download?: boolean;\n}\n\nexport interface AuthOptions extends CommonOptions {\n    /**\n     * If autoRefreshThreshold is set it will take care to auto refresh\n     * when necessary the auth data before each request to ensure that\n     * the auth state is always valid.\n     *\n     * The value must be in seconds, aka. the amount of seconds\n     * that will be subtracted from the current token `exp` claim in order\n     * to determine whether it is going to expire within the specified time threshold.\n     *\n     * For example, if you want to auto refresh the token if it is\n     * going to expire in the next 30mins (or already has expired),\n     * it can be set to `1800`\n     */\n    autoRefreshThreshold?: number;\n}\n\n// -------------------------------------------------------------------\n\n// list of known SendOptions keys (everything else is treated as query param)\nconst knownSendOptionsKeys = [\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\n// modifies in place the provided options by moving unknown send options as query parameters.\nexport function normalizeUnknownQueryParams(options?: SendOptions): void {\n    if (!options) {\n        return;\n    }\n\n    options.query = options.query || {};\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\nexport function serializeQueryParams(params: { [key: string]: any }): string {\n    const result: Array<string> = [];\n\n    for (const key in params) {\n        if (params[key] === null || typeof params[key] === \"undefined\") {\n            // skip null or undefined 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","import { BaseService } from \"@/services/BaseService\";\nimport { isFile, isFormData, convertFormDataToObject } from \"@/tools/formdata\";\nimport {\n    SendOptions,\n    RecordOptions,\n    normalizeUnknownQueryParams,\n    serializeQueryParams,\n} from \"@/tools/options\";\n\nexport interface BatchRequest {\n    method: string;\n    url: string;\n    json?: { [key: string]: any };\n    files?: { [key: string]: Array<any> };\n    headers?: { [key: string]: string };\n}\n\nexport interface BatchRequestResult {\n    status: number;\n    body: any;\n}\n\nexport class BatchService extends BaseService {\n    private requests: Array<BatchRequest> = [];\n    private subs: { [key: string]: SubBatchService } = {};\n\n    /**\n     * Starts constructing a batch request entry for the specified collection.\n     */\n    collection(collectionIdOrName: string): SubBatchService {\n        if (!this.subs[collectionIdOrName]) {\n            this.subs[collectionIdOrName] = new SubBatchService(\n                this.requests,\n                collectionIdOrName,\n            );\n        }\n\n        return this.subs[collectionIdOrName];\n    }\n\n    /**\n     * Sends the batch requests.\n     *\n     * @throws {ClientResponseError}\n     */\n    send(options?: SendOptions): Array<BatchRequestResult> {\n        const formData = new FormData();\n\n        const jsonData = [];\n\n        for (let i = 0; i < this.requests.length; i++) {\n            const req = this.requests[i];\n\n            jsonData.push({\n                method: req.method,\n                url: req.url,\n                headers: req.headers,\n                body: req.json,\n            });\n\n            if (req.files) {\n                for (let key in req.files) {\n                    const files = req.files[key] || [];\n                    for (let file of files) {\n                        formData.append(\"requests.\" + i + \".\" + key, file);\n                    }\n                }\n            }\n        }\n\n        formData.append(\"@jsonPayload\", JSON.stringify({ requests: jsonData }));\n\n        options = Object.assign(\n            {\n                method: \"POST\",\n                body: formData,\n            },\n            options,\n        );\n\n        return this.client.send(\"/api/batch\", options);\n    }\n}\n\nexport class SubBatchService {\n    private requests: Array<BatchRequest> = [];\n    private readonly collectionIdOrName: string;\n\n    constructor(requests: Array<BatchRequest>, collectionIdOrName: string) {\n        this.requests = requests;\n        this.collectionIdOrName = collectionIdOrName;\n    }\n\n    /**\n     * Registers a record upsert request into the current batch queue.\n     *\n     * The request will be executed as update if `bodyParams` have a valid existing record `id` value, otherwise - create.\n     */\n    upsert(\n        bodyParams?: { [key: string]: any } | FormData,\n        options?: RecordOptions,\n    ): void {\n        options = Object.assign(\n            {\n                body: bodyParams || {},\n            },\n            options,\n        );\n\n        const request: BatchRequest = {\n            method: \"PUT\",\n            url:\n                \"/api/collections/\" +\n                encodeURIComponent(this.collectionIdOrName) +\n                \"/records\",\n        };\n\n        this.prepareRequest(request, options);\n\n        this.requests.push(request);\n    }\n\n    /**\n     * Registers a record create request into the current batch queue.\n     */\n    create(\n        bodyParams?: { [key: string]: any } | FormData,\n        options?: RecordOptions,\n    ): void {\n        options = Object.assign(\n            {\n                body: bodyParams || {},\n            },\n            options,\n        );\n\n        const request: BatchRequest = {\n            method: \"POST\",\n            url:\n                \"/api/collections/\" +\n                encodeURIComponent(this.collectionIdOrName) +\n                \"/records\",\n        };\n\n        this.prepareRequest(request, options);\n\n        this.requests.push(request);\n    }\n\n    /**\n     * Registers a record update request into the current batch queue.\n     */\n    update(\n        id: string,\n        bodyParams?: { [key: string]: any } | FormData,\n        options?: RecordOptions,\n    ): void {\n        options = Object.assign(\n            {\n                body: bodyParams || {},\n            },\n            options,\n        );\n\n        const request: BatchRequest = {\n            method: \"PATCH\",\n            url:\n                \"/api/collections/\" +\n                encodeURIComponent(this.collectionIdOrName) +\n                \"/records/\" +\n                encodeURIComponent(id),\n        };\n\n        this.prepareRequest(request, options);\n\n        this.requests.push(request);\n    }\n\n    /**\n     * Registers a record delete request into the current batch queue.\n     */\n    delete(id: string, options?: SendOptions): void {\n        options = Object.assign({}, options);\n\n        const request: BatchRequest = {\n            method: \"DELETE\",\n            url:\n                \"/api/collections/\" +\n                encodeURIComponent(this.collectionIdOrName) +\n                \"/records/\" +\n                encodeURIComponent(id),\n        };\n\n        this.prepareRequest(request, options);\n\n        this.requests.push(request);\n    }\n\n    private prepareRequest(request: BatchRequest, options: SendOptions) {\n        normalizeUnknownQueryParams(options);\n\n        request.headers = options.headers;\n        request.json = {};\n        request.files = {};\n\n        // serialize query parameters\n        // -----------------------------------------------------------\n        if (typeof options.query !== \"undefined\") {\n            const query = serializeQueryParams(options.query);\n            if (query) {\n                request.url += (request.url.includes(\"?\") ? \"&\" : \"?\") + query;\n            }\n        }\n\n        // extract json and files body data\n        // -----------------------------------------------------------\n        let body = options.body;\n        if (isFormData(body)) {\n            body = convertFormDataToObject(body);\n        }\n\n        for (const key in body) {\n            const val = body[key];\n\n            if (isFile(val)) {\n                request.files[key] = request.files[key] || [];\n                request.files[key].push(val);\n            } else if (Array.isArray(val)) {\n                const foundFiles = [];\n                const foundRegular = [];\n                for (const v of val) {\n                    if (isFile(v)) {\n                        foundFiles.push(v);\n                    } else {\n                        foundRegular.push(v);\n                    }\n                }\n\n                if (foundFiles.length > 0 && foundFiles.length == val.length) {\n                    // only files\n                    // ---\n                    request.files[key] = request.files[key] || [];\n                    for (let file of foundFiles) {\n                        request.files[key].push(file);\n                    }\n                } else {\n                    // empty or mixed array (both regular and File/Blob values)\n                    // ---\n                    request.json[key] = foundRegular;\n\n                    if (foundFiles.length > 0) {\n                        // add \"+\" to append if not already since otherwise\n                        // the existing regular files will be deleted\n                        // (the mixed values order is preserved only within their corresponding groups)\n                        let fileKey = key;\n                        if (!key.startsWith(\"+\") && !key.endsWith(\"+\")) {\n                            fileKey += \"+\";\n                        }\n\n                        request.files[fileKey] = request.files[fileKey] || [];\n                        for (let file of foundFiles) {\n                            request.files[fileKey].push(file);\n                        }\n                    }\n                }\n            } else {\n                request.json[key] = val;\n            }\n        }\n    }\n}\n","import { ClientResponseError } from \"@/ClientResponseError\";\nimport { BaseAuthStore } from \"@/stores/BaseAuthStore\";\nimport { LocalAuthStore } from \"@/stores/LocalAuthStore\";\nimport { SettingsService } from \"@/services/SettingsService\";\nimport { RecordService } from \"@/services/RecordService\";\nimport { CollectionService } from \"@/services/CollectionService\";\nimport { LogService } from \"@/services/LogService\";\nimport { HealthService } from \"@/services/HealthService\";\nimport { FileService } from \"@/services/FileService\";\nimport { BackupService } from \"@/services/BackupService\";\nimport { CronService } from \"@/services/CronService\";\nimport { BatchService } from \"@/services/BatchService\";\nimport { RecordModel } from \"@/tools/dtos\";\nimport {\n    SendOptions,\n    FileOptions,\n    normalizeUnknownQueryParams,\n    serializeQueryParams,\n} from \"@/tools/options\";\nimport { isFormData, convertToFormDataIfNeeded } from \"@/tools/formdata\";\n\ntype Response = {\n    statusCode: number;\n    headers: { [key: string]: Array<string> };\n    cookies: { [key: string]: http.Cookie };\n    raw: string;\n    json: any;\n};\n\nexport interface BeforeSendResult {\n    [key: string]: any; // for backward compatibility\n    url?: string;\n    options?: { [key: string]: any };\n}\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    /**\n     * Legacy getter alias for baseURL.\n     * @deprecated Please replace with baseURL.\n     */\n    get baseUrl(): string {\n        return this.baseURL;\n    }\n\n    /**\n     * Legacy setter alias for baseURL.\n     * @deprecated Please replace with baseURL.\n     */\n    set baseUrl(v: string) {\n        this.baseURL = v;\n    }\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;\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, options) {\n     *     if (response.status != 200) {\n     *         throw new ClientResponseError({\n     *             url:      response.url,\n     *             status:   response.status,\n     *             response: { ... },\n     *         });\n     *     }\n     *\n     *     return data;\n     * };\n     * ```\n     */\n    afterSend?: ((response: Response, data: any) => any) &\n        ((response: Response, data: any, options: SendOptions) => 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 **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    /**\n     * An instance of the service that handles the **Cron APIs**.\n     */\n    readonly crons: CronService;\n\n    private recordServices: { [key: string]: RecordService } = {};\n\n    constructor(baseURL = \"/\", authStore?: BaseAuthStore | null, lang = \"en-US\") {\n        this.baseURL = baseURL;\n        this.lang = lang;\n\n        if (authStore) {\n            this.authStore = authStore;\n        } else if (typeof window != \"undefined\" && !!(window as any).Deno) {\n            // note: to avoid common security issues we fallback to runtime/memory store in case the code is running in Deno env\n            this.authStore = new BaseAuthStore();\n        } else {\n            this.authStore = new LocalAuthStore();\n        }\n\n        // common services\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.health = new HealthService(this);\n        this.backups = new BackupService(this);\n        this.crons = new CronService(this);\n    }\n\n    /**\n     * @deprecated\n     * With PocketBase v0.23.0 admins are converted to a regular auth\n     * collection named \"_superusers\", aka. you can use directly collection(\"_superusers\").\n     */\n    get admins(): RecordService {\n        return this.collection(\"_superusers\");\n    }\n\n    /**\n     * Creates a new batch handler for sending multiple transactional\n     * create/update/upsert/delete collection requests in one network call.\n     *\n     * Example:\n     * ```js\n     * const batch = pb.createBatch();\n     *\n     * batch.collection(\"example1\").create({ ... })\n     * batch.collection(\"example2\").update(\"RECORD_ID\", { ... })\n     * batch.collection(\"example3\").delete(\"RECORD_ID\")\n     * batch.collection(\"example4\").upsert({ ... })\n     *\n     * await batch.send()\n     * ```\n     */\n    createBatch(): BatchService {\n        return new BatchService(this);\n    }\n\n    /**\n     * Returns the RecordService associated to the specified collection.\n     */\n    collection<M = RecordModel>(idOrName: string): RecordService<M> {\n        if (!this.recordServices[idOrName]) {\n            this.recordServices[idOrName] = new RecordService(this, idOrName);\n        }\n\n        return this.recordServices[idOrName];\n    }\n\n    /**\n     * Constructs a filter expression with placeholders populated from a parameters object.\n     *\n     * Placeholder parameters are defined with the `{:paramName}` notation.\n     *\n     * The following parameter values are supported:\n     *\n     * - `string` (_single quotes are autoescaped_)\n     * - `number`\n     * - `boolean`\n     * - `Date` object (_stringified into the PocketBase datetime format_)\n     * - `null`\n     * - everything else is converted to a string using `JSON.stringify()`\n     *\n     * Example:\n     *\n     * ```js\n     * pb.collection(\"example\").getFirstListItem(pb.filter(\n     *    'title ~ {:title} && created >= {:created}',\n     *    { title: \"example\", created: new Date()}\n     * ))\n     * ```\n     */\n    filter(raw: string, params?: { [key: string]: any }): string {\n        if (!params) {\n            return raw;\n        }\n\n        for (let key in params) {\n            let val = params[key];\n            switch (typeof val) {\n                case \"boolean\":\n                case \"number\":\n                    val = \"\" + val;\n                    break;\n                case \"string\":\n                    val = \"'\" + val.replace(/'/g, \"\\\\'\") + \"'\";\n                    break;\n                default:\n                    if (val === null) {\n                        val = \"null\";\n                    } else if (val instanceof Date) {\n                        val = \"'\" + val.toISOString().replace(\"T\", \" \") + \"'\";\n                    } else {\n                        val = \"'\" + JSON.stringify(val).replace(/'/g, \"\\\\'\") + \"'\";\n                    }\n            }\n            raw = raw.replaceAll(\"{:\" + key + \"}\", val);\n        }\n\n        return raw;\n    }\n\n    /**\n     * @deprecated Please use `pb.files.getURL()`.\n     */\n    getFileUrl(\n        record: { [key: string]: any },\n        filename: string,\n        queryParams: FileOptions = {},\n    ): string {\n        console.warn(\"Please replace pb.getFileUrl() with pb.files.getURL()\");\n        return this.files.getURL(record, filename, queryParams);\n    }\n\n    /**\n     * @deprecated Please use `pb.buildURL()`.\n     */\n    buildUrl(path: string): string {\n        console.warn(\"Please replace pb.buildUrl() with pb.buildURL()\");\n        return this.buildURL(path);\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     * @throws {ClientResponseError}\n     */\n    send<T = any>(path: string, options: SendOptions): 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({}, this.beforeSend(url, options));\n            if (\n                typeof result.url !== \"undefined\" ||\n                typeof result.options !== \"undefined\"\n            ) {\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 &&\n                    console.warn(\n                        \"Deprecated format of beforeSend return: please use `return { url, options }`, instead of `return options`.\",\n                    );\n            }\n        }\n\n        // serialize the query parameters\n        if (typeof options.query !== \"undefined\") {\n            const query = 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 &&\n            typeof options.body !== \"string\"\n        ) {\n            options.body = JSON.stringify(options.body);\n        }\n\n        const fetchFunc = options.fetch || $http.send;\n\n        // send the request\n        try {\n            const args = {\n                url: url,\n                method: options.method,\n                headers: options.headers,\n                body: options.body,\n            };\n            const response = fetchFunc(args);\n            let data: any = {};\n\n            try {\n                data = 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 = this.afterSend(response, data, options);\n            }\n\n            if (response.statusCode >= 400) {\n                throw new ClientResponseError({\n                    url,\n                    status: response.statusCode,\n                    data: data,\n                });\n            }\n\n            return data as T;\n        } catch (err) {\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    // @ts-ignore\n    private initSendOptions(path: string, options: SendOptions): SendOptions {\n        options = Object.assign({ method: \"GET\" } as SendOptions, options);\n\n        // auto convert the body to FormData, if needed\n        options.body = convertToFormDataIfNeeded(options.body);\n\n        // move unknown send options as query parameters\n        normalizeUnknownQueryParams(options);\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            !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        return options;\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(\n        headers: { [key: string]: string } | undefined,\n        name: string,\n    ): 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"],"names":["ClientResponseError","Error","constructor","errData","super","this","url","status","response","isAbort","originalError","Object","setPrototypeOf","prototype","data","DOMException","name","message","cause","includes","toJSON","fieldContentRegExp","cookieParse","str","options","result","decode","assign","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","record","model","isValid","isSuperuser","type","collectionName","collectionId","isAdmin","console","warn","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","testEmail","collectionIdOrName","toEmail","emailTemplate","template","collection","generateAppleClientSecret","clientId","teamId","keyId","privateKey","duration","CrudService","getFullList","batchOrqueryParams","_getFullList","batch","getList","page","perPage","query","responseData","baseCrudPath","items","item","getFirstListItem","filter","requestKey","skipTotal","code","getOne","buildURL","create","batchSize","request","list","concat","normalizeLegacyOptionsArgs","legacyWarn","baseOptions","bodyOrOptions","hasQuery","RecordService","baseCollectionPath","isSuperusers","batchOrOptions","params","authStore","authExpand","expand","authRecord","success","delete","authResponse","listAuthMethods","fields","authWithPassword","usernameOrEmail","password","identity","authData","authWithOAuth2Code","provider","codeVerifier","redirectURL","createData","authRefresh","requestPasswordReset","confirmPasswordReset","passwordResetToken","passwordConfirm","requestVerification","confirmVerification","verificationToken","verified","requestEmailChange","newEmail","confirmEmailChange","emailChangeToken","requestOTP","authWithOTP","otpId","impersonate","recordId","headers","Authorization","Client","baseURL","lang","CollectionService","import","collections","deleteMissing","getScaffolds","truncate","LogService","getStats","HealthService","check","FileService","getUrl","filename","queryParams","getURL","parts","download","URLSearchParams","getToken","BackupService","basename","upload","restore","getDownloadURL","CronService","run","jobId","isFile","File","isFormData","FormData","hasFileField","values","v","inferNumberCharsRegex","inferFormDataValue","num","knownSendOptionsKeys","normalizeUnknownQueryParams","serializeQueryParams","encodedKey","toISOString","BatchService","requests","subs","SubBatchService","formData","jsonData","req","json","files","file","append","upsert","prepareRequest","convertFormDataToObject","forEach","k","parsed","err","foundFiles","foundRegular","fileKey","startsWith","endsWith","baseUrl","recordServices","Deno","logs","settings","health","backups","crons","admins","createBatch","idOrName","raw","replaceAll","getFileUrl","buildUrl","location","origin","substring","pathname","initSendOptions","beforeSend","getHeader","fetchFunc","fetch","$http","afterSend","statusCode","convertToFormDataIfNeeded","form"],"mappings":"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"}