Skip to content

Conversation

@hajjarjoseph
Copy link
Contributor

@hajjarjoseph hajjarjoseph commented Jan 7, 2026

  • Add CloudServer.d.ts with comprehensive server-side types
  • Add module augmentation in node.d.ts to expose server types
  • Types include: define, job, beforeSave, afterSave, beforeFind, etc.

Pull Request

Issue

Closes: #2653

Approach

This PR adds TypeScript type definitions for server-side Cloud Code functions when using parse/node.

Problem: When importing parse/node, server-side functions like Parse.Cloud.define, Parse.Cloud.beforeSave, etc. had no type definitions, resulting in any types.

Solution:

  1. Created CloudServer.d.ts with all server-side type definitions (request interfaces, validators, cloud functions)
  2. Used TypeScript module augmentation in node.d.ts to extend the Cloud module with these types
  3. The augmentation uses import() + typeof import() pattern to alias types from CloudServer without duplication

Result:

// parse (browser) - only client functions
Parse.Cloud.run('fn');  // ✅
Parse.Cloud.define(...) // ❌ Type error

// parse/node (server) - all functions available
Parse.Cloud.run('fn');           // ✅
Parse.Cloud.define('fn', req => {
  req.params;  // ✅ typed as Record<string, any>
  req.user;    // ✅ typed as ParseUser | undefined
});
Parse.Cloud.beforeSave('Class', req => {
  req.object;  // ✅ typed as ParseObject
}); 

Tasks

  • Add tests

Summary by CodeRabbit

  • New Features
    • Expanded Cloud Code TypeScript surface with rich, strongly-typed interfaces and overloads for functions, triggers (before/after save/delete/find/login/logout), file/connect hooks, live-query events, jobs, validators, HTTP utilities, and email helper.
  • Documentation
    • Added JSDoc-style docs for Cloud Code APIs to improve generated docs and developer guidance.
  • Tests
    • Added extensive server-side type tests covering Cloud Code APIs, lifecycle hooks, triggers, jobs, live-query, and HTTP/email utilities.

✏️ Tip: You can customize this high-level summary in your review settings.

- Add CloudServer.d.ts with comprehensive server-side type definitions
- Use module augmentation in node.d.ts to extend Cloud module
- Add BeforeDeleteRequest and AfterDeleteRequest interfaces
- Add type tests for server-side Cloud functions

Types include: define, job, beforeSave, afterSave, beforeDelete,
afterDelete, beforeFind, afterFind, beforeLogin, afterLogin,
afterLogout, file triggers, LiveQuery triggers, httpRequest, sendEmail
@parse-github-assistant
Copy link

🚀 Thanks for opening this pull request!

@coderabbitai
Copy link

coderabbitai bot commented Jan 7, 2026

📝 Walkthrough

Walkthrough

Adds comprehensive Cloud Code TypeScript declarations and a Node-specific module augmentation exposing server-side Parse.Cloud types/signatures, plus expanded type tests covering cloud functions, triggers, jobs, HTTP, and LiveQuery typings. All changes are additive to typings and tests.

Changes

Cohort / File(s) Summary
Cloud Code runtime typings
types/CloudCode.d.ts, src/CloudCode.ts
Adds interfaces/types (FunctionRequest/FunctionResponse, TriggerRequest and Before/After variants, File/Connect/LiveQuery/Job, Validator types, HTTPOptions/HTTPResponse, ReadPreferenceOption) and many exported function declarations (define overloads, job, before/after hooks, beforeFind/afterFind, file hooks, connect/subscribe hooks, afterLiveQueryEvent, httpRequest, sendEmail).
Node-specific augmentation
types/node.d.ts
Adds module augmentation for ./Cloud that re-exports CloudCode type aliases and function signatures so server-side Parse.Cloud APIs are available via the node entrypoint.
Type tests
types/tests.ts
Expands tests broadly to validate Cloud.run, Cloud.define, triggers (save/delete/find/login/logout), file/connect hooks, jobs, httpRequest/sendEmail, LiveQuery types, and browser vs. node surface expectations using @ts-expect-error / $ExpectError.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • mtrezza
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding server-side Cloud Code types for parse/node package.
Description check ✅ Passed The description covers the issue (#2653), approach (CloudServer types and module augmentation), problem/solution, and marks the testing task as complete.
Linked Issues check ✅ Passed The PR fully addresses issue #2653 by implementing typed Cloud Code triggers and functions for parse/node with comprehensive type definitions and test coverage.
Out of Scope Changes check ✅ Passed All changes are in-scope: types/node.d.ts augmentation, src/CloudCode.ts and types/CloudCode.d.ts with server types, and types/tests.ts with comprehensive coverage.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@parseplatformorg
Copy link
Contributor

parseplatformorg commented Jan 7, 2026

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@codecov
Copy link

codecov bot commented Jan 7, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.88%. Comparing base (cf2ef13) to head (685cf2d).

Additional details and impacted files
@@           Coverage Diff           @@
##            alpha    #2855   +/-   ##
=======================================
  Coverage   99.88%   99.88%           
=======================================
  Files          64       64           
  Lines        6222     6222           
  Branches     1473     1489   +16     
=======================================
  Hits         6215     6215           
  Misses          7        7           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In @types/CloudServer.d.ts:
- Around line 162-211: The BeforeFindRequest and AfterFindRequest interfaces are
missing the optional context property; add a context?: Record<string, any> (or
context?: any) property to both the BeforeFindRequest and AfterFindRequest
interface declarations so request.context is properly typed and consistent with
other trigger request interfaces (update the types/CloudServer.d.ts file where
those interface declarations exist and ensure the property name is exactly
"context" and optional).

In @types/node.d.ts:
- Around line 23-43: The module augmentation is missing the export for
beforePasswordResetRequest; add an export line mirroring the other function
exports so it reuses the signature from CloudServer (e.g., export const
beforePasswordResetRequest: typeof
import('./CloudServer').beforePasswordResetRequest) alongside the existing
define/job/etc. entries to ensure the type is exposed.
- Line 16: The exported alias LiveQueryEventTrigger currently drops its generic
parameter; update the type alias to preserve the generic (e.g.,
LiveQueryEventTrigger<T extends ParseObject = ParseObject>) and forward that
generic to the imported symbol
(import('./CloudServer').LiveQueryEventTrigger<T>) so callers can specify custom
object types; modify the export of LiveQueryEventTrigger to include the generic
parameter and default just like the other aliases in this file.
- Around line 5-21: Add the two missing re-exports to the module augmentation by
declaring export type FunctionResponse =
import('./CloudServer').FunctionResponse; and export type ReadPreferenceOption =
import('./CloudServer').ReadPreferenceOption; so code using Express-style cloud
function handlers (FunctionResponse) and beforeFind read preference enums
(ReadPreferenceOption) can import them from the augmented types alongside the
existing FunctionRequest/BeforeFindRequest types.
🧹 Nitpick comments (2)
types/CloudServer.d.ts (1)

216-257: AfterFindRequest also lacks context property.

Same as BeforeFindRequest, this interface should likely include the context property for consistency and to match Parse Server's actual request object.

♻️ Suggested addition
 export interface AfterFindRequest<T extends ParseObject = ParseObject> {
   // ... existing properties ...
   /**
    * The Parse Server config.
    */
   config: any;
+  /**
+   * A dictionary that is accessible in triggers.
+   */
+  context: Record<string, unknown>;
 }
types/tests.ts (1)

2260-2279: Consider expanding test coverage for comprehensive type verification.

The current tests verify basic functionality for define, beforeSave, and job, but the PR introduces many more types and functions. Consider adding tests for:

  1. Type inference on request objects (e.g., req.object.get(), req.params.someField)
  2. Other triggers (afterSave, beforeDelete, afterFind, etc.)
  3. Validator options with ValidatorObject
  4. Generic constraints with custom ParseObject subclasses
  5. httpRequest and sendEmail utilities
♻️ Example expanded tests
function test_cloud_server_functions() {
  // Existing tests...

  // Test type inference on request properties
  ParseNode.Cloud.beforeSave('TestClass', req => {
    // Verify req.object is typed
    const obj = req.object;
    const original = req.original;
    const isMaster = req.master;
  });

  // Test with validator
  ParseNode.Cloud.define('validatedFunction', req => req.params, {
    requireUser: true,
    fields: {
      name: { required: true, type: String }
    }
  });

  // Test afterFind with results
  ParseNode.Cloud.afterFind('TestClass', req => {
    return req.results;
  });
}
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cf2ef13 and 2b70e4a.

📒 Files selected for processing (3)
  • types/CloudServer.d.ts
  • types/node.d.ts
  • types/tests.ts
🧰 Additional context used
🧬 Code graph analysis (1)
types/node.d.ts (1)
types/CloudServer.d.ts (16)
  • FunctionRequest (20-61)
  • TriggerRequest (88-137)
  • BeforeSaveRequest (142-142)
  • AfterSaveRequest (147-147)
  • BeforeDeleteRequest (152-152)
  • AfterDeleteRequest (157-157)
  • BeforeFindRequest (162-211)
  • AfterFindRequest (216-257)
  • FileTriggerRequest (262-307)
  • ConnectTriggerRequest (312-337)
  • LiveQueryEventTrigger (342-383)
  • JobRequest (388-401)
  • ValidatorField (410-435)
  • ValidatorObject (440-506)
  • HTTPOptions (515-548)
  • HTTPResponse (553-578)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build (Node 20, 20.19.0)
  • GitHub Check: build (Node 22, 22.12.0)
  • GitHub Check: build (Node 24, 24.1.0)
🔇 Additional comments (8)
types/CloudServer.d.ts (7)

1-12: LGTM!

Clean module documentation and appropriate imports for the server-side Cloud Code types.


20-61: LGTM!

The FunctionRequest interface is well-documented with comprehensive properties. Using any for log and config is appropriate given their complex internal structures.


63-137: LGTM!

Both FunctionResponse and TriggerRequest interfaces are well-structured with proper generic constraints and comprehensive property coverage for trigger hooks.


388-506: LGTM!

The JobRequest interface is appropriately minimal for background jobs, and the ValidatorField and ValidatorObject interfaces provide comprehensive validation configuration including rate limiting options.


515-593: LGTM!

The HTTP-related types and ReadPreferenceOption enum are well-structured. The HTTPOptions method type correctly restricts to valid HTTP methods, and HTTPResponse covers all expected response properties.


613-919: LGTM!

Comprehensive Cloud function declarations with proper generic constraints, overloads for different usage patterns, and excellent JSDoc examples. The coverage of lifecycle hooks, query hooks, auth hooks, file triggers, LiveQuery triggers, and utility functions aligns well with Parse Server's Cloud Code API.


312-337: No action needed. ConnectTriggerRequest and LiveQueryEventTrigger correctly use useMasterKey: boolean while other request interfaces use master: boolean. This property naming reflects Parse Server's actual API design, where LiveQuery triggers use useMasterKey and other cloud triggers use master. The type definitions are accurate and consistent with the official Parse Server API.

types/node.d.ts (1)

3-44: LGTM on the module augmentation pattern!

The declare module './Cloud' augmentation correctly exposes server-side types exclusively for parse/node imports. The use of import('./CloudServer') type aliases and typeof import('./CloudServer') for functions is clean and avoids code duplication.

- Add generic type parameter to LiveQueryEventTrigger
- Export beforePasswordResetRequest function
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @types/node.d.ts:
- Around line 3-45: Add the two missing type exports to the './Cloud' module
augmentation: export FunctionResponse and ReadPreferenceOption from
'./CloudServer' (i.e., add lines exporting FunctionResponse =
import('./CloudServer').FunctionResponse and ReadPreferenceOption =
import('./CloudServer').ReadPreferenceOption) alongside the other type exports
(near the HTTPOptions/HTTPResponse/FunctionRequest block, before the "Functions
- reuse signatures from CloudServer" section) so the Cloud augmentation matches
CloudServer.d.ts.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2b70e4a and 51fab0a.

📒 Files selected for processing (1)
  • types/node.d.ts
🧰 Additional context used
🧬 Code graph analysis (1)
types/node.d.ts (1)
types/CloudServer.d.ts (16)
  • FunctionRequest (20-61)
  • TriggerRequest (88-137)
  • BeforeSaveRequest (142-142)
  • AfterSaveRequest (147-147)
  • BeforeDeleteRequest (152-152)
  • AfterDeleteRequest (157-157)
  • BeforeFindRequest (162-211)
  • AfterFindRequest (216-257)
  • FileTriggerRequest (262-307)
  • ConnectTriggerRequest (312-337)
  • LiveQueryEventTrigger (342-383)
  • JobRequest (388-401)
  • ValidatorField (410-435)
  • ValidatorObject (440-506)
  • HTTPOptions (515-548)
  • HTTPResponse (553-578)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build (Node 20, 20.19.0)
  • GitHub Check: build (Node 24, 24.1.0)
  • GitHub Check: build (Node 22, 22.12.0)

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 7, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds comprehensive TypeScript type definitions for server-side Cloud Code functions when using parse/node. Previously, server-side functions like Parse.Cloud.define, Parse.Cloud.beforeSave, etc. had no type definitions, resulting in any types.

Key changes:

  • Created CloudServer.d.ts with complete server-side type definitions including request interfaces, validators, cloud functions, triggers, and utility functions
  • Added module augmentation in node.d.ts to extend the Cloud module with server-side types when importing parse/node
  • Added basic tests demonstrating the new type definitions

Reviewed changes

Copilot reviewed 1 out of 3 changed files in this pull request and generated 1 comment.

File Description
types/CloudServer.d.ts New file containing comprehensive server-side Cloud Code type definitions (927 lines) including request interfaces, validators, and function declarations for all server-side triggers and utilities
types/node.d.ts Module augmentation to expose server-side types from CloudServer.d.ts into the Cloud module when using parse/node
types/tests.ts Basic tests demonstrating server-side Cloud Code type usage and verifying that server functions are not available on the browser Parse object

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

types/tests.ts Outdated
Comment on lines 2260 to 2279
// Test server-side Cloud Code types (only available in parse/node)
function test_cloud_server_functions() {
// Using ParseNode (parse/node), NOT Parse (parse)
// Server-side functions should be available on ParseNode.Cloud
ParseNode.Cloud.define('testFunction', req => {
return 'result';
});

ParseNode.Cloud.beforeSave('TestClass', req => {
// req.object should be typed
});

ParseNode.Cloud.job('testJob', req => {
req.message('Processing...');
});

// These should NOT exist on regular Parse (browser)
// @ts-expect-error - define should not exist on browser Parse.Cloud
Parse.Cloud.define('test', () => {});
}
Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test coverage for server-side Cloud Code types is minimal. Consider adding more comprehensive tests that verify:

  • Type checking for request properties (e.g., req.params, req.user, req.object)
  • All trigger types (afterSave, beforeDelete, afterDelete, beforeFind, afterFind, etc.)
  • Validator parameter usage
  • File triggers with proper request type checking
  • LiveQuery triggers (beforeConnect, beforeSubscribe, afterLiveQueryEvent)
  • Auth triggers (beforeLogin, afterLogin, beforePasswordResetRequest)
  • Utility functions (httpRequest, sendEmail)
  • Return type validation for handlers

This would ensure the type definitions work correctly across all server-side Cloud Code functions.

Copilot uses AI. Check for mistakes.
@dplewis
Copy link
Member

dplewis commented Jan 8, 2026

@hajjarjoseph We should add this to src/CloudCode.ts and have it autogenerated the definition. This way we can expose these types in the SDK. Also can you add these test cases dplewis/parse-server@d4a44c9?

@hajjarjoseph
Copy link
Contributor Author

hajjarjoseph commented Jan 8, 2026

@hajjarjoseph We should add this to src/CloudCode.ts and have it autogenerated the definition. This way we can expose these types in the SDK. Also can you add these test cases dplewis/parse-server@d4a44c9?

Thanks for the review @dplewis ! I have a question about moving types to src/CloudCode.ts:

The server-side functions (define, beforeSave, etc.) don't exist at runtime in browser contexts. They're injected by Parse Server. The current module augmentation approach in node.d.ts only exposes these types when importing from parse/node, matching the actual runtime behavior.

If we add types directly to CloudCode.ts, they'd be visible in all contexts, including browser and where Parse.Cloud.define doesn't exist.

Should I move it anyway?

@dplewis
Copy link
Member

dplewis commented Jan 8, 2026

If we add types directly to CloudCode.ts, they'd be visible in all contexts, including browser and where Parse.Cloud.define doesn't exist.

It wouldn't be visible, it would be visible in all context if you manually add it to index.d.ts similar to how you are updating node.d.ts in this PR.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
src/CloudCode.ts (4)

45-48: Consider using type aliases instead of empty interfaces.

The linter correctly identifies that these empty interfaces are equivalent to their supertype. While they provide semantic clarity, consider using type aliases:

♻️ Suggested refactor
-export interface BeforeSaveRequest<T extends ParseObject = ParseObject> extends TriggerRequest<T> {}
-export interface AfterSaveRequest<T extends ParseObject = ParseObject> extends TriggerRequest<T> {}
-export interface BeforeDeleteRequest<T extends ParseObject = ParseObject> extends TriggerRequest<T> {}
-export interface AfterDeleteRequest<T extends ParseObject = ParseObject> extends TriggerRequest<T> {}
+export type BeforeSaveRequest<T extends ParseObject = ParseObject> = TriggerRequest<T>;
+export type AfterSaveRequest<T extends ParseObject = ParseObject> = TriggerRequest<T>;
+export type BeforeDeleteRequest<T extends ParseObject = ParseObject> = TriggerRequest<T>;
+export type AfterDeleteRequest<T extends ParseObject = ParseObject> = TriggerRequest<T>;

Alternatively, if you plan to add specific properties to these in the future, keeping them as interfaces is acceptable—just suppress the lint rule with an inline comment.


195-205: Combine function overloads as suggested by the linter.

The two define overloads can be combined into a single signature with a union handler type:

♻️ Suggested fix
-export declare function define<T extends Record<string, any> = Record<string, any>>(
-  name: string,
-  handler: (request: FunctionRequest<T>) => any,
-  validator?: ValidatorObject | ((request: FunctionRequest<T>) => any)
-): void;
-
-export declare function define<T extends Record<string, any> = Record<string, any>>(
-  name: string,
-  handler: (request: FunctionRequest<T>, response: FunctionResponse) => any,
-  validator?: ValidatorObject | ((request: FunctionRequest<T>) => any)
-): void;
+export declare function define<T extends Record<string, any> = Record<string, any>>(
+  name: string,
+  handler:
+    | ((request: FunctionRequest<T>) => any)
+    | ((request: FunctionRequest<T>, response: FunctionResponse) => any),
+  validator?: ValidatorObject | ((request: FunctionRequest<T>) => any)
+): void;

209-214: Use function type syntax for constructor types.

The linter flags the type literal { new (): T }. Use the constructor function type syntax instead:

♻️ Suggested fix (apply to all similar declarations)
 export declare function beforeSave<T extends ParseObject = ParseObject>(
-  className: string | { new (): T },
+  className: string | (new () => T),
   handler: (request: BeforeSaveRequest<T>) => T | void | Promise<T | void>,
   validator?: ValidatorObject | ((request: BeforeSaveRequest<T>) => any)
 ): void;

Apply the same pattern (new () => T instead of { new (): T }) to:

  • afterSave (line 216)
  • beforeDelete (line 222)
  • afterDelete (line 228)
  • beforeFind (line 234)
  • afterFind (line 240)
  • beforeSubscribe (line 285)
  • afterLiveQueryEvent (line 291)

211-211: Consider replacing void with undefined in union return types.

The linter flags void as invalid in union types. TypeScript's void type is intended for functions that don't return a value, while undefined is the actual value type. For union return types, undefined is more appropriate:

-  handler: (request: BeforeSaveRequest<T>) => T | void | Promise<T | void>,
+  handler: (request: BeforeSaveRequest<T>) => T | undefined | Promise<T | undefined>,

This applies to similar patterns in beforeFind (line 235), afterFind (line 241), and beforeSaveFile (line 264). However, if this is intentional for Parse Server compatibility, you may suppress the lint warning instead.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 08766ab and b09807b.

📒 Files selected for processing (4)
  • src/CloudCode.ts
  • types/CloudCode.d.ts
  • types/node.d.ts
  • types/tests.ts
✅ Files skipped from review due to trivial changes (1)
  • types/CloudCode.d.ts
🧰 Additional context used
🧬 Code graph analysis (3)
types/node.d.ts (1)
src/CloudCode.ts (17)
  • FunctionRequest (10-21)
  • FunctionResponse (23-28)
  • TriggerRequest (30-43)
  • BeforeSaveRequest (45-45)
  • AfterSaveRequest (46-46)
  • BeforeDeleteRequest (47-47)
  • AfterDeleteRequest (48-48)
  • BeforeFindRequest (50-64)
  • AfterFindRequest (66-78)
  • FileTriggerRequest (80-92)
  • ConnectTriggerRequest (94-101)
  • LiveQueryEventTrigger (103-114)
  • JobRequest (116-120)
  • ValidatorField (126-133)
  • ValidatorObject (135-153)
  • HTTPOptions (159-168)
  • HTTPResponse (170-177)
types/tests.ts (1)
src/RESTController.ts (1)
  • request (238-343)
src/CloudCode.ts (1)
types/CloudCode.d.ts (17)
  • FunctionRequest (5-16)
  • FunctionResponse (17-22)
  • TriggerRequest (23-36)
  • BeforeSaveRequest (37-38)
  • AfterSaveRequest (39-40)
  • BeforeDeleteRequest (41-42)
  • AfterDeleteRequest (43-44)
  • BeforeFindRequest (45-59)
  • AfterFindRequest (60-72)
  • FileTriggerRequest (73-85)
  • ConnectTriggerRequest (86-93)
  • LiveQueryEventTrigger (94-105)
  • JobRequest (106-110)
  • ValidatorField (111-118)
  • ValidatorObject (119-137)
  • HTTPOptions (138-147)
  • HTTPResponse (148-155)
🪛 GitHub Check: Lint
src/CloudCode.ts

[failure] 222-222:
Type literal only has a call signature, you should use a function type instead


[failure] 216-216:
Type literal only has a call signature, you should use a function type instead


[failure] 211-211:
void is not valid as a constituent in a union type


[failure] 211-211:
void is not valid as a constituent in a union type


[failure] 210-210:
Type literal only has a call signature, you should use a function type instead


[failure] 203-203:
These overloads can be combined into one signature taking (request: FunctionRequest<T>) => any | (request: FunctionRequest<T>, response: FunctionResponse) => any


[failure] 48-48:
An interface declaring no members is equivalent to its supertype


[failure] 47-47:
An interface declaring no members is equivalent to its supertype


[failure] 46-46:
An interface declaring no members is equivalent to its supertype


[failure] 45-45:
An interface declaring no members is equivalent to its supertype

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build (Node 20, 20.19.0)
  • GitHub Check: build (Node 24, 24.1.0)
  • GitHub Check: build (Node 22, 22.12.0)
🔇 Additional comments (4)
types/tests.ts (1)

2259-2484: Comprehensive test coverage for server-side Cloud Code types.

The tests thoroughly exercise all the new Cloud Code typings including triggers, jobs, and utility functions. The browser exclusion tests using @ts-expect-error appropriately verify that server-only APIs are not exposed in the browser context.

types/node.d.ts (1)

3-47: Well-structured module augmentation for server-side Cloud types.

The module augmentation pattern using declare module './Cloud' is appropriate for exposing server-side types exclusively through parse/node. The use of import() type syntax and typeof import() for function signatures avoids duplication while maintaining type safety.

src/CloudCode.ts (2)

1-189: Well-structured type definitions for Cloud Code.

The interface definitions are comprehensive and accurately model Parse Server's Cloud Code API. The organization with section comments improves readability. The ReadPreferenceOption enum correctly maps MongoDB read preference values.


306-634: JSDoc documentation is thorough.

The extensive JSDoc blocks will support documentation generation and provide helpful context for developers using these APIs.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 8, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
types/tests.ts (3)

2267-2464: Consider adding explicit type assertions for consistency.

The existing test patterns in this file extensively use // $ExpectType comments to assert expected types (see examples at lines 33-38, 75-78, 294-299). Adding similar assertions to the Cloud Code tests would improve consistency, catch type regressions, and document expected types more clearly.

For example:

ParseNode.Cloud.define('basicFunc', (request) => {
  // $ExpectType Params
  request.params;
  // $ExpectType ParseUser<Attributes> | undefined
  request.user;
  // $ExpectType boolean
  request.master;
  return 'result';
});

2279-2290: Add negative test cases to validate type safety.

Following the pattern established elsewhere in this file (see lines 566-577, 700-709), consider adding // $ExpectError test cases to ensure invalid Cloud Code usage is caught at compile time.

Examples:

// Validator with wrong field type
ParseNode.Cloud.define('invalidValidator', () => {}, {
  fields: {
    // $ExpectError
    name: { type: Boolean, required: true } // String field with Boolean type
  }
});

// Wrong request property access
ParseNode.Cloud.beforeSave('Test', (request) => {
  // $ExpectError
  request.nonExistentProperty;
});

2297-2324: Optionally add async/await patterns for completeness.

While the current tests use Promise.resolve() to test async returns, consider adding async/await patterns to better reflect real-world Cloud Code usage:

ParseNode.Cloud.beforeSave('TestClass', async (request) => {
  const result = await someAsyncOperation(request.object);
  request.object.set('processed', true);
});

This would demonstrate that async handlers are properly typed and commonly match actual implementation patterns.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b09807b and 0cc5c26.

📒 Files selected for processing (1)
  • types/tests.ts
🧰 Additional context used
🧬 Code graph analysis (1)
types/tests.ts (1)
src/RESTController.ts (1)
  • request (238-343)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build (Node 22, 22.12.0)
  • GitHub Check: build (Node 20, 20.19.0)
  • GitHub Check: build (Node 24, 24.1.0)
🔇 Additional comments (2)
types/tests.ts (2)

2260-2478: Excellent comprehensive coverage of Cloud Code server-side APIs!

The test suite thoroughly exercises the new server-side type definitions including Cloud functions, all lifecycle triggers, query triggers, auth triggers, file triggers, LiveQuery triggers, jobs, and utility functions. The browser exclusion tests properly verify that these APIs are not available on the browser Parse.Cloud.


2470-2477: Browser exclusion tests properly validate parse vs parse/node distinction.

The @ts-expect-error annotations correctly verify that server-side Cloud Code functions are not available on the browser Parse.Cloud, which aligns perfectly with the PR's module augmentation approach and objectives.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 8, 2026
@hajjarjoseph
Copy link
Contributor Author

hajjarjoseph commented Jan 8, 2026

If we add types directly to CloudCode.ts, they'd be visible in all contexts, including browser and where Parse.Cloud.define doesn't exist.

It wouldn't be visible, it would be visible in all context if you manually add it to index.d.ts similar to how you are updating node.d.ts in this PR.

Thanks for clarifying @dplewis ! I've updated the PR to follow your suggestion:

  • Moved types to src/CloudCode.ts so they auto-generate on build
  • node.d.ts handles the module augmentation for parse/node users
  • Added comprehensive type tests covering all triggers, validators, and utility functions

Yes while as you and @mtrezza mentioned, the ideal solution would be to have these types in parse-server since that's where the implementations live. But For now, this provides working type support for server-side Cloud Code

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
types/CloudCode.d.ts (1)

287-287: Fix typo in JSDoc.

The word "rquesting" should be "requesting".

📝 Proposed fix
- * If you want to replace the rquesting Parse.File with a Parse.File that is already saved, simply return the already saved Parse.File.
+ * If you want to replace the requesting Parse.File with a Parse.File that is already saved, simply return the already saved Parse.File.
src/CloudCode.ts (1)

410-410: Fix typo in JSDoc.

The word "rquesting" should be "requesting" (same issue as in types/CloudCode.d.ts).

📝 Proposed fix
- * If you want to replace the rquesting Parse.File with a Parse.File that is already saved, simply return the already saved Parse.File.
+ * If you want to replace the requesting Parse.File with a Parse.File that is already saved, simply return the already saved Parse.File.
🧹 Nitpick comments (1)
src/CloudCode.ts (1)

1-298: Consider future DRY improvement for type definitions.

The interfaces and function declarations in this file are duplicated in types/CloudCode.d.ts. While this works correctly, maintaining identical definitions in two files increases the risk of inconsistencies if one is updated without the other.

As noted in the PR discussion, ideally these types would be defined once in src/CloudCode.ts and the .d.ts file would be auto-generated during the build process. This would eliminate duplication and ensure the declaration file always matches the implementation.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0cc5c26 and 62ff1f1.

📒 Files selected for processing (2)
  • src/CloudCode.ts
  • types/CloudCode.d.ts
🧰 Additional context used
🧬 Code graph analysis (2)
src/CloudCode.ts (3)
types/CloudCode.d.ts (17)
  • FunctionRequest (5-16)
  • FunctionResponse (17-22)
  • TriggerRequest (23-36)
  • BeforeSaveRequest (37-37)
  • AfterSaveRequest (38-38)
  • BeforeDeleteRequest (39-39)
  • AfterDeleteRequest (40-40)
  • BeforeFindRequest (41-55)
  • AfterFindRequest (56-68)
  • FileTriggerRequest (69-81)
  • ConnectTriggerRequest (82-89)
  • LiveQueryEventTrigger (90-101)
  • JobRequest (102-106)
  • ValidatorField (107-114)
  • ValidatorObject (115-133)
  • HTTPOptions (134-143)
  • HTTPResponse (144-151)
types/node.d.ts (39)
  • FunctionRequest (6-6)
  • FunctionResponse (7-7)
  • TriggerRequest (8-8)
  • BeforeSaveRequest (9-9)
  • AfterSaveRequest (10-10)
  • BeforeDeleteRequest (11-11)
  • AfterDeleteRequest (12-12)
  • BeforeFindRequest (13-13)
  • AfterFindRequest (14-14)
  • FileTriggerRequest (15-15)
  • ConnectTriggerRequest (16-16)
  • LiveQueryEventTrigger (17-17)
  • JobRequest (18-18)
  • ValidatorField (19-19)
  • ValidatorObject (20-20)
  • HTTPOptions (21-21)
  • HTTPResponse (22-22)
  • ReadPreferenceOption (23-23)
  • define (26-26)
  • job (27-27)
  • beforeSave (28-28)
  • afterSave (29-29)
  • beforeDelete (30-30)
  • afterDelete (31-31)
  • beforeFind (32-32)
  • afterFind (33-33)
  • beforeLogin (34-34)
  • afterLogin (35-35)
  • afterLogout (36-36)
  • beforePasswordResetRequest (37-37)
  • beforeSaveFile (38-38)
  • afterSaveFile (39-39)
  • beforeDeleteFile (40-40)
  • afterDeleteFile (41-41)
  • beforeConnect (42-42)
  • beforeSubscribe (43-43)
  • afterLiveQueryEvent (44-44)
  • sendEmail (46-46)
  • httpRequest (45-45)
src/RESTController.ts (1)
  • request (238-343)
types/CloudCode.d.ts (1)
types/node.d.ts (39)
  • FunctionRequest (6-6)
  • FunctionResponse (7-7)
  • TriggerRequest (8-8)
  • BeforeSaveRequest (9-9)
  • AfterSaveRequest (10-10)
  • BeforeDeleteRequest (11-11)
  • AfterDeleteRequest (12-12)
  • BeforeFindRequest (13-13)
  • AfterFindRequest (14-14)
  • FileTriggerRequest (15-15)
  • ConnectTriggerRequest (16-16)
  • LiveQueryEventTrigger (17-17)
  • JobRequest (18-18)
  • ValidatorField (19-19)
  • ValidatorObject (20-20)
  • HTTPOptions (21-21)
  • HTTPResponse (22-22)
  • ReadPreferenceOption (23-23)
  • define (26-26)
  • job (27-27)
  • beforeSave (28-28)
  • afterSave (29-29)
  • beforeDelete (30-30)
  • afterDelete (31-31)
  • beforeFind (32-32)
  • afterFind (33-33)
  • beforeLogin (34-34)
  • afterLogin (35-35)
  • afterLogout (36-36)
  • beforePasswordResetRequest (37-37)
  • beforeSaveFile (38-38)
  • afterSaveFile (39-39)
  • beforeDeleteFile (40-40)
  • afterDeleteFile (41-41)
  • beforeConnect (42-42)
  • beforeSubscribe (43-43)
  • afterLiveQueryEvent (44-44)
  • sendEmail (46-46)
  • httpRequest (45-45)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build (Node 20, 20.19.0)
  • GitHub Check: build (Node 24, 24.1.0)
  • GitHub Check: build (Node 22, 22.12.0)
🔇 Additional comments (4)
types/CloudCode.d.ts (3)

1-133: LGTM! Comprehensive interface definitions.

The interfaces are well-structured and cover all major Cloud Code request types. The use of type-only imports is good practice. Property definitions match Parse Server's actual API.


134-158: LGTM! HTTP types and enum are correct.

The HTTP interfaces properly define the Parse.Cloud.httpRequest API including callback-based error handling. The ReadPreferenceOption enum correctly matches MongoDB read preference constants.


159-185: LGTM! Function declarations are correctly typed.

All Cloud Code trigger and utility functions are properly declared with appropriate:

  • Generic type parameters for ParseObject subclasses
  • Handler signatures with correct request types
  • Optional validator parameters where applicable
  • Return types matching Parse Server's behavior (e.g., beforeSave can return modified object, after hooks return void)
src/CloudCode.ts (1)

6-8: Nice addition of section comments for organization.

The section headers improve code readability and make it easier to navigate the file. This is a good practice for maintainability.

Also applies to: 122-124, 155-157, 179-181, 191-193, 300-302

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 8, 2026
@dplewis
Copy link
Member

dplewis commented Jan 8, 2026

We want to ensure backwards compatibility with @types/parse, can you add these test cases if you already haven't https://github.com/DefinitelyTyped/DefinitelyTyped/blob/b23a36e669fa127d1035e22ca93faab85b98e49f/types/parse/parse-tests.ts#L557

@hajjarjoseph
Copy link
Contributor Author

hajjarjoseph commented Jan 8, 2026

We want to ensure backwards compatibility with @types/parse, can you add these test cases if you already haven't https://github.com/DefinitelyTyped/DefinitelyTyped/blob/b23a36e669fa127d1035e22ca93faab85b98e49f/types/parse/parse-tests.ts#L557

Those cases are already in types/tests.ts: the browser Parse.Cloud.run expectations live at types/tests.ts, and the server-onlyParseNode.Cloud triggers and utilities are covered also at types/tests.ts.

Running npm run test:types exercises them via @typescript-eslint/expect-type, so any future drift from the DefinitelyTyped contract will fail the build (I even flipped one $ExpectType temporarily to confirm it errors).

@dplewis
Copy link
Member

dplewis commented Jan 8, 2026

If you look at the file I sent there are tests for generics, interfaces, expected-types, etc. I would recommend replacing your tests with those (except the browser tests)

src/CloudCode.ts Outdated

// ============================================================================
// Request Interfaces
// ============================================================================
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove these type / style of comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

src/CloudCode.ts Outdated

// ============================================================================
// JSDoc Documentation (for documentation generation)
// ============================================================================
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move the documentation to their approprate function and ensure jsdocs run and the docs are viewable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Moved JSDoc documentation directly above each function declaration in CloudCode.ts
  • Verified npm run docs runs successfully without errors

- Move JSDoc documentation directly above each function declaration
- Remove section divider comments (// ====)
- Merge test_cloud_server_functions into test_cloud_functions
- Use ParseNode.Cloud for server-side tests
- Add proper descriptions to @ts-expect-error comments
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/CloudCode.ts (1)

575-588: Add individual @param tags for sendEmail data properties to satisfy linter.

The static analysis tool reports missing @param declarations for the nested properties of data. Expanding the JSDoc will improve documentation clarity and resolve the lint failures.

📝 Proposed JSDoc fix
 /**
  * Sends an email.
  *
  * **Available in Cloud Code only.**
  *
- * @param data The email data including to, from, subject, text, and html.
+ * @param data The email data object.
+ * @param data.from The sender email address.
+ * @param data.to The recipient email address.
+ * @param data.subject The email subject.
+ * @param data.text The plain text content of the email.
+ * @param data.html The HTML content of the email.
  */
 export declare function sendEmail(data: {
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 62ff1f1 and 17da4a8.

📒 Files selected for processing (2)
  • src/CloudCode.ts
  • types/tests.ts
🧰 Additional context used
🧬 Code graph analysis (2)
types/tests.ts (1)
src/RESTController.ts (1)
  • request (238-343)
src/CloudCode.ts (1)
types/CloudCode.d.ts (17)
  • FunctionRequest (5-16)
  • FunctionResponse (17-22)
  • TriggerRequest (23-36)
  • BeforeSaveRequest (37-37)
  • AfterSaveRequest (38-38)
  • BeforeDeleteRequest (39-39)
  • AfterDeleteRequest (40-40)
  • BeforeFindRequest (41-55)
  • AfterFindRequest (56-68)
  • FileTriggerRequest (69-81)
  • ConnectTriggerRequest (82-89)
  • LiveQueryEventTrigger (90-101)
  • JobRequest (102-106)
  • ValidatorField (107-114)
  • ValidatorObject (115-133)
  • HTTPOptions (134-143)
  • HTTPResponse (144-151)
🪛 GitHub Check: Lint
src/CloudCode.ts

[failure] 580-580:
Missing @param "data.html"


[failure] 580-580:
Missing @param "data.text"


[failure] 580-580:
Missing @param "data.subject"


[failure] 580-580:
Missing @param "data.to"


[failure] 580-580:
Missing @param "data.from"


[warning] 575-575:
Missing JSDoc @param "data.html" declaration


[warning] 575-575:
Missing JSDoc @param "data.text" declaration


[warning] 575-575:
Missing JSDoc @param "data.subject" declaration


[warning] 575-575:
Missing JSDoc @param "data.to" declaration


[warning] 575-575:
Missing JSDoc @param "data.from" declaration

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build (Node 24, 24.1.0)
  • GitHub Check: build (Node 22, 22.12.0)
  • GitHub Check: build (Node 20, 20.19.0)
🔇 Additional comments (11)
types/tests.ts (3)

549-582: LGTM!

The Parse.Cloud.run tests thoroughly cover generic signatures, parameter validation, and master key usage. The @ts-expect-error annotations correctly enforce type constraints for required parameters and type mismatches.


583-670: LGTM!

Comprehensive trigger tests covering all lifecycle hooks (save, delete, find, login, logout) and file triggers. The beforeSave test properly validates the original vs current object pattern for immutable field checks, and the beforeFind tests correctly exercise all ReadPreferenceOption enum values.


671-734: LGTM!

The define tests comprehensively cover the ValidatorObject options. The browser exclusion tests correctly enforce that server-only APIs (define, beforeSave, job, httpRequest) are unavailable on the browser Parse.Cloud namespace. Note that startJob, getJobStatus, and getJobsData correctly remain on Parse.Cloud as they are client-callable APIs.

src/CloudCode.ts (8)

1-31: LGTM!

Type imports are correctly used, and the FunctionRequest<T> and FunctionResponse interfaces align with the corresponding declarations in types/CloudCode.d.ts.


33-63: LGTM!

The TriggerRequest<T> interface and related type aliases are well-structured and match the reference definitions. The JSDoc documentation adequately describes the request properties.


65-118: LGTM!

The BeforeFindRequest, AfterFindRequest, and FileTriggerRequest interfaces are correctly defined. The FileTriggerRequest intentionally omits the context property, which aligns with the reference definitions and reflects the different context model for file triggers.


120-160: LGTM!

The ConnectTriggerRequest, LiveQueryEventTrigger, and JobRequest interfaces are correctly defined. The distinction between useMasterKey (in connect/LiveQuery contexts) and master (in trigger contexts) is intentional and matches the Parse Server implementation.


162-235: LGTM!

The validation interfaces (ValidatorField, ValidatorObject) are comprehensive. The HTTPOptions includes both promise-style and callback-style (success/error) patterns for backwards compatibility. The ReadPreferenceOption enum values correctly use MongoDB-standard uppercase naming.


237-372: LGTM!

The function declarations for define, job, and object lifecycle hooks (beforeSave, afterSave, beforeDelete, afterDelete) are well-typed with appropriate generics, optional validators, and clear JSDoc documentation. The return type differences (e.g., beforeSave can return the modified object) correctly reflect the Parse Server behavior.


374-573: LGTM!

The find hooks, auth hooks, file triggers, and LiveQuery triggers are well-defined. The afterLogout correctly uses TriggerRequest without the ParseUser generic (the session is already invalidated). The beforeSaveFile appropriately allows returning a modified ParseFile.


590-611: LGTM!

The httpRequest function declaration is well-documented with a practical example. The signature correctly types the options and return value.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 8, 2026
@hajjarjoseph
Copy link
Contributor Author

If you look at the file I sent there are tests for generics, interfaces, expected-types, etc. I would recommend replacing your tests with those (except the browser tests)

merged my test_cloud_server_functions() tests into the existing test_cloud_functions ( using the existing one and ParseNode.Cloud for server-side functions while keeping browser exclusion tests at the end

async function test_cloud_functions() {
  // $ExpectType any
  await Parse.Cloud.run('SomeFunction');

  // $ExpectType any
  await Parse.Cloud.run('SomeFunction', { something: 'whatever' });

  // $ExpectType any
  await Parse.Cloud.run('SomeFunction', null, { useMasterKey: true });

  // $ExpectType boolean
  await Parse.Cloud.run<() => boolean>('SomeFunction');

  // $ExpectType boolean
  await Parse.Cloud.run<() => boolean>('SomeFunction', null);

  // $ExpectType boolean
  await Parse.Cloud.run<() => boolean>('SomeFunction', null, { useMasterKey: true });

  // $ExpectType number
  await Parse.Cloud.run<(params: { paramA: string }) => number>('SomeFunction', { paramA: 'hello' });

  // @ts-expect-error - params are required
  await Parse.Cloud.run<(params: { paramA: string }) => number>('SomeFunction');

  // @ts-expect-error - wrong param name
  await Parse.Cloud.run<(params: { paramA: string }) => number>('SomeFunction', { paramZ: 'hello' });

  // @ts-expect-error - params are required, null not allowed
  await Parse.Cloud.run<(params: { paramA: string }) => number>('SomeFunction', null, { useMasterKey: true });

  // @ts-expect-error - params must be object not string
  await Parse.Cloud.run<(params: string) => any>('SomeFunction', 'hello');

  ParseNode.Cloud.afterDelete('MyCustomClass', request => {
    request.object;
    request.user;
  });

  ParseNode.Cloud.afterSave('MyCustomClass', request => {
    if (!request.context) {
      throw new Error('Request context should be defined');
    }
    request.object;
  });

  ParseNode.Cloud.beforeDelete('MyCustomClass', request => {
    request.object;
  });

  ParseNode.Cloud.beforeSave('MyCustomClass', request => {
    if (request.object.isNew()) {
      if (!request.object.has('immutable')) throw new Error('Field immutable is required');
    } else {
      const original = request.original;
      if (original == null) {
        throw new Error('Original must be defined for an existing object');
      }
      if (original.get('immutable') !== request.object.get('immutable')) {
        throw new Error('This field cannot be changed');
      }
    }
    if (!request.context) {
      throw new Error('Request context should be defined');
    }
  });

  ParseNode.Cloud.beforeFind('MyCustomClass', request => {
    request.query;
    request.user;
    request.master;
    request.count;
    request.isGet;

    request.readPreference = ParseNode.Cloud.ReadPreferenceOption.Primary;
    request.readPreference = ParseNode.Cloud.ReadPreferenceOption.PrimaryPreferred;
    request.readPreference = ParseNode.Cloud.ReadPreferenceOption.Secondary;
    request.readPreference = ParseNode.Cloud.ReadPreferenceOption.SecondaryPreferred;
    request.readPreference = ParseNode.Cloud.ReadPreferenceOption.Nearest;
  });

  ParseNode.Cloud.beforeFind('MyCustomClass', request => {
    request.query;
    return new Parse.Query('QueryMe!');
  });

  ParseNode.Cloud.afterFind('MyCustomClass', request => {
    request.results;
    return request.results;
  });

  ParseNode.Cloud.beforeLogin(request => {
    request.object;
    request.user;
  });

  ParseNode.Cloud.afterLogin(request => {
    request.object;
  });

  ParseNode.Cloud.afterLogout(request => {
    request.object;
  });

  ParseNode.Cloud.beforeSaveFile(request => {
    request.file;
    request.fileSize;
    return new Parse.File('myFile.txt', { base64: '' });
  });

  ParseNode.Cloud.beforeSaveFile(request => {
    request.file;
  });

  ParseNode.Cloud.beforeDeleteFile(request => {
    request.file;
  });

  ParseNode.Cloud.afterDeleteFile(request => {
    request.file;
  });

  ParseNode.Cloud.define('AFunc', request => {
    request.params;
    return 'Some result';
  });

  ParseNode.Cloud.define(
    'AFunc',
    request => {
      request.params;
      return 'Some result';
    },
    {
      requireUser: true,
      requireMaster: true,
      validateMasterKey: true,
      skipWithMasterKey: true,
      requireAnyUserRoles: ['a'],
      requireAllUserRoles: ['a'],
      fields: {
        name: {
          type: String,
          constant: true,
          default: true,
          options: [],
          error: 'invalid field.',
        },
      },
      requireUserKeys: {
        name: {
          type: String,
          constant: true,
          default: true,
          options: [],
          error: 'invalid field.',
        },
      },
    },
  );

  ParseNode.Cloud.define('AFunc', request => {
    request.params;
    request.params.anything;
  });

  ParseNode.Cloud.job('AJob', request => {
    request.params;
    request.message('Message to associate with this job run');
  });

  void Parse.Cloud.startJob('AJob', {}).then(v => v);

  void Parse.Cloud.getJobStatus('AJob').then(v => v);

  void Parse.Cloud.getJobsData().then(v => v);

  // @ts-expect-error - define should not exist on browser Parse.Cloud
  Parse.Cloud.define('test', () => {});
  // @ts-expect-error - beforeSave should not exist on browser Parse.Cloud
  Parse.Cloud.beforeSave('Test', () => {});
  // @ts-expect-error - job should not exist on browser Parse.Cloud
  Parse.Cloud.job('test', () => {});
  // @ts-expect-error - httpRequest should not exist on browser Parse.Cloud
  void Parse.Cloud.httpRequest({ url: '' });
}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
types/CloudCode.d.ts (1)

60-74: Consider using ReadPreferenceOption enum for stronger typing.

The readPreference field is currently typed as string, but the ReadPreferenceOption enum (lines 214-220) defines the valid MongoDB read preference values. Using the enum would prevent invalid values and improve type safety.

♻️ Suggested type improvement
 export interface BeforeFindRequest<T extends ParseObject = ParseObject> {
     installationId?: string;
     master: boolean;
     user?: ParseUser;
     query: ParseQuery<T>;
     ip: string;
     headers: Record<string, string>;
     triggerName: string;
     log: any;
     isGet: boolean;
     config: any;
     context: Record<string, unknown>;
-    readPreference?: string;
+    readPreference?: ReadPreferenceOption | `${ReadPreferenceOption}`;
     count?: boolean;
 }

Note: The union with template literal type allows both enum values and their string equivalents for flexibility.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 469b4db and 685cf2d.

📒 Files selected for processing (1)
  • types/CloudCode.d.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build (Node 22, 22.12.0)
  • GitHub Check: build (Node 24, 24.1.0)
  • GitHub Check: build (Node 20, 20.19.0)
🔇 Additional comments (6)
types/CloudCode.d.ts (6)

1-4: LGTM!

The type-only imports are appropriate and cover all the Parse types needed for the Cloud Code type definitions.


5-29: Well-structured request and response interfaces.

The generic FunctionRequest<T> interface properly types cloud function parameters, and FunctionResponse provides a clear fluent API for responses.


30-59: Clean trigger type hierarchy.

The generic TriggerRequest<T extends ParseObject> interface and its type aliases provide strong typing for object lifecycle hooks. The structure correctly includes both current and original object states.


88-140: Comprehensive coverage of specialized trigger types.

The file, connection, and LiveQuery trigger interfaces correctly capture their respective contexts. The naming difference (useMasterKey vs master) in ConnectTriggerRequest likely reflects Parse Server's actual API.


221-523: Comprehensive and well-typed Cloud Code function declarations.

The function signatures correctly cover the entire Parse Server Cloud Code API:

  • Generics appropriately constrain class-based hooks
  • Return types match expected behavior (e.g., triggers can return modified objects, handlers return void/Promise)
  • The className: string | (new () => T) pattern supports both string names and class constructors
  • Validator parameters are consistently optional
  • JSDoc documentation provides clear guidance and examples

187-196: Remove the success and error callback properties from the HTTPOptions interface.

The HTTPOptions interface includes success and error callback properties, but these are not documented in the JSDoc comments (which only mention body, followRedirects, headers, method, params, and url), not demonstrated in any examples, and have no usage throughout the codebase. The httpRequest function exclusively uses a Promise-based API. These callback properties should be removed as they represent either legacy dead code or accidental additions that don't match the actual API behavior.

Likely an incorrect or invalid review comment.

@hajjarjoseph hajjarjoseph requested a review from dplewis January 10, 2026 09:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parse.Coud incomplete typings

3 participants