UNPKG

parse

Version:
1,540 lines 2.03 MB
(function(factory) { typeof define === "function" && define.amd ? define(factory) : factory(); })(function() { "use strict"; function _mergeNamespaces(n, m) { for (var i2 = 0; i2 < m.length; i2++) { const e = m[i2]; if (typeof e !== "string" && !Array.isArray(e)) { for (const k in e) { if (k !== "default" && !(k in n)) { const d = Object.getOwnPropertyDescriptor(e, k); if (d) { Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: () => e[k] }); } } } } } return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: "Module" })); } function getDefaultExportFromCjs$1(x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x; } var browser$d = { exports: {} }; var process = browser$d.exports = {}; var cachedSetTimeout; var cachedClearTimeout; function defaultSetTimout() { throw new Error("setTimeout has not been defined"); } function defaultClearTimeout() { throw new Error("clearTimeout has not been defined"); } (function() { try { if (typeof setTimeout === "function") { cachedSetTimeout = setTimeout; } else { cachedSetTimeout = defaultSetTimout; } } catch (e) { cachedSetTimeout = defaultSetTimout; } try { if (typeof clearTimeout === "function") { cachedClearTimeout = clearTimeout; } else { cachedClearTimeout = defaultClearTimeout; } } catch (e) { cachedClearTimeout = defaultClearTimeout; } })(); function runTimeout(fun) { if (cachedSetTimeout === setTimeout) { return setTimeout(fun, 0); } if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { cachedSetTimeout = setTimeout; return setTimeout(fun, 0); } try { return cachedSetTimeout(fun, 0); } catch (e) { try { return cachedSetTimeout.call(null, fun, 0); } catch (e2) { return cachedSetTimeout.call(this, fun, 0); } } } function runClearTimeout(marker) { if (cachedClearTimeout === clearTimeout) { return clearTimeout(marker); } if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { cachedClearTimeout = clearTimeout; return clearTimeout(marker); } try { return cachedClearTimeout(marker); } catch (e) { try { return cachedClearTimeout.call(null, marker); } catch (e2) { return cachedClearTimeout.call(this, marker); } } } var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { if (!draining || !currentQueue) { return; } draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); } else { queueIndex = -1; } if (queue.length) { drainQueue(); } } function drainQueue() { if (draining) { return; } var timeout = runTimeout(cleanUpNextTick); draining = true; var len2 = queue.length; while (len2) { currentQueue = queue; queue = []; while (++queueIndex < len2) { if (currentQueue) { currentQueue[queueIndex].run(); } } queueIndex = -1; len2 = queue.length; } currentQueue = null; draining = false; runClearTimeout(timeout); } process.nextTick = function(fun) { var args = new Array(arguments.length - 1); if (arguments.length > 1) { for (var i2 = 1; i2 < arguments.length; i2++) { args[i2 - 1] = arguments[i2]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { runTimeout(drainQueue); } }; function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function() { this.fun.apply(null, this.array); }; process.title = "browser"; process.browser = true; process.env = {}; process.argv = []; process.version = ""; process.versions = {}; function noop() { } process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.prependListener = noop; process.prependOnceListener = noop; process.listeners = function(name) { return []; }; process.binding = function(name) { throw new Error("process.binding is not supported"); }; process.cwd = function() { return "/"; }; process.chdir = function(dir) { throw new Error("process.chdir is not supported"); }; process.umask = function() { return 0; }; var browserExports$1 = browser$d.exports; const process$1 = /* @__PURE__ */ getDefaultExportFromCjs$1(browserExports$1); const config = { IS_NODE: typeof process$1 !== "undefined" && !!process$1.versions && !!process$1.versions.node && !process$1.versions.electron, REQUEST_ATTEMPT_LIMIT: 5, REQUEST_BATCH_SIZE: 20, REQUEST_HEADERS: {}, SERVER_URL: "https://api.parse.com/1", LIVEQUERY_SERVER_URL: null, ENCRYPTED_KEY: null, VERSION: "js8.0.0", APPLICATION_ID: null, JAVASCRIPT_KEY: null, MAINTENANCE_KEY: null, MASTER_KEY: null, USE_MASTER_KEY: false, PERFORM_USER_REWRITE: true, FORCE_REVOCABLE_SESSION: false, ENCRYPTED_USER: false, IDEMPOTENCY: false, ALLOW_CUSTOM_OBJECT_ID: false, PARSE_ERRORS: [], NODE_LOGGING: false }; function requireMethods(name, methods, controller) { methods.forEach((func) => { if (typeof controller[func] !== "function") { throw new Error(`${name} must implement ${func}()`); } }); } const CoreManager = { get: function(key2) { if (Object.hasOwn(config, key2)) { return config[key2]; } throw new Error("Configuration key not found: " + key2); }, set: function(key2, value) { config[key2] = value; }, setIfNeeded: function(key2, value) { if (!Object.hasOwn(config, key2)) { config[key2] = value; } return config[key2]; }, /* Specialized Controller Setters/Getters */ setAnalyticsController(controller) { requireMethods("AnalyticsController", ["track"], controller); config["AnalyticsController"] = controller; }, getAnalyticsController() { return config["AnalyticsController"]; }, setCloudController(controller) { requireMethods("CloudController", ["run", "getJobsData", "startJob"], controller); config["CloudController"] = controller; }, getCloudController() { return config["CloudController"]; }, setConfigController(controller) { requireMethods("ConfigController", ["current", "get", "save"], controller); config["ConfigController"] = controller; }, getConfigController() { return config["ConfigController"]; }, setCryptoController(controller) { requireMethods("CryptoController", ["encrypt", "decrypt"], controller); config["CryptoController"] = controller; }, getCryptoController() { return config["CryptoController"]; }, setEventEmitter(eventEmitter) { config["EventEmitter"] = eventEmitter; }, getEventEmitter() { return config["EventEmitter"]; }, setFileController(controller) { requireMethods("FileController", ["saveFile", "saveBase64"], controller); config["FileController"] = controller; }, setEventuallyQueue(controller) { requireMethods("EventuallyQueue", ["poll", "save", "destroy"], controller); config["EventuallyQueue"] = controller; }, getEventuallyQueue() { return config["EventuallyQueue"]; }, getFileController() { return config["FileController"]; }, setInstallationController(controller) { requireMethods( "InstallationController", ["currentInstallationId", "currentInstallation", "updateInstallationOnDisk"], controller ); config["InstallationController"] = controller; }, getInstallationController() { return config["InstallationController"]; }, setLiveQuery(liveQuery) { config["LiveQuery"] = liveQuery; }, getLiveQuery() { return config["LiveQuery"]; }, setObjectController(controller) { requireMethods("ObjectController", ["save", "fetch", "destroy"], controller); config["ObjectController"] = controller; }, getObjectController() { return config["ObjectController"]; }, setObjectStateController(controller) { requireMethods( "ObjectStateController", [ "getState", "initializeState", "removeState", "getServerData", "setServerData", "getPendingOps", "setPendingOp", "pushPendingState", "popPendingState", "mergeFirstPendingState", "getObjectCache", "estimateAttribute", "estimateAttributes", "commitServerChanges", "enqueueTask", "clearAllState" ], controller ); config["ObjectStateController"] = controller; }, getObjectStateController() { return config["ObjectStateController"]; }, setPushController(controller) { requireMethods("PushController", ["send"], controller); config["PushController"] = controller; }, getPushController() { return config["PushController"]; }, setQueryController(controller) { requireMethods("QueryController", ["find", "aggregate"], controller); config["QueryController"] = controller; }, getQueryController() { return config["QueryController"]; }, setRESTController(controller) { requireMethods("RESTController", ["request", "ajax"], controller); config["RESTController"] = controller; }, getRESTController() { return config["RESTController"]; }, setSchemaController(controller) { requireMethods( "SchemaController", ["get", "create", "update", "delete", "send", "purge"], controller ); config["SchemaController"] = controller; }, getSchemaController() { return config["SchemaController"]; }, setSessionController(controller) { requireMethods("SessionController", ["getSession"], controller); config["SessionController"] = controller; }, getSessionController() { return config["SessionController"]; }, setStorageController(controller) { if (controller.async) { requireMethods( "An async StorageController", ["getItemAsync", "setItemAsync", "removeItemAsync", "getAllKeysAsync"], controller ); } else { requireMethods( "A synchronous StorageController", ["getItem", "setItem", "removeItem", "getAllKeys"], controller ); } config["StorageController"] = controller; }, setLocalDatastoreController(controller) { requireMethods( "LocalDatastoreController", ["pinWithName", "fromPinWithName", "unPinWithName", "getAllContents", "clear"], controller ); config["LocalDatastoreController"] = controller; }, getLocalDatastoreController() { return config["LocalDatastoreController"]; }, setLocalDatastore(store) { config["LocalDatastore"] = store; }, getLocalDatastore() { return config["LocalDatastore"]; }, getStorageController() { return config["StorageController"]; }, setAsyncStorage(storage) { config["AsyncStorage"] = storage; }, getAsyncStorage() { return config["AsyncStorage"]; }, setWebSocketController(controller) { config["WebSocketController"] = controller; }, getWebSocketController() { return config["WebSocketController"]; }, setUserController(controller) { requireMethods( "UserController", [ "setCurrentUser", "currentUser", "currentUserAsync", "signUp", "logIn", "become", "logOut", "me", "requestPasswordReset", "upgradeToRevocableSession", "requestEmailVerification", "verifyPassword", "linkWith" ], controller ); config["UserController"] = controller; }, getUserController() { return config["UserController"]; }, setLiveQueryController(controller) { requireMethods( "LiveQueryController", ["setDefaultLiveQueryClient", "getDefaultLiveQueryClient", "_clearCachedDefaultClient"], controller ); config["LiveQueryController"] = controller; }, getLiveQueryController() { return config["LiveQueryController"]; }, setHooksController(controller) { requireMethods("HooksController", ["create", "get", "update", "remove"], controller); config["HooksController"] = controller; }, getHooksController() { return config["HooksController"]; }, setParseOp(op) { config["ParseOp"] = op; }, getParseOp() { return config["ParseOp"]; }, setParseObject(object) { config["ParseObject"] = object; }, getParseObject() { return config["ParseObject"]; }, setParseQuery(query) { config["ParseQuery"] = query; }, getParseQuery() { return config["ParseQuery"]; }, setParseRole(role) { config["ParseRole"] = role; }, getParseRole() { return config["ParseRole"]; }, setParseUser(user) { config["ParseUser"] = user; }, getParseUser() { return config["ParseUser"]; } }; const _ParseError = class _ParseError extends Error { /** * @param {number} code An error code constant from <code>Parse.Error</code>. * @param {string} message A detailed description of the error. */ constructor(code2, message) { super(message); this.code = code2; let customMessage = message; CoreManager.get("PARSE_ERRORS").forEach((error) => { if (error.code === code2 && error.code) { customMessage = error.message; } }); Object.defineProperty(this, "message", { enumerable: true, value: customMessage }); } toString() { return "ParseError: " + this.code + " " + this.message; } }; _ParseError.OTHER_CAUSE = -1; _ParseError.INTERNAL_SERVER_ERROR = 1; _ParseError.CONNECTION_FAILED = 100; _ParseError.OBJECT_NOT_FOUND = 101; _ParseError.INVALID_QUERY = 102; _ParseError.INVALID_CLASS_NAME = 103; _ParseError.MISSING_OBJECT_ID = 104; _ParseError.INVALID_KEY_NAME = 105; _ParseError.INVALID_POINTER = 106; _ParseError.INVALID_JSON = 107; _ParseError.COMMAND_UNAVAILABLE = 108; _ParseError.NOT_INITIALIZED = 109; _ParseError.INCORRECT_TYPE = 111; _ParseError.INVALID_CHANNEL_NAME = 112; _ParseError.PUSH_MISCONFIGURED = 115; _ParseError.OBJECT_TOO_LARGE = 116; _ParseError.OPERATION_FORBIDDEN = 119; _ParseError.CACHE_MISS = 120; _ParseError.INVALID_NESTED_KEY = 121; _ParseError.INVALID_FILE_NAME = 122; _ParseError.INVALID_ACL = 123; _ParseError.TIMEOUT = 124; _ParseError.INVALID_EMAIL_ADDRESS = 125; _ParseError.MISSING_CONTENT_TYPE = 126; _ParseError.MISSING_CONTENT_LENGTH = 127; _ParseError.INVALID_CONTENT_LENGTH = 128; _ParseError.FILE_TOO_LARGE = 129; _ParseError.FILE_SAVE_ERROR = 130; _ParseError.DUPLICATE_VALUE = 137; _ParseError.INVALID_ROLE_NAME = 139; _ParseError.EXCEEDED_QUOTA = 140; _ParseError.SCRIPT_FAILED = 141; _ParseError.VALIDATION_ERROR = 142; _ParseError.INVALID_IMAGE_DATA = 143; _ParseError.UNSAVED_FILE_ERROR = 151; _ParseError.INVALID_PUSH_TIME_ERROR = 152; _ParseError.FILE_DELETE_ERROR = 153; _ParseError.FILE_DELETE_UNNAMED_ERROR = 161; _ParseError.REQUEST_LIMIT_EXCEEDED = 155; _ParseError.DUPLICATE_REQUEST = 159; _ParseError.INVALID_EVENT_NAME = 160; _ParseError.INVALID_VALUE = 162; _ParseError.USERNAME_MISSING = 200; _ParseError.PASSWORD_MISSING = 201; _ParseError.USERNAME_TAKEN = 202; _ParseError.EMAIL_TAKEN = 203; _ParseError.EMAIL_MISSING = 204; _ParseError.EMAIL_NOT_FOUND = 205; _ParseError.SESSION_MISSING = 206; _ParseError.MUST_CREATE_USER_THROUGH_SIGNUP = 207; _ParseError.ACCOUNT_ALREADY_LINKED = 208; _ParseError.INVALID_SESSION_TOKEN = 209; _ParseError.MFA_ERROR = 210; _ParseError.MFA_TOKEN_REQUIRED = 211; _ParseError.LINKED_ID_MISSING = 250; _ParseError.INVALID_LINKED_SESSION = 251; _ParseError.UNSUPPORTED_SERVICE = 252; _ParseError.INVALID_SCHEMA_OPERATION = 255; _ParseError.AGGREGATE_ERROR = 600; _ParseError.FILE_READ_ERROR = 601; _ParseError.X_DOMAIN_REQUEST = 602; let ParseError = _ParseError; function b64Digit(number) { if (number < 26) { return String.fromCharCode(65 + number); } if (number < 52) { return String.fromCharCode(97 + (number - 26)); } if (number < 62) { return String.fromCharCode(48 + (number - 52)); } if (number === 62) { return "+"; } if (number === 63) { return "/"; } throw new TypeError("Tried to encode large digit " + number + " in base64."); } class ParseFile { /** * @param name {String} The file's name. This will be prefixed by a unique * value once the file has finished saving. The file name must begin with * an alphanumeric character, and consist of alphanumeric characters, * periods, spaces, underscores, or dashes. * @param data {Array} The data for the file, as either: * 1. an Array of byte value Numbers or Uint8Array. * 2. an Object like { base64: "..." } with a base64-encoded String. * 3. an Object like { uri: "..." } with a uri String. * 4. a File object selected with a file upload control. (3) only works * in Firefox 3.6+, Safari 6.0.2+, Chrome 7+, and IE 10+. * For example: * <pre> * var fileUploadControl = $("#profilePhotoFileUpload")[0]; * if (fileUploadControl.files.length > 0) { * var file = fileUploadControl.files[0]; * var name = "photo.jpg"; * var parseFile = new Parse.File(name, file); * parseFile.save().then(function() { * // The file has been saved to Parse. * }, function(error) { * // The file either could not be read, or could not be saved to Parse. * }); * }</pre> * @param type {String} Optional Content-Type header to use for the file. If * this is omitted, the content type will be inferred from the name's * extension. * @param metadata {object} Optional key value pairs to be stored with file object * @param tags {object} Optional key value pairs to be stored with file object */ constructor(name, data, type2, metadata, tags) { const specifiedType = type2 || ""; this._name = name; this._metadata = metadata || {}; this._tags = tags || {}; if (data !== void 0) { if (Array.isArray(data) || data instanceof Uint8Array) { this._data = ParseFile.encodeBase64(data); this._source = { format: "base64", base64: this._data, type: specifiedType }; } else if (typeof Blob !== "undefined" && data instanceof Blob) { this._source = { format: "file", file: data, type: specifiedType }; } else if (data && typeof data.uri === "string" && data.uri !== void 0) { this._source = { format: "uri", uri: data.uri, type: specifiedType }; } else if (data && typeof data.base64 === "string") { const base64 = data.base64.split(",").slice(-1)[0]; const dataType = specifiedType || data.base64.split(";").slice(0, 1)[0].split(":").slice(1, 2)[0] || "text/plain"; this._data = base64; this._source = { format: "base64", base64, type: dataType }; } else { throw new TypeError("Cannot create a Parse.File with that data."); } } } /** * Return the data for the file, downloading it if not already present. * Data is present if initialized with Byte Array, Base64 or Saved with Uri. * Data is cleared if saved with File object selected with a file upload control * * @param {object} options * @param {function} [options.progress] callback for download progress * <pre> * const parseFile = new Parse.File(name, file); * parseFile.getData({ * progress: (progressValue, loaded, total) => { * if (progressValue !== null) { * // Update the UI using progressValue * } * } * }); * </pre> * @returns {Promise} Promise that is resolve with base64 data */ async getData(options) { options = options || {}; if (this._data) { return this._data; } if (!this._url) { throw new Error("Cannot retrieve data for unsaved ParseFile."); } options.requestTask = (task) => this._requestTask = task; const controller = CoreManager.getFileController(); const result = await controller.download(this._url, options); this._data = result.base64; return this._data; } /** * Gets the name of the file. Before save is called, this is the filename * given by the user. After save is called, that name gets prefixed with a * unique identifier. * * @returns {string} */ name() { return this._name; } /** * Gets the url of the file. It is only available after you save the file or * after you get the file from a Parse.Object. * * @param {object} options An object to specify url options * @param {boolean} [options.forceSecure] force the url to be secure * @returns {string | undefined} */ url(options) { options = options || {}; if (!this._url) { return; } if (options.forceSecure) { return this._url.replace(/^http:\/\//i, "https://"); } else { return this._url; } } /** * Gets the metadata of the file. * * @returns {object} */ metadata() { return this._metadata; } /** * Gets the tags of the file. * * @returns {object} */ tags() { return this._tags; } /** * Saves the file to the Parse cloud. * * @param {object} options * Valid options are:<ul> * <li>useMasterKey: In Cloud Code and Node only, causes the Master Key to * be used for this request. * <li>sessionToken: A valid session token, used for making a request on * behalf of a specific user. * <li>progress: callback for upload progress. For example: * <pre> * let parseFile = new Parse.File(name, file); * parseFile.save({ * progress: (progressValue, loaded, total) => { * if (progressValue !== null) { * // Update the UI using progressValue * } * } * }); * </pre> * </ul> * @returns {Promise | undefined} Promise that is resolved when the save finishes. */ save(options) { options = options || {}; options.requestTask = (task) => this._requestTask = task; options.metadata = this._metadata; options.tags = this._tags; const controller = CoreManager.getFileController(); if (!this._previousSave) { if (this._source.format === "file") { this._previousSave = controller.saveFile(this._name, this._source, options).then((res) => { this._name = res.name; this._url = res.url; this._data = null; this._requestTask = null; return this; }); } else if (this._source.format === "uri") { this._previousSave = controller.download(this._source.uri, options).then((result) => { if (!(result && result.base64)) { return {}; } const newSource = { format: "base64", base64: result.base64, type: result.contentType }; this._data = result.base64; this._requestTask = null; return controller.saveBase64(this._name, newSource, options); }).then((res) => { this._name = res.name; this._url = res.url; this._requestTask = null; return this; }); } else { this._previousSave = controller.saveBase64(this._name, this._source, options).then((res) => { this._name = res.name; this._url = res.url; this._requestTask = null; return this; }); } } if (this._previousSave) { return this._previousSave; } } /** * Aborts the request if it has already been sent. */ cancel() { if (this._requestTask && typeof this._requestTask.abort === "function") { this._requestTask._aborted = true; this._requestTask.abort(); } this._requestTask = null; } /** * Deletes the file from the Parse cloud. * In Cloud Code and Node only with Master Key. * * @param {object} options * Valid options are:<ul> * <li>useMasterKey: In Cloud Code and Node only, causes the Master Key to * be used for this request. * <pre> * @returns {Promise} Promise that is resolved when the delete finishes. */ destroy(options = {}) { if (!this._name) { throw new ParseError(ParseError.FILE_DELETE_UNNAMED_ERROR, "Cannot delete an unnamed file."); } const destroyOptions = { useMasterKey: true }; if (Object.hasOwn(options, "useMasterKey")) { destroyOptions.useMasterKey = !!options.useMasterKey; } const controller = CoreManager.getFileController(); return controller.deleteFile(this._name, destroyOptions).then(() => { this._data = void 0; this._requestTask = null; return this; }); } toJSON() { return { __type: "File", name: this._name, url: this._url }; } equals(other) { if (this === other) { return true; } return other instanceof ParseFile && this.name() === other.name() && this.url() === other.url() && typeof this.url() !== "undefined"; } /** * Sets metadata to be saved with file object. Overwrites existing metadata * * @param {object} metadata Key value pairs to be stored with file object */ setMetadata(metadata) { if (metadata && typeof metadata === "object") { Object.keys(metadata).forEach((key2) => { this.addMetadata(key2, metadata[key2]); }); } } /** * Sets metadata to be saved with file object. Adds to existing metadata. * * @param {string} key key to store the metadata * @param {*} value metadata */ addMetadata(key2, value) { if (typeof key2 === "string") { this._metadata[key2] = value; } } /** * Sets tags to be saved with file object. Overwrites existing tags * * @param {object} tags Key value pairs to be stored with file object */ setTags(tags) { if (tags && typeof tags === "object") { Object.keys(tags).forEach((key2) => { this.addTag(key2, tags[key2]); }); } } /** * Sets tags to be saved with file object. Adds to existing tags. * * @param {string} key key to store tags * @param {*} value tag */ addTag(key2, value) { if (typeof key2 === "string") { this._tags[key2] = value; } } static fromJSON(obj) { if (obj.__type !== "File") { throw new TypeError("JSON object does not represent a ParseFile"); } const file = new ParseFile(obj.name); file._url = obj.url; return file; } static encodeBase64(bytes) { const chunks = []; chunks.length = Math.ceil(bytes.length / 3); for (let i2 = 0; i2 < chunks.length; i2++) { const b1 = bytes[i2 * 3]; const b2 = bytes[i2 * 3 + 1] || 0; const b3 = bytes[i2 * 3 + 2] || 0; const has2 = i2 * 3 + 1 < bytes.length; const has3 = i2 * 3 + 2 < bytes.length; chunks[i2] = [ b64Digit(b1 >> 2 & 63), b64Digit(b1 << 4 & 48 | b2 >> 4 & 15), has2 ? b64Digit(b2 << 2 & 60 | b3 >> 6 & 3) : "=", has3 ? b64Digit(b3 & 63) : "=" ].join(""); } return chunks.join(""); } } const DefaultController$a = { saveFile: async function(name, source, options) { if (source.format !== "file") { throw new Error("saveFile can only be used with File-type sources."); } const base64Data = await new Promise((res, rej) => { const reader = new FileReader(); reader.onload = () => res(reader.result); reader.onerror = (error) => rej(error); reader.readAsDataURL(source.file); }); const [first, second] = base64Data.split(","); const data = second ? second : first; const newSource = { format: "base64", base64: data, type: source.type || (source.file ? source.file.type : void 0) }; return await DefaultController$a.saveBase64(name, newSource, options); }, saveBase64: function(name, source, options = {}) { if (source.format !== "base64") { throw new Error("saveBase64 can only be used with Base64-type sources."); } const data = { base64: source.base64, fileData: { metadata: { ...options.metadata }, tags: { ...options.tags } } }; delete options.metadata; delete options.tags; if (source.type) { data._ContentType = source.type; } const path = "files/" + name; return CoreManager.getRESTController().request("POST", path, data, options); }, download: async function(uri2, options) { const controller = new AbortController(); options.requestTask(controller); const { signal } = controller; try { const response = await fetch(uri2, { signal }); const reader = response.body.getReader(); const length = +response.headers.get("Content-Length") || 0; const contentType = response.headers.get("Content-Type"); if (length === 0) { options.progress?.(null, null, null); return { base64: "", contentType }; } let recieved = 0; const chunks = []; while (true) { const { done, value } = await reader.read(); if (done) { break; } chunks.push(value); recieved += value?.length || 0; options.progress?.(recieved / length, recieved, length); } const body = new Uint8Array(recieved); let offset = 0; for (const chunk of chunks) { body.set(chunk, offset); offset += chunk.length; } return { base64: ParseFile.encodeBase64(body), contentType }; } catch (error) { if (error.name === "AbortError") { return {}; } else { throw error; } } }, deleteFile: function(name, options) { const headers = { "X-Parse-Application-ID": CoreManager.get("APPLICATION_ID") }; if (options.useMasterKey) { headers["X-Parse-Master-Key"] = CoreManager.get("MASTER_KEY"); } let url = CoreManager.get("SERVER_URL"); if (url[url.length - 1] !== "/") { url += "/"; } url += "files/" + name; return CoreManager.getRESTController().ajax("DELETE", url, "", headers).catch((response) => { if (!response || response.toString() === "SyntaxError: Unexpected end of JSON input") { return Promise.resolve(); } else { return CoreManager.getRESTController().handleError(response); } }); } }; CoreManager.setFileController(DefaultController$a); class ParseGeoPoint { /** * @param {(number[] | object | number)} arg1 Either a list of coordinate pairs, an object with `latitude`, `longitude`, or the latitude or the point. * @param {number} arg2 The longitude of the GeoPoint */ constructor(arg1, arg2) { if (Array.isArray(arg1)) { ParseGeoPoint._validate(arg1[0], arg1[1]); this._latitude = arg1[0]; this._longitude = arg1[1]; } else if (typeof arg1 === "object") { ParseGeoPoint._validate(arg1.latitude, arg1.longitude); this._latitude = arg1.latitude; this._longitude = arg1.longitude; } else if (arg1 !== void 0 && arg2 !== void 0) { ParseGeoPoint._validate(arg1, arg2); this._latitude = arg1; this._longitude = arg2; } else { this._latitude = 0; this._longitude = 0; } } /** * North-south portion of the coordinate, in range [-90, 90]. * Throws an exception if set out of range in a modern browser. * * @property {number} latitude * @returns {number} */ get latitude() { return this._latitude; } set latitude(val) { ParseGeoPoint._validate(val, this.longitude); this._latitude = val; } /** * East-west portion of the coordinate, in range [-180, 180]. * Throws if set out of range in a modern browser. * * @property {number} longitude * @returns {number} */ get longitude() { return this._longitude; } set longitude(val) { ParseGeoPoint._validate(this.latitude, val); this._longitude = val; } /** * Returns a JSON representation of the GeoPoint, suitable for Parse. * * @returns {object} */ toJSON() { ParseGeoPoint._validate(this._latitude, this._longitude); return { __type: "GeoPoint", latitude: this._latitude, longitude: this._longitude }; } equals(other) { return other instanceof ParseGeoPoint && this.latitude === other.latitude && this.longitude === other.longitude; } /** * Returns the distance from this GeoPoint to another in radians. * * @param {Parse.GeoPoint} point the other Parse.GeoPoint. * @returns {number} */ radiansTo(point) { const d2r = Math.PI / 180; const lat1rad = this.latitude * d2r; const long1rad = this.longitude * d2r; const lat2rad = point.latitude * d2r; const long2rad = point.longitude * d2r; const deltaLat = lat1rad - lat2rad; const deltaLong = long1rad - long2rad; const sinDeltaLatDiv2 = Math.sin(deltaLat / 2); const sinDeltaLongDiv2 = Math.sin(deltaLong / 2); let a = sinDeltaLatDiv2 * sinDeltaLatDiv2 + Math.cos(lat1rad) * Math.cos(lat2rad) * sinDeltaLongDiv2 * sinDeltaLongDiv2; a = Math.min(1, a); return 2 * Math.asin(Math.sqrt(a)); } /** * Returns the distance from this GeoPoint to another in kilometers. * * @param {Parse.GeoPoint} point the other Parse.GeoPoint. * @returns {number} */ kilometersTo(point) { return this.radiansTo(point) * 6371; } /** * Returns the distance from this GeoPoint to another in miles. * * @param {Parse.GeoPoint} point the other Parse.GeoPoint. * @returns {number} */ milesTo(point) { return this.radiansTo(point) * 3958.8; } /* * Throws an exception if the given lat-long is out of bounds. */ static _validate(latitude, longitude) { if (isNaN(latitude) || isNaN(longitude) || typeof latitude !== "number" || typeof longitude !== "number") { throw new TypeError("GeoPoint latitude and longitude must be valid numbers"); } if (latitude < -90) { throw new TypeError("GeoPoint latitude out of bounds: " + latitude + " < -90.0."); } if (latitude > 90) { throw new TypeError("GeoPoint latitude out of bounds: " + latitude + " > 90.0."); } if (longitude < -180) { throw new TypeError("GeoPoint longitude out of bounds: " + longitude + " < -180.0."); } if (longitude > 180) { throw new TypeError("GeoPoint longitude out of bounds: " + longitude + " > 180.0."); } } /** * Creates a GeoPoint with the user's current location, if available. * * @param {object} options The options. * @param {boolean} [options.enableHighAccuracy] A boolean value that indicates the application would like to receive the best possible results. * If true and if the device is able to provide a more accurate position, it will do so. * Note that this can result in slower response times or increased power consumption (with a GPS chip on a mobile device for example). * On the other hand, if false, the device can take the liberty to save resources by responding more quickly and/or using less power. Default: false. * @param {number} [options.timeout] A positive long value representing the maximum length of time (in milliseconds) the device is allowed to take in order to return a position. * The default value is Infinity, meaning that getCurrentPosition() won't return until the position is available. * @param {number} [options.maximumAge] A positive long value indicating the maximum age in milliseconds of a possible cached position that is acceptable to return. * If set to 0, it means that the device cannot use a cached position and must attempt to retrieve the real current position. * If set to Infinity the device must return a cached position regardless of its age. Default: 0. * @static * @returns {Promise<Parse.GeoPoint>} User's current location */ static current(options) { return new Promise((resolve, reject) => { navigator.geolocation.getCurrentPosition( (location) => { resolve(new ParseGeoPoint(location.coords.latitude, location.coords.longitude)); }, reject, options ); }); } } class ParsePolygon { /** * @param {(Coordinates | Parse.GeoPoint[])} coordinates An Array of coordinate pairs */ constructor(coordinates) { this._coordinates = ParsePolygon._validate(coordinates); } /** * Coordinates value for this Polygon. * Throws an exception if not valid type. * * @property {(Coordinates | Parse.GeoPoint[])} coordinates list of coordinates * @returns {Coordinates} */ get coordinates() { return this._coordinates; } set coordinates(coords) { this._coordinates = ParsePolygon._validate(coords); } /** * Returns a JSON representation of the Polygon, suitable for Parse. * * @returns {object} */ toJSON() { ParsePolygon._validate(this._coordinates); return { __type: "Polygon", coordinates: this._coordinates }; } /** * Checks if two polygons are equal * * @param {(Parse.Polygon | object)} other * @returns {boolean} */ equals(other) { if (!(other instanceof ParsePolygon) || this.coordinates.length !== other.coordinates.length) { return false; } let isEqual = true; for (let i2 = 1; i2 < this._coordinates.length; i2 += 1) { if (this._coordinates[i2][0] != other.coordinates[i2][0] || this._coordinates[i2][1] != other.coordinates[i2][1]) { isEqual = false; break; } } return isEqual; } /** * * @param {Parse.GeoPoint} point * @returns {boolean} Returns if the point is contained in the polygon */ containsPoint(point) { let minX = this._coordinates[0][0]; let maxX = this._coordinates[0][0]; let minY = this._coordinates[0][1]; let maxY = this._coordinates[0][1]; for (let i2 = 1; i2 < this._coordinates.length; i2 += 1) { const p = this._coordinates[i2]; minX = Math.min(p[0], minX); maxX = Math.max(p[0], maxX); minY = Math.min(p[1], minY); maxY = Math.max(p[1], maxY); } const outside = point.latitude < minX || point.latitude > maxX || point.longitude < minY || point.longitude > maxY; if (outside) { return false; } let inside = false; for (let i2 = 0, j = this._coordinates.length - 1; i2 < this._coordinates.length; j = i2++) { const startX = this._coordinates[i2][0]; const startY = this._coordinates[i2][1]; const endX = this._coordinates[j][0]; const endY = this._coordinates[j][1]; const intersect = startY > point.longitude != endY > point.longitude && point.latitude < (endX - startX) * (point.longitude - startY) / (endY - startY) + startX; if (intersect) { inside = !inside; } } return inside; } /** * Validates that the list of coordinates can form a valid polygon * * @param {Array} coords the list of coordinates to validate as a polygon * @throws {TypeError} * @returns {number[][]} Array of coordinates if validated. */ static _validate(coords) { if (!Array.isArray(coords)) { throw new TypeError("Coordinates must be an Array"); } if (coords.length < 3) { throw new TypeError("Polygon must have at least 3 GeoPoints or Points"); } const points = []; for (let i2 = 0; i2 < coords.length; i2 += 1) { const coord = coords[i2]; let geoPoint; if (coord instanceof ParseGeoPoint) { geoPoint = coord; } else if (Array.isArray(coord) && coord.length === 2) { geoPoint = new ParseGeoPoint(coord[0], coord[1]); } else { throw new TypeError("Coordinates must be an Array of GeoPoints or Points"); } points.push([geoPoint.latitude, geoPoint.longitude]); } return points; } } class ParseRelation { /** * @param {Parse.Object} parent The parent of this relation. * @param {string} key The key for this relation on the parent. */ constructor(parent, key2) { this.parent = parent; this.key = key2; this.targetClassName = null; } /* * Makes sure that this relation has the right parent and key. */ _ensureParentAndKey(parent, key2) { this.key = this.key || key2; if (this.key !== key2) { throw new Error("Internal Error. Relation retrieved from two different keys."); } if (this.parent) { if (this.parent.className !== parent.className) { throw new Error("Internal Error. Relation retrieved from two different Objects."); } if (this.parent.id) { if (this.parent.id !== parent.id) { throw new Error("Internal Error. Relation retrieved from two different Objects."); } } else if (parent.id) { this.parent = parent; } } else { this.parent = parent; } } /** * Adds a Parse.Object or an array of Parse.Objects to the relation. * * @param {(Parse.Object|Array)} objects The item or items to add. * @returns {Parse.Object} The parent of the relation. */ add(objects) { if (!Array.isArray(objects)) { objects = [objects]; } const { RelationOp: RelationOp2 } = CoreManager.getParseOp(); const change = new RelationOp2(objects, []); const parent = this.parent; if (!parent) { throw new Error("Cannot add to a Relation without a parent"); } if (objects.length === 0) { return parent; } parent.set(this.key, change); this.targetClassName = change._targetClassName; return parent; } /** * Removes a Parse.Object or an array of Parse.Objects from this relation. * * @param {(Parse.Object|Array)} objects The item or items to remove. */ remove(objects) { if (!Array.isArray(objects)) { objects = [objects]; } const { RelationOp: RelationOp2 } = CoreManager.getParseOp(); const change = new RelationOp2([], objects); if (!this.parent) { throw new Error("Cannot remove from a Relation without a parent"); } if (objects.length === 0) { return; } this.parent.set(this.key, change); this.targetClassName = change._targetClassName; } /** * Returns a JSON version of the object suitable for saving to disk. * * @returns {object} JSON representation of Relation */ toJSON() { return { __type: "Relation", className: this.targetClassName }; } /** * Returns a Parse.Query that is limited to objects in this * relation. * * @returns {Parse.Query} Relation Query */ query() { let query; const parent = this.parent; if (!parent) { throw new Error("Cannot construct a query for a Relation without a parent"); } const ParseQuery2 = CoreManager.getParseQuery(); if (!this.targetClassName) { query = new ParseQuery2(parent.className); query._extraOptions.redirectClassNameForKey = this.key; } else { query = new ParseQuery2(this.targetClassName); } query._addCondition("$relatedTo", "object", { __type: "Pointer", className: parent.className, objectId: parent.id }); query._addCondition("$relatedTo", "key", this.key); return query; } } function isDangerousKey(key2) { const dangerousKeys = ["__proto__", "constructor", "prototype"]; if (dangerousKeys.includes(key2)) { return true; } if (key2.includes(".")) { const parts = key2.split("."); return parts.some((part) => dangerousKeys.includes(part)); } return false; } function decode(value) { if (value === null || typeof value !== "object" || value instanceof Date) { return value; } if (Array.isArray(value)) { const dup = []; value.forEach((v, i2) => { dup[i2] = decode(v); }); return dup; } if (typeof value.__op === "string") { const { opFromJSON: opFromJSON2 } = CoreManager.getParseOp(); return opFromJSON2(value); } const ParseObject2 = CoreManager.getParseObject(); if (value.__type === "Pointer" && value.className) { return ParseObject2.fromJSON(value); } if (value.__type === "Object" && value.className) { return ParseObject2.fromJSON(value); } if (value.__type === "Relation") { const relation = new ParseRelation(null, null); relation.targetClassName = value.className; return relation; } if (value.__type === "Date") { return new Date(value.iso); } if (value.__type === "File") { return ParseFile.fromJSON(value); } if (value.__type === "GeoPoint") { return new ParseGeoPoint({ latitude: value.latitude, longitude: value.longitude }); } if (value.__type === "Polygon") { return new ParsePolygon(value.coordinates); } const copy = {}; for (const k in value) { if (Object.prototype.hasOwnProperty.call(value, k)) { if (isDangerousKey(k)) { continue; } copy[k] = decode(value[k]); } } return copy; } const PUBLIC_KEY$1 = "*"; class ParseACL { /** * @param {(Parse.User | object | null)} arg1 The user to initialize the ACL for */ constructor(arg1) { this.permissionsById = {}; if (arg1 && typeof arg1 === "object") { const ParseUser2 = CoreManager.getParseUser(); if (arg1 instanceof ParseUser2) { this.setReadAccess(arg1, true); this.setWriteAccess(arg1, true); } else { for (const userId in arg1) { const accessList = arg1[userId]; this.permissionsById[userId] = {}; for (const permission in accessList) { const allowed = accessList[permission]; if (permission !== "read" && permission !== "write") { throw new TypeError("Tried to create an ACL with an invalid permission type."); } if (typeof allowed !== "boolean") { throw new TypeError("Tried to create an ACL with an invalid permission value."); } this.permissionsById[userId][permission] = allowed; } } } } else if (typeof arg1 === "function") { throw new TypeError("ParseACL constructed with a function. Did you forget ()?"); } } /** * Returns a JSON-encoded version of the ACL. * * @returns {object} */ toJSON() { const permissions = {}; for (const p in this.permissionsById) { permissions[p] = this.permissionsById[p]; } return permissions; } /** * Returns whether this ACL is equal to another object * * @param {ParseACL} other The other object's ACL to compare to * @returns {boolean} */ equals(other) { if (!(