From 0eb66d7fb0031f29bd0e75e80672e102df301949 Mon Sep 17 00:00:00 2001 From: Marcus Olsson Date: Sun, 25 May 2025 01:36:56 +0200 Subject: [PATCH 1/6] fix: Add fix for when passing null as Parse.Cloud.run option (#2622) --- src/ParseObject.ts | 3 +++ src/__tests__/ParseObject-test.js | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/ParseObject.ts b/src/ParseObject.ts index 9ecb3292e..6b3c6595b 100644 --- a/src/ParseObject.ts +++ b/src/ParseObject.ts @@ -514,6 +514,9 @@ class ParseObject { static _getRequestOptions(options: RequestOptions & FullOptions & { json?: boolean } = {}) { const requestOptions: RequestOptions & FullOptions & { json?: boolean } = {}; + if (!options) { + return requestOptions; + } const { hasOwn } = Object; if (hasOwn(options, 'useMasterKey')) { requestOptions.useMasterKey = !!options.useMasterKey; diff --git a/src/__tests__/ParseObject-test.js b/src/__tests__/ParseObject-test.js index 60f7cecab..0e37f0e50 100644 --- a/src/__tests__/ParseObject-test.js +++ b/src/__tests__/ParseObject-test.js @@ -3543,3 +3543,23 @@ describe('ParseObject pin', () => { CoreManager.set('NODE_LOGGING', false); }); }); + +describe('ParseObject._getRequestOptions', () => { + it('returns empty object when options is null', () => { + const requestOptions = ParseObject._getRequestOptions(null); + + expect(requestOptions).toEqual({}); + }); + + it('returns empty object when options is an empty string', () => { + const requestOptions = ParseObject._getRequestOptions(""); + + expect(requestOptions).toEqual({}); + }); + + it('returns empty object when options is undefined', () => { + const requestOptions = ParseObject._getRequestOptions(undefined); + + expect(requestOptions).toEqual({}); + }); +}); From a8bb14b97ff535368efe52bad3508aa3b45d19a5 Mon Sep 17 00:00:00 2001 From: Marcus Olsson Date: Mon, 2 Jun 2025 16:26:34 +0200 Subject: [PATCH 2/6] fix: Null fix in ParseObject (#2622) --- src/ParseObject.ts | 4 ++-- src/__tests__/Cloud-test.js | 27 +++++++++++++++++++++++++++ src/__tests__/ParseObject-test.js | 20 -------------------- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/ParseObject.ts b/src/ParseObject.ts index 6b3c6595b..59a486618 100644 --- a/src/ParseObject.ts +++ b/src/ParseObject.ts @@ -514,8 +514,8 @@ class ParseObject { static _getRequestOptions(options: RequestOptions & FullOptions & { json?: boolean } = {}) { const requestOptions: RequestOptions & FullOptions & { json?: boolean } = {}; - if (!options) { - return requestOptions; + if (Object.prototype.toString.call(options) !== '[object Object]') { + throw new Error('request options must be of type Object'); } const { hasOwn } = Object; if (hasOwn(options, 'useMasterKey')) { diff --git a/src/__tests__/Cloud-test.js b/src/__tests__/Cloud-test.js index 6ed1e84e1..11aeca9b9 100644 --- a/src/__tests__/Cloud-test.js +++ b/src/__tests__/Cloud-test.js @@ -356,4 +356,31 @@ describe('CloudController', () => { }); expect(options.useMasterKey).toBe(false); }); + + it('run passes with empty options', () => { + const values = [undefined, {}]; + + const mockRun = jest.fn(); + mockRun.mockReturnValue(Promise.resolve({ result: {} })); + + CoreManager.setCloudController({ + run: mockRun, + getJobsData: jest.fn(), + startJob: jest.fn(), + }); + + for (const value of values) { + mockRun.mockClear(); + expect(() => Cloud.run('myfunction', {}, value)).not.toThrow(); + expect(mockRun).toHaveBeenLastCalledWith('myfunction', {}, {}); + } + }); + + it('run throws with invalid options', () => { + const values = [null, []]; + for (const value of values) { + expect(() => Cloud.run('myfunction', {}, value)).toThrow(); + } + }); + }); diff --git a/src/__tests__/ParseObject-test.js b/src/__tests__/ParseObject-test.js index 0e37f0e50..60f7cecab 100644 --- a/src/__tests__/ParseObject-test.js +++ b/src/__tests__/ParseObject-test.js @@ -3543,23 +3543,3 @@ describe('ParseObject pin', () => { CoreManager.set('NODE_LOGGING', false); }); }); - -describe('ParseObject._getRequestOptions', () => { - it('returns empty object when options is null', () => { - const requestOptions = ParseObject._getRequestOptions(null); - - expect(requestOptions).toEqual({}); - }); - - it('returns empty object when options is an empty string', () => { - const requestOptions = ParseObject._getRequestOptions(""); - - expect(requestOptions).toEqual({}); - }); - - it('returns empty object when options is undefined', () => { - const requestOptions = ParseObject._getRequestOptions(undefined); - - expect(requestOptions).toEqual({}); - }); -}); From 5adcb79a93cd110c563da4dcc485522f4bb8843e Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Wed, 4 Jun 2025 01:47:45 +0200 Subject: [PATCH 3/6] lint Signed-off-by: Manuel <5673677+mtrezza@users.noreply.github.com> --- src/__tests__/Cloud-test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/__tests__/Cloud-test.js b/src/__tests__/Cloud-test.js index 11aeca9b9..23de2bf94 100644 --- a/src/__tests__/Cloud-test.js +++ b/src/__tests__/Cloud-test.js @@ -356,7 +356,6 @@ describe('CloudController', () => { }); expect(options.useMasterKey).toBe(false); }); - it('run passes with empty options', () => { const values = [undefined, {}]; @@ -382,5 +381,4 @@ describe('CloudController', () => { expect(() => Cloud.run('myfunction', {}, value)).toThrow(); } }); - }); From 29fa2c53c4272a0007f154ab4ab54477ea010b82 Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Wed, 4 Jun 2025 01:48:23 +0200 Subject: [PATCH 4/6] format Signed-off-by: Manuel <5673677+mtrezza@users.noreply.github.com> --- src/__tests__/Cloud-test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/__tests__/Cloud-test.js b/src/__tests__/Cloud-test.js index 23de2bf94..dba85b255 100644 --- a/src/__tests__/Cloud-test.js +++ b/src/__tests__/Cloud-test.js @@ -356,6 +356,7 @@ describe('CloudController', () => { }); expect(options.useMasterKey).toBe(false); }); + it('run passes with empty options', () => { const values = [undefined, {}]; From a5b4b5ac48c1389fa750f4f13e1e8c55d177b438 Mon Sep 17 00:00:00 2001 From: Marcus Olsson Date: Mon, 27 Oct 2025 16:13:05 +0100 Subject: [PATCH 5/6] Adds default options object to cloud function Ensures that the `options` argument in the `run` function is initialized to an empty object if it is undefined, preventing potential errors when accessing properties of `options` later in the function. Signed-off-by: Marcus Olsson --- src/Cloud.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Cloud.ts b/src/Cloud.ts index c8fd781ad..7f4c3c8de 100644 --- a/src/Cloud.ts +++ b/src/Cloud.ts @@ -46,6 +46,8 @@ export function run< T extends (param: { [P in keyof Parameters[0]]: Parameters[0][P] }) => any, >(name: string, data: Parameters[0], options?: RequestOptions): Promise>; export function run(name: string, data?: any, options?: RequestOptions): Promise { + options = options || {}; + if (typeof name !== 'string' || name.length === 0) { throw new TypeError('Cloud function name must be a string.'); } From 1e087b5904029e9c73ad3bb75ce0fd481a652813 Mon Sep 17 00:00:00 2001 From: Marcus Olsson Date: Mon, 27 Oct 2025 16:33:26 +0100 Subject: [PATCH 6/6] Lint fix Signed-off-by: Marcus Olsson --- src/Cloud.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Cloud.ts b/src/Cloud.ts index 7f4c3c8de..b9b785708 100644 --- a/src/Cloud.ts +++ b/src/Cloud.ts @@ -47,7 +47,6 @@ export function run< >(name: string, data: Parameters[0], options?: RequestOptions): Promise>; export function run(name: string, data?: any, options?: RequestOptions): Promise { options = options || {}; - if (typeof name !== 'string' || name.length === 0) { throw new TypeError('Cloud function name must be a string.'); }