vikunja-mcp-ng 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +123 -0
- package/dist/auth/AuthManager.d.ts +63 -0
- package/dist/auth/AuthManager.d.ts.map +1 -0
- package/dist/auth/AuthManager.js +137 -0
- package/dist/auth/AuthManager.js.map +1 -0
- package/dist/auth/index.d.ts +7 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +14 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/permissions.d.ts +60 -0
- package/dist/auth/permissions.d.ts.map +1 -0
- package/dist/auth/permissions.js +173 -0
- package/dist/auth/permissions.js.map +1 -0
- package/dist/client/VikunjaClientFactory.d.ts +41 -0
- package/dist/client/VikunjaClientFactory.d.ts.map +1 -0
- package/dist/client/VikunjaClientFactory.js +58 -0
- package/dist/client/VikunjaClientFactory.js.map +1 -0
- package/dist/client.d.ts +70 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +136 -0
- package/dist/client.js.map +1 -0
- package/dist/config/ConfigurationManager.d.ts +106 -0
- package/dist/config/ConfigurationManager.d.ts.map +1 -0
- package/dist/config/ConfigurationManager.js +509 -0
- package/dist/config/ConfigurationManager.js.map +1 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +36 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/secrets.d.ts +33 -0
- package/dist/config/secrets.d.ts.map +1 -0
- package/dist/config/secrets.js +90 -0
- package/dist/config/secrets.js.map +1 -0
- package/dist/config/types.d.ts +1113 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +189 -0
- package/dist/config/types.js.map +1 -0
- package/dist/formatters/BatchImportResponseFormatter.d.ts +89 -0
- package/dist/formatters/BatchImportResponseFormatter.d.ts.map +1 -0
- package/dist/formatters/BatchImportResponseFormatter.js +125 -0
- package/dist/formatters/BatchImportResponseFormatter.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +130 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/direct-middleware.d.ts +9 -0
- package/dist/middleware/direct-middleware.d.ts.map +1 -0
- package/dist/middleware/direct-middleware.js +49 -0
- package/dist/middleware/direct-middleware.js.map +1 -0
- package/dist/middleware/index.d.ts +8 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +21 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/simplified-rate-limit.d.ts +147 -0
- package/dist/middleware/simplified-rate-limit.d.ts.map +1 -0
- package/dist/middleware/simplified-rate-limit.js +533 -0
- package/dist/middleware/simplified-rate-limit.js.map +1 -0
- package/dist/parsers/CSVParser.d.ts +36 -0
- package/dist/parsers/CSVParser.d.ts.map +1 -0
- package/dist/parsers/CSVParser.js +69 -0
- package/dist/parsers/CSVParser.js.map +1 -0
- package/dist/parsers/InputParserFactory.d.ts +17 -0
- package/dist/parsers/InputParserFactory.d.ts.map +1 -0
- package/dist/parsers/InputParserFactory.js +137 -0
- package/dist/parsers/InputParserFactory.js.map +1 -0
- package/dist/parsers/JSONParser.d.ts +74 -0
- package/dist/parsers/JSONParser.d.ts.map +1 -0
- package/dist/parsers/JSONParser.js +69 -0
- package/dist/parsers/JSONParser.js.map +1 -0
- package/dist/services/EntityResolver.d.ts +92 -0
- package/dist/services/EntityResolver.d.ts.map +1 -0
- package/dist/services/EntityResolver.js +201 -0
- package/dist/services/EntityResolver.js.map +1 -0
- package/dist/services/TaskCreationService.d.ts +99 -0
- package/dist/services/TaskCreationService.d.ts.map +1 -0
- package/dist/services/TaskCreationService.js +392 -0
- package/dist/services/TaskCreationService.js.map +1 -0
- package/dist/storage/SimpleFilterStorage.d.ts +103 -0
- package/dist/storage/SimpleFilterStorage.d.ts.map +1 -0
- package/dist/storage/SimpleFilterStorage.js +350 -0
- package/dist/storage/SimpleFilterStorage.js.map +1 -0
- package/dist/storage/filtering/FilterSerializer.d.ts +45 -0
- package/dist/storage/filtering/FilterSerializer.d.ts.map +1 -0
- package/dist/storage/filtering/FilterSerializer.js +171 -0
- package/dist/storage/filtering/FilterSerializer.js.map +1 -0
- package/dist/storage/filtering/FilterValidator.d.ts +59 -0
- package/dist/storage/filtering/FilterValidator.d.ts.map +1 -0
- package/dist/storage/filtering/FilterValidator.js +183 -0
- package/dist/storage/filtering/FilterValidator.js.map +1 -0
- package/dist/storage/index.d.ts +61 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +125 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/templateFileStore.d.ts +62 -0
- package/dist/storage/templateFileStore.d.ts.map +1 -0
- package/dist/storage/templateFileStore.js +151 -0
- package/dist/storage/templateFileStore.js.map +1 -0
- package/dist/tools/admin.d.ts +51 -0
- package/dist/tools/admin.d.ts.map +1 -0
- package/dist/tools/admin.js +207 -0
- package/dist/tools/admin.js.map +1 -0
- package/dist/tools/auth.d.ts +9 -0
- package/dist/tools/auth.d.ts.map +1 -0
- package/dist/tools/auth.js +175 -0
- package/dist/tools/auth.js.map +1 -0
- package/dist/tools/batch-import.d.ts +5 -0
- package/dist/tools/batch-import.d.ts.map +1 -0
- package/dist/tools/batch-import.js +153 -0
- package/dist/tools/batch-import.js.map +1 -0
- package/dist/tools/caldav-tokens.d.ts +45 -0
- package/dist/tools/caldav-tokens.d.ts.map +1 -0
- package/dist/tools/caldav-tokens.js +93 -0
- package/dist/tools/caldav-tokens.js.map +1 -0
- package/dist/tools/export.d.ts +14 -0
- package/dist/tools/export.d.ts.map +1 -0
- package/dist/tools/export.js +252 -0
- package/dist/tools/export.js.map +1 -0
- package/dist/tools/filters.d.ts +50 -0
- package/dist/tools/filters.d.ts.map +1 -0
- package/dist/tools/filters.js +512 -0
- package/dist/tools/filters.js.map +1 -0
- package/dist/tools/index.d.ts +53 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +217 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/labels.d.ts +22 -0
- package/dist/tools/labels.d.ts.map +1 -0
- package/dist/tools/labels.js +206 -0
- package/dist/tools/labels.js.map +1 -0
- package/dist/tools/notifications.d.ts +17 -0
- package/dist/tools/notifications.d.ts.map +1 -0
- package/dist/tools/notifications.js +171 -0
- package/dist/tools/notifications.js.map +1 -0
- package/dist/tools/projects/backgrounds.d.ts +80 -0
- package/dist/tools/projects/backgrounds.d.ts.map +1 -0
- package/dist/tools/projects/backgrounds.js +154 -0
- package/dist/tools/projects/backgrounds.js.map +1 -0
- package/dist/tools/projects/buckets.d.ts +147 -0
- package/dist/tools/projects/buckets.d.ts.map +1 -0
- package/dist/tools/projects/buckets.js +291 -0
- package/dist/tools/projects/buckets.js.map +1 -0
- package/dist/tools/projects/crud.d.ts +145 -0
- package/dist/tools/projects/crud.d.ts.map +1 -0
- package/dist/tools/projects/crud.js +425 -0
- package/dist/tools/projects/crud.js.map +1 -0
- package/dist/tools/projects/duplicate.d.ts +41 -0
- package/dist/tools/projects/duplicate.d.ts.map +1 -0
- package/dist/tools/projects/duplicate.js +49 -0
- package/dist/tools/projects/duplicate.js.map +1 -0
- package/dist/tools/projects/hierarchy.d.ts +77 -0
- package/dist/tools/projects/hierarchy.d.ts.map +1 -0
- package/dist/tools/projects/hierarchy.js +300 -0
- package/dist/tools/projects/hierarchy.js.map +1 -0
- package/dist/tools/projects/index.d.ts +34 -0
- package/dist/tools/projects/index.d.ts.map +1 -0
- package/dist/tools/projects/index.js +522 -0
- package/dist/tools/projects/index.js.map +1 -0
- package/dist/tools/projects/permission.d.ts +26 -0
- package/dist/tools/projects/permission.d.ts.map +1 -0
- package/dist/tools/projects/permission.js +53 -0
- package/dist/tools/projects/permission.js.map +1 -0
- package/dist/tools/projects/response-formatter.d.ts +54 -0
- package/dist/tools/projects/response-formatter.d.ts.map +1 -0
- package/dist/tools/projects/response-formatter.js +139 -0
- package/dist/tools/projects/response-formatter.js.map +1 -0
- package/dist/tools/projects/sharing-access.d.ts +165 -0
- package/dist/tools/projects/sharing-access.d.ts.map +1 -0
- package/dist/tools/projects/sharing-access.js +450 -0
- package/dist/tools/projects/sharing-access.js.map +1 -0
- package/dist/tools/projects/sharing.d.ts +105 -0
- package/dist/tools/projects/sharing.d.ts.map +1 -0
- package/dist/tools/projects/sharing.js +258 -0
- package/dist/tools/projects/sharing.js.map +1 -0
- package/dist/tools/projects/validation.d.ts +51 -0
- package/dist/tools/projects/validation.d.ts.map +1 -0
- package/dist/tools/projects/validation.js +160 -0
- package/dist/tools/projects/validation.js.map +1 -0
- package/dist/tools/projects/views.d.ts +161 -0
- package/dist/tools/projects/views.d.ts.map +1 -0
- package/dist/tools/projects/views.js +234 -0
- package/dist/tools/projects/views.js.map +1 -0
- package/dist/tools/projects.d.ts +20 -0
- package/dist/tools/projects.d.ts.map +1 -0
- package/dist/tools/projects.js +66 -0
- package/dist/tools/projects.js.map +1 -0
- package/dist/tools/reactions.d.ts +25 -0
- package/dist/tools/reactions.d.ts.map +1 -0
- package/dist/tools/reactions.js +108 -0
- package/dist/tools/reactions.js.map +1 -0
- package/dist/tools/subscriptions.d.ts +23 -0
- package/dist/tools/subscriptions.d.ts.map +1 -0
- package/dist/tools/subscriptions.js +111 -0
- package/dist/tools/subscriptions.js.map +1 -0
- package/dist/tools/task-assignees.d.ts +13 -0
- package/dist/tools/task-assignees.d.ts.map +1 -0
- package/dist/tools/task-assignees.js +74 -0
- package/dist/tools/task-assignees.js.map +1 -0
- package/dist/tools/task-bulk.d.ts +13 -0
- package/dist/tools/task-bulk.d.ts.map +1 -0
- package/dist/tools/task-bulk.js +117 -0
- package/dist/tools/task-bulk.js.map +1 -0
- package/dist/tools/task-comments.d.ts +12 -0
- package/dist/tools/task-comments.d.ts.map +1 -0
- package/dist/tools/task-comments.js +65 -0
- package/dist/tools/task-comments.js.map +1 -0
- package/dist/tools/task-crud.d.ts +13 -0
- package/dist/tools/task-crud.d.ts.map +1 -0
- package/dist/tools/task-crud.js +168 -0
- package/dist/tools/task-crud.js.map +1 -0
- package/dist/tools/task-labels.d.ts +13 -0
- package/dist/tools/task-labels.d.ts.map +1 -0
- package/dist/tools/task-labels.js +64 -0
- package/dist/tools/task-labels.js.map +1 -0
- package/dist/tools/task-relations.d.ts +13 -0
- package/dist/tools/task-relations.d.ts.map +1 -0
- package/dist/tools/task-relations.js +74 -0
- package/dist/tools/task-relations.js.map +1 -0
- package/dist/tools/task-reminders.d.ts +13 -0
- package/dist/tools/task-reminders.d.ts.map +1 -0
- package/dist/tools/task-reminders.js +69 -0
- package/dist/tools/task-reminders.js.map +1 -0
- package/dist/tools/tasks/assignees/AssigneeOperationsService.d.ts +63 -0
- package/dist/tools/tasks/assignees/AssigneeOperationsService.d.ts.map +1 -0
- package/dist/tools/tasks/assignees/AssigneeOperationsService.js +152 -0
- package/dist/tools/tasks/assignees/AssigneeOperationsService.js.map +1 -0
- package/dist/tools/tasks/assignees/AssigneeResponseFormatter.d.ts +28 -0
- package/dist/tools/tasks/assignees/AssigneeResponseFormatter.d.ts.map +1 -0
- package/dist/tools/tasks/assignees/AssigneeResponseFormatter.js +73 -0
- package/dist/tools/tasks/assignees/AssigneeResponseFormatter.js.map +1 -0
- package/dist/tools/tasks/assignees/AssigneeValidationService.d.ts +46 -0
- package/dist/tools/tasks/assignees/AssigneeValidationService.d.ts.map +1 -0
- package/dist/tools/tasks/assignees/AssigneeValidationService.js +70 -0
- package/dist/tools/tasks/assignees/AssigneeValidationService.js.map +1 -0
- package/dist/tools/tasks/assignees/index.d.ts +52 -0
- package/dist/tools/tasks/assignees/index.d.ts.map +1 -0
- package/dist/tools/tasks/assignees/index.js +103 -0
- package/dist/tools/tasks/assignees/index.js.map +1 -0
- package/dist/tools/tasks/attach.d.ts +39 -0
- package/dist/tools/tasks/attach.d.ts.map +1 -0
- package/dist/tools/tasks/attach.js +90 -0
- package/dist/tools/tasks/attach.js.map +1 -0
- package/dist/tools/tasks/attachments.d.ts +67 -0
- package/dist/tools/tasks/attachments.d.ts.map +1 -0
- package/dist/tools/tasks/attachments.js +153 -0
- package/dist/tools/tasks/attachments.js.map +1 -0
- package/dist/tools/tasks/buckets.d.ts +41 -0
- package/dist/tools/tasks/buckets.d.ts.map +1 -0
- package/dist/tools/tasks/buckets.js +75 -0
- package/dist/tools/tasks/buckets.js.map +1 -0
- package/dist/tools/tasks/bulk/BatchProcessorFactory.d.ts +30 -0
- package/dist/tools/tasks/bulk/BatchProcessorFactory.d.ts.map +1 -0
- package/dist/tools/tasks/bulk/BatchProcessorFactory.js +69 -0
- package/dist/tools/tasks/bulk/BatchProcessorFactory.js.map +1 -0
- package/dist/tools/tasks/bulk/BulkOperationErrorHandler.d.ts +50 -0
- package/dist/tools/tasks/bulk/BulkOperationErrorHandler.d.ts.map +1 -0
- package/dist/tools/tasks/bulk/BulkOperationErrorHandler.js +183 -0
- package/dist/tools/tasks/bulk/BulkOperationErrorHandler.js.map +1 -0
- package/dist/tools/tasks/bulk/BulkOperationProcessor.d.ts +101 -0
- package/dist/tools/tasks/bulk/BulkOperationProcessor.d.ts.map +1 -0
- package/dist/tools/tasks/bulk/BulkOperationProcessor.js +416 -0
- package/dist/tools/tasks/bulk/BulkOperationProcessor.js.map +1 -0
- package/dist/tools/tasks/bulk/BulkOperationTypes.d.ts +50 -0
- package/dist/tools/tasks/bulk/BulkOperationTypes.d.ts.map +1 -0
- package/dist/tools/tasks/bulk/BulkOperationTypes.js +6 -0
- package/dist/tools/tasks/bulk/BulkOperationTypes.js.map +1 -0
- package/dist/tools/tasks/bulk/BulkOperationValidator.d.ts +53 -0
- package/dist/tools/tasks/bulk/BulkOperationValidator.d.ts.map +1 -0
- package/dist/tools/tasks/bulk/BulkOperationValidator.js +216 -0
- package/dist/tools/tasks/bulk/BulkOperationValidator.js.map +1 -0
- package/dist/tools/tasks/bulk/index.d.ts +9 -0
- package/dist/tools/tasks/bulk/index.d.ts.map +1 -0
- package/dist/tools/tasks/bulk/index.js +15 -0
- package/dist/tools/tasks/bulk/index.js.map +1 -0
- package/dist/tools/tasks/bulk-operations-simplified.d.ts +62 -0
- package/dist/tools/tasks/bulk-operations-simplified.d.ts.map +1 -0
- package/dist/tools/tasks/bulk-operations-simplified.js +416 -0
- package/dist/tools/tasks/bulk-operations-simplified.js.map +1 -0
- package/dist/tools/tasks/bulk-operations.d.ts +8 -0
- package/dist/tools/tasks/bulk-operations.d.ts.map +1 -0
- package/dist/tools/tasks/bulk-operations.js +13 -0
- package/dist/tools/tasks/bulk-operations.js.map +1 -0
- package/dist/tools/tasks/by-index.d.ts +36 -0
- package/dist/tools/tasks/by-index.d.ts.map +1 -0
- package/dist/tools/tasks/by-index.js +52 -0
- package/dist/tools/tasks/by-index.js.map +1 -0
- package/dist/tools/tasks/comments/CommentOperationsService.d.ts +44 -0
- package/dist/tools/tasks/comments/CommentOperationsService.d.ts.map +1 -0
- package/dist/tools/tasks/comments/CommentOperationsService.js +86 -0
- package/dist/tools/tasks/comments/CommentOperationsService.js.map +1 -0
- package/dist/tools/tasks/comments/CommentResponseFormatter.d.ts +41 -0
- package/dist/tools/tasks/comments/CommentResponseFormatter.d.ts.map +1 -0
- package/dist/tools/tasks/comments/CommentResponseFormatter.js +114 -0
- package/dist/tools/tasks/comments/CommentResponseFormatter.js.map +1 -0
- package/dist/tools/tasks/comments/CommentValidationService.d.ts +62 -0
- package/dist/tools/tasks/comments/CommentValidationService.d.ts.map +1 -0
- package/dist/tools/tasks/comments/CommentValidationService.js +105 -0
- package/dist/tools/tasks/comments/CommentValidationService.js.map +1 -0
- package/dist/tools/tasks/comments/index.d.ts +66 -0
- package/dist/tools/tasks/comments/index.d.ts.map +1 -0
- package/dist/tools/tasks/comments/index.js +99 -0
- package/dist/tools/tasks/comments/index.js.map +1 -0
- package/dist/tools/tasks/constants.d.ts +19 -0
- package/dist/tools/tasks/constants.d.ts.map +1 -0
- package/dist/tools/tasks/constants.js +82 -0
- package/dist/tools/tasks/constants.js.map +1 -0
- package/dist/tools/tasks/crud/TaskCreationService.d.ts +29 -0
- package/dist/tools/tasks/crud/TaskCreationService.d.ts.map +1 -0
- package/dist/tools/tasks/crud/TaskCreationService.js +274 -0
- package/dist/tools/tasks/crud/TaskCreationService.js.map +1 -0
- package/dist/tools/tasks/crud/TaskDeletionService.d.ts +19 -0
- package/dist/tools/tasks/crud/TaskDeletionService.d.ts.map +1 -0
- package/dist/tools/tasks/crud/TaskDeletionService.js +96 -0
- package/dist/tools/tasks/crud/TaskDeletionService.js.map +1 -0
- package/dist/tools/tasks/crud/TaskReadService.d.ts +19 -0
- package/dist/tools/tasks/crud/TaskReadService.d.ts.map +1 -0
- package/dist/tools/tasks/crud/TaskReadService.js +66 -0
- package/dist/tools/tasks/crud/TaskReadService.js.map +1 -0
- package/dist/tools/tasks/crud/TaskResponseFormatter.d.ts +18 -0
- package/dist/tools/tasks/crud/TaskResponseFormatter.d.ts.map +1 -0
- package/dist/tools/tasks/crud/TaskResponseFormatter.js +248 -0
- package/dist/tools/tasks/crud/TaskResponseFormatter.js.map +1 -0
- package/dist/tools/tasks/crud/TaskUpdateService.d.ts +33 -0
- package/dist/tools/tasks/crud/TaskUpdateService.d.ts.map +1 -0
- package/dist/tools/tasks/crud/TaskUpdateService.js +294 -0
- package/dist/tools/tasks/crud/TaskUpdateService.js.map +1 -0
- package/dist/tools/tasks/crud/index.d.ts +17 -0
- package/dist/tools/tasks/crud/index.d.ts.map +1 -0
- package/dist/tools/tasks/crud/index.js +20 -0
- package/dist/tools/tasks/crud/index.js.map +1 -0
- package/dist/tools/tasks/duplicate.d.ts +28 -0
- package/dist/tools/tasks/duplicate.d.ts.map +1 -0
- package/dist/tools/tasks/duplicate.js +41 -0
- package/dist/tools/tasks/duplicate.js.map +1 -0
- package/dist/tools/tasks/filtering/FilterExecutor.d.ts +39 -0
- package/dist/tools/tasks/filtering/FilterExecutor.d.ts.map +1 -0
- package/dist/tools/tasks/filtering/FilterExecutor.js +214 -0
- package/dist/tools/tasks/filtering/FilterExecutor.js.map +1 -0
- package/dist/tools/tasks/filtering/FilterValidator.d.ts +59 -0
- package/dist/tools/tasks/filtering/FilterValidator.d.ts.map +1 -0
- package/dist/tools/tasks/filtering/FilterValidator.js +257 -0
- package/dist/tools/tasks/filtering/FilterValidator.js.map +1 -0
- package/dist/tools/tasks/filtering/TaskFilteringOrchestrator.d.ts +78 -0
- package/dist/tools/tasks/filtering/TaskFilteringOrchestrator.d.ts.map +1 -0
- package/dist/tools/tasks/filtering/TaskFilteringOrchestrator.js +195 -0
- package/dist/tools/tasks/filtering/TaskFilteringOrchestrator.js.map +1 -0
- package/dist/tools/tasks/filtering/evaluators.d.ts +41 -0
- package/dist/tools/tasks/filtering/evaluators.d.ts.map +1 -0
- package/dist/tools/tasks/filtering/evaluators.js +224 -0
- package/dist/tools/tasks/filtering/evaluators.js.map +1 -0
- package/dist/tools/tasks/filtering/index.d.ts +11 -0
- package/dist/tools/tasks/filtering/index.d.ts.map +1 -0
- package/dist/tools/tasks/filtering/index.js +26 -0
- package/dist/tools/tasks/filtering/index.js.map +1 -0
- package/dist/tools/tasks/index.d.ts +9 -0
- package/dist/tools/tasks/index.d.ts.map +1 -0
- package/dist/tools/tasks/index.js +337 -0
- package/dist/tools/tasks/index.js.map +1 -0
- package/dist/tools/tasks/labels.d.ts +49 -0
- package/dist/tools/tasks/labels.d.ts.map +1 -0
- package/dist/tools/tasks/labels.js +223 -0
- package/dist/tools/tasks/labels.js.map +1 -0
- package/dist/tools/tasks/mark-read.d.ts +27 -0
- package/dist/tools/tasks/mark-read.d.ts.map +1 -0
- package/dist/tools/tasks/mark-read.js +38 -0
- package/dist/tools/tasks/mark-read.js.map +1 -0
- package/dist/tools/tasks/position.d.ts +53 -0
- package/dist/tools/tasks/position.d.ts.map +1 -0
- package/dist/tools/tasks/position.js +83 -0
- package/dist/tools/tasks/position.js.map +1 -0
- package/dist/tools/tasks/reminders.d.ts +56 -0
- package/dist/tools/tasks/reminders.d.ts.map +1 -0
- package/dist/tools/tasks/reminders.js +213 -0
- package/dist/tools/tasks/reminders.js.map +1 -0
- package/dist/tools/tasks/subtasks.d.ts +85 -0
- package/dist/tools/tasks/subtasks.d.ts.map +1 -0
- package/dist/tools/tasks/subtasks.js +286 -0
- package/dist/tools/tasks/subtasks.js.map +1 -0
- package/dist/tools/tasks/types/filters.d.ts +136 -0
- package/dist/tools/tasks/types/filters.d.ts.map +1 -0
- package/dist/tools/tasks/types/filters.js +7 -0
- package/dist/tools/tasks/types/filters.js.map +1 -0
- package/dist/tools/tasks/validation.d.ts +47 -0
- package/dist/tools/tasks/validation.d.ts.map +1 -0
- package/dist/tools/tasks/validation.js +131 -0
- package/dist/tools/tasks/validation.js.map +1 -0
- package/dist/tools/tasks-relations.d.ts +25 -0
- package/dist/tools/tasks-relations.d.ts.map +1 -0
- package/dist/tools/tasks-relations.js +271 -0
- package/dist/tools/tasks-relations.js.map +1 -0
- package/dist/tools/tasks.d.ts +6 -0
- package/dist/tools/tasks.d.ts.map +1 -0
- package/dist/tools/tasks.js +10 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/tools/teams.d.ts +9 -0
- package/dist/tools/teams.d.ts.map +1 -0
- package/dist/tools/teams.js +255 -0
- package/dist/tools/teams.js.map +1 -0
- package/dist/tools/templates.d.ts +9 -0
- package/dist/tools/templates.d.ts.map +1 -0
- package/dist/tools/templates.js +450 -0
- package/dist/tools/templates.js.map +1 -0
- package/dist/tools/tokens.d.ts +37 -0
- package/dist/tools/tokens.d.ts.map +1 -0
- package/dist/tools/tokens.js +122 -0
- package/dist/tools/tokens.js.map +1 -0
- package/dist/tools/user-deletion.d.ts +41 -0
- package/dist/tools/user-deletion.d.ts.map +1 -0
- package/dist/tools/user-deletion.js +126 -0
- package/dist/tools/user-deletion.js.map +1 -0
- package/dist/tools/users.d.ts +9 -0
- package/dist/tools/users.d.ts.map +1 -0
- package/dist/tools/users.js +418 -0
- package/dist/tools/users.js.map +1 -0
- package/dist/tools/webhooks.d.ts +31 -0
- package/dist/tools/webhooks.d.ts.map +1 -0
- package/dist/tools/webhooks.js +414 -0
- package/dist/tools/webhooks.js.map +1 -0
- package/dist/transforms/base.d.ts +204 -0
- package/dist/transforms/base.d.ts.map +1 -0
- package/dist/transforms/base.js +175 -0
- package/dist/transforms/base.js.map +1 -0
- package/dist/transforms/field-selector.d.ts +27 -0
- package/dist/transforms/field-selector.d.ts.map +1 -0
- package/dist/transforms/field-selector.js +91 -0
- package/dist/transforms/field-selector.js.map +1 -0
- package/dist/transforms/index.d.ts +15 -0
- package/dist/transforms/index.d.ts.map +1 -0
- package/dist/transforms/index.js +50 -0
- package/dist/transforms/index.js.map +1 -0
- package/dist/transforms/size-calculator.d.ts +131 -0
- package/dist/transforms/size-calculator.d.ts.map +1 -0
- package/dist/transforms/size-calculator.js +284 -0
- package/dist/transforms/size-calculator.js.map +1 -0
- package/dist/transforms/task.d.ts +207 -0
- package/dist/transforms/task.d.ts.map +1 -0
- package/dist/transforms/task.js +259 -0
- package/dist/transforms/task.js.map +1 -0
- package/dist/types/errors.d.ts +65 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +44 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/filters.d.ts +149 -0
- package/dist/types/filters.d.ts.map +1 -0
- package/dist/types/filters.js +26 -0
- package/dist/types/filters.js.map +1 -0
- package/dist/types/index.d.ts +147 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +24 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/node-vikunja-extended.d.ts +36 -0
- package/dist/types/node-vikunja-extended.d.ts.map +1 -0
- package/dist/types/node-vikunja-extended.js +25 -0
- package/dist/types/node-vikunja-extended.js.map +1 -0
- package/dist/types/responses.d.ts +121 -0
- package/dist/types/responses.d.ts.map +1 -0
- package/dist/types/responses.js +26 -0
- package/dist/types/responses.js.map +1 -0
- package/dist/types/vikunja.d.ts +319 -0
- package/dist/types/vikunja.d.ts.map +1 -0
- package/dist/types/vikunja.js +7 -0
- package/dist/types/vikunja.js.map +1 -0
- package/dist/utils/auth-error-handler.d.ts +23 -0
- package/dist/utils/auth-error-handler.d.ts.map +1 -0
- package/dist/utils/auth-error-handler.js +162 -0
- package/dist/utils/auth-error-handler.js.map +1 -0
- package/dist/utils/composite-operation.d.ts +184 -0
- package/dist/utils/composite-operation.d.ts.map +1 -0
- package/dist/utils/composite-operation.js +293 -0
- package/dist/utils/composite-operation.js.map +1 -0
- package/dist/utils/error-handler.d.ts +39 -0
- package/dist/utils/error-handler.d.ts.map +1 -0
- package/dist/utils/error-handler.js +336 -0
- package/dist/utils/error-handler.js.map +1 -0
- package/dist/utils/filtering/ClientSideFilteringStrategy.d.ts +13 -0
- package/dist/utils/filtering/ClientSideFilteringStrategy.d.ts.map +1 -0
- package/dist/utils/filtering/ClientSideFilteringStrategy.js +129 -0
- package/dist/utils/filtering/ClientSideFilteringStrategy.js.map +1 -0
- package/dist/utils/filtering/FilteringContext.d.ts +40 -0
- package/dist/utils/filtering/FilteringContext.d.ts.map +1 -0
- package/dist/utils/filtering/FilteringContext.js +58 -0
- package/dist/utils/filtering/FilteringContext.js.map +1 -0
- package/dist/utils/filtering/HybridFilteringStrategy.d.ts +15 -0
- package/dist/utils/filtering/HybridFilteringStrategy.d.ts.map +1 -0
- package/dist/utils/filtering/HybridFilteringStrategy.js +55 -0
- package/dist/utils/filtering/HybridFilteringStrategy.js.map +1 -0
- package/dist/utils/filtering/RestCrossProjectFilteringStrategy.d.ts +42 -0
- package/dist/utils/filtering/RestCrossProjectFilteringStrategy.d.ts.map +1 -0
- package/dist/utils/filtering/RestCrossProjectFilteringStrategy.js +120 -0
- package/dist/utils/filtering/RestCrossProjectFilteringStrategy.js.map +1 -0
- package/dist/utils/filtering/ServerSideFilteringStrategy.d.ts +13 -0
- package/dist/utils/filtering/ServerSideFilteringStrategy.d.ts.map +1 -0
- package/dist/utils/filtering/ServerSideFilteringStrategy.js +88 -0
- package/dist/utils/filtering/ServerSideFilteringStrategy.js.map +1 -0
- package/dist/utils/filtering/TaskFilteringStrategy.d.ts +19 -0
- package/dist/utils/filtering/TaskFilteringStrategy.d.ts.map +1 -0
- package/dist/utils/filtering/TaskFilteringStrategy.js +10 -0
- package/dist/utils/filtering/TaskFilteringStrategy.js.map +1 -0
- package/dist/utils/filtering/index.d.ts +14 -0
- package/dist/utils/filtering/index.d.ts.map +1 -0
- package/dist/utils/filtering/index.js +22 -0
- package/dist/utils/filtering/index.js.map +1 -0
- package/dist/utils/filtering/types.d.ts +108 -0
- package/dist/utils/filtering/types.d.ts.map +1 -0
- package/dist/utils/filtering/types.js +6 -0
- package/dist/utils/filtering/types.js.map +1 -0
- package/dist/utils/filters.d.ts +70 -0
- package/dist/utils/filters.d.ts.map +1 -0
- package/dist/utils/filters.js +812 -0
- package/dist/utils/filters.js.map +1 -0
- package/dist/utils/http-error-detail.d.ts +28 -0
- package/dist/utils/http-error-detail.d.ts.map +1 -0
- package/dist/utils/http-error-detail.js +67 -0
- package/dist/utils/http-error-detail.js.map +1 -0
- package/dist/utils/label-bulk.d.ts +21 -0
- package/dist/utils/label-bulk.d.ts.map +1 -0
- package/dist/utils/label-bulk.js +51 -0
- package/dist/utils/label-bulk.js.map +1 -0
- package/dist/utils/logger.d.ts +20 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +66 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/memory.d.ts +73 -0
- package/dist/utils/memory.d.ts.map +1 -0
- package/dist/utils/memory.js +194 -0
- package/dist/utils/memory.js.map +1 -0
- package/dist/utils/performance/batch-processor.d.ts +77 -0
- package/dist/utils/performance/batch-processor.d.ts.map +1 -0
- package/dist/utils/performance/batch-processor.js +218 -0
- package/dist/utils/performance/batch-processor.js.map +1 -0
- package/dist/utils/performance/index.d.ts +42 -0
- package/dist/utils/performance/index.d.ts.map +1 -0
- package/dist/utils/performance/index.js +49 -0
- package/dist/utils/performance/index.js.map +1 -0
- package/dist/utils/performance/performance-monitor.d.ts +116 -0
- package/dist/utils/performance/performance-monitor.d.ts.map +1 -0
- package/dist/utils/performance/performance-monitor.js +307 -0
- package/dist/utils/performance/performance-monitor.js.map +1 -0
- package/dist/utils/read-only.d.ts +111 -0
- package/dist/utils/read-only.d.ts.map +1 -0
- package/dist/utils/read-only.js +503 -0
- package/dist/utils/read-only.js.map +1 -0
- package/dist/utils/response-factory.d.ts +81 -0
- package/dist/utils/response-factory.d.ts.map +1 -0
- package/dist/utils/response-factory.js +86 -0
- package/dist/utils/response-factory.js.map +1 -0
- package/dist/utils/retry.d.ts +160 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +316 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/security.d.ts +70 -0
- package/dist/utils/security.d.ts.map +1 -0
- package/dist/utils/security.js +358 -0
- package/dist/utils/security.js.map +1 -0
- package/dist/utils/simple-response.d.ts +75 -0
- package/dist/utils/simple-response.d.ts.map +1 -0
- package/dist/utils/simple-response.js +311 -0
- package/dist/utils/simple-response.js.map +1 -0
- package/dist/utils/storage-errors.d.ts +9 -0
- package/dist/utils/storage-errors.d.ts.map +1 -0
- package/dist/utils/storage-errors.js +20 -0
- package/dist/utils/storage-errors.js.map +1 -0
- package/dist/utils/task-rest-transport.d.ts +28 -0
- package/dist/utils/task-rest-transport.d.ts.map +1 -0
- package/dist/utils/task-rest-transport.js +33 -0
- package/dist/utils/task-rest-transport.js.map +1 -0
- package/dist/utils/unicode-fix.d.ts +19 -0
- package/dist/utils/unicode-fix.d.ts.map +1 -0
- package/dist/utils/unicode-fix.js +70 -0
- package/dist/utils/unicode-fix.js.map +1 -0
- package/dist/utils/validation.d.ts +75 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +758 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/utils/vikunja-rest.d.ts +159 -0
- package/dist/utils/vikunja-rest.d.ts.map +1 -0
- package/dist/utils/vikunja-rest.js +378 -0
- package/dist/utils/vikunja-rest.js.map +1 -0
- package/docs/CONFIGURATION.md +957 -0
- package/docs/DOCKER-DESKTOP-MCP.md +207 -0
- package/docs/TOOLS.md +422 -0
- package/package.json +145 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Simplified Error Handling using Zod + Security Patterns
|
|
4
|
+
*
|
|
5
|
+
* Replaces 461 lines of custom error handling with concise,
|
|
6
|
+
* secure patterns using Zod validation and minimal sanitization.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ErrorSchema = exports.handleFetchError = exports.createInternalError = exports.createValidationError = exports.wrapAuthError = exports.createAuthRequiredError = exports.wrapToolError = exports.transformApiError = exports.wrapIfRestOrigin = exports.handleStatusCodeError = void 0;
|
|
10
|
+
exports.isMCPError = isMCPError;
|
|
11
|
+
exports.hasStatusCode = hasStatusCode;
|
|
12
|
+
const zod_1 = require("zod");
|
|
13
|
+
const errors_1 = require("../types/errors");
|
|
14
|
+
/**
|
|
15
|
+
* Shared prefix for every `MCPError` thrown by `vikunjaRestRequest`/
|
|
16
|
+
* `vikunjaRestMultipartRequest` (`src/utils/vikunja-rest.ts`) — kept as a
|
|
17
|
+
* local constant (rather than importing `isRestOriginError` from that
|
|
18
|
+
* module) so this file doesn't require every test that `jest.mock()`s
|
|
19
|
+
* `vikunja-rest` wholesale to also stub a new export. Must be kept in sync
|
|
20
|
+
* with `REST_ERROR_MESSAGE_PREFIX` in `vikunja-rest.ts` if that ever changes.
|
|
21
|
+
*/
|
|
22
|
+
const REST_ERROR_MESSAGE_PREFIX = 'Vikunja REST request failed (';
|
|
23
|
+
/**
|
|
24
|
+
* Security-sensitive patterns that should be sanitized from error messages
|
|
25
|
+
* Minimal set of patterns for essential security while maintaining usability
|
|
26
|
+
*/
|
|
27
|
+
const SECURITY_PATTERNS = [
|
|
28
|
+
// File paths and system paths
|
|
29
|
+
/\/[a-zA-Z0-9_\-/.]+\.(json|js|ts|yml|yaml|conf|config|env|key|pem|p12|jks)/g,
|
|
30
|
+
/[A-Z]:\\[a-zA-Z0-9_\-\\]+\.(json|js|ts|yml|yaml|conf|config|env|key|pem|p12|jks)/g,
|
|
31
|
+
// Database connection strings
|
|
32
|
+
/mysql:\/\/[^@\s]+@[^/\s]+\/[a-zA-Z0-9_-]+/g,
|
|
33
|
+
/postgresql:\/\/[^@\s]+@[^/\s]+\/[a-zA-Z0-9_-]+/g,
|
|
34
|
+
/mongodb:\/\/[^@\s]+/g,
|
|
35
|
+
// Network details
|
|
36
|
+
/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/g,
|
|
37
|
+
/Bearer\s+[a-zA-Z0-9-_.]+/g,
|
|
38
|
+
/tk_[a-zA-Z0-9]{32,}/g,
|
|
39
|
+
// Stack traces
|
|
40
|
+
/at\s+[a-zA-Z_$][a-zA-Z0-9_$]*\s*\([^)]*\)/g,
|
|
41
|
+
/:\d+:\d+\)/g,
|
|
42
|
+
];
|
|
43
|
+
/**
|
|
44
|
+
* Type-safe error handler that preserves security while reducing complexity
|
|
45
|
+
*/
|
|
46
|
+
class SecureErrorHandler {
|
|
47
|
+
/**
|
|
48
|
+
* Sanitize error message by detecting and replacing ONLY security-sensitive information
|
|
49
|
+
* Preserves original error messages when they don't contain sensitive data
|
|
50
|
+
*/
|
|
51
|
+
sanitize(message) {
|
|
52
|
+
if (typeof message !== 'string') {
|
|
53
|
+
return 'Unknown error';
|
|
54
|
+
}
|
|
55
|
+
const lowerMessage = message.toLowerCase();
|
|
56
|
+
// Only sanitize if we detect specific security-sensitive patterns
|
|
57
|
+
// Stack traces and internal file references (highest priority - most sensitive)
|
|
58
|
+
if (lowerMessage.includes(' at ') ||
|
|
59
|
+
lowerMessage.includes('.js:') ||
|
|
60
|
+
lowerMessage.includes('parseconfig') ||
|
|
61
|
+
lowerMessage.includes('loadconfig') ||
|
|
62
|
+
lowerMessage.includes('index.js:') ||
|
|
63
|
+
lowerMessage.includes('json.parse') ||
|
|
64
|
+
lowerMessage.includes('position 42') // Common JSON parse error pattern
|
|
65
|
+
) {
|
|
66
|
+
return 'Internal system error';
|
|
67
|
+
}
|
|
68
|
+
// Database schema and connection details (table names, hosts, passwords)
|
|
69
|
+
if (lowerMessage.includes('er_no_such_table') ||
|
|
70
|
+
lowerMessage.includes('table \'') ||
|
|
71
|
+
lowerMessage.includes('mysql://') ||
|
|
72
|
+
lowerMessage.includes('postgresql://') ||
|
|
73
|
+
lowerMessage.includes('mongodb://') ||
|
|
74
|
+
lowerMessage.includes('schema') ||
|
|
75
|
+
lowerMessage.includes('column ')) {
|
|
76
|
+
return 'Database access error';
|
|
77
|
+
}
|
|
78
|
+
// Authentication tokens and mechanisms (JWT details, crypto keys)
|
|
79
|
+
if (lowerMessage.includes('jwt validation failed') ||
|
|
80
|
+
lowerMessage.includes('signature verification') ||
|
|
81
|
+
lowerMessage.includes('/etc/keys/') ||
|
|
82
|
+
lowerMessage.includes('jwt-public.pem') ||
|
|
83
|
+
lowerMessage.includes('tk_') ||
|
|
84
|
+
lowerMessage.includes('bearer ')) {
|
|
85
|
+
return 'Authentication error';
|
|
86
|
+
}
|
|
87
|
+
// Network details with IP addresses and ports (preserve general network errors)
|
|
88
|
+
if (/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/.test(message) || // IP addresses
|
|
89
|
+
lowerMessage.includes(':54321') ||
|
|
90
|
+
lowerMessage.includes(':443') ||
|
|
91
|
+
lowerMessage.includes('192.168.') ||
|
|
92
|
+
lowerMessage.includes('api.vikunja')) {
|
|
93
|
+
return 'Network connection error';
|
|
94
|
+
}
|
|
95
|
+
// API endpoints and internal structures (preserve general API errors)
|
|
96
|
+
if (lowerMessage.includes('/api/v1/') ||
|
|
97
|
+
lowerMessage.includes('projects/123/tasks') ||
|
|
98
|
+
lowerMessage.includes('status=completed&limit=50')) {
|
|
99
|
+
return 'API access error';
|
|
100
|
+
}
|
|
101
|
+
// File paths and system details (absolute paths, file extensions with content)
|
|
102
|
+
if (/\b\/[a-zA-Z0-9_\-/.]+\.[a-zA-Z]/.test(message) || // Unix paths with files
|
|
103
|
+
/\b[A-Z]:\\[a-zA-Z0-9_\\\-/.]+\.[a-zA-Z]/.test(message) || // Windows paths
|
|
104
|
+
lowerMessage.includes('permission denied') ||
|
|
105
|
+
lowerMessage.includes('no such file') ||
|
|
106
|
+
lowerMessage.includes('secrets.json') ||
|
|
107
|
+
lowerMessage.includes('config.js') ||
|
|
108
|
+
lowerMessage.includes('index.js')) {
|
|
109
|
+
return 'File system access error';
|
|
110
|
+
}
|
|
111
|
+
// Check for other security patterns
|
|
112
|
+
const hasSensitiveInfo = SECURITY_PATTERNS.some(pattern => pattern.test(message));
|
|
113
|
+
if (hasSensitiveInfo) {
|
|
114
|
+
return 'System error occurred';
|
|
115
|
+
}
|
|
116
|
+
// If no security patterns detected, return original message
|
|
117
|
+
return message;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Restore the conventional "Failed to <operation>: <message>" wrapping on
|
|
121
|
+
* an MCPError that originated from the direct-REST layer
|
|
122
|
+
* (`vikunjaRestRequest`, which throws `MCPError` itself now that
|
|
123
|
+
* node-vikunja is gone — see PR #73), while preserving the original
|
|
124
|
+
* `code`/`details` (including `.details.statusCode`) so callers can still
|
|
125
|
+
* branch on the underlying failure type (e.g. `NOT_FOUND`).
|
|
126
|
+
*
|
|
127
|
+
* Many call sites re-throw `instanceof MCPError` errors unmodified so
|
|
128
|
+
* their OWN validation/internal errors (e.g. "Task ID is required") aren't
|
|
129
|
+
* silently re-wrapped. Before PR #73, a task-refresh/assignee-update REST
|
|
130
|
+
* failure was a plain `Error`, so it fell through to `handleStatusCode`
|
|
131
|
+
* and got the friendly wrapping. After PR #73, the same failure is itself
|
|
132
|
+
* an `MCPError`, so that `instanceof MCPError` guard now short-circuits it
|
|
133
|
+
* too, leaking the raw "Vikunja REST request failed (...)" string to the
|
|
134
|
+
* user. REST-origin errors are distinguished from this tool's own
|
|
135
|
+
* validation/internal `MCPError`s by the message prefix `vikunjaRestRequest`
|
|
136
|
+
* always uses (`.details.statusCode` alone isn't reliable: network-level
|
|
137
|
+
* REST failures carry `.details.transient` instead, not a statusCode);
|
|
138
|
+
* errors that aren't REST-origin pass through unchanged.
|
|
139
|
+
*/
|
|
140
|
+
wrapIfRestOrigin(error, operation) {
|
|
141
|
+
if (!error.message.startsWith(REST_ERROR_MESSAGE_PREFIX)) {
|
|
142
|
+
return error;
|
|
143
|
+
}
|
|
144
|
+
const sanitized = this.sanitize(error.message);
|
|
145
|
+
return new errors_1.MCPError(error.code, `Failed to ${operation}: ${sanitized}`, error.details);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Handle status code errors (404, etc.)
|
|
149
|
+
*/
|
|
150
|
+
handleStatusCode(error, operation, resourceId, customMessage) {
|
|
151
|
+
if (this.isStatusCodeError(error) && error.statusCode === 404) {
|
|
152
|
+
if (customMessage) {
|
|
153
|
+
return new errors_1.MCPError(errors_1.ErrorCode.NOT_FOUND, customMessage);
|
|
154
|
+
}
|
|
155
|
+
const resourceInfo = resourceId ? ` with ID ${resourceId}` : '';
|
|
156
|
+
const resourceType = this.extractResourceType(operation);
|
|
157
|
+
return new errors_1.MCPError(errors_1.ErrorCode.NOT_FOUND, `${resourceType.charAt(0).toUpperCase() + resourceType.slice(1)}${resourceInfo} not found`);
|
|
158
|
+
}
|
|
159
|
+
// Real Error instances and explicitly-thrown strings contribute their
|
|
160
|
+
// message to the output. Any other shape (numbers, plain objects, null,
|
|
161
|
+
// undefined, etc.) becomes "Unknown error" so that arbitrary upstream
|
|
162
|
+
// API payloads never leak into the user-visible MCP error surface. This
|
|
163
|
+
// intentionally differs from transform() (which does stringify numbers/
|
|
164
|
+
// booleans) - tests/tools/tasks-relations.test.ts and
|
|
165
|
+
// tests/utils/error-handler.test.ts both assert this stricter behavior
|
|
166
|
+
// for handleStatusCode specifically.
|
|
167
|
+
let message;
|
|
168
|
+
if (error instanceof Error) {
|
|
169
|
+
message = error.message;
|
|
170
|
+
}
|
|
171
|
+
else if (typeof error === 'string') {
|
|
172
|
+
message = error;
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
message = 'Unknown error';
|
|
176
|
+
}
|
|
177
|
+
const sanitized = this.sanitize(message);
|
|
178
|
+
return new errors_1.MCPError(errors_1.ErrorCode.API_ERROR, `Failed to ${operation}: ${sanitized}`);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Transform any error to MCPError with security sanitization
|
|
182
|
+
*/
|
|
183
|
+
transform(error, context) {
|
|
184
|
+
if (error instanceof errors_1.MCPError) {
|
|
185
|
+
return error;
|
|
186
|
+
}
|
|
187
|
+
let message;
|
|
188
|
+
if (error instanceof Error) {
|
|
189
|
+
message = error.message;
|
|
190
|
+
}
|
|
191
|
+
else if (typeof error === 'string') {
|
|
192
|
+
message = error;
|
|
193
|
+
}
|
|
194
|
+
else if (typeof error === 'number' || typeof error === 'boolean') {
|
|
195
|
+
message = String(error);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
// Plain objects (even those with a message property), null, undefined,
|
|
199
|
+
// symbols, and bigints all become "Unknown error" here. Extracting
|
|
200
|
+
// .message from untrusted plain objects would let arbitrary upstream
|
|
201
|
+
// payloads into user-visible MCP errors.
|
|
202
|
+
message = 'Unknown error';
|
|
203
|
+
}
|
|
204
|
+
const sanitized = this.sanitize(message);
|
|
205
|
+
return new errors_1.MCPError(errors_1.ErrorCode.API_ERROR, `${context}: ${sanitized}`);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Wrap tool errors with consistent handling
|
|
209
|
+
*/
|
|
210
|
+
wrap(error, toolName, operation, resourceId, customMessage) {
|
|
211
|
+
if (error instanceof errors_1.MCPError) {
|
|
212
|
+
return error;
|
|
213
|
+
}
|
|
214
|
+
if (this.isStatusCodeError(error)) {
|
|
215
|
+
return this.handleStatusCode(error, operation, resourceId, customMessage);
|
|
216
|
+
}
|
|
217
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
218
|
+
const sanitized = this.sanitize(message);
|
|
219
|
+
return new errors_1.MCPError(errors_1.ErrorCode.API_ERROR, `${toolName}.${operation} failed: ${sanitized}`);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Create standardized errors
|
|
223
|
+
*/
|
|
224
|
+
createAuthRequired(operation) {
|
|
225
|
+
const context = operation ? ` to ${operation}` : '';
|
|
226
|
+
return new errors_1.MCPError(errors_1.ErrorCode.AUTH_REQUIRED, `Authentication required${context}. Please connect first:\n` +
|
|
227
|
+
`vikunja_auth.connect({\n` +
|
|
228
|
+
` apiUrl: 'https://your-vikunja.com/api/v1',\n` +
|
|
229
|
+
` apiToken: 'your-api-token'\n` +
|
|
230
|
+
`})\n\n` +
|
|
231
|
+
`Get your API token from Vikunja Settings > API Access.`);
|
|
232
|
+
}
|
|
233
|
+
createValidationError(message) {
|
|
234
|
+
return new errors_1.MCPError(errors_1.ErrorCode.VALIDATION_ERROR, message);
|
|
235
|
+
}
|
|
236
|
+
createInternalError(message, originalError) {
|
|
237
|
+
if (originalError instanceof Error) {
|
|
238
|
+
const sanitized = this.sanitize(originalError.message);
|
|
239
|
+
// Only include error details if they weren't sanitized to a generic message
|
|
240
|
+
if (sanitized !== originalError.message) {
|
|
241
|
+
// Security-sensitive content was detected and sanitized
|
|
242
|
+
return new errors_1.MCPError(errors_1.ErrorCode.INTERNAL_ERROR, message);
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
// Safe to include the original error message
|
|
246
|
+
return new errors_1.MCPError(errors_1.ErrorCode.INTERNAL_ERROR, `${message}: ${sanitized}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return new errors_1.MCPError(errors_1.ErrorCode.INTERNAL_ERROR, message);
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Handle fetch errors with authentication guidance
|
|
253
|
+
*/
|
|
254
|
+
handleFetchError(error, operation) {
|
|
255
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
256
|
+
const lowerMessage = message.toLowerCase();
|
|
257
|
+
// Authentication-related fetch failures
|
|
258
|
+
if (lowerMessage.includes('fetch failed') ||
|
|
259
|
+
lowerMessage.includes('econnrefused') ||
|
|
260
|
+
lowerMessage.includes('enotfound') ||
|
|
261
|
+
lowerMessage.includes('401') ||
|
|
262
|
+
lowerMessage.includes('403')) {
|
|
263
|
+
return new errors_1.MCPError(errors_1.ErrorCode.AUTH_REQUIRED, `Failed to ${operation}. Please check authentication and API access.`);
|
|
264
|
+
}
|
|
265
|
+
// Timeout errors
|
|
266
|
+
if (lowerMessage.includes('timeout')) {
|
|
267
|
+
return new errors_1.MCPError(errors_1.ErrorCode.API_ERROR, `Request timeout while trying to ${operation}. Please try again.`);
|
|
268
|
+
}
|
|
269
|
+
return this.transform(error, `Failed to ${operation}`);
|
|
270
|
+
}
|
|
271
|
+
// Helper methods
|
|
272
|
+
isStatusCodeError(error) {
|
|
273
|
+
return error !== null && typeof error === 'object' && 'statusCode' in error;
|
|
274
|
+
}
|
|
275
|
+
extractResourceType(operation) {
|
|
276
|
+
// Remove action verbs and get resource type
|
|
277
|
+
const cleaned = operation.replace(/^(get|update|delete|create|list)\s+/, '');
|
|
278
|
+
// Fallback mapping
|
|
279
|
+
if (cleaned === operation) {
|
|
280
|
+
if (operation.includes('project'))
|
|
281
|
+
return 'project';
|
|
282
|
+
if (operation.includes('task'))
|
|
283
|
+
return 'task';
|
|
284
|
+
if (operation.includes('label'))
|
|
285
|
+
return 'label';
|
|
286
|
+
if (operation.includes('share'))
|
|
287
|
+
return 'share';
|
|
288
|
+
return 'resource';
|
|
289
|
+
}
|
|
290
|
+
return cleaned || 'resource';
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
// Create singleton instance
|
|
294
|
+
const errorHandler = new SecureErrorHandler();
|
|
295
|
+
// Export simplified API
|
|
296
|
+
const handleStatusCodeError = (error, operation, resourceId, customMessage) => errorHandler.handleStatusCode(error, operation, resourceId, customMessage);
|
|
297
|
+
exports.handleStatusCodeError = handleStatusCodeError;
|
|
298
|
+
const wrapIfRestOrigin = (error, operation) => errorHandler.wrapIfRestOrigin(error, operation);
|
|
299
|
+
exports.wrapIfRestOrigin = wrapIfRestOrigin;
|
|
300
|
+
const transformApiError = (error, context) => errorHandler.transform(error, context);
|
|
301
|
+
exports.transformApiError = transformApiError;
|
|
302
|
+
const wrapToolError = (error, toolName, operation, resourceId, customMessage) => errorHandler.wrap(error, toolName, operation, resourceId, customMessage);
|
|
303
|
+
exports.wrapToolError = wrapToolError;
|
|
304
|
+
const createAuthRequiredError = (operation) => errorHandler.createAuthRequired(operation);
|
|
305
|
+
exports.createAuthRequiredError = createAuthRequiredError;
|
|
306
|
+
const wrapAuthError = (error, operation) => {
|
|
307
|
+
if (error instanceof errors_1.MCPError) {
|
|
308
|
+
return error;
|
|
309
|
+
}
|
|
310
|
+
if (errorHandler.isStatusCodeError(error)) {
|
|
311
|
+
return errorHandler.handleStatusCode(error, operation);
|
|
312
|
+
}
|
|
313
|
+
return errorHandler.transform(error, 'Authentication error');
|
|
314
|
+
};
|
|
315
|
+
exports.wrapAuthError = wrapAuthError;
|
|
316
|
+
const createValidationError = (message) => errorHandler.createValidationError(message);
|
|
317
|
+
exports.createValidationError = createValidationError;
|
|
318
|
+
const createInternalError = (message, originalError) => errorHandler.createInternalError(message, originalError);
|
|
319
|
+
exports.createInternalError = createInternalError;
|
|
320
|
+
const handleFetchError = (error, operation) => errorHandler.handleFetchError(error, operation);
|
|
321
|
+
exports.handleFetchError = handleFetchError;
|
|
322
|
+
// Type guards for better TypeScript support
|
|
323
|
+
function isMCPError(error) {
|
|
324
|
+
return error instanceof errors_1.MCPError;
|
|
325
|
+
}
|
|
326
|
+
function hasStatusCode(error) {
|
|
327
|
+
return error !== null && typeof error === 'object' && 'statusCode' in error;
|
|
328
|
+
}
|
|
329
|
+
// Zod schema for error validation
|
|
330
|
+
exports.ErrorSchema = zod_1.z.object({
|
|
331
|
+
message: zod_1.z.string(),
|
|
332
|
+
statusCode: zod_1.z.number().optional(),
|
|
333
|
+
code: zod_1.z.string().optional(),
|
|
334
|
+
stack: zod_1.z.string().optional(),
|
|
335
|
+
});
|
|
336
|
+
//# sourceMappingURL=error-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/utils/error-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side filtering strategy
|
|
3
|
+
*
|
|
4
|
+
* This strategy loads all tasks from the API and then applies filtering
|
|
5
|
+
* logic on the client side. This is the traditional approach that works
|
|
6
|
+
* with all versions of Vikunja but may be less efficient for large datasets.
|
|
7
|
+
*/
|
|
8
|
+
import type { TaskFilteringStrategy } from './TaskFilteringStrategy';
|
|
9
|
+
import type { FilteringParams, FilteringResult } from './types';
|
|
10
|
+
export declare class ClientSideFilteringStrategy implements TaskFilteringStrategy {
|
|
11
|
+
execute(params: FilteringParams): Promise<FilteringResult>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=ClientSideFilteringStrategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClientSideFilteringStrategy.d.ts","sourceRoot":"","sources":["../../../src/utils/filtering/ClientSideFilteringStrategy.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAkC,MAAM,SAAS,CAAC;AAoFhG,qBAAa,2BAA4B,YAAW,qBAAqB;IACjE,OAAO,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;CAoEjE"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Client-side filtering strategy
|
|
4
|
+
*
|
|
5
|
+
* This strategy loads all tasks from the API and then applies filtering
|
|
6
|
+
* logic on the client side. This is the traditional approach that works
|
|
7
|
+
* with all versions of Vikunja but may be less efficient for large datasets.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.ClientSideFilteringStrategy = void 0;
|
|
11
|
+
const vikunja_rest_1 = require("../vikunja-rest");
|
|
12
|
+
const types_1 = require("../../types");
|
|
13
|
+
const validation_1 = require("../../tools/tasks/validation");
|
|
14
|
+
const filtering_1 = require("../../tools/tasks/filtering");
|
|
15
|
+
const logger_1 = require("../logger");
|
|
16
|
+
const RestCrossProjectFilteringStrategy_1 = require("./RestCrossProjectFilteringStrategy");
|
|
17
|
+
/**
|
|
18
|
+
* Fetches a single project's tasks. Calls the same `GET /projects/{id}/tasks`
|
|
19
|
+
* path the legacy client's `getProjectTasks` used pre-migration — this is a
|
|
20
|
+
* literal call-site migration (legacy client -> `vikunjaRestRequest`),
|
|
21
|
+
* not an endpoint redesign, so it is preserved byte-for-byte even though
|
|
22
|
+
* `docs/vikunja-openapi.json` does not document a GET method at this path
|
|
23
|
+
* (verified via `jq '.paths["/projects/{id}/tasks"]'`) — the per-view
|
|
24
|
+
* `GET /projects/{id}/views/{view}/tasks` endpoint the spec does document is
|
|
25
|
+
* a different, wider-scoped migration (extra view-resolution round trip,
|
|
26
|
+
* different Kanban response shape per docs/API_NOTES.md) left to a future
|
|
27
|
+
* item rather than folded into this refactor.
|
|
28
|
+
*/
|
|
29
|
+
async function fetchProjectTasks(authManager, projectId, params) {
|
|
30
|
+
// Client-side filtering never sends `filter` server-side (that's the whole
|
|
31
|
+
// point of this strategy) — apiParams never carries one for this code
|
|
32
|
+
// path, but the query is built explicitly without it for clarity.
|
|
33
|
+
const query = (0, RestCrossProjectFilteringStrategy_1.buildTasksListQuery)(params, undefined, {});
|
|
34
|
+
const path = `/projects/${projectId}/tasks${query ? `?${query}` : ''}`;
|
|
35
|
+
const tasks = await (0, vikunja_rest_1.vikunjaRestRequest)(authManager, 'GET', path);
|
|
36
|
+
return Array.isArray(tasks) ? tasks : [];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Loads tasks from every project the user can access.
|
|
40
|
+
*
|
|
41
|
+
* Vikunja's dedicated "all tasks" endpoint (the legacy client's `getAllTasks` ->
|
|
42
|
+
* GET /tasks/all) returns HTTP 400 "Invalid model provided" on some servers
|
|
43
|
+
* (reproduced on v2.3.0), so it cannot be relied on for cross-project listing.
|
|
44
|
+
* This aggregates GET /projects/{id}/tasks across every project instead, which
|
|
45
|
+
* is consistently available. A project that fails individually is skipped
|
|
46
|
+
* rather than failing the whole listing.
|
|
47
|
+
*/
|
|
48
|
+
async function loadTasksAcrossProjects(authManager, params) {
|
|
49
|
+
const projects = await (0, vikunja_rest_1.vikunjaRestRequest)(authManager, 'GET', '/projects?per_page=1000');
|
|
50
|
+
const safeProjects = Array.isArray(projects) ? projects : [];
|
|
51
|
+
const perProject = await Promise.all(safeProjects.map(async (project) => {
|
|
52
|
+
const projectId = project.id;
|
|
53
|
+
// Skip pseudo-projects (e.g. Favorites uses a negative id) to avoid duplicate tasks.
|
|
54
|
+
if (typeof projectId !== 'number' || projectId <= 0) {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
return await fetchProjectTasks(authManager, projectId, params);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
logger_1.logger.warn('Skipping a project that failed during all-projects task aggregation', {
|
|
62
|
+
projectId,
|
|
63
|
+
error: error instanceof Error ? error.message : String(error),
|
|
64
|
+
});
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
}));
|
|
68
|
+
return perProject.flat();
|
|
69
|
+
}
|
|
70
|
+
class ClientSideFilteringStrategy {
|
|
71
|
+
async execute(params) {
|
|
72
|
+
const { args, filterExpression, filterString, params: apiParams, authManager } = params;
|
|
73
|
+
if (!authManager) {
|
|
74
|
+
// Programmer error: FilteringContext must only select this strategy
|
|
75
|
+
// when an authManager was threaded through from the tool handler.
|
|
76
|
+
throw new types_1.MCPError(types_1.ErrorCode.INTERNAL_ERROR, 'ClientSideFilteringStrategy requires an authManager');
|
|
77
|
+
}
|
|
78
|
+
logger_1.logger.info('Using client-side filtering', {
|
|
79
|
+
filter: filterString,
|
|
80
|
+
endpoint: args.projectId && !args.allProjects
|
|
81
|
+
? 'getProjectTasks'
|
|
82
|
+
: 'getProjectTasks (aggregated across all projects)'
|
|
83
|
+
});
|
|
84
|
+
// Load tasks without server-side filtering
|
|
85
|
+
let tasks;
|
|
86
|
+
if (args.projectId !== undefined && !args.allProjects) {
|
|
87
|
+
// Validate project ID
|
|
88
|
+
(0, validation_1.validateId)(args.projectId, 'projectId');
|
|
89
|
+
// Get tasks for specific project without filter
|
|
90
|
+
tasks = await fetchProjectTasks(authManager, args.projectId, apiParams);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
// Aggregate tasks across all projects (GET /tasks/all is unreliable).
|
|
94
|
+
tasks = await loadTasksAcrossProjects(authManager, apiParams);
|
|
95
|
+
}
|
|
96
|
+
logger_1.logger.info('Tasks loaded for client-side filtering', {
|
|
97
|
+
totalTasksLoaded: tasks?.length || 0,
|
|
98
|
+
filter: filterString
|
|
99
|
+
});
|
|
100
|
+
// Apply client-side filtering if we have a filter expression
|
|
101
|
+
const safeTasks = tasks || [];
|
|
102
|
+
let filteredTasks = safeTasks;
|
|
103
|
+
if (filterExpression) {
|
|
104
|
+
const originalCount = safeTasks.length;
|
|
105
|
+
// applyFilter (evaluators.ts) and this strategy both type tasks as the
|
|
106
|
+
// generated `models.Task`; the cast here bridges the two nominally-
|
|
107
|
+
// distinct aliases at this boundary.
|
|
108
|
+
filteredTasks = (0, filtering_1.applyFilter)(safeTasks, filterExpression);
|
|
109
|
+
logger_1.logger.debug('Applied client-side filter', {
|
|
110
|
+
originalCount,
|
|
111
|
+
filteredCount: filteredTasks?.length || 0,
|
|
112
|
+
filter: filterString,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
tasks: filteredTasks || [],
|
|
117
|
+
metadata: {
|
|
118
|
+
serverSideFilteringUsed: false,
|
|
119
|
+
serverSideFilteringAttempted: false,
|
|
120
|
+
clientSideFiltering: Boolean(filterExpression),
|
|
121
|
+
filteringNote: filterExpression
|
|
122
|
+
? 'Client-side filtering applied'
|
|
123
|
+
: 'No filter applied; tasks returned as loaded'
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
exports.ClientSideFilteringStrategy = ClientSideFilteringStrategy;
|
|
129
|
+
//# sourceMappingURL=ClientSideFilteringStrategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClientSideFilteringStrategy.js","sourceRoot":"","sources":["../../../src/utils/filtering/ClientSideFilteringStrategy.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAKH,kDAAqD;AACrD,uCAAkD;AAClD,6DAA0D;AAC1D,2DAA0D;AAC1D,sCAAmC;AACnC,2FAA0E;AAQ1E;;;;;;;;;;;GAWG;AACH,KAAK,UAAU,iBAAiB,CAC9B,WAAwB,EACxB,SAAiB,EACjB,MAAyB;IAEzB,2EAA2E;IAC3E,sEAAsE;IACtE,kEAAkE;IAClE,MAAM,KAAK,GAAG,IAAA,uDAAmB,EAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG,aAAa,SAAS,SAAS,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACvE,MAAM,KAAK,GAAG,MAAM,IAAA,iCAAkB,EAAgB,WAAW,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAChF,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3C,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,uBAAuB,CACpC,WAAwB,EACxB,MAAyB;IAEzB,MAAM,QAAQ,GAAG,MAAM,IAAA,iCAAkB,EACvC,WAAW,EACX,KAAK,EACL,yBAAyB,CAC1B,CAAC;IACF,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAE7D,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAClC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAA0B,EAAE;QACzD,MAAM,SAAS,GAAG,OAAO,CAAC,EAAE,CAAC;QAC7B,qFAAqF;QACrF,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;YACpD,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,IAAI,CAAC;YACH,OAAO,MAAM,iBAAiB,CAAC,WAAW,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QACjE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAM,CAAC,IAAI,CAAC,qEAAqE,EAAE;gBACjF,SAAS;gBACT,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC,CAAC;YACH,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IAEF,OAAO,UAAU,CAAC,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED,MAAa,2BAA2B;IACtC,KAAK,CAAC,OAAO,CAAC,MAAuB;QACnC,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;QAExF,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,oEAAoE;YACpE,kEAAkE;YAClE,MAAM,IAAI,gBAAQ,CAChB,iBAAS,CAAC,cAAc,EACxB,qDAAqD,CACtD,CAAC;QACJ,CAAC;QAED,eAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE;YACzC,MAAM,EAAE,YAAY;YACpB,QAAQ,EAAE,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,WAAW;gBAC3C,CAAC,CAAC,iBAAiB;gBACnB,CAAC,CAAC,kDAAkD;SACvD,CAAC,CAAC;QAEH,2CAA2C;QAC3C,IAAI,KAAK,CAAC;QACV,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtD,sBAAsB;YACtB,IAAA,uBAAU,EAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YACxC,gDAAgD;YAChD,KAAK,GAAG,MAAM,iBAAiB,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAC1E,CAAC;aAAM,CAAC;YACN,sEAAsE;YACtE,KAAK,GAAG,MAAM,uBAAuB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QAChE,CAAC;QAED,eAAM,CAAC,IAAI,CAAC,wCAAwC,EAAE;YACpD,gBAAgB,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC;YACpC,MAAM,EAAE,YAAY;SACrB,CAAC,CAAC;QAEH,6DAA6D;QAC7D,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE,CAAC;QAC9B,IAAI,aAAa,GAAG,SAAS,CAAC;QAE9B,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,aAAa,GAAG,SAAS,CAAC,MAAM,CAAC;YACvC,uEAAuE;YACvE,oEAAoE;YACpE,qCAAqC;YACrC,aAAa,GAAG,IAAA,uBAAW,EACzB,SAAyD,EACzD,gBAAgB,CACW,CAAC;YAC9B,eAAM,CAAC,KAAK,CAAC,4BAA4B,EAAE;gBACzC,aAAa;gBACb,aAAa,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;gBACzC,MAAM,EAAE,YAAY;aACrB,CAAC,CAAC;QACL,CAAC;QAED,OAAO;YACL,KAAK,EAAE,aAAa,IAAI,EAAE;YAC1B,QAAQ,EAAE;gBACR,uBAAuB,EAAE,KAAK;gBAC9B,4BAA4B,EAAE,KAAK;gBACnC,mBAAmB,EAAE,OAAO,CAAC,gBAAgB,CAAC;gBAC9C,aAAa,EAAE,gBAAgB;oBAC7B,CAAC,CAAC,+BAA+B;oBACjC,CAAC,CAAC,6CAA6C;aAClD;SACF,CAAC;IACJ,CAAC;CACF;AArED,kEAqEC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filtering context for strategy selection and execution
|
|
3
|
+
*
|
|
4
|
+
* This class encapsulates the logic for selecting the appropriate filtering
|
|
5
|
+
* strategy based on configuration. HybridFilteringStrategy attempts
|
|
6
|
+
* server-side filtering and transparently falls back to client-side
|
|
7
|
+
* filtering on any server error, so it is safe to use whenever a filter
|
|
8
|
+
* is present.
|
|
9
|
+
*/
|
|
10
|
+
import type { FilteringParams, FilteringResult, StrategyConfig } from './types';
|
|
11
|
+
export declare class FilteringContext {
|
|
12
|
+
private strategy;
|
|
13
|
+
constructor(config: StrategyConfig);
|
|
14
|
+
/**
|
|
15
|
+
* Execute filtering using the selected strategy
|
|
16
|
+
*/
|
|
17
|
+
execute(params: FilteringParams): Promise<FilteringResult>;
|
|
18
|
+
/**
|
|
19
|
+
* Select the appropriate filtering strategy based on configuration.
|
|
20
|
+
*
|
|
21
|
+
* - enableServerSide -> HybridFilteringStrategy (server-side attempt with
|
|
22
|
+
* automatic client-side fallback on any server error).
|
|
23
|
+
* - otherwise -> ClientSideFilteringStrategy.
|
|
24
|
+
*
|
|
25
|
+
* Server-side filtering used to be gated behind NODE_ENV=production or the
|
|
26
|
+
* VIKUNJA_ENABLE_SERVER_SIDE_FILTERING env var. That gate only ever disabled
|
|
27
|
+
* a self-healing path: with it off, every filtered list fetched a raw page
|
|
28
|
+
* and filtered it in memory, so `done`/`filter` were applied *after*
|
|
29
|
+
* pagination and matching tasks were scattered unpredictably across pages.
|
|
30
|
+
*
|
|
31
|
+
* - crossProject -> RestCrossProjectFilteringStrategy (direct REST GET
|
|
32
|
+
* /tasks, one call, falling back to per-project aggregation on
|
|
33
|
+
* failure) takes priority over `enableServerSide`: it is strictly
|
|
34
|
+
* better than the N+1 aggregation whether or not a filter is present.
|
|
35
|
+
* - enableServerSide (single-project) -> HybridFilteringStrategy.
|
|
36
|
+
* - otherwise -> ClientSideFilteringStrategy.
|
|
37
|
+
*/
|
|
38
|
+
private getStrategy;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=FilteringContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilteringContext.d.ts","sourceRoot":"","sources":["../../../src/utils/filtering/FilteringContext.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAKhF,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAwB;gBAE5B,MAAM,EAAE,cAAc;IAIlC;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;IAIhE;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,WAAW;CAWpB"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Filtering context for strategy selection and execution
|
|
4
|
+
*
|
|
5
|
+
* This class encapsulates the logic for selecting the appropriate filtering
|
|
6
|
+
* strategy based on configuration. HybridFilteringStrategy attempts
|
|
7
|
+
* server-side filtering and transparently falls back to client-side
|
|
8
|
+
* filtering on any server error, so it is safe to use whenever a filter
|
|
9
|
+
* is present.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.FilteringContext = void 0;
|
|
13
|
+
const ClientSideFilteringStrategy_1 = require("./ClientSideFilteringStrategy");
|
|
14
|
+
const HybridFilteringStrategy_1 = require("./HybridFilteringStrategy");
|
|
15
|
+
const RestCrossProjectFilteringStrategy_1 = require("./RestCrossProjectFilteringStrategy");
|
|
16
|
+
class FilteringContext {
|
|
17
|
+
strategy;
|
|
18
|
+
constructor(config) {
|
|
19
|
+
this.strategy = this.getStrategy(config);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Execute filtering using the selected strategy
|
|
23
|
+
*/
|
|
24
|
+
async execute(params) {
|
|
25
|
+
return this.strategy.execute(params);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Select the appropriate filtering strategy based on configuration.
|
|
29
|
+
*
|
|
30
|
+
* - enableServerSide -> HybridFilteringStrategy (server-side attempt with
|
|
31
|
+
* automatic client-side fallback on any server error).
|
|
32
|
+
* - otherwise -> ClientSideFilteringStrategy.
|
|
33
|
+
*
|
|
34
|
+
* Server-side filtering used to be gated behind NODE_ENV=production or the
|
|
35
|
+
* VIKUNJA_ENABLE_SERVER_SIDE_FILTERING env var. That gate only ever disabled
|
|
36
|
+
* a self-healing path: with it off, every filtered list fetched a raw page
|
|
37
|
+
* and filtered it in memory, so `done`/`filter` were applied *after*
|
|
38
|
+
* pagination and matching tasks were scattered unpredictably across pages.
|
|
39
|
+
*
|
|
40
|
+
* - crossProject -> RestCrossProjectFilteringStrategy (direct REST GET
|
|
41
|
+
* /tasks, one call, falling back to per-project aggregation on
|
|
42
|
+
* failure) takes priority over `enableServerSide`: it is strictly
|
|
43
|
+
* better than the N+1 aggregation whether or not a filter is present.
|
|
44
|
+
* - enableServerSide (single-project) -> HybridFilteringStrategy.
|
|
45
|
+
* - otherwise -> ClientSideFilteringStrategy.
|
|
46
|
+
*/
|
|
47
|
+
getStrategy(config) {
|
|
48
|
+
if (config.crossProject) {
|
|
49
|
+
return new RestCrossProjectFilteringStrategy_1.RestCrossProjectFilteringStrategy();
|
|
50
|
+
}
|
|
51
|
+
if (config.enableServerSide) {
|
|
52
|
+
return new HybridFilteringStrategy_1.HybridFilteringStrategy();
|
|
53
|
+
}
|
|
54
|
+
return new ClientSideFilteringStrategy_1.ClientSideFilteringStrategy();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.FilteringContext = FilteringContext;
|
|
58
|
+
//# sourceMappingURL=FilteringContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilteringContext.js","sourceRoot":"","sources":["../../../src/utils/filtering/FilteringContext.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAIH,+EAA4E;AAC5E,uEAAoE;AACpE,2FAAwF;AAExF,MAAa,gBAAgB;IACnB,QAAQ,CAAwB;IAExC,YAAY,MAAsB;QAChC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,MAAuB;QACnC,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACK,WAAW,CAAC,MAAsB;QACxC,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YACxB,OAAO,IAAI,qEAAiC,EAAE,CAAC;QACjD,CAAC;QAED,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC;YAC5B,OAAO,IAAI,iDAAuB,EAAE,CAAC;QACvC,CAAC;QAED,OAAO,IAAI,yDAA2B,EAAE,CAAC;IAC3C,CAAC;CACF;AA7CD,4CA6CC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hybrid filtering strategy
|
|
3
|
+
*
|
|
4
|
+
* This strategy attempts server-side filtering first, and falls back to
|
|
5
|
+
* client-side filtering if server-side fails. This provides the best of
|
|
6
|
+
* both worlds: efficiency when possible, reliability always.
|
|
7
|
+
*/
|
|
8
|
+
import type { TaskFilteringStrategy } from './TaskFilteringStrategy';
|
|
9
|
+
import type { FilteringParams, FilteringResult } from './types';
|
|
10
|
+
export declare class HybridFilteringStrategy implements TaskFilteringStrategy {
|
|
11
|
+
private serverSideStrategy;
|
|
12
|
+
private clientSideStrategy;
|
|
13
|
+
execute(params: FilteringParams): Promise<FilteringResult>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=HybridFilteringStrategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HybridFilteringStrategy.d.ts","sourceRoot":"","sources":["../../../src/utils/filtering/HybridFilteringStrategy.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAKhE,qBAAa,uBAAwB,YAAW,qBAAqB;IACnE,OAAO,CAAC,kBAAkB,CAAqC;IAC/D,OAAO,CAAC,kBAAkB,CAAqC;IAEzD,OAAO,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;CA2CjE"}
|