;
+ comparator?: string;
+ }
+
+ interface AddOptions extends SilentOption {
+ /**
+ * The index at which to add the models.
+ */
+ at?: number;
+ }
+
+ interface CreateOptions extends SuccessFailureOptions, WaitOption, SilentOption, ScopeOptions {
+ }
+
+ interface FetchOptions extends SuccessFailureOptions, SilentOption, ScopeOptions { }
+
+ interface RemoveOptions extends SilentOption { }
+
+ interface ResetOptions extends SilentOption { }
+
+ interface SortOptions extends SilentOption { }
+ }
+
+ /**
+ * @class
+ *
+ * Parse.Events is a fork of Backbone's Events module, provided for your
+ * convenience.
+ *
+ * A module that can be mixed in to any object in order to provide
+ * it with custom events. You may bind callback functions to an event
+ * with `on`, or remove these functions with `off`.
+ * Triggering an event fires all callbacks in the order that `on` was
+ * called.
+ *
+ *
+ * var object = {};
+ * _.extend(object, Parse.Events);
+ * object.on('expand', function(){ alert('expanded'); });
+ * object.trigger('expand');
+ *
+ * For more information, see the
+ * Backbone
+ * documentation .
+ */
+ class Events {
+
+ static off(events: string[], callback?: Function, context?: any): Events;
+ static on(events: string[], callback?: Function, context?: any): Events;
+ static trigger(events: string[]): Events;
+ static bind(): Events;
+ static unbind(): Events;
+
+ on(eventName: string, callback?: Function, context?: any): Events;
+ off(eventName?: string | null, callback?: Function | null, context?: any): Events;
+ trigger(eventName: string, ...args: any[]): Events;
+ bind(eventName: string, callback: Function, context?: any): Events;
+ unbind(eventName?: string, callback?: Function, context?: any): Events;
+
+ }
+
+ /**
+ * Creates a new parse Parse.Query for the given Parse.Object subclass.
+ * @param objectClass -
+ * An instance of a subclass of Parse.Object, or a Parse className string.
+ * @class
+ *
+ * Parse.Query defines a query that is used to fetch Parse.Objects. The
+ * most common use case is finding all objects that match a query through the
+ * find method. For example, this sample code fetches all objects
+ * of class MyClass. It calls a different function depending on
+ * whether the fetch succeeded or not.
+ *
+ *
+ * var query = new Parse.Query(MyClass);
+ * query.find({
+ * success: function(results) {
+ * // results is an array of Parse.Object.
+ * },
+ *
+ * error: function(error) {
+ * // error is an instance of Parse.Error.
+ * }
+ * });
+ *
+ * A Parse.Query can also be used to retrieve a single object whose id is
+ * known, through the get method. For example, this sample code fetches an
+ * object of class MyClass and id myId. It calls a
+ * different function depending on whether the fetch succeeded or not.
+ *
+ *
+ * var query = new Parse.Query(MyClass);
+ * query.get(myId, {
+ * success: function(object) {
+ * // object is an instance of Parse.Object.
+ * },
+ *
+ * error: function(object, error) {
+ * // error is an instance of Parse.Error.
+ * }
+ * });
+ *
+ * A Parse.Query can also be used to count the number of objects that match
+ * the query without retrieving all of those objects. For example, this
+ * sample code counts the number of objects of the class MyClass
+ *
+ * var query = new Parse.Query(MyClass);
+ * query.count({
+ * success: function(number) {
+ * // There are number instances of MyClass.
+ * },
+ *
+ * error: function(error) {
+ * // error is an instance of Parse.Error.
+ * }
+ * });
+ */
+ class Query extends BaseObject {
+
+ objectClass: any;
+ className: string;
+
+ constructor(objectClass: string);
+ constructor(objectClass: new (...args: any[]) => T);
+
+ static or(...var_args: Query[]): Query;
+
+ aggregate(pipeline: Query.AggregationOptions|Query.AggregationOptions[]): Query;
+ addAscending(key: string): Query;
+ addAscending(key: string[]): Query;
+ addDescending(key: string): Query;
+ addDescending(key: string[]): Query;
+ ascending(key: string): Query;
+ ascending(key: string[]): Query;
+ collection(items?: Object[], options?: Collection.Options): Collection;
+ containedIn(key: string, values: any[]): Query;
+ contains(key: string, substring: string): Query;
+ containsAll(key: string, values: any[]): Query;
+ count(options?: Query.CountOptions): Promise;
+ descending(key: string): Query;
+ descending(key: string[]): Query;
+ doesNotExist(key: string): Query;
+ doesNotMatchKeyInQuery(key: string, queryKey: string, query: Query): Query;
+ doesNotMatchQuery(key: string, query: Query): Query;
+ distinct(key: string): Query;
+ each(callback: Function, options?: Query.EachOptions): Promise;
+ endsWith(key: string, suffix: string): Query;
+ equalTo(key: string, value: any): Query;
+ exists(key: string): Query;
+ find(options?: Query.FindOptions): Promise;
+ first(options?: Query.FirstOptions): Promise;
+ fullText(key: string, value: string, options?: Query.FullTextOptions): Query;
+ get(objectId: string, options?: Query.GetOptions): Promise;
+ greaterThan(key: string, value: any): Query;
+ greaterThanOrEqualTo(key: string, value: any): Query;
+ include(key: string): Query;
+ include(keys: string[]): Query;
+ lessThan(key: string, value: any): Query;
+ lessThanOrEqualTo(key: string, value: any): Query;
+ limit(n: number): Query;
+ matches(key: string, regex: RegExp, modifiers: any): Query;
+ matchesKeyInQuery(key: string, queryKey: string, query: Query): Query;
+ matchesQuery(key: string, query: Query): Query;
+ near(key: string, point: GeoPoint): Query;
+ notContainedIn(key: string, values: any[]): Query;
+ notEqualTo(key: string, value: any): Query;
+ select(...keys: string[]): Query;
+ skip(n: number): Query;
+ startsWith(key: string, prefix: string): Query;
+ subscribe(): Events;
+ withinGeoBox(key: string, southwest: GeoPoint, northeast: GeoPoint): Query;
+ withinKilometers(key: string, point: GeoPoint, maxDistance: number): Query;
+ withinMiles(key: string, point: GeoPoint, maxDistance: number): Query;
+ withinRadians(key: string, point: GeoPoint, maxDistance: number): Query;
+ }
+
+ namespace Query {
+ interface EachOptions extends SuccessFailureOptions, ScopeOptions { }
+ interface CountOptions extends SuccessFailureOptions, ScopeOptions { }
+ interface FindOptions extends SuccessFailureOptions, ScopeOptions { }
+ interface FirstOptions extends SuccessFailureOptions, ScopeOptions { }
+ interface GetOptions extends SuccessFailureOptions, ScopeOptions { }
+
+ // According to http://docs.parseplatform.org/rest/guide/#aggregate-queries
+ interface AggregationOptions {
+ group?: { objectId?: string, [key:string]: any };
+ match?: {[key: string]: any};
+ project?: {[key: string]: any};
+ limit?: number;
+ skip?: number;
+ // Sort documentation https://docs.mongodb.com/v3.2/reference/operator/aggregation/sort/#pipe._S_sort
+ sort?: {[key: string]: 1|-1};
+ }
+
+ // According to https://parseplatform.org/Parse-SDK-JS/api/2.1.0/Parse.Query.html#fullText
+ interface FullTextOptions {
+ language?: string;
+ caseSensitive?: boolean;
+ diacriticSensitive?: boolean;
+ }
+ }
+
+ /**
+ * Represents a Role on the Parse server. Roles represent groupings of
+ * Users for the purposes of granting permissions (e.g. specifying an ACL
+ * for an Object). Roles are specified by their sets of child users and
+ * child roles, all of which are granted any permissions that the parent
+ * role has.
+ *
+ * Roles must have a name (which cannot be changed after creation of the
+ * role), and must specify an ACL.
+ * @class
+ * A Parse.Role is a local representation of a role persisted to the Parse
+ * cloud.
+ */
+ class Role extends Object {
+
+ constructor(name: string, acl: ACL);
+
+ getRoles(): Relation;
+ getUsers(): Relation;
+ getName(): string;
+ setName(name: string, options?: SuccessFailureOptions): any;
+ }
+
+ class Config extends Object {
+ static get(options?: SuccessFailureOptions): Promise;
+ static current(): Config;
+
+ get(attr: string): any;
+ escape(attr: string): any;
+ }
+
+ class Session extends Object {
+ static current(): Promise;
+
+ getSessionToken(): string;
+ isCurrentSessionRevocable(): boolean;
+ }
+
+ /**
+ * Routers map faux-URLs to actions, and fire events when routes are
+ * matched. Creating a new one sets its `routes` hash, if not set statically.
+ * @class
+ *
+ * A fork of Backbone.Router, provided for your convenience.
+ * For more information, see the
+ * Backbone
+ * documentation .
+ * Available in the client SDK only.
+ */
+ class Router extends Events {
+
+ routes: Router.RouteMap;
+
+ constructor(options?: Router.Options);
+ static extend(instanceProps: any, classProps: any): any;
+
+ initialize(): void;
+ navigate(fragment: string, options?: Router.NavigateOptions): Router;
+ navigate(fragment: string, trigger?: boolean): Router;
+ route(route: string, name: string, callback: Function): Router;
+ }
+
+ namespace Router {
+ interface Options {
+ routes: RouteMap;
+ }
+
+ interface RouteMap {
+ [url: string]: string;
+ }
+
+ interface NavigateOptions {
+ trigger?: boolean;
+ }
+ }
+
+ /**
+ * @class
+ *
+ * A Parse.User object is a local representation of a user persisted to the
+ * Parse cloud. This class is a subclass of a Parse.Object, and retains the
+ * same functionality of a Parse.Object, but also extends it with various
+ * user specific methods, like authentication, signing up, and validation of
+ * uniqueness.
+ */
+ class User extends Object {
+
+ static current(): User | undefined;
+ static signUp(username: string, password: string, attrs: any, options?: SignUpOptions): Promise;
+ static logIn(username: string, password: string, options?: SuccessFailureOptions): Promise;
+ static logOut(): Promise;
+ static allowCustomUserClass(isAllowed: boolean): void;
+ static become(sessionToken: string, options?: SuccessFailureOptions): Promise;
+ static requestPasswordReset(email: string, options?: SuccessFailureOptions): Promise;
+ static extend(protoProps?: any, classProps?: any): any;
+
+ signUp(attrs: any, options?: SignUpOptions): Promise;
+ logIn(options?: SuccessFailureOptions): Promise;
+ authenticated(): boolean;
+ isCurrent(): boolean;
+
+ getEmail(): string | undefined;
+ setEmail(email: string, options?: SuccessFailureOptions): boolean;
+
+ getUsername(): string | undefined;
+ setUsername(username: string, options?: SuccessFailureOptions): boolean;
+
+ setPassword(password: string, options?: SuccessFailureOptions): boolean;
+ getSessionToken(): string;
+ }
+
+ /**
+ * Creating a Parse.View creates its initial element outside of the DOM,
+ * if an existing element is not provided...
+ * @class
+ *
+ * A fork of Backbone.View, provided for your convenience. If you use this
+ * class, you must also include jQuery, or another library that provides a
+ * jQuery-compatible $ function. For more information, see the
+ * Backbone
+ * documentation .
+ * Available in the client SDK only.
+ */
+ class View extends Events {
+
+ model: any;
+ collection: any;
+ id: string;
+ cid: string;
+ className: string;
+ tagName: string;
+ el: any;
+ $el: JQuery;
+ attributes: any;
+
+ constructor(options?: View.Options);
+
+ static extend(properties: any, classProperties?: any): any;
+
+ $(selector?: string): JQuery;
+ setElement(element: HTMLElement, delegate?: boolean): View;
+ setElement(element: JQuery, delegate?: boolean): View;
+ render(): View;
+ remove(): View;
+ make(tagName: any, attributes?: View.Attribute[], content?: any): any;
+ delegateEvents(events?: any): any;
+ undelegateEvents(): any;
+
+ }
+
+ namespace View {
+ interface Options {
+ model?: any;
+ collection?: any;
+ el?: any;
+ id?: string;
+ className?: string;
+ tagName?: string;
+ attributes?: Attribute[];
+ }
+
+ interface Attribute {
+ [attributeName: string]: string | number | boolean;
+ }
+ }
+
+ namespace Analytics {
+
+ function track(name: string, dimensions: any): Promise;
+ }
+
+ /**
+ * Provides a set of utilities for using Parse with Facebook.
+ * @namespace
+ * Provides a set of utilities for using Parse with Facebook.
+ */
+ namespace FacebookUtils {
+
+ function init(options?: any): void;
+ function isLinked(user: User): boolean;
+ function link(user: User, permissions: any, options?: SuccessFailureOptions): void;
+ function logIn(permissions: any, options?: SuccessFailureOptions): void;
+ function unlink(user: User, options?: SuccessFailureOptions): void;
+ }
+
+ /**
+ * @namespace Contains functions for calling and declaring
+ * cloud functions .
+ *
+ * Some functions are only available from Cloud Code.
+ *
+ */
+ namespace Cloud {
+
+ interface CookieOptions {
+ domain?: string;
+ expires?: Date;
+ httpOnly?: boolean;
+ maxAge?: number;
+ path?: string;
+ secure?: boolean;
+ }
+
+ interface HttpResponse {
+ buffer?: Buffer;
+ cookies?: any;
+ data?: any;
+ headers?: any;
+ status?: number;
+ text?: string;
+ }
+
+ interface JobRequest {
+ params: any;
+ }
+
+ interface JobStatus {
+ error?: (response: any) => void;
+ message?: (response: any) => void;
+ success?: (response: any) => void;
+ }
+
+ interface FunctionRequest {
+ installationId?: String;
+ master?: boolean;
+ params?: any;
+ user?: User;
+ }
+
+ interface FunctionResponse {
+ success: (response: any) => void;
+ error (code: number, response: any): void;
+ error (response: any): void;
+ }
+
+ interface Cookie {
+ name?: string;
+ options?: CookieOptions;
+ value?: string;
+ }
+
+ interface TriggerRequest {
+ installationId?: String;
+ master?: boolean;
+ user?: User;
+ ip: string;
+ headers: any;
+ triggerName: string;
+ log: any;
+ object: Object;
+ original?: Parse.Object;
+ }
+
+ interface AfterSaveRequest extends TriggerRequest { }
+ interface AfterDeleteRequest extends TriggerRequest { }
+ interface BeforeDeleteRequest extends TriggerRequest { }
+ interface BeforeDeleteResponse extends FunctionResponse { }
+ interface BeforeSaveRequest extends TriggerRequest { }
+ interface BeforeSaveResponse extends FunctionResponse {
+ success: () => void;
+ }
+
+ // Read preference describes how MongoDB driver route read operations to the members of a replica set.
+ enum ReadPreferenceOption {
+ Primary = 'PRIMARY',
+ PrimaryPreferred = 'PRIMARY_PREFERRED',
+ Secondary = 'SECONDARY',
+ SecondaryPreferred = 'SECONDARY_PREFERRED',
+ Nearest = 'NEAREST'
+ }
+
+ interface BeforeFindRequest extends TriggerRequest {
+ query: Query
+ count: boolean
+ isGet: boolean
+ readPreference?: ReadPreferenceOption
+ }
+
+ interface AfterFindRequest extends TriggerRequest {
+ objects: Object[]
+ }
+
+ interface AfterFindResponse extends FunctionResponse {
+ success: (objects: Object[]) => void;
+ }
+
+ function afterDelete(arg1: any, func?: (request: AfterDeleteRequest) => void): void;
+ function afterSave(arg1: any, func?: (request: AfterSaveRequest) => void): void;
+ function beforeDelete(arg1: any, func?: (request: BeforeDeleteRequest, response: BeforeDeleteResponse) => void): void;
+ function beforeSave(arg1: any, func?: (request: BeforeSaveRequest, response: BeforeSaveResponse) => void): void;
+ function beforeFind(arg1: any, func?: (request: BeforeFindRequest) => void): void;
+ function afterFind(arg1: any, func?: (request: AfterFindRequest, response: AfterFindResponse) => void): void;
+ function define(name: string, func?: (request: FunctionRequest, response: FunctionResponse) => void): void;
+ function httpRequest(options: HTTPOptions): Promise;
+ function job(name: string, func?: (request: JobRequest, status: JobStatus) => void): HttpResponse;
+ function run(name: string, data?: any, options?: RunOptions): Promise;
+ function useMasterKey(): void;
+
+ interface RunOptions extends SuccessFailureOptions, ScopeOptions { }
+
+ /**
+ * To use this Cloud Module in Cloud Code, you must require 'buffer' in your JavaScript file.
+ *
+ * import Buffer = require("buffer").Buffer;
+ */
+ let HTTPOptions: new () => HTTPOptions;
+ interface HTTPOptions {
+ /**
+ * The body of the request.
+ * If it is a JSON object, then the Content-Type set in the headers must be application/x-www-form-urlencoded or application/json.
+ * You can also set this to a Buffer object to send raw bytes.
+ * If you use a Buffer, you should also set the Content-Type header explicitly to describe what these bytes represent.
+ */
+ body?: string | Buffer | Object;
+ /**
+ * Defaults to 'false'.
+ */
+ followRedirects?: boolean;
+ /**
+ * The headers for the request.
+ */
+ headers?: {
+ [headerName: string]: string | number | boolean;
+ };
+ /**
+ *The method of the request (i.e GET, POST, etc).
+ */
+ method?: string;
+ /**
+ * The query portion of the url.
+ */
+ params?: any;
+ /**
+ * The url to send the request to.
+ */
+ url: string;
+
+ success?: (response: any) => void;
+ error?: (response: any) => void;
+ }
+ }
+
+
+ class Error {
+
+ code: ErrorCode;
+ message: string;
+
+ constructor(code: ErrorCode, message: string);
+
+ }
+
+ /*
+ * We need to inline the codes in order to make compilation work without this type definition as dependency.
+ */
+ const enum ErrorCode {
+
+ OTHER_CAUSE = -1,
+ INTERNAL_SERVER_ERROR = 1,
+ CONNECTION_FAILED = 100,
+ OBJECT_NOT_FOUND = 101,
+ INVALID_QUERY = 102,
+ INVALID_CLASS_NAME = 103,
+ MISSING_OBJECT_ID = 104,
+ INVALID_KEY_NAME = 105,
+ INVALID_POINTER = 106,
+ INVALID_JSON = 107,
+ COMMAND_UNAVAILABLE = 108,
+ NOT_INITIALIZED = 109,
+ INCORRECT_TYPE = 111,
+ INVALID_CHANNEL_NAME = 112,
+ PUSH_MISCONFIGURED = 115,
+ OBJECT_TOO_LARGE = 116,
+ OPERATION_FORBIDDEN = 119,
+ CACHE_MISS = 120,
+ INVALID_NESTED_KEY = 121,
+ INVALID_FILE_NAME = 122,
+ INVALID_ACL = 123,
+ TIMEOUT = 124,
+ INVALID_EMAIL_ADDRESS = 125,
+ MISSING_CONTENT_TYPE = 126,
+ MISSING_CONTENT_LENGTH = 127,
+ INVALID_CONTENT_LENGTH = 128,
+ FILE_TOO_LARGE = 129,
+ FILE_SAVE_ERROR = 130,
+ DUPLICATE_VALUE = 137,
+ INVALID_ROLE_NAME = 139,
+ EXCEEDED_QUOTA = 140,
+ SCRIPT_FAILED = 141,
+ VALIDATION_ERROR = 142,
+ INVALID_IMAGE_DATA = 150,
+ UNSAVED_FILE_ERROR = 151,
+ INVALID_PUSH_TIME_ERROR = 152,
+ FILE_DELETE_ERROR = 153,
+ REQUEST_LIMIT_EXCEEDED = 155,
+ INVALID_EVENT_NAME = 160,
+ USERNAME_MISSING = 200,
+ PASSWORD_MISSING = 201,
+ USERNAME_TAKEN = 202,
+ EMAIL_TAKEN = 203,
+ EMAIL_MISSING = 204,
+ EMAIL_NOT_FOUND = 205,
+ SESSION_MISSING = 206,
+ MUST_CREATE_USER_THROUGH_SIGNUP = 207,
+ ACCOUNT_ALREADY_LINKED = 208,
+ INVALID_SESSION_TOKEN = 209,
+ LINKED_ID_MISSING = 250,
+ INVALID_LINKED_SESSION = 251,
+ UNSUPPORTED_SERVICE = 252,
+ AGGREGATE_ERROR = 600,
+ FILE_READ_ERROR = 601,
+ X_DOMAIN_REQUEST = 602
+ }
+
+ /**
+ * @class
+ * A Parse.Op is an atomic operation that can be applied to a field in a
+ * Parse.Object. For example, calling object.set("foo", "bar")
+ * is an example of a Parse.Op.Set. Calling object.unset("foo")
+ * is a Parse.Op.Unset. These operations are stored in a Parse.Object and
+ * sent to the server as part of object.save() operations.
+ * Instances of Parse.Op should be immutable.
+ *
+ * You should not create subclasses of Parse.Op or instantiate Parse.Op
+ * directly.
+ */
+ namespace Op {
+
+ interface BaseOperation extends IBaseObject {
+ objects(): any[];
+ }
+
+ interface Add extends BaseOperation {
+ }
+
+ interface AddUnique extends BaseOperation {
+ }
+
+ interface Increment extends IBaseObject {
+ amount: number;
+ }
+
+ interface Relation extends IBaseObject {
+ added(): Object[];
+ removed: Object[];
+ }
+
+ interface Set extends IBaseObject {
+ value(): any;
+ }
+
+ interface Unset extends IBaseObject {
+ }
+
+ }
+
+ /**
+ * Contains functions to deal with Push in Parse
+ * @name Parse.Push
+ * @namespace
+ */
+ namespace Push {
+ function send(data: PushData, options?: SendOptions): Promise;
+
+ interface PushData {
+ channels?: string[];
+ push_time?: Date;
+ expiration_time?: Date;
+ expiration_interval?: number;
+ where?: Query;
+ data?: any;
+ alert?: string;
+ badge?: string;
+ sound?: string;
+ title?: string;
+ }
+
+ interface SendOptions extends UseMasterKeyOption {
+ success?: () => void;
+ error?: (error: Error) => void;
+ }
+ }
+
+ /**
+ * Call this method first to set up your authentication tokens for Parse.
+ * You can get your keys from the Data Browser on parse.com.
+ * @param {String} applicationId Your Parse Application ID.
+ * @param {String} javaScriptKey (optional) Your Parse JavaScript Key (Not needed for parse-server)
+ * @param {String} masterKey (optional) Your Parse Master Key. (Node.js only!)
+ */
+ function initialize(applicationId: string, javaScriptKey?: string, masterKey?: string): void;
+
+ /**
+ * Additionally on React-Native / Expo environments, add AsyncStorage from 'react-native' package
+ * @param AsyncStorage AsyncStorage from 'react-native' package
+ */
+ function setAsyncStorage(AsyncStorage: any): void;
+
+}
+
+declare module "parse/node" {
+ export = Parse;
+}
+
+declare module "parse" {
+ import * as parse from "parse/node";
+ export = parse
+}
+
+declare module "parse/react-native" {
+ import * as parse from "parse/node";
+ export = parse
+}
diff --git a/types/parse/v1/parse-tests.ts b/types/parse/v1/parse-tests.ts
new file mode 100644
index 0000000000..7f7f72e072
--- /dev/null
+++ b/types/parse/v1/parse-tests.ts
@@ -0,0 +1,561 @@
+
+
+function test_events() {
+
+ const object = new Parse.Events();
+ object.on("alert", (eventName: string) => alert("Triggered " + eventName));
+
+ object.trigger("alert", "an event");
+
+ const onChange = () => console.log('whatever');
+ let context: any;
+
+ object.off("change", onChange);
+ object.off("change");
+ object.off(null, onChange);
+ object.off(null, null, context);
+ object.off();
+}
+
+class GameScore extends Parse.Object {
+
+ constructor(options?: any) {
+
+ super("GameScore", options);
+ }
+}
+
+class Game extends Parse.Object {
+
+ constructor(options?: any) {
+
+ super("Game", options);
+ }
+}
+
+function test_object() {
+
+ const game = new Game();
+
+ if (!game.isNew()) {
+ console.error("Game should be new");
+ }
+
+ if (game.toPointer().className !== "Game") {
+ console.log("Class name should be 'Game")
+ }
+
+ game.fetch({
+ success(g: Game) { }
+ });
+
+ // Create a new instance of that class.
+ const gameScore = new GameScore();
+
+ gameScore.set("score", 1337);
+ gameScore.set("playerName", "Sean Plott");
+ gameScore.set("cheatMode", false);
+
+
+ // Setting attrs using object
+ gameScore.set({
+ level: '10',
+ difficult: 15
+ });
+
+ const score = gameScore.get("score");
+ const playerName = gameScore.get("playerName");
+ const cheatMode = gameScore.get("cheatMode");
+
+ gameScore.increment("score");
+ gameScore.addUnique("skills", "flying");
+ gameScore.addUnique("skills", "kungfu");
+
+ game.set("gameScore", gameScore);
+
+ const gameCopy = Game.fromJSON(JSON.parse(JSON.stringify(game)), true);
+}
+
+function test_query() {
+
+ const gameScore = new GameScore();
+
+ const query = new Parse.Query(GameScore);
+ query.equalTo("playerName", "Dan Stemkoski");
+ query.notEqualTo("playerName", "Michael Yabuti");
+ query.fullText("playerName", "dan", { language: 'en', caseSensitive: false, diacriticSensitive: true });
+ query.greaterThan("playerAge", 18);
+ query.limit(10);
+ query.skip(10);
+
+ // Sorts the results in ascending order by the score field
+ query.ascending("score");
+
+ // Sorts the results in descending order by the score field
+ query.descending("score");
+
+ // Restricts to wins < 50
+ query.lessThan("wins", 50);
+
+ // Restricts to wins <= 50
+ query.lessThanOrEqualTo("wins", 50);
+
+ // Restricts to wins > 50
+ query.greaterThan("wins", 50);
+
+ // Restricts to wins >= 50
+ query.greaterThanOrEqualTo("wins", 50);
+
+ // Finds scores from any of Jonathan, Dario, or Shawn
+ query.containedIn("playerName",
+ ["Jonathan Walsh", "Dario Wunsch", "Shawn Simon"]);
+
+ // Finds scores from anyone who is neither Jonathan, Dario, nor Shawn
+ query.notContainedIn("playerName",
+ ["Jonathan Walsh", "Dario Wunsch", "Shawn Simon"]);
+
+ // Finds objects that have the score set
+ query.exists("score");
+
+ // Finds objects that don't have the score set
+ query.doesNotExist("score");
+ query.matchesKeyInQuery("hometown", "city", query);
+ query.doesNotMatchKeyInQuery("hometown", "city", query);
+ query.select("score", "playerName");
+
+ // Find objects where the array in arrayKey contains 2.
+ query.equalTo("arrayKey", 2);
+
+ // Find objects where the array in arrayKey contains all of the elements 2, 3, and 4.
+ query.containsAll("arrayKey", [2, 3, 4]);
+
+ query.startsWith("name", "Big Daddy's");
+ query.equalTo("score", gameScore);
+ query.exists("score");
+ query.include("score");
+ query.include(["score.team"]);
+
+ // Find objects that match the aggregation pipeline
+ query.aggregate({
+ group:{
+ objectId: '$name'
+ }
+ });
+
+ // Find objects with distinct key
+ query.distinct('name');
+
+ const testQuery = Parse.Query.or(query, query);
+}
+
+class TestCollection extends Parse.Collection {
+
+ constructor(models?: Parse.Object[]) {
+
+ super(models);
+ }
+}
+
+function return_a_generic_query(): Parse.Query {
+ return new Parse.Query(Game);
+}
+
+function return_a_query(): Parse.Query {
+ return new Parse.Query(Game);
+}
+
+function test_collections() {
+
+ let collection = new TestCollection();
+
+ const query = new Parse.Query(Game);
+ query.equalTo("temperature", "hot");
+ query.greaterThan("degreesF", 100);
+
+ collection = query.collection();
+
+ collection.comparator = (object) => {
+ return object.get("temperature");
+ };
+
+ collection.add([
+ { "name": "Duke" },
+ { "name": "Scarlett" }
+ ]);
+
+ collection.fetch().then(
+ (data) => {
+
+ },
+ (error) => {
+ console.log("Error: " + error.code + " " + error.message);
+ }
+ );
+
+ const model = collection.at(0);
+
+ // Or you can get it by Parse objectId.
+ const modelAgain = collection.get(model.id);
+
+ // Remove "Duke" from the collection.
+ collection.remove(model);
+
+ // Completely replace all items in the collection.
+ collection.reset([
+ { "name": "Hawk" },
+ { "name": "Jane" }
+ ]);
+}
+
+function test_file() {
+
+ const base64 = "V29ya2luZyBhdCBQYXJzZSBpcyBncmVhdCE=";
+ let file = new Parse.File("myfile.txt", { base64: base64 });
+
+ const bytes = [0xBE, 0xEF, 0xCA, 0xFE];
+ file = new Parse.File("myfile.txt", bytes);
+
+ file = new Parse.File("myfile.zzz", {}, "image/png");
+
+ const src = file.url();
+
+ file.save().then(
+ () => {
+ // The file has been saved to Parse.
+ },
+ (error) => {
+ // The file either could n ot be read, or could not be saved to Parse.
+ });
+
+ Parse.Cloud.httpRequest({ url: file.url() }).then((response: Parse.Cloud.HttpResponse) => {
+ // result
+ });
+
+ // TODO: Check
+}
+
+function test_analytics() {
+
+ const dimensions = {
+ // Define ranges to bucket data points into meaningful segments
+ priceRange: '1000-1500',
+ // Did the user filter the query?
+ source: 'craigslist',
+ // Do searches happen more often on weekdays or weekends?
+ dayType: 'weekday'
+ };
+ // Send the dimensions to Parse along with the 'search' event
+ Parse.Analytics.track('search', dimensions);
+
+ const codeString = '404';
+ Parse.Analytics.track('error', { code: codeString })
+}
+
+function test_relation() {
+ var game1 = new Game();
+ var game2 = new Game();
+
+ new Parse.User().relation("games").query().find().then((g: Game[]) => { });
+ new Parse.User().relation("games").add(game1)
+ new Parse.User().relation("games").add([game1, game2])
+
+ new Parse.User().relation("games").remove(game1)
+ new Parse.User().relation("games").remove([game1, game2])
+}
+
+function test_user() {
+ const user = new Parse.User();
+ user.set("username", "my name");
+ user.set("password", "my pass");
+ user.set("email", "email@example.com");
+ user.signUp(null, { useMasterKey: true });
+}
+
+function test_user_acl_roles() {
+
+ const user = new Parse.User();
+ user.set("username", "my name");
+ user.set("password", "my pass");
+ user.set("email", "email@example.com");
+
+ // other fields can be set just like with Parse.Object
+ user.set("phone", "415-392-0202");
+
+ const currentUser = Parse.User.current();
+ if (currentUser) {
+ // do stuff with the user
+ } else {
+ // show the signup or login page
+ }
+
+ Parse.User.become("session-token-here").then(function (user) {
+ // The current user is now set to user.
+ }, function (error) {
+ // The token could not be validated.
+ });
+
+ const game = new Game();
+ game.set("score", new GameScore());
+ game.setACL(new Parse.ACL(Parse.User.current()));
+ game.save().then((game: Game) => { });
+ game.save(null, { useMasterKey: true });
+ game.save({ score: '10' }, { useMasterKey: true }).then(function (game) {
+ // Update game then revert it to the last saved state.
+ game.set("score", '20');
+ game.revert();
+ }, function (error) {
+ // The save failed
+ });
+
+ const groupACL = new Parse.ACL();
+
+ const userList: Parse.User[] = [Parse.User.current()!];
+ // userList is an array with the users we are sending this message to.
+ for (let i = 0; i < userList.length; i++) {
+ groupACL.setReadAccess(userList[i], true);
+ groupACL.setWriteAccess(userList[i], true);
+ }
+
+ groupACL.setPublicReadAccess(true);
+
+ game.setACL(groupACL);
+
+ Parse.User.requestPasswordReset("email@example.com").then(function (data) {
+ // The current user is now set to user.
+ }, function (error) {
+ // The token could not be validated.
+ });
+
+ // By specifying no write privileges for the ACL, we can ensure the role cannot be altered.
+ const role = new Parse.Role("Administrator", groupACL);
+ role.getUsers().add(userList[0]);
+ role.getRoles().add(role);
+ role.save();
+
+ Parse.User.logOut().then(function (data) {
+ // logged out
+ });
+}
+
+function test_facebook_util() {
+
+ Parse.FacebookUtils.init({
+ appId: 'YOUR_APP_ID', // Facebook App ID
+ channelUrl: '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel File
+ cookie: true, // enable cookies to allow Parse to access the session
+ xfbml: true // parse XFBML
+ });
+
+ Parse.FacebookUtils.logIn(null, {
+ success: (user: Parse.User) => {
+ if (!user.existed()) {
+ alert("User signed up and logged in through Facebook!");
+ } else {
+ alert("User logged in through Facebook!");
+ }
+ },
+ error: (user: Parse.User, error: any) => {
+ alert("User cancelled the Facebook login or did not fully authorize.");
+ }
+ });
+
+ const user = Parse.User.current()!;
+
+ if (!Parse.FacebookUtils.isLinked(user)) {
+ Parse.FacebookUtils.link(user, null, {
+ success: (user: any) => {
+ alert("Woohoo, user logged in with Facebook!");
+ },
+ error: (user: any, error: any) => {
+ alert("User cancelled the Facebook login or did not fully authorize.");
+ }
+ });
+ }
+
+ Parse.FacebookUtils.unlink(user, {
+ success: (user: Parse.User) => {
+ alert("The user is no longer associated with their Facebook account.");
+ }
+ });
+}
+
+function test_cloud_functions() {
+
+ Parse.Cloud.run('hello', {}, {
+ success: (result: any) => {
+ // result
+ },
+ error: (error: any) => {
+ }
+ });
+
+ Parse.Cloud.afterDelete('MyCustomClass', (request: Parse.Cloud.AfterDeleteRequest) => {
+ // result
+ });
+
+ Parse.Cloud.afterSave('MyCustomClass', (request: Parse.Cloud.AfterSaveRequest) => {
+ // result
+ });
+
+ Parse.Cloud.beforeDelete('MyCustomClass', (request: Parse.Cloud.BeforeDeleteRequest,
+ response: Parse.Cloud.BeforeDeleteResponse) => {
+ // result
+ });
+
+ const CUSTOM_ERROR_INVALID_CONDITION = 1001
+ const CUSTOM_ERROR_IMMUTABLE_FIELD = 1002
+
+ Parse.Cloud.beforeSave('MyCustomClass', (request: Parse.Cloud.BeforeSaveRequest,
+ response: Parse.Cloud.BeforeSaveResponse) => {
+
+ if (request.object.isNew()) {
+ if (!request.object.has('immutable')) return response.error('Field immutable is required')
+ } else {
+ const original = request.original;
+ if (original == null) { // When the object is not new, request.original must be defined
+ return response.error(CUSTOM_ERROR_INVALID_CONDITION, 'Original must me defined for an existing object')
+ }
+
+ if (original.get('immutable') !== request.object.get('immutable')) {
+ return response.error(CUSTOM_ERROR_IMMUTABLE_FIELD, 'This field cannot be changed')
+ }
+ }
+ response.success()
+ });
+
+ Parse.Cloud.beforeFind('MyCustomClass', (request: Parse.Cloud.BeforeFindRequest) => {
+ let query = request.query; // the Parse.Query
+ let user = request.user; // the user
+ let isMaster = request.master; // if the query is run with masterKey
+ let isCount = request.count; // if the query is a count operation (available on parse-server 2.4.0 or up)
+ let isGet = request.isGet; // if the query is a get operation
+
+ // All possible read preferences
+ request.readPreference = Parse.Cloud.ReadPreferenceOption.Primary
+ request.readPreference = Parse.Cloud.ReadPreferenceOption.PrimaryPreferred
+ request.readPreference = Parse.Cloud.ReadPreferenceOption.Secondary
+ request.readPreference = Parse.Cloud.ReadPreferenceOption.SecondaryPreferred
+ request.readPreference = Parse.Cloud.ReadPreferenceOption.Nearest
+ });
+}
+
+class PlaceObject extends Parse.Object { }
+
+function test_geo_points() {
+
+ const point = new Parse.GeoPoint({ latitude: 40.0, longitude: -30.0 });
+
+ const userObject = Parse.User.current()!;
+
+ // User's location
+ const userGeoPoint = userObject.get("location");
+
+ // Create a query for places
+ const query = new Parse.Query(Parse.User);
+ // Interested in locations near user.
+ query.near("location", userGeoPoint);
+ // Limit what could be a lot of points.
+ query.limit(10);
+
+ const southwestOfSF = new Parse.GeoPoint(37.708813, -122.526398);
+ const northeastOfSF = new Parse.GeoPoint(37.822802, -122.373962);
+
+ const query2 = new Parse.Query(PlaceObject);
+ query2.withinGeoBox("location", southwestOfSF, northeastOfSF);
+
+ const query3 = new Parse.Query("PlaceObject").find().then((o: Parse.Object[]) => { });
+}
+
+function test_push() {
+
+ Parse.Push.send({
+ channels: ["Gia nts", "Mets"],
+ data: {
+ alert: "The Giants won against the Mets 2-3."
+ }
+ }, {
+ success: () => {
+ // Push was successful
+ },
+ error: (error: any) => {
+ // Handle error
+ }
+ });
+
+ const query = new Parse.Query(Parse.Installation);
+ query.equalTo('injuryReports', true);
+
+ Parse.Push.send({
+ where: query, // Set our Installation query
+ data: {
+ alert: "Willie Hayes injured by own pop fly."
+ }
+ }, {
+ success: function () {
+ // Push was successful
+ },
+ error: function (error: any) {
+ // Handle error
+ }
+ });
+}
+
+function test_view() {
+
+ const model = Parse.User.current();
+ const view = new Parse.View();
+}
+
+function test_promise() {
+ let resolved = Parse.Promise.as(true);
+ let rejected = Parse.Promise.error("an error object");
+ Parse.Promise.when([resolved, rejected]).then(function () {
+ // success
+ }, function () {
+ // failed
+ });
+
+ // Test promise with a query
+ const query = new Parse.Query('Test');
+ query.find()
+ .then(() => {
+ // success
+ }).catch(() => {
+ // error
+ });
+
+ // can check whether an object is a Parse.Promise object or not
+ Parse.Promise.is(resolved);
+}
+
+function test_batch_operations() {
+ const game1 = new Game()
+ const game2 = new Game()
+ const games = [game1, game2]
+
+ // Master key
+ Parse.Object.saveAll(games, { useMasterKey: true })
+ Parse.Object.destroyAll(games, { useMasterKey: true })
+ Parse.Object.fetchAll(games, { useMasterKey: true })
+ Parse.Object.fetchAllIfNeeded(games, { useMasterKey: true })
+
+ // Session token
+ Parse.Object.saveAll(games, { sessionToken: '' })
+ Parse.Object.destroyAll(games, { sessionToken: '' })
+ Parse.Object.fetchAll(games, { sessionToken: '' })
+ Parse.Object.fetchAllIfNeeded(games, { sessionToken: '' })
+}
+
+function test_query_subscribe() {
+ // create new query from Game object type
+ const query = new Parse.Query(Game);
+
+ // create subscription to Game object
+ const subscription = query.subscribe();
+
+ // listen for new Game objects created on Parse server
+ subscription.on('create', (game: any) => {
+ console.log(game);
+ });
+}
+
diff --git a/types/parse/v1/tsconfig.json b/types/parse/v1/tsconfig.json
new file mode 100644
index 0000000000..971be64447
--- /dev/null
+++ b/types/parse/v1/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "compilerOptions": {
+ "module": "commonjs",
+ "lib": ["es6", "dom"],
+ "noImplicitAny": true,
+ "noImplicitThis": true,
+ "strictNullChecks": true,
+ "strictFunctionTypes": true,
+ "baseUrl": "../../",
+ "typeRoots": ["../../"],
+ "paths": {
+ "parse": ["parse/v1"],
+ "parse/*": ["parse/v1/*"]
+ },
+ "types": [],
+ "noEmit": true,
+ "forceConsistentCasingInFileNames": true
+ },
+ "files": ["index.d.ts", "parse-tests.ts"]
+}
diff --git a/types/parse/v1/tslint.json b/types/parse/v1/tslint.json
new file mode 100644
index 0000000000..e2172b7f24
--- /dev/null
+++ b/types/parse/v1/tslint.json
@@ -0,0 +1,81 @@
+{
+ "extends": "dtslint/dt.json",
+ "rules": {
+ "adjacent-overload-signatures": false,
+ "array-type": false,
+ "arrow-return-shorthand": false,
+ "ban-types": false,
+ "callable-types": false,
+ "comment-format": false,
+ "dt-header": false,
+ "eofline": false,
+ "export-just-namespace": false,
+ "import-spacing": false,
+ "interface-name": false,
+ "interface-over-type-literal": false,
+ "jsdoc-format": false,
+ "max-line-length": false,
+ "member-access": false,
+ "new-parens": false,
+ "no-any-union": false,
+ "no-boolean-literal-compare": false,
+ "no-conditional-assignment": false,
+ "no-consecutive-blank-lines": false,
+ "no-const-enum": false,
+ "no-construct": false,
+ "no-declare-current-package": false,
+ "no-duplicate-imports": false,
+ "no-duplicate-variable": false,
+ "no-empty-interface": false,
+ "no-for-in-array": false,
+ "no-inferrable-types": false,
+ "no-internal-module": false,
+ "no-irregular-whitespace": false,
+ "no-mergeable-namespace": false,
+ "no-misused-new": false,
+ "no-namespace": false,
+ "no-object-literal-type-assertion": false,
+ "no-padding": false,
+ "no-redundant-jsdoc": false,
+ "no-redundant-jsdoc-2": false,
+ "no-redundant-undefined": false,
+ "no-reference-import": false,
+ "no-relative-import-in-test": false,
+ "no-self-import": false,
+ "no-single-declare-module": false,
+ "no-string-throw": false,
+ "no-unnecessary-callback-wrapper": false,
+ "no-unnecessary-class": false,
+ "no-unnecessary-generics": false,
+ "no-unnecessary-qualifier": false,
+ "no-unnecessary-type-assertion": false,
+ "no-useless-files": false,
+ "no-var-keyword": false,
+ "no-var-requires": false,
+ "no-void-expression": false,
+ "no-trailing-whitespace": false,
+ "object-literal-key-quotes": false,
+ "object-literal-shorthand": false,
+ "one-line": false,
+ "one-variable-per-declaration": false,
+ "only-arrow-functions": false,
+ "prefer-conditional-expression": false,
+ "prefer-const": false,
+ "prefer-declare-function": false,
+ "prefer-for-of": false,
+ "prefer-method-signature": false,
+ "prefer-template": false,
+ "radix": false,
+ "semicolon": false,
+ "space-before-function-paren": false,
+ "space-within-parens": false,
+ "strict-export-declare-modifiers": false,
+ "trim-file": false,
+ "triple-equals": false,
+ "typedef-whitespace": false,
+ "unified-signatures": false,
+ "use-default-type-parameter": false,
+ "void-return": false,
+ "whitespace": false
+ }
+}