@panoptic-it-solutions/zoho-projects-client 0.2.4 → 0.2.6

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 (178) hide show
  1. package/README.md +75 -7
  2. package/dist/__tests__/fixtures/attachments.d.ts +59 -39
  3. package/dist/__tests__/fixtures/attachments.d.ts.map +1 -1
  4. package/dist/__tests__/fixtures/attachments.js +2 -4
  5. package/dist/__tests__/fixtures/attachments.js.map +1 -1
  6. package/dist/__tests__/fixtures/comments.d.ts +25 -13
  7. package/dist/__tests__/fixtures/comments.d.ts.map +1 -1
  8. package/dist/__tests__/fixtures/events.d.ts +27 -15
  9. package/dist/__tests__/fixtures/events.d.ts.map +1 -1
  10. package/dist/__tests__/fixtures/forums.d.ts +25 -13
  11. package/dist/__tests__/fixtures/forums.d.ts.map +1 -1
  12. package/dist/__tests__/fixtures/issues.d.ts +50 -26
  13. package/dist/__tests__/fixtures/issues.d.ts.map +1 -1
  14. package/dist/__tests__/fixtures/phases.d.ts +325 -41
  15. package/dist/__tests__/fixtures/phases.d.ts.map +1 -1
  16. package/dist/__tests__/fixtures/projects.d.ts +176 -8
  17. package/dist/__tests__/fixtures/projects.d.ts.map +1 -1
  18. package/dist/__tests__/fixtures/tasklists.d.ts +71 -25
  19. package/dist/__tests__/fixtures/tasklists.d.ts.map +1 -1
  20. package/dist/__tests__/fixtures/tasklists.js +1 -3
  21. package/dist/__tests__/fixtures/tasklists.js.map +1 -1
  22. package/dist/__tests__/fixtures/tasks.d.ts +257 -62
  23. package/dist/__tests__/fixtures/tasks.d.ts.map +1 -1
  24. package/dist/__tests__/fixtures/timelogs.d.ts +2 -2
  25. package/dist/__tests__/integration/api-v3.test.d.ts +2 -0
  26. package/dist/__tests__/integration/api-v3.test.d.ts.map +1 -0
  27. package/dist/__tests__/integration/api-v3.test.js +180 -0
  28. package/dist/__tests__/integration/api-v3.test.js.map +1 -0
  29. package/dist/__tests__/integration/setup.d.ts +0 -3
  30. package/dist/__tests__/integration/setup.d.ts.map +1 -1
  31. package/dist/__tests__/integration/setup.js +7 -1
  32. package/dist/__tests__/integration/setup.js.map +1 -1
  33. package/dist/__tests__/unit/client/attachments.test.js +31 -10
  34. package/dist/__tests__/unit/client/attachments.test.js.map +1 -1
  35. package/dist/__tests__/unit/client/blueprints.test.js +11 -11
  36. package/dist/__tests__/unit/client/blueprints.test.js.map +1 -1
  37. package/dist/__tests__/unit/client/clients.test.js +6 -6
  38. package/dist/__tests__/unit/client/clients.test.js.map +1 -1
  39. package/dist/__tests__/unit/client/comments.test.js +7 -7
  40. package/dist/__tests__/unit/client/comments.test.js.map +1 -1
  41. package/dist/__tests__/unit/client/contacts.test.js +6 -6
  42. package/dist/__tests__/unit/client/contacts.test.js.map +1 -1
  43. package/dist/__tests__/unit/client/customviews.test.js +8 -8
  44. package/dist/__tests__/unit/client/customviews.test.js.map +1 -1
  45. package/dist/__tests__/unit/client/dashboards.test.js +6 -6
  46. package/dist/__tests__/unit/client/dashboards.test.js.map +1 -1
  47. package/dist/__tests__/unit/client/events.test.js +6 -6
  48. package/dist/__tests__/unit/client/events.test.js.map +1 -1
  49. package/dist/__tests__/unit/client/followers.test.js +8 -8
  50. package/dist/__tests__/unit/client/followers.test.js.map +1 -1
  51. package/dist/__tests__/unit/client/forums.test.js +6 -6
  52. package/dist/__tests__/unit/client/forums.test.js.map +1 -1
  53. package/dist/__tests__/unit/client/groups.test.js +6 -6
  54. package/dist/__tests__/unit/client/groups.test.js.map +1 -1
  55. package/dist/__tests__/unit/client/issues.test.js +6 -6
  56. package/dist/__tests__/unit/client/issues.test.js.map +1 -1
  57. package/dist/__tests__/unit/client/leaves.test.js +6 -6
  58. package/dist/__tests__/unit/client/leaves.test.js.map +1 -1
  59. package/dist/__tests__/unit/client/modules.test.js +7 -7
  60. package/dist/__tests__/unit/client/modules.test.js.map +1 -1
  61. package/dist/__tests__/unit/client/phases.test.js +6 -6
  62. package/dist/__tests__/unit/client/phases.test.js.map +1 -1
  63. package/dist/__tests__/unit/client/portals.test.js +3 -3
  64. package/dist/__tests__/unit/client/portals.test.js.map +1 -1
  65. package/dist/__tests__/unit/client/profiles.test.js +6 -6
  66. package/dist/__tests__/unit/client/profiles.test.js.map +1 -1
  67. package/dist/__tests__/unit/client/projects.test.js +18 -18
  68. package/dist/__tests__/unit/client/projects.test.js.map +1 -1
  69. package/dist/__tests__/unit/client/reports.test.js +9 -9
  70. package/dist/__tests__/unit/client/reports.test.js.map +1 -1
  71. package/dist/__tests__/unit/client/roles.test.js +6 -6
  72. package/dist/__tests__/unit/client/roles.test.js.map +1 -1
  73. package/dist/__tests__/unit/client/search.test.js +7 -7
  74. package/dist/__tests__/unit/client/search.test.js.map +1 -1
  75. package/dist/__tests__/unit/client/tags.test.js +9 -9
  76. package/dist/__tests__/unit/client/tags.test.js.map +1 -1
  77. package/dist/__tests__/unit/client/tasklists.test.js +12 -12
  78. package/dist/__tests__/unit/client/tasklists.test.js.map +1 -1
  79. package/dist/__tests__/unit/client/tasks.test.js +17 -17
  80. package/dist/__tests__/unit/client/tasks.test.js.map +1 -1
  81. package/dist/__tests__/unit/client/teams.test.js +8 -8
  82. package/dist/__tests__/unit/client/teams.test.js.map +1 -1
  83. package/dist/__tests__/unit/client/timelogs.test.js +7 -7
  84. package/dist/__tests__/unit/client/timelogs.test.js.map +1 -1
  85. package/dist/__tests__/unit/client/timers.test.js +11 -11
  86. package/dist/__tests__/unit/client/timers.test.js.map +1 -1
  87. package/dist/__tests__/unit/client/trash.test.js +8 -8
  88. package/dist/__tests__/unit/client/trash.test.js.map +1 -1
  89. package/dist/__tests__/unit/client/users.test.js +8 -8
  90. package/dist/__tests__/unit/client/users.test.js.map +1 -1
  91. package/dist/__tests__/unit/client/widgets.test.js +6 -6
  92. package/dist/__tests__/unit/client/widgets.test.js.map +1 -1
  93. package/dist/client.d.ts +63 -11
  94. package/dist/client.d.ts.map +1 -1
  95. package/dist/client.js +470 -274
  96. package/dist/client.js.map +1 -1
  97. package/dist/types/attachments.d.ts +1525 -512
  98. package/dist/types/attachments.d.ts.map +1 -1
  99. package/dist/types/attachments.js +51 -10
  100. package/dist/types/attachments.js.map +1 -1
  101. package/dist/types/clients.js +2 -2
  102. package/dist/types/clients.js.map +1 -1
  103. package/dist/types/comments.d.ts +325 -169
  104. package/dist/types/comments.d.ts.map +1 -1
  105. package/dist/types/common.d.ts +33 -15
  106. package/dist/types/common.d.ts.map +1 -1
  107. package/dist/types/common.js +12 -7
  108. package/dist/types/common.js.map +1 -1
  109. package/dist/types/contacts.d.ts +6 -6
  110. package/dist/types/dashboards.d.ts +979 -511
  111. package/dist/types/dashboards.d.ts.map +1 -1
  112. package/dist/types/dashboards.js +1 -1
  113. package/dist/types/dashboards.js.map +1 -1
  114. package/dist/types/documents.d.ts +1300 -676
  115. package/dist/types/documents.d.ts.map +1 -1
  116. package/dist/types/events.d.ts +351 -195
  117. package/dist/types/events.d.ts.map +1 -1
  118. package/dist/types/forums.d.ts +325 -169
  119. package/dist/types/forums.d.ts.map +1 -1
  120. package/dist/types/forums.js +2 -2
  121. package/dist/types/forums.js.map +1 -1
  122. package/dist/types/groups.js +1 -1
  123. package/dist/types/groups.js.map +1 -1
  124. package/dist/types/index.d.ts +2 -1
  125. package/dist/types/index.d.ts.map +1 -1
  126. package/dist/types/index.js +3 -1
  127. package/dist/types/index.js.map +1 -1
  128. package/dist/types/issues.d.ts +650 -338
  129. package/dist/types/issues.d.ts.map +1 -1
  130. package/dist/types/issues.js +3 -3
  131. package/dist/types/issues.js.map +1 -1
  132. package/dist/types/phases.d.ts +4358 -561
  133. package/dist/types/phases.d.ts.map +1 -1
  134. package/dist/types/phases.js +103 -25
  135. package/dist/types/phases.js.map +1 -1
  136. package/dist/types/portals.js +5 -5
  137. package/dist/types/portals.js.map +1 -1
  138. package/dist/types/profiles.js +1 -1
  139. package/dist/types/profiles.js.map +1 -1
  140. package/dist/types/projects.d.ts +6324 -1368
  141. package/dist/types/projects.d.ts.map +1 -1
  142. package/dist/types/projects.js +123 -39
  143. package/dist/types/projects.js.map +1 -1
  144. package/dist/types/reports.d.ts +650 -338
  145. package/dist/types/reports.d.ts.map +1 -1
  146. package/dist/types/reports.js +1 -1
  147. package/dist/types/reports.js.map +1 -1
  148. package/dist/types/search.js +1 -1
  149. package/dist/types/search.js.map +1 -1
  150. package/dist/types/tags.js +1 -1
  151. package/dist/types/tags.js.map +1 -1
  152. package/dist/types/tasklists.d.ts +938 -326
  153. package/dist/types/tasklists.d.ts.map +1 -1
  154. package/dist/types/tasklists.js +43 -16
  155. package/dist/types/tasklists.js.map +1 -1
  156. package/dist/types/tasks.d.ts +3516 -876
  157. package/dist/types/tasks.d.ts.map +1 -1
  158. package/dist/types/tasks.js +70 -23
  159. package/dist/types/tasks.js.map +1 -1
  160. package/dist/types/teams.js +2 -2
  161. package/dist/types/teams.js.map +1 -1
  162. package/dist/types/timelogs.d.ts +232 -230
  163. package/dist/types/timelogs.d.ts.map +1 -1
  164. package/dist/types/timelogs.js.map +1 -1
  165. package/dist/types/timers.d.ts +750 -390
  166. package/dist/types/timers.d.ts.map +1 -1
  167. package/dist/types/trash.d.ts +650 -338
  168. package/dist/types/trash.d.ts.map +1 -1
  169. package/dist/types/workdrive.d.ts +1002 -0
  170. package/dist/types/workdrive.d.ts.map +1 -0
  171. package/dist/types/workdrive.js +70 -0
  172. package/dist/types/workdrive.js.map +1 -0
  173. package/dist/utils/pagination.d.ts +9 -9
  174. package/dist/utils/pagination.d.ts.map +1 -1
  175. package/dist/utils/pagination.js +11 -11
  176. package/dist/utils/pagination.js.map +1 -1
  177. package/package.json +3 -1
  178. package/templates/CLAUDE.md +185 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workdrive.d.ts","sourceRoot":"","sources":["../../src/types/workdrive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAmBhB,CAAC;AAEjB,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE;;GAEG;AACH,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAE1B,CAAC;AAEjB,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF;;GAEG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAQtB,CAAC;AAEjB,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAMhB,CAAC;AAEjB,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAMhE;;GAEG;AACH,eAAO,MAAM,0BAA0B;IACrC,oCAAoC;;IAEpC,wDAAwD;;IAExD,sEAAsE;;;;;;;;;;EAEtE,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { z } from "zod";
2
+ // ─────────────────────────────────────────────────────────────────────────────
3
+ // WORKDRIVE SCHEMAS
4
+ // ─────────────────────────────────────────────────────────────────────────────
5
+ /**
6
+ * WorkDrive file upload response
7
+ */
8
+ export const WorkDriveFileSchema = z.object({
9
+ id: z.string(),
10
+ type: z.string().optional(),
11
+ attributes: z.object({
12
+ name: z.string(),
13
+ type: z.string().optional(),
14
+ extn: z.string().optional(),
15
+ resource_id: z.string().optional(),
16
+ parent_id: z.string().optional(),
17
+ storage_info: z.object({
18
+ size: z.string().optional(),
19
+ files_count: z.string().optional(),
20
+ folders_count: z.string().optional(),
21
+ }).optional(),
22
+ download_url: z.string().optional(),
23
+ permalink: z.string().optional(),
24
+ created_time: z.string().optional(),
25
+ modified_time: z.string().optional(),
26
+ }).passthrough(),
27
+ }).passthrough();
28
+ /**
29
+ * WorkDrive upload response schema
30
+ */
31
+ export const WorkDriveUploadResponseSchema = z.object({
32
+ data: z.array(WorkDriveFileSchema),
33
+ }).passthrough();
34
+ /**
35
+ * WorkDrive team folder schema
36
+ */
37
+ export const WorkDriveTeamFolderSchema = z.object({
38
+ id: z.string(),
39
+ type: z.string().optional(),
40
+ attributes: z.object({
41
+ name: z.string(),
42
+ is_default: z.boolean().optional(),
43
+ parent_id: z.string().optional(),
44
+ }).passthrough(),
45
+ }).passthrough();
46
+ /**
47
+ * WorkDrive team schema
48
+ */
49
+ export const WorkDriveTeamSchema = z.object({
50
+ id: z.string(),
51
+ type: z.string().optional(),
52
+ attributes: z.object({
53
+ name: z.string(),
54
+ }).passthrough(),
55
+ }).passthrough();
56
+ // ─────────────────────────────────────────────────────────────────────────────
57
+ // INPUT SCHEMAS
58
+ // ─────────────────────────────────────────────────────────────────────────────
59
+ /**
60
+ * Input for uploading a file to WorkDrive
61
+ */
62
+ export const WorkDriveUploadInputSchema = z.object({
63
+ /** Parent folder ID in WorkDrive */
64
+ parent_id: z.string(),
65
+ /** Optional custom filename (URL-encoded with UTF-8) */
66
+ filename: z.string().optional(),
67
+ /** If true, overwrites existing file with same name as new version */
68
+ override_name_exist: z.boolean().optional(),
69
+ });
70
+ //# sourceMappingURL=workdrive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workdrive.js","sourceRoot":"","sources":["../../src/types/workdrive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,gFAAgF;AAChF,oBAAoB;AACpB,gFAAgF;AAEhF;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC3B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC3B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAClC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAChC,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC3B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAClC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;SACrC,CAAC,CAAC,QAAQ,EAAE;QACb,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACnC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAChC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACnC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KACrC,CAAC,CAAC,WAAW,EAAE;CACjB,CAAC,CAAC,WAAW,EAAE,CAAC;AAIjB;;GAEG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC;IACpD,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC;CACnC,CAAC,CAAC,WAAW,EAAE,CAAC;AAIjB;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;QAClC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KACjC,CAAC,CAAC,WAAW,EAAE;CACjB,CAAC,CAAC,WAAW,EAAE,CAAC;AAIjB;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;KACjB,CAAC,CAAC,WAAW,EAAE;CACjB,CAAC,CAAC,WAAW,EAAE,CAAC;AAIjB,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF;;GAEG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,oCAAoC;IACpC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,wDAAwD;IACxD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,sEAAsE;IACtE,mBAAmB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CAC5C,CAAC,CAAC"}
@@ -27,19 +27,19 @@ export interface AutoPaginateOptions {
27
27
  /**
28
28
  * Create an async generator that automatically handles pagination
29
29
  *
30
- * Usage:
30
+ * Usage (V3 API - page-based):
31
31
  * ```ts
32
- * for await (const project of autoPaginate((index) =>
33
- * client.projects.list({ index, range: 100 })
32
+ * for await (const project of autoPaginate((page, per_page) =>
33
+ * client.projects.list({ page, per_page })
34
34
  * )) {
35
35
  * console.log(project);
36
36
  * }
37
37
  * ```
38
38
  *
39
- * @param fetchPage Function that fetches a page given the index (0-based)
39
+ * @param fetchPage Function that fetches a page given page number (1-based) and page size
40
40
  * @param options Pagination options
41
41
  */
42
- export declare function autoPaginate<T>(fetchPage: (index: number, range: number) => Promise<PaginatedResponse<T>>, options?: AutoPaginateOptions): AsyncGenerator<T, void, unknown>;
42
+ export declare function autoPaginate<T>(fetchPage: (page: number, per_page: number) => Promise<PaginatedResponse<T>>, options?: AutoPaginateOptions): AsyncGenerator<T, void, unknown>;
43
43
  /**
44
44
  * Collect all items from an async generator into an array
45
45
  *
@@ -50,10 +50,10 @@ export declare function autoPaginate<T>(fetchPage: (index: number, range: number
50
50
  */
51
51
  export declare function collectAll<T>(generator: AsyncGenerator<T, void, unknown>): Promise<T[]>;
52
52
  /**
53
- * Helper to create pagination params for Zoho API
53
+ * Helper to create pagination params for Zoho V3 API
54
54
  */
55
- export declare function createPaginationParams(index?: number, range?: number): {
56
- index: number;
57
- range: number;
55
+ export declare function createPaginationParams(page?: number, per_page?: number): {
56
+ page: number;
57
+ per_page: number;
58
58
  };
59
59
  //# sourceMappingURL=pagination.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/utils/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC;;GAEG;AACH,eAAO,MAAM,aAAa,MAAM,CAAC;AAEjC;;GAEG;AACH,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAuB,YAAY,CAAC,CAAC,EACnC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAC1E,OAAO,GAAE,mBAAwB,GAChC,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAqClC;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,CAAC,EAChC,SAAS,EAAE,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAC1C,OAAO,CAAC,CAAC,EAAE,CAAC,CAMd;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,GAAE,MAAU,EACjB,KAAK,GAAE,MAA0B,GAChC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAKlC"}
1
+ {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/utils/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC;;GAEG;AACH,eAAO,MAAM,aAAa,MAAM,CAAC;AAEjC;;GAEG;AACH,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAuB,YAAY,CAAC,CAAC,EACnC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAC5E,OAAO,GAAE,mBAAwB,GAChC,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAqClC;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,CAAC,EAChC,SAAS,EAAE,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAC1C,OAAO,CAAC,CAAC,EAAE,CAAC,CAMd;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,GAAE,MAAU,EAChB,QAAQ,GAAE,MAA0B,GACnC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAKpC"}
@@ -10,26 +10,26 @@ export const MAX_PAGE_SIZE = 200;
10
10
  /**
11
11
  * Create an async generator that automatically handles pagination
12
12
  *
13
- * Usage:
13
+ * Usage (V3 API - page-based):
14
14
  * ```ts
15
- * for await (const project of autoPaginate((index) =>
16
- * client.projects.list({ index, range: 100 })
15
+ * for await (const project of autoPaginate((page, per_page) =>
16
+ * client.projects.list({ page, per_page })
17
17
  * )) {
18
18
  * console.log(project);
19
19
  * }
20
20
  * ```
21
21
  *
22
- * @param fetchPage Function that fetches a page given the index (0-based)
22
+ * @param fetchPage Function that fetches a page given page number (1-based) and page size
23
23
  * @param options Pagination options
24
24
  */
25
25
  export async function* autoPaginate(fetchPage, options = {}) {
26
26
  const pageSize = Math.min(options.pageSize ?? DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE);
27
27
  const maxItems = options.maxItems ?? Infinity;
28
- let index = 0;
28
+ let page = 1; // V3 API uses 1-based pages
29
29
  let itemsYielded = 0;
30
30
  let hasMore = true;
31
31
  while (hasMore && itemsYielded < maxItems) {
32
- const response = await fetchPage(index, pageSize);
32
+ const response = await fetchPage(page, pageSize);
33
33
  const items = response.data;
34
34
  if (items.length === 0) {
35
35
  // No more items
@@ -53,7 +53,7 @@ export async function* autoPaginate(fetchPage, options = {}) {
53
53
  }
54
54
  else {
55
55
  // Move to next page
56
- index += pageSize;
56
+ page++;
57
57
  }
58
58
  }
59
59
  }
@@ -73,12 +73,12 @@ export async function collectAll(generator) {
73
73
  return items;
74
74
  }
75
75
  /**
76
- * Helper to create pagination params for Zoho API
76
+ * Helper to create pagination params for Zoho V3 API
77
77
  */
78
- export function createPaginationParams(index = 0, range = DEFAULT_PAGE_SIZE) {
78
+ export function createPaginationParams(page = 1, per_page = DEFAULT_PAGE_SIZE) {
79
79
  return {
80
- index,
81
- range: Math.min(range, MAX_PAGE_SIZE),
80
+ page,
81
+ per_page: Math.min(per_page, MAX_PAGE_SIZE),
82
82
  };
83
83
  }
84
84
  //# sourceMappingURL=pagination.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/utils/pagination.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAErC;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAC;AAoBjC;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,YAAY,CACjC,SAA0E,EAC1E,UAA+B,EAAE;IAEjC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,iBAAiB,EAAE,aAAa,CAAC,CAAC;IAChF,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC;IAE9C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,OAAO,GAAG,IAAI,CAAC;IAEnB,OAAO,OAAO,IAAI,YAAY,GAAG,QAAQ,EAAE,CAAC;QAC1C,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC;QAE5B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,gBAAgB;YAChB,OAAO,GAAG,KAAK,CAAC;YAChB,MAAM;QACR,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,YAAY,IAAI,QAAQ,EAAE,CAAC;gBAC7B,OAAO;YACT,CAAC;YACD,MAAM,IAAI,CAAC;YACX,YAAY,EAAE,CAAC;QACjB,CAAC;QAED,oCAAoC;QACpC,IAAI,QAAQ,CAAC,QAAQ,EAAE,aAAa,KAAK,KAAK,EAAE,CAAC;YAC/C,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;YACnC,wDAAwD;YACxD,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,oBAAoB;YACpB,KAAK,IAAI,QAAQ,CAAC;QACpB,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,SAA2C;IAE3C,MAAM,KAAK,GAAQ,EAAE,CAAC;IACtB,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,QAAgB,CAAC,EACjB,QAAgB,iBAAiB;IAEjC,OAAO;QACL,KAAK;QACL,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,aAAa,CAAC;KACtC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/utils/pagination.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAErC;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAC;AAoBjC;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,YAAY,CACjC,SAA4E,EAC5E,UAA+B,EAAE;IAEjC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,iBAAiB,EAAE,aAAa,CAAC,CAAC;IAChF,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC;IAE9C,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,4BAA4B;IAC1C,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,OAAO,GAAG,IAAI,CAAC;IAEnB,OAAO,OAAO,IAAI,YAAY,GAAG,QAAQ,EAAE,CAAC;QAC1C,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC;QAE5B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,gBAAgB;YAChB,OAAO,GAAG,KAAK,CAAC;YAChB,MAAM;QACR,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,YAAY,IAAI,QAAQ,EAAE,CAAC;gBAC7B,OAAO;YACT,CAAC;YACD,MAAM,IAAI,CAAC;YACX,YAAY,EAAE,CAAC;QACjB,CAAC;QAED,oCAAoC;QACpC,IAAI,QAAQ,CAAC,QAAQ,EAAE,aAAa,KAAK,KAAK,EAAE,CAAC;YAC/C,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;YACnC,wDAAwD;YACxD,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,oBAAoB;YACpB,IAAI,EAAE,CAAC;QACT,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,SAA2C;IAE3C,MAAM,KAAK,GAAQ,EAAE,CAAC;IACtB,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAAe,CAAC,EAChB,WAAmB,iBAAiB;IAEpC,OAAO;QACL,IAAI;QACJ,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC;KAC5C,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panoptic-it-solutions/zoho-projects-client",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "TypeScript client for Zoho Projects V3 API with OAuth 2.0 and rate limiting",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -25,6 +25,7 @@
25
25
  "test:watch": "vitest",
26
26
  "test:coverage": "vitest run --coverage",
27
27
  "test:integration": "vitest run --config vitest.integration.config.ts",
28
+ "oauth": "npx tsx scripts/get-refresh-token.ts",
28
29
  "prepublishOnly": "npm run clean && npm run build"
29
30
  },
30
31
  "keywords": [
@@ -55,6 +56,7 @@
55
56
  "@faker-js/faker": "^9.3.0",
56
57
  "@types/node": "^22.0.0",
57
58
  "@vitest/coverage-v8": "^2.1.0",
59
+ "dotenv": "^17.2.3",
58
60
  "msw": "^2.7.0",
59
61
  "typescript": "^5.6.0",
60
62
  "vitest": "^2.1.0"
@@ -19,6 +19,9 @@ const client = createZohoProjectsClient({
19
19
  clientSecret: process.env.ZOHO_CLIENT_SECRET!,
20
20
  refreshToken: process.env.ZOHO_REFRESH_TOKEN!,
21
21
  portalId: process.env.ZOHO_PORTAL_ID!,
22
+ // For EU region:
23
+ apiUrl: 'https://projectsapi.zoho.eu',
24
+ accountsUrl: 'https://accounts.zoho.eu',
22
25
  });
23
26
  ```
24
27
 
@@ -29,8 +32,173 @@ ZOHO_CLIENT_ID= # OAuth client ID from Zoho API Console
29
32
  ZOHO_CLIENT_SECRET= # OAuth client secret
30
33
  ZOHO_REFRESH_TOKEN= # Refresh token from OAuth flow
31
34
  ZOHO_PORTAL_ID= # Your Zoho Projects portal ID
35
+
36
+ # Optional - Region URLs (defaults to US)
37
+ ZOHO_API_URL=https://projectsapi.zoho.eu
38
+ ZOHO_ACCOUNTS_URL=https://accounts.zoho.eu
39
+ ```
40
+
41
+ ## Required OAuth Scopes
42
+
43
+ For full V3 API functionality:
44
+ ```
45
+ ZohoProjects.projects.ALL,ZohoProjects.tasks.ALL,ZohoProjects.tasklists.ALL,ZohoProjects.portals.READ,ZohoProjects.users.ALL,ZohoProjects.timesheets.ALL,ZohoProjects.bugs.ALL,ZohoProjects.milestones.ALL,ZohoProjects.events.ALL,ZohoProjects.forums.ALL,ZohoProjects.documents.ALL,ZohoProjects.tags.ALL,ZohoProjects.status.READ,ZohoProjects.search.READ
46
+ ```
47
+
48
+ **For file attachments (requires WorkDrive integration):**
49
+ ```
50
+ ZohoPC.files.ALL,WorkDrive.team.ALL,WorkDrive.workspace.ALL,WorkDrive.files.ALL,WorkDrive.teamfolders.ALL
32
51
  ```
33
52
 
53
+ Use `scripts/get-refresh-token.ts` to generate a token with all scopes. This script will open a browser window for OAuth authorization and automatically request all required scopes.
54
+
55
+ ---
56
+
57
+ ## File Attachment Workflow (AI Agent Instructions)
58
+
59
+ Zoho Projects uses **WorkDrive** for file storage. There are two methods to attach files to tasks:
60
+
61
+ ### Method 1: Simple Direct Upload (Recommended)
62
+
63
+ Use the legacy `/restapi/` endpoint with `uploaddoc` form field. This is the **simplest and most reliable** method - it handles WorkDrive upload and task association in a single request.
64
+
65
+ #### Required OAuth Scopes
66
+
67
+ | Scope | Purpose |
68
+ |-------|---------|
69
+ | `ZohoProjects.tasks.ALL` | Task operations |
70
+ | `ZohoProjects.documents.ALL` | Document access |
71
+ | `ZohoPC.files.ALL` | Attachments API |
72
+
73
+ #### Upload File to Task
74
+
75
+ ```typescript
76
+ import FormData from 'form-data';
77
+ import axios from 'axios';
78
+
79
+ const formData = new FormData();
80
+ formData.append('uploaddoc', fileBuffer, {
81
+ filename: 'test.txt',
82
+ contentType: 'text/plain'
83
+ });
84
+
85
+ const response = await axios.post(
86
+ `https://projectsapi.zoho.eu/restapi/portal/${portalId}/projects/${projectId}/tasks/${taskId}/attachments/`,
87
+ formData,
88
+ {
89
+ headers: {
90
+ Authorization: `Zoho-oauthtoken ${accessToken}`,
91
+ ...formData.getHeaders()
92
+ }
93
+ }
94
+ );
95
+
96
+ // Response contains the attachment with WorkDrive file ID
97
+ const attachment = response.data.thirdparty_attachments[0];
98
+ console.log('Attachment ID:', attachment.attachment_id);
99
+ console.log('WorkDrive File ID:', attachment.third_party_file_id);
100
+ ```
101
+
102
+ #### List Task Attachments
103
+
104
+ ```typescript
105
+ // Via V3 API (preferred)
106
+ const listRes = await axios.get(
107
+ `https://projectsapi.zoho.eu/api/v3/portal/${portalId}/projects/${projectId}/attachments`,
108
+ {
109
+ params: { entity_type: 'task', entity_id: taskId },
110
+ headers: { Authorization: `Zoho-oauthtoken ${accessToken}` }
111
+ }
112
+ );
113
+ // V3 returns { attachment: [...] } (singular key)
114
+ const attachments = listRes.data.attachment || [];
115
+ ```
116
+
117
+ ### Method 2: Manual WorkDrive Upload (Advanced)
118
+
119
+ For more control over the upload process, you can upload to WorkDrive first, then register with Zoho Projects.
120
+
121
+ #### Additional OAuth Scopes Required
122
+
123
+ | Scope | Purpose |
124
+ |-------|---------|
125
+ | `WorkDrive.team.ALL` | Access WorkDrive teams |
126
+ | `WorkDrive.workspace.ALL` | Access workspaces |
127
+ | `WorkDrive.files.ALL` | Upload/manage files |
128
+ | `WorkDrive.teamfolders.ALL` | Access team folders |
129
+
130
+ #### Step 1: Get WorkDrive User Info
131
+ ```typescript
132
+ const userRes = await axios.get('https://workdrive.zoho.eu/api/v1/users/me', {
133
+ headers: {
134
+ Authorization: `Zoho-oauthtoken ${accessToken}`,
135
+ Accept: 'application/vnd.api+json'
136
+ }
137
+ });
138
+ const preferredTeamId = userRes.data.data.attributes.preferred_team_id;
139
+ ```
140
+
141
+ #### Step 2: Find the "Zoho Projects" Team Folder
142
+ ```typescript
143
+ const foldersRes = await axios.get(
144
+ `https://workdrive.zoho.eu/api/v1/teams/${preferredTeamId}/teamfolders`,
145
+ { headers: workdriveHeaders }
146
+ );
147
+
148
+ const projectsFolder = foldersRes.data.data.find(
149
+ f => f.attributes.name === 'Zoho Projects'
150
+ );
151
+ const projectsFolderId = projectsFolder.id;
152
+ ```
153
+
154
+ #### Step 3: Find the Project-Specific Subfolder
155
+ ```typescript
156
+ const subFoldersRes = await axios.get(
157
+ `https://workdrive.zoho.eu/api/v1/teamfolders/${projectsFolderId}/folders`,
158
+ { headers: workdriveHeaders }
159
+ );
160
+
161
+ // Find folder named like "PA-{num}-{projectName}-Attachments"
162
+ const projectFolder = subFoldersRes.data.data.find(
163
+ f => f.attributes.name.includes(projectName) && f.attributes.name.includes('-Attachments')
164
+ );
165
+ ```
166
+
167
+ #### Step 4: Upload File to WorkDrive
168
+ ```typescript
169
+ const formData = new FormData();
170
+ formData.append('content', fileBuffer, {
171
+ filename: 'test.txt',
172
+ contentType: 'text/plain'
173
+ });
174
+ formData.append('parent_id', projectFolderId);
175
+
176
+ const uploadRes = await axios.post(
177
+ 'https://workdrive.zoho.eu/api/v1/upload',
178
+ formData,
179
+ { headers: { ...workdriveHeaders, ...formData.getHeaders() } }
180
+ );
181
+
182
+ const workdriveFileId = uploadRes.data.data[0].attributes.resource_id;
183
+ ```
184
+
185
+ ### Regional API URLs
186
+
187
+ | Region | WorkDrive API | Projects API | Accounts URL |
188
+ |--------|--------------|--------------|--------------|
189
+ | US | workdrive.zoho.com | projectsapi.zoho.com | accounts.zoho.com |
190
+ | EU | workdrive.zoho.eu | projectsapi.zoho.eu | accounts.zoho.eu |
191
+ | IN | workdrive.zoho.in | projectsapi.zoho.in | accounts.zoho.in |
192
+ | AU | workdrive.zoho.com.au | projectsapi.zoho.com.au | accounts.zoho.com.au |
193
+
194
+ ### Troubleshooting
195
+
196
+ - **INVALID_OAUTHSCOPE on V3 `/attachments` endpoint**: Use Method 1 (direct upload via `/restapi/`) instead
197
+ - **No team folders found**: Use `users/me` to get `preferred_team_id`, then query `/teams/{teamId}/teamfolders`
198
+ - **Project folder not found**: Zoho automatically creates project folders; wait a moment after project creation
199
+
200
+ ---
201
+
34
202
  ## Available Namespaces
35
203
 
36
204
  ### Portal-Level (no projectId needed)
@@ -46,6 +214,9 @@ ZOHO_PORTAL_ID= # Your Zoho Projects portal ID
46
214
  ## Common Patterns
47
215
 
48
216
  ```typescript
217
+ // List with V3 pagination (page/per_page)
218
+ const { data, pageInfo } = await client.projects.list({ page: 1, per_page: 100 });
219
+
49
220
  // List all (auto-paginate)
50
221
  const allProjects = await client.projects.listAll();
51
222
 
@@ -54,12 +225,24 @@ for await (const project of client.projects.iterate()) {
54
225
  console.log(project.name);
55
226
  }
56
227
 
57
- // CRUD operations
58
- await client.tasks.create(projectId, { name: 'New task', tasklist_id: tasklistId });
228
+ // Create task (V3 uses nested tasklist object)
229
+ await client.tasks.create(projectId, {
230
+ name: 'New task',
231
+ tasklist: { id: tasklistId },
232
+ });
233
+
234
+ // Update and delete
59
235
  await client.tasks.update(projectId, taskId, { status: 'completed' });
60
236
  await client.tasks.delete(projectId, taskId);
61
237
  ```
62
238
 
239
+ ## V3 API Notes
240
+
241
+ - **Pagination**: Uses `page` (1-based) and `per_page` instead of `index`/`range`
242
+ - **IDs**: Returns string IDs, not numbers
243
+ - **Nested objects**: Many fields like `owner`, `status`, `tasklist` are nested objects
244
+ - **Response format**: V3 returns data directly, not wrapped in arrays
245
+
63
246
  ## Package Documentation
64
247
 
65
248
  - [GitHub Repository](https://github.com/Panoptic-IT-Solutions/zoho-projects-client)