motionmcp 1.0.2 → 2.1.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.
Files changed (159) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +241 -450
  3. package/dist/handlers/CommentHandler.d.ts +9 -0
  4. package/dist/handlers/CommentHandler.d.ts.map +1 -0
  5. package/dist/handlers/CommentHandler.js +66 -0
  6. package/dist/handlers/CommentHandler.js.map +1 -0
  7. package/dist/handlers/CustomFieldHandler.d.ts +14 -0
  8. package/dist/handlers/CustomFieldHandler.d.ts.map +1 -0
  9. package/dist/handlers/CustomFieldHandler.js +95 -0
  10. package/dist/handlers/CustomFieldHandler.js.map +1 -0
  11. package/dist/handlers/HandlerFactory.d.ts +15 -0
  12. package/dist/handlers/HandlerFactory.d.ts.map +1 -0
  13. package/dist/handlers/HandlerFactory.js +58 -0
  14. package/dist/handlers/HandlerFactory.js.map +1 -0
  15. package/dist/handlers/ProjectHandler.d.ts +10 -0
  16. package/dist/handlers/ProjectHandler.d.ts.map +1 -0
  17. package/dist/handlers/ProjectHandler.js +63 -0
  18. package/dist/handlers/ProjectHandler.js.map +1 -0
  19. package/dist/handlers/RecurringTaskHandler.d.ts +10 -0
  20. package/dist/handlers/RecurringTaskHandler.d.ts.map +1 -0
  21. package/dist/handlers/RecurringTaskHandler.js +68 -0
  22. package/dist/handlers/RecurringTaskHandler.js.map +1 -0
  23. package/dist/handlers/ScheduleHandler.d.ts +8 -0
  24. package/dist/handlers/ScheduleHandler.d.ts.map +1 -0
  25. package/dist/handlers/ScheduleHandler.js +43 -0
  26. package/dist/handlers/ScheduleHandler.js.map +1 -0
  27. package/dist/handlers/SearchHandler.d.ts +10 -0
  28. package/dist/handlers/SearchHandler.d.ts.map +1 -0
  29. package/dist/handlers/SearchHandler.js +116 -0
  30. package/dist/handlers/SearchHandler.js.map +1 -0
  31. package/dist/handlers/StatusHandler.d.ts +8 -0
  32. package/dist/handlers/StatusHandler.d.ts.map +1 -0
  33. package/dist/handlers/StatusHandler.js +22 -0
  34. package/dist/handlers/StatusHandler.js.map +1 -0
  35. package/dist/handlers/TaskHandler.d.ts +22 -0
  36. package/dist/handlers/TaskHandler.d.ts.map +1 -0
  37. package/dist/handlers/TaskHandler.js +324 -0
  38. package/dist/handlers/TaskHandler.js.map +1 -0
  39. package/dist/handlers/UserHandler.d.ts +9 -0
  40. package/dist/handlers/UserHandler.d.ts.map +1 -0
  41. package/dist/handlers/UserHandler.js +36 -0
  42. package/dist/handlers/UserHandler.js.map +1 -0
  43. package/dist/handlers/WorkspaceHandler.d.ts +10 -0
  44. package/dist/handlers/WorkspaceHandler.d.ts.map +1 -0
  45. package/dist/handlers/WorkspaceHandler.js +49 -0
  46. package/dist/handlers/WorkspaceHandler.js.map +1 -0
  47. package/dist/handlers/base/BaseHandler.d.ts +16 -0
  48. package/dist/handlers/base/BaseHandler.d.ts.map +1 -0
  49. package/dist/handlers/base/BaseHandler.js +31 -0
  50. package/dist/handlers/base/BaseHandler.js.map +1 -0
  51. package/dist/handlers/base/HandlerInterface.d.ts +18 -0
  52. package/dist/handlers/base/HandlerInterface.d.ts.map +1 -0
  53. package/dist/handlers/base/HandlerInterface.js +3 -0
  54. package/dist/handlers/base/HandlerInterface.js.map +1 -0
  55. package/dist/handlers/index.d.ts +14 -0
  56. package/dist/handlers/index.d.ts.map +1 -0
  57. package/dist/handlers/index.js +31 -0
  58. package/dist/handlers/index.js.map +1 -0
  59. package/dist/mcp-server.d.ts +15 -0
  60. package/dist/mcp-server.d.ts.map +1 -0
  61. package/dist/mcp-server.js +145 -0
  62. package/dist/mcp-server.js.map +1 -0
  63. package/dist/schemas/motion.d.ts +4971 -0
  64. package/dist/schemas/motion.d.ts.map +1 -0
  65. package/dist/schemas/motion.js +328 -0
  66. package/dist/schemas/motion.js.map +1 -0
  67. package/dist/services/motionApi.d.ts +199 -0
  68. package/dist/services/motionApi.d.ts.map +1 -0
  69. package/dist/services/motionApi.js +1950 -0
  70. package/dist/services/motionApi.js.map +1 -0
  71. package/dist/tools/ToolConfigurator.d.ts +19 -0
  72. package/dist/tools/ToolConfigurator.d.ts.map +1 -0
  73. package/dist/tools/ToolConfigurator.js +89 -0
  74. package/dist/tools/ToolConfigurator.js.map +1 -0
  75. package/dist/tools/ToolDefinitions.d.ts +25 -0
  76. package/dist/tools/ToolDefinitions.d.ts.map +1 -0
  77. package/dist/tools/ToolDefinitions.js +508 -0
  78. package/dist/tools/ToolDefinitions.js.map +1 -0
  79. package/dist/tools/ToolRegistry.d.ts +16 -0
  80. package/dist/tools/ToolRegistry.d.ts.map +1 -0
  81. package/dist/tools/ToolRegistry.js +89 -0
  82. package/dist/tools/ToolRegistry.js.map +1 -0
  83. package/dist/tools/index.d.ts +4 -0
  84. package/dist/tools/index.d.ts.map +1 -0
  85. package/dist/tools/index.js +21 -0
  86. package/dist/tools/index.js.map +1 -0
  87. package/dist/types/mcp-tool-args.d.ts +123 -0
  88. package/dist/types/mcp-tool-args.d.ts.map +1 -0
  89. package/dist/types/mcp-tool-args.js +7 -0
  90. package/dist/types/mcp-tool-args.js.map +1 -0
  91. package/dist/types/mcp.d.ts +32 -0
  92. package/dist/types/mcp.d.ts.map +1 -0
  93. package/dist/types/mcp.js +3 -0
  94. package/dist/types/mcp.js.map +1 -0
  95. package/dist/types/motion.d.ts +304 -0
  96. package/dist/types/motion.d.ts.map +1 -0
  97. package/dist/types/motion.js +3 -0
  98. package/dist/types/motion.js.map +1 -0
  99. package/dist/utils/cache.d.ts +25 -0
  100. package/dist/utils/cache.d.ts.map +1 -0
  101. package/dist/utils/cache.js +135 -0
  102. package/dist/utils/cache.js.map +1 -0
  103. package/dist/utils/constants.d.ts +88 -0
  104. package/dist/utils/constants.d.ts.map +1 -0
  105. package/dist/utils/constants.js +188 -0
  106. package/dist/utils/constants.js.map +1 -0
  107. package/dist/utils/errorHandling.d.ts +50 -0
  108. package/dist/utils/errorHandling.d.ts.map +1 -0
  109. package/dist/utils/errorHandling.js +86 -0
  110. package/dist/utils/errorHandling.js.map +1 -0
  111. package/dist/utils/index.d.ts +13 -0
  112. package/dist/utils/index.d.ts.map +1 -0
  113. package/dist/utils/index.js +38 -0
  114. package/dist/utils/index.js.map +1 -0
  115. package/dist/utils/logger.d.ts +13 -0
  116. package/dist/utils/logger.d.ts.map +1 -0
  117. package/dist/utils/logger.js +47 -0
  118. package/dist/utils/logger.js.map +1 -0
  119. package/dist/utils/pagination.d.ts +61 -0
  120. package/dist/utils/pagination.d.ts.map +1 -0
  121. package/dist/utils/pagination.js +168 -0
  122. package/dist/utils/pagination.js.map +1 -0
  123. package/dist/utils/paginationNew.d.ts +44 -0
  124. package/dist/utils/paginationNew.d.ts.map +1 -0
  125. package/dist/utils/paginationNew.js +149 -0
  126. package/dist/utils/paginationNew.js.map +1 -0
  127. package/dist/utils/parameterUtils.d.ts +79 -0
  128. package/dist/utils/parameterUtils.d.ts.map +1 -0
  129. package/dist/utils/parameterUtils.js +189 -0
  130. package/dist/utils/parameterUtils.js.map +1 -0
  131. package/dist/utils/responseFormatters.d.ts +95 -0
  132. package/dist/utils/responseFormatters.d.ts.map +1 -0
  133. package/dist/utils/responseFormatters.js +342 -0
  134. package/dist/utils/responseFormatters.js.map +1 -0
  135. package/dist/utils/responseWrapper.d.ts +38 -0
  136. package/dist/utils/responseWrapper.d.ts.map +1 -0
  137. package/dist/utils/responseWrapper.js +201 -0
  138. package/dist/utils/responseWrapper.js.map +1 -0
  139. package/dist/utils/sanitize.d.ts +51 -0
  140. package/dist/utils/sanitize.d.ts.map +1 -0
  141. package/dist/utils/sanitize.js +138 -0
  142. package/dist/utils/sanitize.js.map +1 -0
  143. package/dist/utils/validator.d.ts +37 -0
  144. package/dist/utils/validator.d.ts.map +1 -0
  145. package/dist/utils/validator.js +74 -0
  146. package/dist/utils/validator.js.map +1 -0
  147. package/dist/utils/workspaceResolver.d.ts +40 -0
  148. package/dist/utils/workspaceResolver.d.ts.map +1 -0
  149. package/dist/utils/workspaceResolver.js +207 -0
  150. package/dist/utils/workspaceResolver.js.map +1 -0
  151. package/package.json +41 -17
  152. package/.claude/settings.local.json +0 -15
  153. package/.env.example +0 -3
  154. package/sample.png +0 -0
  155. package/src/index.js +0 -179
  156. package/src/mcp-server.js +0 -1137
  157. package/src/routes/motion.js +0 -152
  158. package/src/services/motionApi.js +0 -1177
  159. package/src/worker.js +0 -248
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ /**
3
+ * Centralized MCP-compliant logger
4
+ * Outputs structured JSON logs to stderr as required by MCP protocol
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.mcpLog = void 0;
8
+ const SENSITIVE_FIELDS = ['apiKey', 'password', 'token', 'secret', 'authorization'];
9
+ /**
10
+ * Sanitizes sensitive information from log data
11
+ */
12
+ function sanitizeLogData(data) {
13
+ const sanitized = {};
14
+ for (const [key, value] of Object.entries(data)) {
15
+ // Check if key contains sensitive field names
16
+ if (SENSITIVE_FIELDS.some(field => key.toLowerCase().includes(field))) {
17
+ sanitized[key] = '[REDACTED]';
18
+ }
19
+ else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
20
+ // Recursively sanitize nested objects
21
+ sanitized[key] = sanitizeLogData(value);
22
+ }
23
+ else {
24
+ sanitized[key] = value;
25
+ }
26
+ }
27
+ return sanitized;
28
+ }
29
+ /**
30
+ * MCP-compliant logger that outputs to stderr in JSON format
31
+ * @param level - Log level (ERROR, WARN, INFO, DEBUG)
32
+ * @param message - Log message
33
+ * @param extra - Additional context data
34
+ */
35
+ const mcpLog = (level, message, extra = {}) => {
36
+ const sanitizedExtra = sanitizeLogData(extra);
37
+ const logEntry = {
38
+ level,
39
+ msg: message,
40
+ time: new Date().toISOString(),
41
+ ...sanitizedExtra
42
+ };
43
+ // MCP servers should log to stderr in JSON format
44
+ console.error(JSON.stringify(logEntry));
45
+ };
46
+ exports.mcpLog = mcpLog;
47
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAIH,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;AAEpF;;GAEG;AACH,SAAS,eAAe,CAAC,IAAyB;IAChD,MAAM,SAAS,GAAwB,EAAE,CAAC;IAE1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,8CAA8C;QAC9C,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACtE,SAAS,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC;QAChC,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChF,sCAAsC;YACtC,SAAS,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACzB,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACI,MAAM,MAAM,GAAG,CAAC,KAAe,EAAE,OAAe,EAAE,QAA6B,EAAE,EAAQ,EAAE;IAChG,MAAM,cAAc,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAE9C,MAAM,QAAQ,GAAG;QACf,KAAK;QACL,GAAG,EAAE,OAAO;QACZ,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC9B,GAAG,cAAc;KAClB,CAAC;IAEF,kDAAkD;IAClD,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC1C,CAAC,CAAC;AAZW,QAAA,MAAM,UAYjB"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Pagination Utilities - Shared pagination logic for Motion API calls
3
+ *
4
+ * Provides utilities to handle cursor-based and offset-based pagination
5
+ * consistently across all API endpoints.
6
+ */
7
+ import { AxiosResponse } from 'axios';
8
+ export interface PaginatedResponse<T> {
9
+ items: T[];
10
+ nextCursor?: string;
11
+ hasMore: boolean;
12
+ totalFetched: number;
13
+ }
14
+ export interface PaginationMeta {
15
+ nextCursor?: string;
16
+ hasMore?: boolean;
17
+ total?: number;
18
+ page?: number;
19
+ limit?: number;
20
+ }
21
+ export interface CursorPaginationOptions {
22
+ maxPages?: number;
23
+ pageSize?: number;
24
+ logProgress?: boolean;
25
+ }
26
+ export interface PaginatedApiResponse<T> {
27
+ meta?: PaginationMeta;
28
+ items?: T[];
29
+ tasks?: T[];
30
+ projects?: T[];
31
+ users?: T[];
32
+ comments?: T[];
33
+ customFields?: T[];
34
+ recurringTasks?: T[];
35
+ schedules?: T[];
36
+ statuses?: T[];
37
+ }
38
+ /**
39
+ * Generic cursor-based pagination handler
40
+ * Automatically fetches all pages or up to maxPages limit
41
+ */
42
+ export declare function fetchAllPages<T>(fetchPage: (cursor?: string) => Promise<AxiosResponse<PaginatedApiResponse<T>>>, options?: CursorPaginationOptions): Promise<PaginatedResponse<T>>;
43
+ /**
44
+ * Simple pagination for APIs that might not have explicit pagination
45
+ * but could benefit from batching large requests
46
+ */
47
+ export interface BatchOptions {
48
+ batchSize?: number;
49
+ maxBatches?: number;
50
+ delayMs?: number;
51
+ }
52
+ export declare function fetchInBatches<T, TParams>(fetchBatch: (params: TParams, offset: number, limit: number) => Promise<T[]>, params: TParams, options?: BatchOptions): Promise<T[]>;
53
+ /**
54
+ * Check if a response indicates more pages are available
55
+ */
56
+ export declare function hasMorePages<T>(response: PaginatedApiResponse<T>): boolean;
57
+ /**
58
+ * Get pagination info from response
59
+ */
60
+ export declare function getPaginationInfo<T>(response: PaginatedApiResponse<T>): PaginationMeta | null;
61
+ //# sourceMappingURL=pagination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/utils/pagination.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAItC,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;IACZ,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;IACZ,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;IACZ,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC;IACnB,cAAc,CAAC,EAAE,CAAC,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,SAAS,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,EAC/E,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAqF/B;AAyBD;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,cAAc,CAAC,CAAC,EAAE,OAAO,EAC7C,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,EAC5E,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,CAAC,EAAE,CAAC,CAuCd;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,OAAO,CAE1E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,cAAc,GAAG,IAAI,CAE7F"}
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ /**
3
+ * Pagination Utilities - Shared pagination logic for Motion API calls
4
+ *
5
+ * Provides utilities to handle cursor-based and offset-based pagination
6
+ * consistently across all API endpoints.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.fetchAllPages = fetchAllPages;
10
+ exports.fetchInBatches = fetchInBatches;
11
+ exports.hasMorePages = hasMorePages;
12
+ exports.getPaginationInfo = getPaginationInfo;
13
+ const logger_1 = require("./logger");
14
+ const constants_1 = require("./constants");
15
+ /**
16
+ * Generic cursor-based pagination handler
17
+ * Automatically fetches all pages or up to maxPages limit
18
+ */
19
+ async function fetchAllPages(fetchPage, options = {}) {
20
+ const { maxPages = 10, logProgress = true } = options;
21
+ let allItems = [];
22
+ let cursor;
23
+ let pageCount = 0;
24
+ let hasMore = true;
25
+ // Infinite loop protection - ensure we never fetch more than absolute max pages
26
+ const absoluteMaxPages = Math.min(maxPages, 50); // Hard limit to prevent infinite loops
27
+ while (hasMore && pageCount < absoluteMaxPages) {
28
+ try {
29
+ if (logProgress && pageCount > 0) {
30
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.DEBUG, `Fetching page ${pageCount + 1}`, { cursor });
31
+ }
32
+ const response = await fetchPage(cursor);
33
+ const data = response.data;
34
+ // Extract items from various possible response structures
35
+ const pageItems = extractItemsFromResponse(data);
36
+ // Enforce page size limit to prevent memory exhaustion
37
+ if (pageItems.length > constants_1.LIMITS.MAX_PAGE_SIZE) {
38
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.WARN, `Page size ${pageItems.length} exceeds maximum allowed ${constants_1.LIMITS.MAX_PAGE_SIZE}, truncating`, {
39
+ pageNumber: pageCount + 1,
40
+ originalSize: pageItems.length,
41
+ truncatedSize: constants_1.LIMITS.MAX_PAGE_SIZE
42
+ });
43
+ pageItems.splice(constants_1.LIMITS.MAX_PAGE_SIZE); // Truncate to limit
44
+ }
45
+ allItems = allItems.concat(pageItems);
46
+ // Update pagination state
47
+ const newCursor = data.meta?.nextCursor;
48
+ // Infinite loop protection: If cursor doesn't change, break
49
+ if (cursor && newCursor === cursor) {
50
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.WARN, 'Pagination cursor not advancing - breaking to prevent infinite loop', {
51
+ cursor,
52
+ pageCount,
53
+ itemsCount: pageItems.length
54
+ });
55
+ break;
56
+ }
57
+ cursor = newCursor;
58
+ hasMore = !!cursor && pageItems.length > 0;
59
+ pageCount++;
60
+ if (logProgress) {
61
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.DEBUG, `Page ${pageCount} fetched`, {
62
+ pageItems: pageItems.length,
63
+ totalItems: allItems.length,
64
+ hasMore,
65
+ nextCursor: cursor
66
+ });
67
+ }
68
+ }
69
+ catch (error) {
70
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.ERROR, `Pagination failed on page ${pageCount + 1}`, {
71
+ error: error instanceof Error ? error.message : String(error),
72
+ cursor
73
+ });
74
+ // Return what we have so far
75
+ break;
76
+ }
77
+ }
78
+ if (pageCount >= absoluteMaxPages && hasMore) {
79
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.WARN, `Reached maximum page limit (${absoluteMaxPages})`, {
80
+ totalFetched: allItems.length,
81
+ finalCursor: cursor
82
+ });
83
+ }
84
+ return {
85
+ items: allItems,
86
+ nextCursor: cursor,
87
+ hasMore,
88
+ totalFetched: allItems.length
89
+ };
90
+ }
91
+ /**
92
+ * Extract items from various API response structures
93
+ * Handles the different ways Motion API can structure responses
94
+ */
95
+ function extractItemsFromResponse(data) {
96
+ // Try different possible array locations
97
+ if (data.tasks && Array.isArray(data.tasks))
98
+ return data.tasks;
99
+ if (data.projects && Array.isArray(data.projects))
100
+ return data.projects;
101
+ if (data.users && Array.isArray(data.users))
102
+ return data.users;
103
+ if (data.comments && Array.isArray(data.comments))
104
+ return data.comments;
105
+ if (data.customFields && Array.isArray(data.customFields))
106
+ return data.customFields;
107
+ if (data.recurringTasks && Array.isArray(data.recurringTasks))
108
+ return data.recurringTasks;
109
+ if (data.schedules && Array.isArray(data.schedules))
110
+ return data.schedules;
111
+ if (data.statuses && Array.isArray(data.statuses))
112
+ return data.statuses;
113
+ if (data.items && Array.isArray(data.items))
114
+ return data.items;
115
+ // Fallback: if data itself is an array
116
+ if (Array.isArray(data))
117
+ return data;
118
+ // No items found
119
+ return [];
120
+ }
121
+ async function fetchInBatches(fetchBatch, params, options = {}) {
122
+ const { batchSize = 100, maxBatches = 10, delayMs = 100 } = options;
123
+ let allItems = [];
124
+ let offset = 0;
125
+ let batchCount = 0;
126
+ let hasMore = true;
127
+ while (hasMore && batchCount < maxBatches) {
128
+ try {
129
+ const batchItems = await fetchBatch(params, offset, batchSize);
130
+ if (batchItems.length === 0) {
131
+ hasMore = false;
132
+ }
133
+ else {
134
+ allItems = allItems.concat(batchItems);
135
+ offset += batchSize;
136
+ batchCount++;
137
+ // Small delay to be API-friendly
138
+ if (delayMs > 0 && hasMore) {
139
+ await new Promise(resolve => setTimeout(resolve, delayMs));
140
+ }
141
+ // If we got fewer items than batch size, we've reached the end
142
+ if (batchItems.length < batchSize) {
143
+ hasMore = false;
144
+ }
145
+ }
146
+ }
147
+ catch (error) {
148
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.ERROR, `Batch fetch failed at offset ${offset}`, {
149
+ error: error instanceof Error ? error.message : String(error)
150
+ });
151
+ break;
152
+ }
153
+ }
154
+ return allItems;
155
+ }
156
+ /**
157
+ * Check if a response indicates more pages are available
158
+ */
159
+ function hasMorePages(response) {
160
+ return !!(response.meta?.nextCursor || response.meta?.hasMore);
161
+ }
162
+ /**
163
+ * Get pagination info from response
164
+ */
165
+ function getPaginationInfo(response) {
166
+ return response.meta || null;
167
+ }
168
+ //# sourceMappingURL=pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/utils/pagination.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Enhanced Pagination Utilities with Proper Response Wrapper Support
3
+ *
4
+ * This replaces the old pagination utility with proper handling of Motion API's
5
+ * inconsistent response patterns using the ResponseWrapper utility.
6
+ */
7
+ import { AxiosResponse } from 'axios';
8
+ import { UnwrappedResponse } from './responseWrapper';
9
+ export interface PaginatedResponse<T> {
10
+ items: T[];
11
+ nextCursor?: string;
12
+ hasMore: boolean;
13
+ totalFetched: number;
14
+ }
15
+ export interface CursorPaginationOptions {
16
+ maxPages?: number;
17
+ pageSize?: number;
18
+ logProgress?: boolean;
19
+ maxItems?: number;
20
+ }
21
+ /**
22
+ * Enhanced pagination handler that properly uses response wrapper
23
+ *
24
+ * @param fetchPage - Function that fetches a single page of data
25
+ * @param apiEndpoint - The API endpoint name for proper response unwrapping
26
+ * @param options - Pagination options
27
+ * @returns All items from all pages with pagination metadata
28
+ */
29
+ export declare function fetchAllPages<T>(fetchPage: (cursor?: string) => Promise<AxiosResponse<any>>, apiEndpoint: string, options?: CursorPaginationOptions): Promise<PaginatedResponse<T>>;
30
+ /**
31
+ * Fetches a single page with proper response unwrapping
32
+ *
33
+ * @param fetchPage - Function that fetches a single page
34
+ * @param apiEndpoint - The API endpoint name for proper response unwrapping
35
+ * @param cursor - Optional cursor for the specific page
36
+ * @returns Single page of data with pagination metadata
37
+ */
38
+ export declare function fetchSinglePage<T>(fetchPage: (cursor?: string) => Promise<AxiosResponse<any>>, apiEndpoint: string, cursor?: string): Promise<UnwrappedResponse<T>>;
39
+ /**
40
+ * Check if an endpoint supports pagination
41
+ */
42
+ export declare function endpointSupportsPagination(apiEndpoint: string): boolean;
43
+ export { UnwrappedResponse } from './responseWrapper';
44
+ //# sourceMappingURL=paginationNew.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paginationNew.d.ts","sourceRoot":"","sources":["../../src/utils/paginationNew.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAGtC,OAAO,EAAyC,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG7F,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,SAAS,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EAC3D,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAuH/B;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,CAAC,EACrC,SAAS,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EAC3D,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAG/B;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAEvE;AAGD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ /**
3
+ * Enhanced Pagination Utilities with Proper Response Wrapper Support
4
+ *
5
+ * This replaces the old pagination utility with proper handling of Motion API's
6
+ * inconsistent response patterns using the ResponseWrapper utility.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.fetchAllPages = fetchAllPages;
10
+ exports.fetchSinglePage = fetchSinglePage;
11
+ exports.endpointSupportsPagination = endpointSupportsPagination;
12
+ const logger_1 = require("./logger");
13
+ const constants_1 = require("./constants");
14
+ const responseWrapper_1 = require("./responseWrapper");
15
+ /**
16
+ * Enhanced pagination handler that properly uses response wrapper
17
+ *
18
+ * @param fetchPage - Function that fetches a single page of data
19
+ * @param apiEndpoint - The API endpoint name for proper response unwrapping
20
+ * @param options - Pagination options
21
+ * @returns All items from all pages with pagination metadata
22
+ */
23
+ async function fetchAllPages(fetchPage, apiEndpoint, options = {}) {
24
+ const { maxPages = constants_1.LIMITS.MAX_PAGES, logProgress = true, maxItems = constants_1.LIMITS.MAX_PAGE_SIZE * 10 } = options;
25
+ let allItems = [];
26
+ let cursor;
27
+ let pageCount = 0;
28
+ let hasMore = true;
29
+ // Infinite loop protection - ensure we never fetch more than absolute max pages
30
+ const absoluteMaxPages = Math.min(maxPages, constants_1.LIMITS.ABSOLUTE_MAX_PAGES); // Hard limit to prevent infinite loops
31
+ while (hasMore && pageCount < absoluteMaxPages) {
32
+ try {
33
+ if (logProgress && pageCount > 0) {
34
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.DEBUG, `Fetching page ${pageCount + 1} for ${apiEndpoint}`, {
35
+ cursor,
36
+ pageCount,
37
+ itemsSoFar: allItems.length
38
+ });
39
+ }
40
+ const response = await fetchPage(cursor);
41
+ const unwrapped = (0, responseWrapper_1.unwrapApiResponse)(response.data, apiEndpoint);
42
+ // Enforce page size limit to prevent memory exhaustion
43
+ if (unwrapped.data.length > constants_1.LIMITS.MAX_PAGE_SIZE) {
44
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.WARN, `Page size ${unwrapped.data.length} exceeds maximum allowed ${constants_1.LIMITS.MAX_PAGE_SIZE}, truncating`, {
45
+ pageNumber: pageCount + 1,
46
+ endpoint: apiEndpoint,
47
+ originalSize: unwrapped.data.length,
48
+ truncatedSize: constants_1.LIMITS.MAX_PAGE_SIZE
49
+ });
50
+ unwrapped.data = unwrapped.data.slice(0, constants_1.LIMITS.MAX_PAGE_SIZE);
51
+ }
52
+ // Add items to our collection, but check memory limits first
53
+ const itemsToAdd = unwrapped.data;
54
+ if (allItems.length + itemsToAdd.length > maxItems) {
55
+ // Limit reached - add only what fits
56
+ const remainingSlots = maxItems - allItems.length;
57
+ if (remainingSlots > 0) {
58
+ allItems.push(...itemsToAdd.slice(0, remainingSlots));
59
+ }
60
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.WARN, `Memory limit reached for ${apiEndpoint}, stopping pagination`, {
61
+ totalItems: allItems.length,
62
+ maxItems,
63
+ pageCount: pageCount + 1,
64
+ endpoint: apiEndpoint
65
+ });
66
+ hasMore = false;
67
+ }
68
+ else {
69
+ allItems.push(...itemsToAdd);
70
+ }
71
+ pageCount++;
72
+ // Determine if there are more pages
73
+ if (unwrapped.meta?.nextCursor) {
74
+ const newCursor = unwrapped.meta.nextCursor;
75
+ // Additional safety: detect cursor not advancing (API bug protection)
76
+ if (pageCount > 1 && cursor === newCursor) {
77
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.WARN, `Cursor not advancing for ${apiEndpoint}, stopping pagination`, {
78
+ oldCursor: cursor,
79
+ newCursor,
80
+ pageCount,
81
+ endpoint: apiEndpoint
82
+ });
83
+ hasMore = false;
84
+ }
85
+ else {
86
+ cursor = newCursor;
87
+ }
88
+ }
89
+ else {
90
+ hasMore = false;
91
+ }
92
+ // If we got no items on this page, stop
93
+ if (unwrapped.data.length === 0) {
94
+ hasMore = false;
95
+ }
96
+ if (logProgress) {
97
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.DEBUG, `Page ${pageCount} fetched for ${apiEndpoint}`, {
98
+ pageItems: unwrapped.data.length,
99
+ totalItems: allItems.length,
100
+ hasMore,
101
+ nextCursor: cursor,
102
+ endpoint: apiEndpoint
103
+ });
104
+ }
105
+ }
106
+ catch (error) {
107
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.ERROR, `Failed to fetch page ${pageCount + 1} for ${apiEndpoint}`, {
108
+ error: error instanceof Error ? error.message : String(error),
109
+ pageCount,
110
+ cursor,
111
+ endpoint: apiEndpoint
112
+ });
113
+ // Don't completely fail - return what we have so far
114
+ hasMore = false;
115
+ }
116
+ }
117
+ if (pageCount >= absoluteMaxPages && hasMore) {
118
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.WARN, `Reached maximum page limit for ${apiEndpoint}`, {
119
+ maxPages: absoluteMaxPages,
120
+ totalItems: allItems.length,
121
+ endpoint: apiEndpoint
122
+ });
123
+ }
124
+ return {
125
+ items: allItems,
126
+ nextCursor: cursor,
127
+ hasMore: hasMore && pageCount < absoluteMaxPages,
128
+ totalFetched: allItems.length
129
+ };
130
+ }
131
+ /**
132
+ * Fetches a single page with proper response unwrapping
133
+ *
134
+ * @param fetchPage - Function that fetches a single page
135
+ * @param apiEndpoint - The API endpoint name for proper response unwrapping
136
+ * @param cursor - Optional cursor for the specific page
137
+ * @returns Single page of data with pagination metadata
138
+ */
139
+ async function fetchSinglePage(fetchPage, apiEndpoint, cursor) {
140
+ const response = await fetchPage(cursor);
141
+ return (0, responseWrapper_1.unwrapApiResponse)(response.data, apiEndpoint);
142
+ }
143
+ /**
144
+ * Check if an endpoint supports pagination
145
+ */
146
+ function endpointSupportsPagination(apiEndpoint) {
147
+ return (0, responseWrapper_1.supportsPagination)(apiEndpoint);
148
+ }
149
+ //# sourceMappingURL=paginationNew.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paginationNew.js","sourceRoot":"","sources":["../../src/utils/paginationNew.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AA8BH,sCA2HC;AAUD,0CAOC;AAKD,gEAEC;AA9KD,qCAAkC;AAClC,2CAAiD;AACjD,uDAA6F;AAiB7F;;;;;;;GAOG;AACI,KAAK,UAAU,aAAa,CACjC,SAA2D,EAC3D,WAAmB,EACnB,UAAmC,EAAE;IAErC,MAAM,EAAE,QAAQ,GAAG,kBAAM,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI,EAAE,QAAQ,GAAG,kBAAM,CAAC,aAAa,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;IAE1G,IAAI,QAAQ,GAAQ,EAAE,CAAC;IACvB,IAAI,MAA0B,CAAC;IAC/B,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,OAAO,GAAG,IAAI,CAAC;IAEnB,gFAAgF;IAChF,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,kBAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,uCAAuC;IAE/G,OAAO,OAAO,IAAI,SAAS,GAAG,gBAAgB,EAAE,CAAC;QAC/C,IAAI,CAAC;YACH,IAAI,WAAW,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;gBACjC,IAAA,eAAM,EAAC,sBAAU,CAAC,KAAK,EAAE,iBAAiB,SAAS,GAAG,CAAC,QAAQ,WAAW,EAAE,EAAE;oBAC5E,MAAM;oBACN,SAAS;oBACT,UAAU,EAAE,QAAQ,CAAC,MAAM;iBAC5B,CAAC,CAAC;YACL,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;YACzC,MAAM,SAAS,GAAG,IAAA,mCAAiB,EAAI,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YAEnE,uDAAuD;YACvD,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,GAAG,kBAAM,CAAC,aAAa,EAAE,CAAC;gBACjD,IAAA,eAAM,EAAC,sBAAU,CAAC,IAAI,EAAE,aAAa,SAAS,CAAC,IAAI,CAAC,MAAM,4BAA4B,kBAAM,CAAC,aAAa,cAAc,EAAE;oBACxH,UAAU,EAAE,SAAS,GAAG,CAAC;oBACzB,QAAQ,EAAE,WAAW;oBACrB,YAAY,EAAE,SAAS,CAAC,IAAI,CAAC,MAAM;oBACnC,aAAa,EAAE,kBAAM,CAAC,aAAa;iBACpC,CAAC,CAAC;gBACH,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,kBAAM,CAAC,aAAa,CAAC,CAAC;YACjE,CAAC;YAED,6DAA6D;YAC7D,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC;YAClC,IAAI,QAAQ,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;gBACnD,qCAAqC;gBACrC,MAAM,cAAc,GAAG,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC;gBAClD,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;oBACvB,QAAQ,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;gBACxD,CAAC;gBAED,IAAA,eAAM,EAAC,sBAAU,CAAC,IAAI,EAAE,4BAA4B,WAAW,uBAAuB,EAAE;oBACtF,UAAU,EAAE,QAAQ,CAAC,MAAM;oBAC3B,QAAQ;oBACR,SAAS,EAAE,SAAS,GAAG,CAAC;oBACxB,QAAQ,EAAE,WAAW;iBACtB,CAAC,CAAC;gBAEH,OAAO,GAAG,KAAK,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;YAC/B,CAAC;YACD,SAAS,EAAE,CAAC;YAEZ,oCAAoC;YACpC,IAAI,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC;gBAC/B,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC;gBAE5C,sEAAsE;gBACtE,IAAI,SAAS,GAAG,CAAC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBAC1C,IAAA,eAAM,EAAC,sBAAU,CAAC,IAAI,EAAE,4BAA4B,WAAW,uBAAuB,EAAE;wBACtF,SAAS,EAAE,MAAM;wBACjB,SAAS;wBACT,SAAS;wBACT,QAAQ,EAAE,WAAW;qBACtB,CAAC,CAAC;oBACH,OAAO,GAAG,KAAK,CAAC;gBAClB,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,SAAS,CAAC;gBACrB,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,GAAG,KAAK,CAAC;YAClB,CAAC;YAED,wCAAwC;YACxC,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAChC,OAAO,GAAG,KAAK,CAAC;YAClB,CAAC;YAED,IAAI,WAAW,EAAE,CAAC;gBAChB,IAAA,eAAM,EAAC,sBAAU,CAAC,KAAK,EAAE,QAAQ,SAAS,gBAAgB,WAAW,EAAE,EAAE;oBACvE,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,MAAM;oBAChC,UAAU,EAAE,QAAQ,CAAC,MAAM;oBAC3B,OAAO;oBACP,UAAU,EAAE,MAAM;oBAClB,QAAQ,EAAE,WAAW;iBACtB,CAAC,CAAC;YACL,CAAC;QAEH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAA,eAAM,EAAC,sBAAU,CAAC,KAAK,EAAE,wBAAwB,SAAS,GAAG,CAAC,QAAQ,WAAW,EAAE,EAAE;gBACnF,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;gBAC7D,SAAS;gBACT,MAAM;gBACN,QAAQ,EAAE,WAAW;aACtB,CAAC,CAAC;YAEH,qDAAqD;YACrD,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;IACH,CAAC;IAED,IAAI,SAAS,IAAI,gBAAgB,IAAI,OAAO,EAAE,CAAC;QAC7C,IAAA,eAAM,EAAC,sBAAU,CAAC,IAAI,EAAE,kCAAkC,WAAW,EAAE,EAAE;YACvE,QAAQ,EAAE,gBAAgB;YAC1B,UAAU,EAAE,QAAQ,CAAC,MAAM;YAC3B,QAAQ,EAAE,WAAW;SACtB,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,KAAK,EAAE,QAAQ;QACf,UAAU,EAAE,MAAM;QAClB,OAAO,EAAE,OAAO,IAAI,SAAS,GAAG,gBAAgB;QAChD,YAAY,EAAE,QAAQ,CAAC,MAAM;KAC9B,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACI,KAAK,UAAU,eAAe,CACnC,SAA2D,EAC3D,WAAmB,EACnB,MAAe;IAEf,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;IACzC,OAAO,IAAA,mCAAiB,EAAI,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;AAC1D,CAAC;AAED;;GAEG;AACH,SAAgB,0BAA0B,CAAC,WAAmB;IAC5D,OAAO,IAAA,oCAAkB,EAAC,WAAW,CAAC,CAAC;AACzC,CAAC"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Parameter Utilities - Parameter parsing and validation helpers
3
+ *
4
+ * This module provides utilities for parsing, validating, and setting
5
+ * default values for MCP handler parameters, reducing duplication and
6
+ * ensuring consistent parameter handling.
7
+ */
8
+ interface WorkspaceArgs {
9
+ workspaceId?: string;
10
+ workspaceName?: string;
11
+ }
12
+ interface SearchArgs extends WorkspaceArgs {
13
+ query?: string;
14
+ searchScope?: 'both' | 'tasks' | 'projects';
15
+ limit?: number;
16
+ }
17
+ interface TaskArgs extends WorkspaceArgs {
18
+ name?: string;
19
+ description?: string;
20
+ projectId?: string;
21
+ projectName?: string;
22
+ status?: string;
23
+ priority?: 'ASAP' | 'HIGH' | 'MEDIUM' | 'LOW';
24
+ dueDate?: string;
25
+ duration?: string | number;
26
+ labels?: string[];
27
+ assigneeId?: string;
28
+ autoScheduled?: Record<string, unknown> | null;
29
+ }
30
+ interface ProjectArgs extends WorkspaceArgs {
31
+ name?: string;
32
+ description?: string;
33
+ color?: string;
34
+ status?: string;
35
+ }
36
+ /**
37
+ * Parse workspace-related arguments from MCP request
38
+ */
39
+ export declare function parseWorkspaceArgs(args?: Record<string, unknown>): WorkspaceArgs;
40
+ /**
41
+ * Parse search-related arguments from MCP request
42
+ */
43
+ export declare function parseSearchArgs(args?: Record<string, unknown>): SearchArgs;
44
+ /**
45
+ * Parse task creation/update arguments from MCP request
46
+ */
47
+ export declare function parseTaskArgs(args?: Record<string, unknown>): TaskArgs;
48
+ /**
49
+ * Parse project creation/update arguments from MCP request
50
+ */
51
+ export declare function parseProjectArgs(args?: Record<string, unknown>): ProjectArgs;
52
+ /**
53
+ * Set default values for parameters
54
+ */
55
+ export declare function setDefaults<T extends object, D extends Partial<T>>(args?: T, defaults?: D): T & D;
56
+ /**
57
+ * Validate that required parameters are present
58
+ * @throws {ValidationError} If required parameters are missing
59
+ */
60
+ export declare function validateRequiredParams(args?: Record<string, unknown>, required?: string[]): void;
61
+ /**
62
+ * Validate parameter types
63
+ * @throws {ValidationError} If parameters have wrong types
64
+ */
65
+ export declare function validateParameterTypes(args?: Record<string, unknown>, types?: Record<string, string>): void;
66
+ /**
67
+ * Sanitize string parameters (trim whitespace, handle empty strings)
68
+ * Following NULL_UNDEFINED_POLICY: empty strings become undefined (deleted)
69
+ */
70
+ export declare function sanitizeStringParams<T extends Record<string, any>>(args?: T, stringParams?: (keyof T)[]): T;
71
+ interface ValidationOptions {
72
+ requireWorkspace?: boolean;
73
+ }
74
+ /**
75
+ * Parse and validate workspace parameters with common validation
76
+ */
77
+ export declare function parseAndValidateWorkspace(args?: Record<string, unknown>, options?: ValidationOptions): WorkspaceArgs;
78
+ export {};
79
+ //# sourceMappingURL=parameterUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parameterUtils.d.ts","sourceRoot":"","sources":["../../src/utils/parameterUtils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,UAAU,aAAa;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,UAAW,SAAQ,aAAa;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,QAAS,SAAQ,aAAa;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAChD;AAED,UAAU,WAAY,SAAQ,aAAa;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,aAAa,CAKpF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,UAAU,CAO9E;AAoDD;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,QAAQ,CAe1E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,WAAW,CAQhF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,EAChE,IAAI,GAAE,CAAW,EACjB,QAAQ,GAAE,CAAW,GACpB,CAAC,GAAG,CAAC,CAEP;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAClC,QAAQ,GAAE,MAAM,EAAO,GACtB,IAAI,CAgBN;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAClC,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACjC,IAAI,CAmBN;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAChE,IAAI,GAAE,CAAW,EACjB,YAAY,GAAE,CAAC,MAAM,CAAC,CAAC,EAAO,GAC7B,CAAC,CAoBH;AAED,UAAU,iBAAiB;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAClC,OAAO,GAAE,iBAAsB,GAC9B,aAAa,CAcf"}