Skip to content

refactor: Add more types to pass all type definition tests #2486

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- name: Type Definition Check
run: npm run ci:typecheck
- name: Test Types
run: npm run test:types 2>&1 | tee silent.txt;
run: npm run test:types
check-docs:
name: Check Docs
timeout-minutes: 10
Expand Down
4 changes: 0 additions & 4 deletions eslint.config.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@ export default tseslint.config({
rules: {
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unsafe-return": "off",
},
Expand Down
16 changes: 12 additions & 4 deletions src/Cloud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,15 @@ import type { RequestOptions } from './RESTController';
* @returns {Promise} A promise that will be resolved with the result
* of the function.
*/
export function run(name: string, data: any, options: RequestOptions): Promise<any> {
export function run<T extends () => any>(
name: string,
data?: null,
options?: RequestOptions
): 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> {
if (typeof name !== 'string' || name.length === 0) {
throw new TypeError('Cloud function name must be a string.');
}
Expand Down Expand Up @@ -88,7 +96,7 @@ export function getJobStatus(jobStatusId: string): Promise<ParseObject> {
}

const DefaultController = {
run(name: string, data: any, options: RequestOptions) {
run(name: string, data: any, options?: RequestOptions): Promise<any> {
const RESTController = CoreManager.getRESTController();
const payload = encode(data, true);

Expand All @@ -105,12 +113,12 @@ const DefaultController = {
});
},

getJobsData(options: RequestOptions) {
getJobsData(options?: RequestOptions): Promise<any> {
const RESTController = CoreManager.getRESTController();
return RESTController.request('GET', 'cloud_code/jobs/data', null, options);
},

async startJob(name: string, data: any, options: RequestOptions) {
async startJob(name: string, data: any, options?: RequestOptions): Promise<string> {
const RESTController = CoreManager.getRESTController();

const payload = encode(data, true);
Expand Down
80 changes: 57 additions & 23 deletions src/CoreManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ type AnalyticsController = {
track: (name: string, dimensions: { [key: string]: string }) => Promise<any>;
};
type CloudController = {
run: (name: string, data: any, options: RequestOptions) => Promise<any>;
getJobsData: (options: RequestOptions) => Promise<any>;
run: (name: string, data: any, options?: RequestOptions) => Promise<any>;
getJobsData: (options?: RequestOptions) => Promise<any>;
/** Returns promise which resolves with JobStatusId of the job */
startJob: (name: string, data: any, options: RequestOptions) => Promise<string>;
startJob: (name: string, data: any, options?: RequestOptions) => Promise<string>;
};
type ConfigController = {
current: () => Promise<ParseConfig> | ParseConfig;
Expand Down Expand Up @@ -55,15 +55,15 @@ type ObjectController = {
fetch: (
object: ParseObject | Array<ParseObject>,
forceFetch: boolean,
options: RequestOptions
options?: RequestOptions
) => Promise<Array<ParseObject | undefined> | ParseObject | undefined>;
save: (
object: ParseObject | Array<ParseObject | ParseFile> | null,
options: RequestOptions
options?: RequestOptions
) => Promise<ParseObject | Array<ParseObject> | ParseFile | undefined>;
destroy: (
object: ParseObject | Array<ParseObject>,
options: RequestOptions
options?: RequestOptions
) => Promise<ParseObject | Array<ParseObject>>;
};
type ObjectStateController = {
Expand Down Expand Up @@ -92,18 +92,52 @@ type QueryController = {
find(
className: string,
params: QueryJSON,
options: RequestOptions
options?: RequestOptions
): Promise<{ results?: Array<ParseObject>; className?: string; count?: number }>;
aggregate(
className: string,
params: any,
options: RequestOptions
options?: RequestOptions
): Promise<{ results?: Array<any> }>;
};
type EventuallyQueue = {
save: (object: ParseObject, serverOptions: SaveOptions) => Promise<any>;
destroy: (object: ParseObject, serverOptions: RequestOptions) => Promise<any>;
poll: (ms?: number) => void;
export type QueueObject = {
queueId: string;
action: string;
object: ParseObject;
serverOptions: SaveOptions | RequestOptions;
id: string;
className: string;
hash: string;
createdAt: Date;
};
export type Queue = Array<QueueObject>;
export type EventuallyQueue = {
save: (object: ParseObject, serverOptions?: SaveOptions) => Promise<void>;
destroy: (object: ParseObject, serverOptions?: RequestOptions) => Promise<void>;
generateQueueId: (action: string, object: ParseObject) => string;
enqueue(
action: string,
object: ParseObject,
serverOptions?: SaveOptions | RequestOptions
): Promise<void>;
store(data: Queue): Promise<void>;
load(): Promise<string | null>;
getQueue(): Promise<Queue>;
setQueue(queue: Queue): Promise<void>;
remove(queueId: string): Promise<void>;
clear(): Promise<void>;
queueItemExists(queue: Queue, queueId: string): number;
length(): Promise<number>;
sendQueue(): Promise<boolean>;
sendQueueCallback(object: ParseObject, queueObject: QueueObject): Promise<void>;
poll(ms?: number): void;
stopPoll(): void;
isPolling(): boolean;
process: {
create(ObjectType: any, queueObject: any): Promise<void>;
byId(ObjectType: any, queueObject: any): Promise<void>;
byHash(ObjectType: any, queueObject: any): Promise<void>;
};
};
type RESTController = {
request: (method: string, path: string, data?: any, options?: RequestOptions) => Promise<any>;
Expand All @@ -122,10 +156,10 @@ type SchemaController = {
delete: (className: string, options?: RequestOptions) => Promise<void>;
create: (className: string, params: any, options?: RequestOptions) => Promise<any>;
update: (className: string, params: any, options?: RequestOptions) => Promise<any>;
send(className: string, method: string, params: any, options: RequestOptions): Promise<any>;
send(className: string, method: string, params: any, options?: RequestOptions): Promise<any>;
};
type SessionController = {
getSession: (token: RequestOptions) => Promise<ParseSession>;
getSession: (options?: RequestOptions) => Promise<ParseSession>;
};
type StorageController =
| {
Expand Down Expand Up @@ -165,24 +199,24 @@ type UserController = {
setCurrentUser: (user: ParseUser) => Promise<void>;
currentUser: () => ParseUser | null;
currentUserAsync: () => Promise<ParseUser | null>;
signUp: (user: ParseUser, attrs: AttributeMap, options: RequestOptions) => Promise<ParseUser>;
logIn: (user: ParseUser, options: RequestOptions) => Promise<ParseUser>;
signUp: (user: ParseUser, attrs: AttributeMap, options?: RequestOptions) => Promise<ParseUser>;
logIn: (user: ParseUser, options?: RequestOptions) => Promise<ParseUser>;
loginAs: (user: ParseUser, userId: string) => Promise<ParseUser>;
become: (user: ParseUser, options: RequestOptions) => Promise<ParseUser>;
become: (user: ParseUser, options?: RequestOptions) => Promise<ParseUser>;
hydrate: (user: ParseUser, userJSON: AttributeMap) => Promise<ParseUser>;
logOut: (options: RequestOptions) => Promise<void>;
me: (user: ParseUser, options: RequestOptions) => Promise<ParseUser>;
requestPasswordReset: (email: string, options: RequestOptions) => Promise<void>;
logOut: (options?: RequestOptions) => Promise<void>;
me: (user: ParseUser, options?: RequestOptions) => Promise<ParseUser>;
requestPasswordReset: (email: string, options?: RequestOptions) => Promise<void>;
updateUserOnDisk: (user: ParseUser) => Promise<ParseUser>;
upgradeToRevocableSession: (user: ParseUser, options: RequestOptions) => Promise<void>;
upgradeToRevocableSession: (user: ParseUser, options?: RequestOptions) => Promise<void>;
linkWith: (user: ParseUser, authData: AuthData, options?: FullOptions) => Promise<ParseUser>;
removeUserFromDisk: () => Promise<ParseUser | void>;
verifyPassword: (
username: string,
password: string,
options: RequestOptions
options?: RequestOptions
) => Promise<ParseUser>;
requestEmailVerification: (email: string, options: RequestOptions) => Promise<void>;
requestEmailVerification: (email: string, options?: RequestOptions) => Promise<void>;
};
type HooksController = {
get: (type: string, functionName?: string, triggerName?: string) => Promise<any>;
Expand Down
38 changes: 13 additions & 25 deletions src/EventuallyQueue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,12 @@ import ParseObject from './ParseObject';
import ParseQuery from './ParseQuery';
import Storage from './Storage';

import type { Queue, QueueObject } from './CoreManager';
import type { SaveOptions } from './ParseObject';
import type { RequestOptions } from './RESTController';

type QueueObject = {
queueId: string;
action: string;
object: ParseObject;
serverOptions: SaveOptions | RequestOptions;
id: string;
className: string;
hash: string;
createdAt: Date;
};

type Queue = Array<QueueObject>;

const QUEUE_KEY = 'Parse/Eventually/Queue';
let queueCache: QueueObject[] = [];
let queueCache: Queue = [];
let dirtyCache = true;
let polling: ReturnType<typeof setInterval> | undefined = undefined;

Expand All @@ -44,7 +32,7 @@ const EventuallyQueue = {
* @static
* @see Parse.Object#saveEventually
*/
save(object: ParseObject, serverOptions: SaveOptions = {}): Promise<void> {
save(object: ParseObject, serverOptions?: SaveOptions): Promise<void> {
return this.enqueue('save', object, serverOptions);
},

Expand All @@ -59,7 +47,7 @@ const EventuallyQueue = {
* @static
* @see Parse.Object#destroyEventually
*/
destroy(object: ParseObject, serverOptions: RequestOptions = {}): Promise<void> {
destroy(object: ParseObject, serverOptions?: RequestOptions): Promise<void> {
return this.enqueue('destroy', object, serverOptions);
},

Expand Down Expand Up @@ -92,7 +80,7 @@ const EventuallyQueue = {
async enqueue(
action: string,
object: ParseObject,
serverOptions: SaveOptions | RequestOptions
serverOptions?: SaveOptions | RequestOptions
): Promise<void> {
const queueData = await this.getQueue();
const queueId = this.generateQueueId(action, object);
Expand All @@ -112,7 +100,7 @@ const EventuallyQueue = {
queueId,
action,
object: object.toJSON(),
serverOptions,
serverOptions: serverOptions || {},
id: object.id,
className: object.className,
hash: object.get('hash'),
Expand All @@ -121,11 +109,11 @@ const EventuallyQueue = {
return this.setQueue(queueData);
},

store(data: QueueObject[]) {
store(data: Queue): Promise<void> {
return Storage.setItemAsync(QUEUE_KEY, JSON.stringify(data));
},

load() {
load(): Promise<string | null> {
return Storage.getItemAsync(QUEUE_KEY);
},

Expand All @@ -134,10 +122,10 @@ const EventuallyQueue = {
*
* @function getQueue
* @name Parse.EventuallyQueue.getQueue
* @returns {Promise<QueueObject[]>}
* @returns {Promise<Queue>}
* @static
*/
async getQueue(): Promise<QueueObject[]> {
async getQueue(): Promise<Queue> {
if (dirtyCache) {
queueCache = JSON.parse((await this.load()) || '[]');
dirtyCache = false;
Expand Down Expand Up @@ -297,7 +285,7 @@ const EventuallyQueue = {
* @param [ms] Milliseconds to ping the server. Default 2000ms
* @static
*/
poll(ms = 2000) {
poll(ms?: number): void {
if (polling) {
return;
}
Expand All @@ -311,7 +299,7 @@ const EventuallyQueue = {
}
})
.catch(e => e);
}, ms);
}, ms || 2000);
},

/**
Expand All @@ -321,7 +309,7 @@ const EventuallyQueue = {
* @name Parse.EventuallyQueue.stopPoll
* @static
*/
stopPoll() {
stopPoll(): void {
clearInterval(polling);
polling = undefined;
},
Expand Down
11 changes: 6 additions & 5 deletions src/LiveQuerySubscription.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import CoreManager from './CoreManager';
import { resolvingPromise } from './promiseUtils';
import type ParseQuery from './ParseQuery';
import type { EventEmitter } from 'events';

/**
* Creates a new LiveQuery Subscription.
Expand Down Expand Up @@ -91,9 +92,9 @@ class LiveQuerySubscription {
subscribePromise: any;
unsubscribePromise: any;
subscribed: boolean;
emitter: any;
on: any;
emit: any;
emitter: EventEmitter;
on: EventEmitter['on'];
emit: EventEmitter['emit'];
/*
* @param {string | number} id - subscription id
* @param {string} query - query to subscribe to
Expand All @@ -106,8 +107,8 @@ class LiveQuerySubscription {
this.subscribePromise = resolvingPromise();
this.unsubscribePromise = resolvingPromise();
this.subscribed = false;
const EventEmitter = CoreManager.getEventEmitter();
this.emitter = new EventEmitter();
const Emitter = CoreManager.getEventEmitter();
this.emitter = new Emitter();

this.on = (eventName, listener) => this.emitter.on(eventName, listener);
this.emit = (eventName, ...args) => this.emitter.emit(eventName, ...args);
Expand Down
11 changes: 6 additions & 5 deletions src/Parse.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import decode from './decode';
import encode from './encode';
import CryptoController from './CryptoController';
import EventuallyQueue from './EventuallyQueue';
import EQ from './EventuallyQueue';
import IndexedDBStorageController from './IndexedDBStorageController';
import InstallationController from './InstallationController';
import * as ParseOp from './ParseOp';
Expand Down Expand Up @@ -36,6 +36,7 @@ import LiveQueryClient from './LiveQueryClient';
import LocalDatastoreController from './LocalDatastoreController';
import StorageController from './StorageController';
import WebSocketController from './WebSocketController';
import type { EventuallyQueue } from './CoreManager';

const Parse = {
ACL,
Expand Down Expand Up @@ -79,11 +80,11 @@ const Parse = {
* @member {EventuallyQueue} Parse.EventuallyQueue
* @static
*/
set EventuallyQueue(queue: typeof EventuallyQueue) {
set EventuallyQueue(queue: EventuallyQueue) {
CoreManager.setEventuallyQueue(queue);
},

get EventuallyQueue(): any {
get EventuallyQueue(): EventuallyQueue {
return CoreManager.getEventuallyQueue();
},

Expand Down Expand Up @@ -117,7 +118,7 @@ const Parse = {
CoreManager.setIfNeeded('EventEmitter', EventEmitter);
CoreManager.setIfNeeded('LiveQuery', new ParseLiveQuery());
CoreManager.setIfNeeded('CryptoController', CryptoController);
CoreManager.setIfNeeded('EventuallyQueue', EventuallyQueue);
CoreManager.setIfNeeded('EventuallyQueue', EQ);
CoreManager.setIfNeeded('InstallationController', InstallationController);
CoreManager.setIfNeeded('LocalDatastoreController', LocalDatastoreController);
CoreManager.setIfNeeded('StorageController', StorageController);
Expand Down Expand Up @@ -342,7 +343,7 @@ const Parse = {
* @static
* @returns {boolean}
*/
isLocalDatastoreEnabled() {
isLocalDatastoreEnabled(): boolean {
return this.LocalDatastore.isEnabled;
},
/**
Expand Down
Loading
Loading