Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
1f66ca7
hmm?
Feb 8, 2026
3f4d965
exported types
Feb 8, 2026
9eede2c
removed legacy types file
Feb 8, 2026
dca4507
removed redundant tests and improved method signature
Feb 8, 2026
9d5147e
added more options types, not sure
Feb 8, 2026
9d2d5dc
use options for types
Feb 8, 2026
608820e
better ObjectStatic
Feb 8, 2026
6f3d1de
Merge branch 'alpha' into fix-type-exports
Feb 8, 2026
0c17bfe
fixed object generics on ObjectStatic
Feb 8, 2026
84f3931
reuse baseAttributes
Feb 8, 2026
96dd564
reorder to reduce PR clutter
Feb 8, 2026
05529d8
removed aggregationoptions for now; confusing
Feb 8, 2026
0e12725
removed wait from destory options (not even used in code anymore)
Feb 8, 2026
455f012
traced and simplified union main types
Feb 8, 2026
30f7211
simplify readability with BaseRequestOptions
Feb 8, 2026
9b7c02e
followed recommendations for lint
Feb 8, 2026
5689993
Fix type definition for keys parameter in fetchAll methods
swittk Feb 8, 2026
b326e5a
Update fetchAllIfNeededWithInclude and fetchAllWithInclude signatures
swittk Feb 8, 2026
71c0c74
added options present in newer SDKs previously not present in definit…
Feb 8, 2026
41f9b04
followed suggestion for objectconstructor
Feb 8, 2026
feedf41
followed dirty suggestion -_-
Feb 8, 2026
e359da3
darn stupid formatter
Feb 8, 2026
8b90d7a
code style fixes
Feb 8, 2026
ee6ade6
tightened RunOptions to only those used by actual cloud code
Feb 8, 2026
af5accc
fixed formattings
Feb 9, 2026
c81e6df
indentations again
Feb 9, 2026
fe6d5e0
Merge branch 'alpha' into fix-type-exports
mtrezza Feb 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/Cloud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import encode from './encode';
import ParseError from './ParseError';
import ParseQuery from './ParseQuery';
import ParseObject from './ParseObject';
import type { RequestOptions } from './RESTController';
import type { RequestOptions, FullOptions } from './RESTController';

export interface RunOptions extends RequestOptions, FullOptions { }

/**
* Contains functions for calling and declaring
Expand Down Expand Up @@ -40,12 +42,12 @@ import type { RequestOptions } from './RESTController';
export function run<T extends () => any>(
name: string,
data?: null,
options?: RequestOptions
options?: RunOptions
): Promise<ReturnType<T>>;
export function run<
T extends (param: { [P in keyof Parameters<T>[0]]: Parameters<T>[0][P] }) => any,
>(name: string, data: Parameters<T>[0], options?: RequestOptions): Promise<ReturnType<T>>;
export function run(name: string, data?: any, options?: RequestOptions): Promise<any> {
>(name: string, data: Parameters<T>[0], options?: RunOptions): Promise<ReturnType<T>>;
export function run(name: string, data?: any, options?: RunOptions): Promise<any> {
if (typeof name !== 'string' || name.length === 0) {
throw new TypeError('Cloud function name must be a string.');
}
Expand Down
119 changes: 87 additions & 32 deletions src/ParseObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import * as UniqueInstanceStateController from './UniqueInstanceStateController'
import unsavedChildren from './unsavedChildren';

import type { AttributeMap, OpsMap } from './ObjectStateMutations';
import type { RequestOptions, FullOptions } from './RESTController';
import type { RequestOptions, FullOptions, BaseRequestOptions } from './RESTController';
import type ParseGeoPoint from './ParseGeoPoint';
import type ParsePolygon from './ParsePolygon';

Expand All @@ -45,35 +45,58 @@ interface SaveParams {
body: AttributeMap;
}

export type SaveOptions = FullOptions & {
export interface SaveOptions extends BaseRequestOptions {
/** If `false`, nested objects will not be saved (default is `true`). */
cascadeSave?: boolean;
context?: AttributeMap;
batchSize?: number;
transaction?: boolean;
};
}

interface FetchOptions {
useMasterKey?: boolean;
sessionToken?: string;
export interface FetchOptions extends BaseRequestOptions {
include?: string | string[];
context?: AttributeMap;
}

export interface SetOptions {
ignoreValidation?: boolean;
unset?: boolean;
}

export type DestroyOptions = BaseRequestOptions;

/** Options for destroyAll batch operation */
export interface DestroyAllOptions extends BaseRequestOptions {
batchSize?: number;
}

/** Options for saveAll batch operation */
export interface SaveAllOptions extends BaseRequestOptions {
batchSize?: number;
/** If `false`, nested objects will not be saved (default is `true`). */
cascadeSave?: boolean;
transaction?: boolean;
}

/** Options for fetchAll batch operation */
export interface FetchAllOptions extends BaseRequestOptions {
include?: string | string[];
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

export type AttributeKey<T> = Extract<keyof T, string>;

export type Attributes = Record<string, any>;

interface JSONBaseAttributes {
export interface JSONBaseAttributes {
objectId: string;
createdAt: string;
updatedAt: string;
}

export interface BaseAttributes {
objectId: string;
createdAt: Date;
updatedAt: Date;
}

interface CommonAttributes {
ACL: ParseACL;
}
Expand All @@ -82,21 +105,21 @@ type AtomicKey<T> = {
[K in keyof T]: NonNullable<T[K]> extends any[] ? K : never;
};

type Encode<T> = T extends ParseObject
export type Encode<T> = T extends ParseObject
? ReturnType<T['toJSON']> | Pointer
: T extends ParseACL | ParseGeoPoint | ParsePolygon | ParseRelation | ParseFile
? ReturnType<T['toJSON']>
: T extends Date
? { __type: 'Date'; iso: string }
: T extends RegExp
? string
: T extends (infer R)[]
? Encode<R>[]
: T extends object
? ToJSON<T>
: T;

type ToJSON<T> = {
? ReturnType<T['toJSON']>
Comment thread
swittk marked this conversation as resolved.
Resolved
: T extends Date
? { __type: 'Date'; iso: string }
: T extends RegExp
? string
: T extends (infer R)[]
? Encode<R>[]
: T extends object
? ToJSON<T>
: T;

export type ToJSON<T> = {
[K in keyof T]: Encode<T[K]>;
};

Expand Down Expand Up @@ -151,7 +174,7 @@ class ParseObject<T extends Attributes = Attributes> {
* @param {boolean} [options.ignoreValidation] Set to `true` ignore any attribute validation errors.
*/
constructor(
className?: string | { className: string; [attr: string]: any },
className?: string | { className: string;[attr: string]: any },
attributes?: T,
options?: SetOptions
) {
Expand Down Expand Up @@ -188,8 +211,7 @@ class ParseObject<T extends Attributes = Attributes> {
}
if (CoreManager.get('NODE_LOGGING')) {
this[Symbol.for('nodejs.util.inspect.custom')] = function () {
return `ParseObject: className: ${this.className}, id: ${
this.id
return `ParseObject: className: ${this.className}, id: ${this.id
}\nAttributes: ${JSON.stringify(this.attributes, null, 2)}`;
};
}
Expand Down Expand Up @@ -1481,7 +1503,7 @@ class ParseObject<T extends Attributes = Attributes> {
* @returns {Promise} A promise that is fulfilled when the destroy
* completes.
*/
destroy(options?: RequestOptions): Promise<ParseObject | undefined> {
destroy(options?: DestroyOptions): Promise<ParseObject | undefined> {
if (!this.id) {
return Promise.resolve(undefined);
}
Expand Down Expand Up @@ -1637,7 +1659,7 @@ class ParseObject<T extends Attributes = Attributes> {
* @static
* @returns {Parse.Object[]}
*/
static fetchAll<T extends ParseObject>(list: T[], options?: RequestOptions): Promise<T[]> {
static fetchAll<T extends ParseObject>(list: T[], options?: FetchAllOptions): Promise<T[]> {
const fetchOptions = ParseObject._getRequestOptions(options);
return CoreManager.getObjectController().fetch(list, true, fetchOptions) as Promise<T[]>;
}
Expand Down Expand Up @@ -1748,7 +1770,7 @@ class ParseObject<T extends Attributes = Attributes> {
* @static
* @returns {Parse.Object[]}
*/
static fetchAllIfNeeded<T extends ParseObject>(list: T[], options?: FetchOptions): Promise<T[]> {
static fetchAllIfNeeded<T extends ParseObject>(list: T[], options?: FetchAllOptions): Promise<T[]> {
const fetchOptions = ParseObject._getRequestOptions(options);
return CoreManager.getObjectController().fetch(list, false, fetchOptions) as Promise<T[]>;
}
Expand Down Expand Up @@ -1824,9 +1846,9 @@ class ParseObject<T extends Attributes = Attributes> {
* @returns {Promise} A promise that is fulfilled when the destroyAll
* completes.
*/
static destroyAll(list: ParseObject[], options?: SaveOptions) {
static destroyAll<T extends ParseObject>(list: T[], options?: DestroyAllOptions): Promise<T[]> {
const destroyOptions = ParseObject._getRequestOptions(options);
return CoreManager.getObjectController().destroy(list, destroyOptions);
return CoreManager.getObjectController().destroy(list, destroyOptions) as Promise<T[]>;
}

/**
Expand Down Expand Up @@ -1858,7 +1880,7 @@ class ParseObject<T extends Attributes = Attributes> {
* @static
* @returns {Parse.Object[]}
*/
static saveAll<T extends ParseObject[]>(list: T, options?: SaveOptions): Promise<T> {
static saveAll<T extends ParseObject[]>(list: T, options?: SaveAllOptions): Promise<T> {
const saveOptions = ParseObject._getRequestOptions(options);
return CoreManager.getObjectController().save(list, saveOptions) as any;
}
Expand Down Expand Up @@ -1948,7 +1970,7 @@ class ParseObject<T extends Attributes = Attributes> {
if (typeof constructor !== 'function') {
throw new TypeError(
'You must register the subclass constructor. ' +
'Did you attempt to register an instance of the subclass?'
'Did you attempt to register an instance of the subclass?'
);
}
classMap[className] = constructor;
Expand Down Expand Up @@ -2657,4 +2679,37 @@ const DefaultController = {
CoreManager.setParseObject(ParseObject);
CoreManager.setObjectController(DefaultController);

export interface ObjectStatic<T extends ParseObject = ParseObject> {
new(...args: any[]): T;
createWithoutData(id: string): T;
destroyAll<U extends ParseObject>(list: U[], options?: DestroyAllOptions): Promise<U[]>;
extend(className: string | { className: string }, protoProps?: any, classProps?: any): any;
fetchAll<U extends ParseObject>(list: U[], options?: FetchAllOptions): Promise<U[]>;
fetchAllIfNeeded<U extends ParseObject>(list: U[], options?: FetchAllOptions): Promise<U[]>;
fetchAllIfNeededWithInclude<U extends ParseObject>(
list: U[],
keys: keyof U["attributes"] | (keyof U["attributes"])[],
options?: RequestOptions,
): Promise<U[]>;
fetchAllWithInclude<U extends ParseObject>(
list: U[],
keys: keyof U["attributes"] | (keyof U["attributes"])[],
options?: RequestOptions,
): Promise<U[]>;
fromJSON(json: any, override?: boolean): T;
pinAll(objects: ParseObject[]): Promise<void>;
pinAllWithName(name: string, objects: ParseObject[]): Promise<void>;
registerSubclass(className: string, clazz: new (options?: any) => T): void;
saveAll<U extends ParseObject[]>(list: U, options?: SaveAllOptions): Promise<U>;
unPinAll(objects: ParseObject[]): Promise<void>;
unPinAllObjects(): Promise<void>;
unPinAllObjectsWithName(name: string): Promise<void>;
unPinAllWithName(name: string, objects: ParseObject[]): Promise<void>;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

export interface ObjectConstructor extends ObjectStatic {
new <T extends Attributes>(className: string, attributes: T, options?: any): ParseObject<T>;
new(className?: string, attributes?: Attributes, options?: any): ParseObject;
}

export default ParseObject;
Loading