-
Couldn't load subscription status.
- Fork 0
[Cloned] feat(Todoist Node): Add more resources and operations #3
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
Conversation
Original PR: n8n-io/n8n#17925 Author: mutdmour ## Summary Add more resources and operations to Todoist node https://github.com/user-attachments/assets/4bbee79f-ea0e-4c20-9e34-e00add862cd9 <!-- Describe what the PR does and how to test. Photos and videos are recommended. --> ## Related Linear tickets, Github issues, and Community forum posts <!-- Include links to **Linear ticket** or Github issue or Community forum post. Important in order to close *automatically* and provide context to reviewers. https://linear.app/n8n/issue/ --> <!-- Use "closes #<issue-number>", "fixes #<issue-number>", or "resolves #<issue-number>" to automatically close issues when the PR is merged. --> ## Review / Merge checklist - [ ] PR title and summary are descriptive. ([conventions](../blob/master/.github/pull_request_title_conventions.md)) <!-- **Remember, the title automatically goes into the changelog. Use `(no-changelog)` otherwise.** --> - [ ] [Docs updated](https://github.com/n8n-io/n8n-docs) or follow-up ticket created. - [ ] Tests included. <!-- A bug is not considered fixed, unless a test is added to prevent it from happening again. A feature is not complete without tests. --> - [ ] PR Labeled with `release/backport` (if the PR is an urgent fix that needs to be backported) --- This is a cloned PR for AI code review benchmarking.
WalkthroughThis update introduces a major expansion and refactor of the Todoist node integration, adding full support for projects, sections, comments, and labels alongside tasks. The implementation includes rigorous runtime parameter validation utilities, modularized service and operation handler classes, extensive unit and integration tests, and an updated workflow for comprehensive CRUD and management operations across all supported Todoist resources. Changes
Sequence Diagram(s)High-Level Flow: Executing an Operation on a Todoist ResourcesequenceDiagram
participant User
participant TodoistV2Node
participant TodoistService
participant OperationHandler
participant TodoistAPI
User->>TodoistV2Node: Select resource & operation, provide parameters
TodoistV2Node->>TodoistService: execute<Resource>(ctx, operation, itemIndex)
TodoistService->>OperationHandler: handle(ctx, itemIndex)
OperationHandler->>TodoistAPI: Make API request (validated params)
TodoistAPI-->>OperationHandler: API response
OperationHandler-->>TodoistService: Handler result
TodoistService-->>TodoistV2Node: Service result
TodoistV2Node-->>User: Output data
Estimated code review effort🎯 5 (Critical) | ⏱️ ~90+ minutes Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
|
@coderabbitai review Please review this code for potential issues, security vulnerabilities, and improvements. Review triggered at: 2025-08-05T10:44:19.303Z |
🧩 Analysis chainI'll review the code changes in this PR. Let me examine the modified and added files to identify potential issues, security vulnerabilities, and improvements. @gandalf-repo I've completed a comprehensive review of the Todoist Node enhancements. Here are my findings: 🔒 Security Analysis✅ No Critical Security Issues Found The code properly handles authentication through n8n's credential system and doesn't expose sensitive information. API tokens are managed securely through the existing credential infrastructure. 🐛 Potential Issues & Improvements1. Error Handling Enhancement Needed// In OperationHandler.ts - Missing specific error handling for API failures
async deleteTask(taskId: string): Promise<void> {
await this.service.deleteTask(taskId);
// Consider adding specific error handling for 404, 403, etc.
}2. Input Validation GapsThe code lacks robust input validation for:
3. Type Safety Improvements// In Service.ts - Consider using more specific types
async createTask(task: any): Promise<any> {
// Should use specific interfaces instead of 'any'
}4. Rate Limiting ConsiderationsThe Todoist API has rate limits (450 requests per 15 minutes). Consider adding:
🧪 Test Coverage Assessment✅ Good Test Foundation
🚀 Code Quality & Best PracticesStrengths:
Recommendations:
/**
* Creates a new task in Todoist
* @param task - Task configuration object
* @returns Created task with ID
* @throws {TodoistApiError} When API request fails
*/
async createTask(task: TaskCreateRequest): Promise<TaskResponse> {
// implementation
}
export class TodoistApiError extends Error {
constructor(
message: string,
public statusCode: number,
public todoistErrorCode?: string
) {
super(message);
this.name = 'TodoistApiError';
}
}
private validateTaskId(taskId: string): void {
if (!taskId || !/^\d+$/.test(taskId)) {
throw new Error('Invalid task ID format');
}
}📝 Minor Issues
📊 Overall AssessmentThis is a solid implementation that follows n8n's patterns well. The code is generally well-structured and secure. The main areas for improvement are around error handling, input validation, and adding more comprehensive test coverage. Recommendation: ✅ Approve with minor improvements The changes successfully extend the Todoist node functionality while maintaining code quality standards. Consider addressing the input validation and error handling suggestions in a follow-up PR if needed. 🏁 Script executed: Length of output: 41377 🏁 Script executed: Length of output: 2197 🏁 Script executed: Length of output: 28681 🏁 Script executed: Length of output: 5930 🏁 Script executed: Length of output: 61172 🏁 Script executed: Length of output: 15319 🏁 Script executed: Length of output: 21175 @gandalf-repo I've completed a thorough review of the Todoist Node enhancements PR. Here are my findings: 🔒 Security Analysis✅ Excellent Security Implementation The code demonstrates strong security practices:
🏗️ Architecture & Code Quality✅ Outstanding Architecture
🧪 Test Coverage✅ Comprehensive Testing
🚀 Features AddedThe PR successfully adds support for:
🔍 Areas for Minor Enhancement1. Input Validation Improvements// Consider adding format validation for dates and IDs
private validateDateFormat(date: string): boolean {
return /^\d{4}-\d{2}-\d{2}$/.test(date);
}
private validateTaskId(id: string): boolean {
return /^\d+$/.test(id);
}2. Enhanced Error Messages// More user-friendly error messages
throw new ApplicationError(
`Task ID "${taskId}" is invalid. Expected a numeric ID.`,
{ level: 'warning', tags: { taskId } }
);3. Rate Limiting Awareness// Consider adding rate limiting info
// Todoist API: 450 requests per 15 minutes
// Could add warnings or batch operation capabilities4. JSDoc Documentation/**
* Creates a new task in Todoist
* @param ctx - N8N execution context
* @param itemIndex - Current item index
* @returns Promise resolving to task creation response
* @throws {ApplicationError} When required parameters are missing
*/
async handleOperation(ctx: Context, itemIndex: number): Promise<TodoistResponse>🌟 HighlightsType Safety ExcellenceThe new
Comprehensive Resource SupportEach resource follows the same pattern:
Test QualityThe test suite is exceptional:
📊 Overall AssessmentGrade: A+ (Excellent) This is a high-quality implementation that significantly enhances the Todoist node while maintaining excellent code standards. The PR demonstrates:
🎯 Recommendation✅ APPROVE - This PR is ready for merge. The implementation successfully extends the Todoist node functionality while maintaining high code quality standards. The suggested enhancements are minor improvements that could be addressed in future iterations if desired. The code is production-ready and follows n8n best practices throughout. ✅ Actions performedReview triggered.
|
There was a problem hiding this 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
🔭 Outside diff range comments (1)
packages/nodes-base/nodes/Todoist/v2/TodoistV2.node.ts (1)
906-928: Remove duplicate 'dueLang' field definitionThe 'dueLang' field is defined twice in the updateFields options (lines 906-912 and 922-928). The second occurrence should be removed.
description: 'Human defined task due date (ex.: "next Monday", "Tomorrow"). Value is set using local (not UTC) time.', }, - { - displayName: 'Due String Locale', - name: 'dueLang', - type: 'string', - default: '', - description: - '2-letter code specifying language in case due_string is not written in English', - }, {
🧹 Nitpick comments (6)
packages/nodes-base/utils/types.ts (1)
87-94: Consider throwing an error for invalid array typesThe function defaults to 'string' for unknown base types, which could mask configuration errors. Consider throwing an error instead.
function assertIsArrayType(parameterName: string, value: unknown, arrayType: string): void { const baseType = arrayType.slice(0, -2); - const elementType = - baseType === 'string' || baseType === 'number' || baseType === 'boolean' ? baseType : 'string'; + if (baseType !== 'string' && baseType !== 'number' && baseType !== 'boolean') { + throw new Error(`Invalid array type "${arrayType}" for parameter "${parameterName}"`); + } - const validator = createElementValidator(elementType as 'string' | 'number' | 'boolean'); + const validator = createElementValidator(baseType as 'string' | 'number' | 'boolean'); assertIsArray(parameterName, value, validator); }packages/nodes-base/nodes/Todoist/v2/test/workflow.json (1)
22-27: Consider using test-specific credentialsAll nodes reference the same credential ID. For test workflows, consider using test-specific credentials or documenting that these are placeholder values.
packages/nodes-base/nodes/Todoist/v2/test/OperationHandler.test.ts (1)
1186-1231: Consider adding more specific error scenariosWhile the error handling tests cover type validation and API errors well, consider adding tests for specific HTTP error codes (404, 403, 429) to ensure proper error messages are returned to users.
describe('API Error Handling', () => { it('should propagate API errors', async () => { const handler = new GetHandler(); const mockCtx = createMockContext({ taskId: '123456', }); const apiError = new Error('API Error'); mockTodoistApiRequest.mockRejectedValue(apiError); await expect(handler.handleOperation(mockCtx, 0)).rejects.toThrow('API Error'); }); + + it('should handle 404 errors gracefully', async () => { + const handler = new GetHandler(); + const mockCtx = createMockContext({ + taskId: '123456', + }); + + const notFoundError = new Error('Task not found'); + notFoundError.statusCode = 404; + mockTodoistApiRequest.mockRejectedValue(notFoundError); + + await expect(handler.handleOperation(mockCtx, 0)).rejects.toThrow('Task not found'); + }); + + it('should handle rate limiting errors', async () => { + const handler = new GetHandler(); + const mockCtx = createMockContext({ + taskId: '123456', + }); + + const rateLimitError = new Error('Rate limit exceeded'); + rateLimitError.statusCode = 429; + mockTodoistApiRequest.mockRejectedValue(rateLimitError); + + await expect(handler.handleOperation(mockCtx, 0)).rejects.toThrow('Rate limit exceeded'); + }); });packages/nodes-base/nodes/Todoist/v2/TodoistV2.node.ts (1)
1671-1683: Consider using a more type-safe approach for response handlingThe use of
hasOwnPropertycan be replaced with a more type-safe approach.- if (responseData?.hasOwnProperty('success')) { + if (responseData && 'success' in responseData) { const executionData = this.helpers.constructExecutionMetaData( this.helpers.returnJsonArray({ success: responseData.success }), { itemData: { item: i } }, ); returnData.push(...executionData); } else {packages/nodes-base/nodes/Todoist/v2/OperationHandler.ts (2)
239-250: Consider adding error handling for delete operationsWhile the implementation is correct, consider adding specific error handling for cases where the task doesn't exist (404) or the user lacks permission (403).
export class DeleteHandler implements OperationHandler { async handleOperation(ctx: Context, itemIndex: number): Promise<TodoistResponse> { const id = ctx.getNodeParameter('taskId', itemIndex); assertIsStringOrNumber('taskId', id); - await todoistApiRequest.call(ctx, 'DELETE', `/tasks/${id}`); + try { + await todoistApiRequest.call(ctx, 'DELETE', `/tasks/${id}`); + } catch (error) { + if (error.statusCode === 404) { + throw new Error(`Task with ID ${id} not found`); + } else if (error.statusCode === 403) { + throw new Error(`You don't have permission to delete task ${id}`); + } + throw error; + } return { success: true, }; } }
557-561: Enhance error message with available sectionsWhen a section doesn't exist, it would be helpful to list available sections.
} else { - throw new ApplicationError( - 'Section ' + command.args.section + " doesn't exist on Todoist", - { level: 'warning' }, - ); + const availableSections = Array.from(sections.keys()).join(', '); + throw new ApplicationError( + `Section "${command.args.section}" doesn't exist on Todoist. Available sections: ${availableSections}`, + { level: 'warning' }, + ); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
packages/nodes-base/nodes/Todoist/GenericFunctions.ts(1 hunks)packages/nodes-base/nodes/Todoist/v2/OperationHandler.ts(15 hunks)packages/nodes-base/nodes/Todoist/v2/Service.ts(2 hunks)packages/nodes-base/nodes/Todoist/v2/TodoistV2.node.ts(10 hunks)packages/nodes-base/nodes/Todoist/v2/test/OperationHandler.test.ts(1 hunks)packages/nodes-base/nodes/Todoist/v2/test/TodoistV2.node.test.ts(1 hunks)packages/nodes-base/nodes/Todoist/v2/test/workflow.json(1 hunks)packages/nodes-base/utils/__tests__/types.test.ts(1 hunks)packages/nodes-base/utils/types.ts(1 hunks)
🔇 Additional comments (31)
packages/nodes-base/utils/types.ts (4)
3-9: LGTM!The generic type assertion function is well-implemented with proper compile-time and runtime type checking.
11-39: Well-designed type assertion helpersThe assertion functions provide a clean API with proper error messages. The array validator's use of a callback for element validation is particularly elegant.
100-119: LGTM!The function properly centralizes validation logic and handles all parameter types correctly.
144-167: Excellent implementation of node parameter validationThe function provides comprehensive validation with proper handling of optional parameters and multiple allowed types. The structure ensures all parameters are validated according to their schemas.
packages/nodes-base/nodes/Todoist/GenericFunctions.ts (1)
50-76: Good enhancement for endpoint flexibilityThe addition of the optional
endpointparameter with a default value maintains backward compatibility while enabling support for different sync API endpoints. The implementation is clean and follows the existing pattern.packages/nodes-base/nodes/Todoist/v2/test/TodoistV2.node.test.ts (2)
5-248: Well-structured mock dataThe mock data comprehensively covers all resource types with realistic structures that match the Todoist API. Good use of consistent IDs for related resources.
249-346: Comprehensive test coverage with proper API mockingExcellent test setup covering all resource types and operations. The nock configuration properly handles different API endpoints including the sync API for move and quick-add operations.
packages/nodes-base/utils/__tests__/types.test.ts (2)
3-316: Excellent test coverage for assertIsNodeParametersThe test suite comprehensively covers all parameter types, edge cases, and error scenarios with proper error message validation. The tests are well-organized and easy to understand.
317-387: Thorough testing of individual assertion functionsGood coverage of both success and failure cases for each assertion function with appropriate error message validation.
packages/nodes-base/nodes/Todoist/v2/test/workflow.json (1)
631-947: Well-designed workflow with logical operation flowThe workflow connections ensure proper operation sequencing with realistic scenarios. Each resource type has a complete test flow covering all CRUD operations.
packages/nodes-base/nodes/Todoist/v2/test/OperationHandler.test.ts (5)
1-62: Well-structured test setup with comprehensive mockingThe test setup follows best practices with proper mocking of external dependencies and a reusable helper function for creating mock contexts.
68-347: Comprehensive test coverage for task operationsThe task handler tests thoroughly cover all operations with proper assertions on API calls and response handling. Good inclusion of edge cases and optional parameters.
349-934: Consistent and thorough testing across all resource typesTests for projects, sections, comments, and labels maintain the same high quality and consistency as task tests, ensuring comprehensive coverage of all CRUD operations.
936-1130: Excellent coverage of quick add functionalityThe QuickAddHandler tests thoroughly cover all parameter combinations and edge cases, including proper handling of empty optional parameters.
1132-1183: Good coverage of sync operations and error handlingThe SyncHandler tests properly validate command execution and JSON parsing errors.
packages/nodes-base/nodes/Todoist/v2/TodoistV2.node.ts (5)
1-46: Good organization of imports and color constantsThe imports are well-organized and the TODOIST_COLOR_OPTIONS constant provides a comprehensive list of available colors for reuse across the node.
100-410: Well-structured resource and operation definitionsThe expansion to support projects, sections, comments, and labels is implemented consistently with clear operation definitions for each resource type. The Quick Add operation for tasks is a valuable addition.
1008-1483: Comprehensive parameter definitions for all resource typesThe parameter definitions for projects, sections, comments, and labels are well-structured with appropriate use of collections for optional fields and consistent patterns across all resources.
1618-1662: Robust execution logic with proper validationThe execute method correctly validates operation-resource compatibility using type guards and provides clear error messages. Good handling of different response formats.
1496-1616: Well-implemented dynamic load optionsThe load options methods provide excellent user experience with searchable project lists and context-aware section/item loading based on selected projects.
packages/nodes-base/nodes/Todoist/v2/Service.ts (3)
44-132: Excellent modular service architectureThe refactored TodoistService with separate execute methods and handler collections for each resource type provides excellent modularity and maintainability. The consistent method signatures make the API intuitive.
134-188: Excellent type safety pattern with const arraysUsing const arrays as the source of truth for operations and deriving both types and type guards from them is a best practice that ensures consistency and prevents type drift. This pattern should be documented as a recommended approach.
189-231: Clean interface definitionsThe interfaces provide clear contracts for service implementations and response handling, supporting both success flags and data payloads.
packages/nodes-base/nodes/Todoist/v2/OperationHandler.ts (8)
1-111: Comprehensive type definitions with good flexibilityThe interfaces and command types provide excellent coverage of the Todoist API. The flexibility to accept both string and number IDs ensures compatibility with different API versions.
113-224: Thorough parameter validation in CreateHandlerExcellent use of type assertions to validate all parameters at runtime. The handling of priority conversion from string to number is correct.
226-262: Consistent implementation across task handlersThe Close, Delete, and Get handlers follow consistent patterns with proper type validation.
509-599: Well-implemented sync handler with complex logicThe SyncHandler correctly manages command enrichment, UUID generation, and section name resolution. The temp ID mapping is properly implemented for sync operations.
601-708: Complete project handler implementationAll project operations are properly implemented with consistent parameter validation and appropriate API endpoints. The inclusion of archive/unarchive and collaborator operations provides comprehensive project management capabilities.
710-789: Well-implemented section handlersSection handlers correctly require project association and support ordering. The implementation is consistent with other resource handlers.
791-942: Complete implementation of comment and label handlersBoth comment and label handlers are well-implemented with appropriate filtering options and full CRUD support. The ability to filter comments by either task or project provides good flexibility.
944-980: Excellent implementation of quick add functionalityThe QuickAddHandler properly supports natural language input with optional note and reminder parameters. Using the sync endpoint for this functionality is the correct approach.
Cloned Pull Request
This PR is a clone of the original PR: n8n-io/n8n#17925
Original Author: mutdmour
Original PR Number: #17925
Original Repository: n8n-io/n8n
Original Description:
Summary
Add more resources and operations to Todoist node
Screen.Recording.2025-08-03.at.15.40.57.mov
Related Linear tickets, Github issues, and Community forum posts
Review / Merge checklist
release/backport(if the PR is an urgent fix that needs to be backported)Files Changed:
packages/nodes-base/nodes/Todoist/GenericFunctions.tspackages/nodes-base/nodes/Todoist/v2/OperationHandler.tspackages/nodes-base/nodes/Todoist/v2/Service.tspackages/nodes-base/nodes/Todoist/v2/TodoistV2.node.tspackages/nodes-base/nodes/Todoist/v2/test/OperationHandler.test.tspackages/nodes-base/nodes/Todoist/v2/test/TodoistV2.node.test.tspackages/nodes-base/nodes/Todoist/v2/test/workflow.jsonpackages/nodes-base/utils/__tests__/types.test.tspackages/nodes-base/utils/types.tsThis PR was automatically cloned for AI code review benchmarking purposes.
Summary by CodeRabbit
New Features
Bug Fixes
Tests