@panoptic-it-solutions/zoho-projects-client 0.1.4 → 0.2.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 (302) hide show
  1. package/dist/__tests__/fixtures/attachments.d.ts +126 -0
  2. package/dist/__tests__/fixtures/attachments.d.ts.map +1 -0
  3. package/dist/__tests__/fixtures/attachments.js +60 -0
  4. package/dist/__tests__/fixtures/attachments.js.map +1 -0
  5. package/dist/__tests__/fixtures/blueprints.d.ts +114 -0
  6. package/dist/__tests__/fixtures/blueprints.d.ts.map +1 -0
  7. package/dist/__tests__/fixtures/blueprints.js +102 -0
  8. package/dist/__tests__/fixtures/blueprints.js.map +1 -0
  9. package/dist/__tests__/fixtures/comments.d.ts +92 -0
  10. package/dist/__tests__/fixtures/comments.d.ts.map +1 -0
  11. package/dist/__tests__/fixtures/comments.js +42 -0
  12. package/dist/__tests__/fixtures/comments.js.map +1 -0
  13. package/dist/__tests__/fixtures/customviews.d.ts +5 -0
  14. package/dist/__tests__/fixtures/customviews.d.ts.map +1 -0
  15. package/dist/__tests__/fixtures/customviews.js +55 -0
  16. package/dist/__tests__/fixtures/customviews.js.map +1 -0
  17. package/dist/__tests__/fixtures/events.d.ts +133 -0
  18. package/dist/__tests__/fixtures/events.d.ts.map +1 -0
  19. package/dist/__tests__/fixtures/events.js +75 -0
  20. package/dist/__tests__/fixtures/events.js.map +1 -0
  21. package/dist/__tests__/fixtures/forums.d.ts +114 -0
  22. package/dist/__tests__/fixtures/forums.d.ts.map +1 -0
  23. package/dist/__tests__/fixtures/forums.js +53 -0
  24. package/dist/__tests__/fixtures/forums.js.map +1 -0
  25. package/dist/__tests__/fixtures/groups.d.ts +25 -0
  26. package/dist/__tests__/fixtures/groups.d.ts.map +1 -0
  27. package/dist/__tests__/fixtures/groups.js +36 -0
  28. package/dist/__tests__/fixtures/groups.js.map +1 -0
  29. package/dist/__tests__/fixtures/index.d.ts +22 -0
  30. package/dist/__tests__/fixtures/index.d.ts.map +1 -0
  31. package/dist/__tests__/fixtures/index.js +22 -0
  32. package/dist/__tests__/fixtures/index.js.map +1 -0
  33. package/dist/__tests__/fixtures/issues.d.ts +196 -0
  34. package/dist/__tests__/fixtures/issues.d.ts.map +1 -0
  35. package/dist/__tests__/fixtures/issues.js +80 -0
  36. package/dist/__tests__/fixtures/issues.js.map +1 -0
  37. package/dist/__tests__/fixtures/modules.d.ts +6 -0
  38. package/dist/__tests__/fixtures/modules.d.ts.map +1 -0
  39. package/dist/__tests__/fixtures/modules.js +103 -0
  40. package/dist/__tests__/fixtures/modules.js.map +1 -0
  41. package/dist/__tests__/fixtures/phases.d.ts +123 -0
  42. package/dist/__tests__/fixtures/phases.d.ts.map +1 -0
  43. package/dist/__tests__/fixtures/phases.js +68 -0
  44. package/dist/__tests__/fixtures/phases.js.map +1 -0
  45. package/dist/__tests__/fixtures/portals.d.ts +4 -0
  46. package/dist/__tests__/fixtures/portals.d.ts.map +1 -0
  47. package/dist/__tests__/fixtures/portals.js +48 -0
  48. package/dist/__tests__/fixtures/portals.js.map +1 -0
  49. package/dist/__tests__/fixtures/projects.d.ts +298 -0
  50. package/dist/__tests__/fixtures/projects.d.ts.map +1 -0
  51. package/dist/__tests__/fixtures/projects.js +44 -0
  52. package/dist/__tests__/fixtures/projects.js.map +1 -0
  53. package/dist/__tests__/fixtures/tags.d.ts +22 -0
  54. package/dist/__tests__/fixtures/tags.d.ts.map +1 -0
  55. package/dist/__tests__/fixtures/tags.js +33 -0
  56. package/dist/__tests__/fixtures/tags.js.map +1 -0
  57. package/dist/__tests__/fixtures/tasklists.d.ts +107 -0
  58. package/dist/__tests__/fixtures/tasklists.d.ts.map +1 -0
  59. package/dist/__tests__/fixtures/tasklists.js +31 -0
  60. package/dist/__tests__/fixtures/tasklists.js.map +1 -0
  61. package/dist/__tests__/fixtures/tasks.d.ts +209 -0
  62. package/dist/__tests__/fixtures/tasks.d.ts.map +1 -0
  63. package/dist/__tests__/fixtures/tasks.js +69 -0
  64. package/dist/__tests__/fixtures/tasks.js.map +1 -0
  65. package/dist/__tests__/fixtures/timelogs.d.ts +151 -0
  66. package/dist/__tests__/fixtures/timelogs.d.ts.map +1 -0
  67. package/dist/__tests__/fixtures/timelogs.js +79 -0
  68. package/dist/__tests__/fixtures/timelogs.js.map +1 -0
  69. package/dist/__tests__/fixtures/timers.d.ts +5 -0
  70. package/dist/__tests__/fixtures/timers.d.ts.map +1 -0
  71. package/dist/__tests__/fixtures/timers.js +50 -0
  72. package/dist/__tests__/fixtures/timers.js.map +1 -0
  73. package/dist/__tests__/fixtures/users.d.ts +55 -0
  74. package/dist/__tests__/fixtures/users.d.ts.map +1 -0
  75. package/dist/__tests__/fixtures/users.js +47 -0
  76. package/dist/__tests__/fixtures/users.js.map +1 -0
  77. package/dist/__tests__/integration/setup.d.ts +14 -0
  78. package/dist/__tests__/integration/setup.d.ts.map +1 -0
  79. package/dist/__tests__/integration/setup.js +52 -0
  80. package/dist/__tests__/integration/setup.js.map +1 -0
  81. package/dist/__tests__/mocks/handlers.d.ts +34 -0
  82. package/dist/__tests__/mocks/handlers.d.ts.map +1 -0
  83. package/dist/__tests__/mocks/handlers.js +49 -0
  84. package/dist/__tests__/mocks/handlers.js.map +1 -0
  85. package/dist/__tests__/mocks/server.d.ts +2 -0
  86. package/dist/__tests__/mocks/server.d.ts.map +1 -0
  87. package/dist/__tests__/mocks/server.js +7 -0
  88. package/dist/__tests__/mocks/server.js.map +1 -0
  89. package/dist/__tests__/setup.d.ts +2 -0
  90. package/dist/__tests__/setup.d.ts.map +1 -0
  91. package/dist/__tests__/setup.js +18 -0
  92. package/dist/__tests__/setup.js.map +1 -0
  93. package/dist/__tests__/unit/client/attachments.test.d.ts +2 -0
  94. package/dist/__tests__/unit/client/attachments.test.d.ts.map +1 -0
  95. package/dist/__tests__/unit/client/attachments.test.js +55 -0
  96. package/dist/__tests__/unit/client/attachments.test.js.map +1 -0
  97. package/dist/__tests__/unit/client/blueprints.test.d.ts +2 -0
  98. package/dist/__tests__/unit/client/blueprints.test.d.ts.map +1 -0
  99. package/dist/__tests__/unit/client/blueprints.test.js +127 -0
  100. package/dist/__tests__/unit/client/blueprints.test.js.map +1 -0
  101. package/dist/__tests__/unit/client/comments.test.d.ts +2 -0
  102. package/dist/__tests__/unit/client/comments.test.d.ts.map +1 -0
  103. package/dist/__tests__/unit/client/comments.test.js +95 -0
  104. package/dist/__tests__/unit/client/comments.test.js.map +1 -0
  105. package/dist/__tests__/unit/client/customviews.test.d.ts +2 -0
  106. package/dist/__tests__/unit/client/customviews.test.d.ts.map +1 -0
  107. package/dist/__tests__/unit/client/customviews.test.js +112 -0
  108. package/dist/__tests__/unit/client/customviews.test.js.map +1 -0
  109. package/dist/__tests__/unit/client/events.test.d.ts +2 -0
  110. package/dist/__tests__/unit/client/events.test.d.ts.map +1 -0
  111. package/dist/__tests__/unit/client/events.test.js +79 -0
  112. package/dist/__tests__/unit/client/events.test.js.map +1 -0
  113. package/dist/__tests__/unit/client/forums.test.d.ts +2 -0
  114. package/dist/__tests__/unit/client/forums.test.d.ts.map +1 -0
  115. package/dist/__tests__/unit/client/forums.test.js +75 -0
  116. package/dist/__tests__/unit/client/forums.test.js.map +1 -0
  117. package/dist/__tests__/unit/client/groups.test.d.ts +2 -0
  118. package/dist/__tests__/unit/client/groups.test.d.ts.map +1 -0
  119. package/dist/__tests__/unit/client/groups.test.js +74 -0
  120. package/dist/__tests__/unit/client/groups.test.js.map +1 -0
  121. package/dist/__tests__/unit/client/issues.test.d.ts +2 -0
  122. package/dist/__tests__/unit/client/issues.test.d.ts.map +1 -0
  123. package/dist/__tests__/unit/client/issues.test.js +75 -0
  124. package/dist/__tests__/unit/client/issues.test.js.map +1 -0
  125. package/dist/__tests__/unit/client/modules.test.d.ts +2 -0
  126. package/dist/__tests__/unit/client/modules.test.d.ts.map +1 -0
  127. package/dist/__tests__/unit/client/modules.test.js +92 -0
  128. package/dist/__tests__/unit/client/modules.test.js.map +1 -0
  129. package/dist/__tests__/unit/client/phases.test.d.ts +2 -0
  130. package/dist/__tests__/unit/client/phases.test.d.ts.map +1 -0
  131. package/dist/__tests__/unit/client/phases.test.js +79 -0
  132. package/dist/__tests__/unit/client/phases.test.js.map +1 -0
  133. package/dist/__tests__/unit/client/portals.test.d.ts +2 -0
  134. package/dist/__tests__/unit/client/portals.test.d.ts.map +1 -0
  135. package/dist/__tests__/unit/client/portals.test.js +54 -0
  136. package/dist/__tests__/unit/client/portals.test.js.map +1 -0
  137. package/dist/__tests__/unit/client/projects.test.d.ts +2 -0
  138. package/dist/__tests__/unit/client/projects.test.d.ts.map +1 -0
  139. package/dist/__tests__/unit/client/projects.test.js +171 -0
  140. package/dist/__tests__/unit/client/projects.test.js.map +1 -0
  141. package/dist/__tests__/unit/client/tags.test.d.ts +2 -0
  142. package/dist/__tests__/unit/client/tags.test.d.ts.map +1 -0
  143. package/dist/__tests__/unit/client/tags.test.js +99 -0
  144. package/dist/__tests__/unit/client/tags.test.js.map +1 -0
  145. package/dist/__tests__/unit/client/tasklists.test.d.ts +2 -0
  146. package/dist/__tests__/unit/client/tasklists.test.d.ts.map +1 -0
  147. package/dist/__tests__/unit/client/tasklists.test.js +75 -0
  148. package/dist/__tests__/unit/client/tasklists.test.js.map +1 -0
  149. package/dist/__tests__/unit/client/tasks.test.d.ts +2 -0
  150. package/dist/__tests__/unit/client/tasks.test.d.ts.map +1 -0
  151. package/dist/__tests__/unit/client/tasks.test.js +157 -0
  152. package/dist/__tests__/unit/client/tasks.test.js.map +1 -0
  153. package/dist/__tests__/unit/client/timers.test.d.ts +2 -0
  154. package/dist/__tests__/unit/client/timers.test.d.ts.map +1 -0
  155. package/dist/__tests__/unit/client/timers.test.js +122 -0
  156. package/dist/__tests__/unit/client/timers.test.js.map +1 -0
  157. package/dist/__tests__/unit/client/users.test.d.ts +2 -0
  158. package/dist/__tests__/unit/client/users.test.d.ts.map +1 -0
  159. package/dist/__tests__/unit/client/users.test.js +89 -0
  160. package/dist/__tests__/unit/client/users.test.js.map +1 -0
  161. package/dist/cli/init.d.ts +3 -0
  162. package/dist/cli/init.d.ts.map +1 -0
  163. package/dist/cli/init.js +130 -0
  164. package/dist/cli/init.js.map +1 -0
  165. package/dist/client.d.ts +2613 -1
  166. package/dist/client.d.ts.map +1 -1
  167. package/dist/client.js +1623 -1
  168. package/dist/client.js.map +1 -1
  169. package/dist/types/attachments.d.ts +1545 -0
  170. package/dist/types/attachments.d.ts.map +1 -0
  171. package/dist/types/attachments.js +78 -0
  172. package/dist/types/attachments.js.map +1 -0
  173. package/dist/types/blueprints.d.ts +5070 -0
  174. package/dist/types/blueprints.d.ts.map +1 -0
  175. package/dist/types/blueprints.js +111 -0
  176. package/dist/types/blueprints.js.map +1 -0
  177. package/dist/types/clients.d.ts +384 -0
  178. package/dist/types/clients.d.ts.map +1 -0
  179. package/dist/types/clients.js +77 -0
  180. package/dist/types/clients.js.map +1 -0
  181. package/dist/types/comments.d.ts +1111 -0
  182. package/dist/types/comments.d.ts.map +1 -0
  183. package/dist/types/comments.js +73 -0
  184. package/dist/types/comments.js.map +1 -0
  185. package/dist/types/contacts.d.ts +444 -0
  186. package/dist/types/contacts.d.ts.map +1 -0
  187. package/dist/types/contacts.js +86 -0
  188. package/dist/types/contacts.js.map +1 -0
  189. package/dist/types/customviews.d.ts +1593 -0
  190. package/dist/types/customviews.d.ts.map +1 -0
  191. package/dist/types/customviews.js +117 -0
  192. package/dist/types/customviews.js.map +1 -0
  193. package/dist/types/dashboards.d.ts +1675 -0
  194. package/dist/types/dashboards.d.ts.map +1 -0
  195. package/dist/types/dashboards.js +77 -0
  196. package/dist/types/dashboards.js.map +1 -0
  197. package/dist/types/documents.d.ts +2322 -0
  198. package/dist/types/documents.d.ts.map +1 -0
  199. package/dist/types/documents.js +121 -0
  200. package/dist/types/documents.js.map +1 -0
  201. package/dist/types/events.d.ts +1747 -0
  202. package/dist/types/events.d.ts.map +1 -0
  203. package/dist/types/events.js +122 -0
  204. package/dist/types/events.js.map +1 -0
  205. package/dist/types/followers.d.ts +198 -0
  206. package/dist/types/followers.d.ts.map +1 -0
  207. package/dist/types/followers.js +44 -0
  208. package/dist/types/followers.js.map +1 -0
  209. package/dist/types/forums.d.ts +1443 -0
  210. package/dist/types/forums.d.ts.map +1 -0
  211. package/dist/types/forums.js +89 -0
  212. package/dist/types/forums.js.map +1 -0
  213. package/dist/types/groups.d.ts +237 -0
  214. package/dist/types/groups.d.ts.map +1 -0
  215. package/dist/types/groups.js +52 -0
  216. package/dist/types/groups.js.map +1 -0
  217. package/dist/types/index.d.ts +31 -4
  218. package/dist/types/index.d.ts.map +1 -1
  219. package/dist/types/index.js +58 -4
  220. package/dist/types/index.js.map +1 -1
  221. package/dist/types/issues.d.ts +2600 -0
  222. package/dist/types/issues.d.ts.map +1 -0
  223. package/dist/types/issues.js +147 -0
  224. package/dist/types/issues.js.map +1 -0
  225. package/dist/types/leaves.d.ts +435 -0
  226. package/dist/types/leaves.d.ts.map +1 -0
  227. package/dist/types/leaves.js +92 -0
  228. package/dist/types/leaves.js.map +1 -0
  229. package/dist/types/modules.d.ts +469 -0
  230. package/dist/types/modules.d.ts.map +1 -0
  231. package/dist/types/modules.js +91 -0
  232. package/dist/types/modules.js.map +1 -0
  233. package/dist/types/phases.d.ts +1564 -0
  234. package/dist/types/phases.d.ts.map +1 -0
  235. package/dist/types/phases.js +98 -0
  236. package/dist/types/phases.js.map +1 -0
  237. package/dist/types/portals.d.ts +1050 -0
  238. package/dist/types/portals.d.ts.map +1 -0
  239. package/dist/types/portals.js +58 -0
  240. package/dist/types/portals.js.map +1 -0
  241. package/dist/types/profiles.d.ts +243 -0
  242. package/dist/types/profiles.d.ts.map +1 -0
  243. package/dist/types/profiles.js +59 -0
  244. package/dist/types/profiles.js.map +1 -0
  245. package/dist/types/projects.d.ts +128 -0
  246. package/dist/types/projects.d.ts.map +1 -1
  247. package/dist/types/projects.js +44 -0
  248. package/dist/types/projects.js.map +1 -1
  249. package/dist/types/reports.d.ts +2010 -0
  250. package/dist/types/reports.d.ts.map +1 -0
  251. package/dist/types/reports.js +110 -0
  252. package/dist/types/reports.js.map +1 -0
  253. package/dist/types/roles.d.ts +243 -0
  254. package/dist/types/roles.d.ts.map +1 -0
  255. package/dist/types/roles.js +59 -0
  256. package/dist/types/roles.js.map +1 -0
  257. package/dist/types/search.d.ts +1091 -0
  258. package/dist/types/search.d.ts.map +1 -0
  259. package/dist/types/search.js +83 -0
  260. package/dist/types/search.js.map +1 -0
  261. package/dist/types/tags.d.ts +198 -0
  262. package/dist/types/tags.d.ts.map +1 -0
  263. package/dist/types/tags.js +49 -0
  264. package/dist/types/tags.js.map +1 -0
  265. package/dist/types/tasklists.d.ts +1317 -0
  266. package/dist/types/tasklists.d.ts.map +1 -0
  267. package/dist/types/tasklists.js +78 -0
  268. package/dist/types/tasklists.js.map +1 -0
  269. package/dist/types/tasks.d.ts +182 -0
  270. package/dist/types/tasks.d.ts.map +1 -1
  271. package/dist/types/tasks.js +52 -0
  272. package/dist/types/tasks.js.map +1 -1
  273. package/dist/types/teams.d.ts +504 -0
  274. package/dist/types/teams.d.ts.map +1 -0
  275. package/dist/types/teams.js +75 -0
  276. package/dist/types/teams.js.map +1 -0
  277. package/dist/types/timelogs.d.ts +245 -0
  278. package/dist/types/timelogs.d.ts.map +1 -1
  279. package/dist/types/timelogs.js +53 -0
  280. package/dist/types/timelogs.js.map +1 -1
  281. package/dist/types/timers.d.ts +1334 -0
  282. package/dist/types/timers.d.ts.map +1 -0
  283. package/dist/types/timers.js +108 -0
  284. package/dist/types/timers.js.map +1 -0
  285. package/dist/types/trash.d.ts +1447 -0
  286. package/dist/types/trash.d.ts.map +1 -0
  287. package/dist/types/trash.js +77 -0
  288. package/dist/types/trash.js.map +1 -0
  289. package/dist/types/users.d.ts +100 -0
  290. package/dist/types/users.d.ts.map +1 -1
  291. package/dist/types/users.js +56 -0
  292. package/dist/types/users.js.map +1 -1
  293. package/dist/types/widgets.d.ts +1083 -0
  294. package/dist/types/widgets.d.ts.map +1 -0
  295. package/dist/types/widgets.js +87 -0
  296. package/dist/types/widgets.js.map +1 -0
  297. package/package.json +15 -3
  298. package/templates/CLAUDE.md +66 -0
  299. package/templates/commands/zoho-auth.md +195 -0
  300. package/templates/commands/zoho-examples.md +375 -0
  301. package/templates/commands/zoho-projects.md +183 -0
  302. package/templates/types/zoho-projects-api.d.ts +364 -0
@@ -0,0 +1,375 @@
1
+ # Zoho Projects Client - Common Usage Examples
2
+
3
+ ## Setup
4
+
5
+ ```typescript
6
+ import { createZohoProjectsClient } from '@panoptic-it-solutions/zoho-projects-client';
7
+ import 'dotenv/config';
8
+
9
+ const client = createZohoProjectsClient({
10
+ clientId: process.env.ZOHO_CLIENT_ID!,
11
+ clientSecret: process.env.ZOHO_CLIENT_SECRET!,
12
+ refreshToken: process.env.ZOHO_REFRESH_TOKEN!,
13
+ portalId: process.env.ZOHO_PORTAL_ID!,
14
+ });
15
+ ```
16
+
17
+ ## Projects
18
+
19
+ ### List All Projects
20
+
21
+ ```typescript
22
+ // Get first page
23
+ const response = await client.projects.list();
24
+ console.log(response.projects);
25
+
26
+ // Get all projects (auto-paginate)
27
+ const allProjects = await client.projects.listAll();
28
+
29
+ // Iterate through all projects (memory-efficient)
30
+ for await (const project of client.projects.iterate()) {
31
+ console.log(project.name);
32
+ }
33
+
34
+ // With filters
35
+ const activeProjects = await client.projects.listAll({
36
+ status: 'active',
37
+ });
38
+ ```
39
+
40
+ ### Create a Project
41
+
42
+ ```typescript
43
+ const newProject = await client.projects.create({
44
+ name: 'New Website Redesign',
45
+ description: 'Complete redesign of company website',
46
+ start_date: '2025-01-15',
47
+ end_date: '2025-06-30',
48
+ status: 'active',
49
+ });
50
+
51
+ console.log('Created project:', newProject.projects[0].id_string);
52
+ ```
53
+
54
+ ### Update a Project
55
+
56
+ ```typescript
57
+ await client.projects.update(projectId, {
58
+ name: 'Updated Project Name',
59
+ status: 'on_hold',
60
+ });
61
+ ```
62
+
63
+ ### Delete a Project
64
+
65
+ ```typescript
66
+ await client.projects.delete(projectId);
67
+ ```
68
+
69
+ ## Tasks
70
+
71
+ ### List Tasks in a Project
72
+
73
+ ```typescript
74
+ const tasks = await client.tasks.list(projectId);
75
+
76
+ // With filters
77
+ const openTasks = await client.tasks.list(projectId, {
78
+ status: 'open',
79
+ owner: 'userId',
80
+ });
81
+
82
+ // Get all tasks
83
+ const allTasks = await client.tasks.listAll(projectId);
84
+ ```
85
+
86
+ ### Create a Task
87
+
88
+ ```typescript
89
+ const task = await client.tasks.create(projectId, {
90
+ name: 'Implement user authentication',
91
+ description: 'Add OAuth 2.0 login flow',
92
+ start_date: '2025-01-20',
93
+ end_date: '2025-01-25',
94
+ priority: 'high',
95
+ owners: ['userId1', 'userId2'],
96
+ tasklist_id: tasklistId,
97
+ });
98
+ ```
99
+
100
+ ### Update a Task
101
+
102
+ ```typescript
103
+ await client.tasks.update(projectId, taskId, {
104
+ status: 'completed',
105
+ percent_complete: 100,
106
+ });
107
+ ```
108
+
109
+ ## Task Lists
110
+
111
+ ### Create a Task List
112
+
113
+ ```typescript
114
+ const tasklist = await client.tasklists.create(projectId, {
115
+ name: 'Sprint 1 Tasks',
116
+ flag: 'internal',
117
+ });
118
+ ```
119
+
120
+ ### List Task Lists
121
+
122
+ ```typescript
123
+ const tasklists = await client.tasklists.list(projectId);
124
+ ```
125
+
126
+ ## Time Logs
127
+
128
+ ### Log Time
129
+
130
+ ```typescript
131
+ await client.timelogs.create(projectId, {
132
+ task_id: taskId,
133
+ date: '2025-01-20',
134
+ hours: 2,
135
+ minutes: 30,
136
+ bill_status: 'Billable',
137
+ notes: 'Implemented login UI',
138
+ });
139
+ ```
140
+
141
+ ### Get Time Logs for a Task
142
+
143
+ ```typescript
144
+ const timelogs = await client.timelogs.list(projectId, {
145
+ task_id: taskId,
146
+ });
147
+ ```
148
+
149
+ ## Issues/Bugs
150
+
151
+ ### Create a Bug
152
+
153
+ ```typescript
154
+ const bug = await client.issues.create(projectId, {
155
+ title: 'Login button not working on mobile',
156
+ description: 'The login button is unresponsive on iOS Safari',
157
+ severity: 'major',
158
+ reproducible: 'Always',
159
+ module: 'Authentication',
160
+ });
161
+ ```
162
+
163
+ ### List Bugs
164
+
165
+ ```typescript
166
+ const bugs = await client.issues.list(projectId, {
167
+ status: 'open',
168
+ });
169
+ ```
170
+
171
+ ## Comments
172
+
173
+ ### Add a Comment to a Task
174
+
175
+ ```typescript
176
+ const taskComments = client.comments.forTask(projectId, taskId);
177
+
178
+ await taskComments.create({
179
+ content: 'This task is blocked waiting for API access.',
180
+ });
181
+
182
+ // List comments
183
+ const comments = await taskComments.list();
184
+ ```
185
+
186
+ ### Add a Comment to a Bug
187
+
188
+ ```typescript
189
+ const bugComments = client.comments.forIssue(projectId, bugId);
190
+
191
+ await bugComments.create({
192
+ content: 'Unable to reproduce this issue.',
193
+ });
194
+ ```
195
+
196
+ ## Followers
197
+
198
+ ### Add Followers to a Task
199
+
200
+ ```typescript
201
+ const taskFollowers = client.followers.forTask(projectId, taskId);
202
+
203
+ await taskFollowers.add({
204
+ users: ['userId1', 'userId2'],
205
+ });
206
+
207
+ // List followers
208
+ const followers = await taskFollowers.list();
209
+ ```
210
+
211
+ ## Users
212
+
213
+ ### List All Users
214
+
215
+ ```typescript
216
+ const users = await client.users.listAll();
217
+
218
+ for (const user of users) {
219
+ console.log(`${user.name} (${user.email})`);
220
+ }
221
+ ```
222
+
223
+ ### Get a Specific User
224
+
225
+ ```typescript
226
+ const user = await client.users.get(userId);
227
+ ```
228
+
229
+ ## Search
230
+
231
+ ### Global Search
232
+
233
+ ```typescript
234
+ const results = await client.search.search({
235
+ search_term: 'authentication',
236
+ entity_type: 'task', // 'all', 'project', 'task', 'bug', etc.
237
+ });
238
+
239
+ for (const result of results.results || []) {
240
+ console.log(`${result.entity_type}: ${result.name}`);
241
+ }
242
+ ```
243
+
244
+ ## Dashboards and Widgets
245
+
246
+ ### List Dashboards
247
+
248
+ ```typescript
249
+ const dashboards = await client.dashboards.list();
250
+ ```
251
+
252
+ ### Get Dashboard Widgets
253
+
254
+ ```typescript
255
+ const widgets = await client.dashboards.listWidgets(dashboardId);
256
+ ```
257
+
258
+ ## Error Handling
259
+
260
+ ```typescript
261
+ import {
262
+ ZohoProjectsError,
263
+ ZohoRateLimitError,
264
+ ZohoAuthError,
265
+ ZohoNotFoundError,
266
+ } from '@panoptic-it-solutions/zoho-projects-client';
267
+
268
+ async function safeApiCall() {
269
+ try {
270
+ const project = await client.projects.get(projectId);
271
+ return project;
272
+ } catch (error) {
273
+ if (error instanceof ZohoNotFoundError) {
274
+ console.log('Project not found');
275
+ return null;
276
+ }
277
+ if (error instanceof ZohoRateLimitError) {
278
+ console.log(`Rate limited. Retry after ${error.retryAfter}ms`);
279
+ await new Promise(r => setTimeout(r, error.retryAfter));
280
+ return safeApiCall(); // Retry
281
+ }
282
+ if (error instanceof ZohoAuthError) {
283
+ console.log('Authentication failed - check credentials');
284
+ throw error;
285
+ }
286
+ if (error instanceof ZohoProjectsError) {
287
+ console.log(`API Error: ${error.message} (${error.code})`);
288
+ throw error;
289
+ }
290
+ throw error;
291
+ }
292
+ }
293
+ ```
294
+
295
+ ## Batch Operations
296
+
297
+ ### Create Multiple Tasks
298
+
299
+ ```typescript
300
+ async function createTasks(projectId: string, tasks: CreateTaskInput[]) {
301
+ const results = [];
302
+ for (const taskInput of tasks) {
303
+ const result = await client.tasks.create(projectId, taskInput);
304
+ results.push(result);
305
+ }
306
+ return results;
307
+ }
308
+
309
+ // Usage
310
+ await createTasks(projectId, [
311
+ { name: 'Task 1', tasklist_id: tasklistId },
312
+ { name: 'Task 2', tasklist_id: tasklistId },
313
+ { name: 'Task 3', tasklist_id: tasklistId },
314
+ ]);
315
+ ```
316
+
317
+ ### Bulk Update Status
318
+
319
+ ```typescript
320
+ async function completeAllTasks(projectId: string, taskIds: string[]) {
321
+ for (const taskId of taskIds) {
322
+ await client.tasks.update(projectId, taskId, {
323
+ status: 'completed',
324
+ percent_complete: 100,
325
+ });
326
+ }
327
+ }
328
+ ```
329
+
330
+ ## Reports
331
+
332
+ ### Get Report Data
333
+
334
+ ```typescript
335
+ const reports = await client.reports.list();
336
+
337
+ // Execute a report
338
+ const reportData = await client.reports.execute(reportId, {
339
+ start_date: '2025-01-01',
340
+ end_date: '2025-01-31',
341
+ });
342
+
343
+ for (const row of reportData.data) {
344
+ console.log(row);
345
+ }
346
+ ```
347
+
348
+ ## Trash Management
349
+
350
+ ### List Deleted Items
351
+
352
+ ```typescript
353
+ const trashedItems = await client.trash.list({
354
+ entity_type: 'task',
355
+ });
356
+
357
+ for (const item of trashedItems.trash || []) {
358
+ console.log(`${item.name} - deleted by ${item.deleted_person}`);
359
+ }
360
+ ```
361
+
362
+ ### Restore a Deleted Item
363
+
364
+ ```typescript
365
+ await client.trash.restore(itemId);
366
+ ```
367
+
368
+ ## Best Practices
369
+
370
+ 1. **Use listAll() for small datasets** - It loads all pages into memory
371
+ 2. **Use iterate() for large datasets** - Memory-efficient streaming
372
+ 3. **Handle rate limits** - Catch `ZohoRateLimitError` and retry
373
+ 4. **Use specific scopes** - Only request the OAuth scopes you need
374
+ 5. **Cache user data** - User lists don't change often
375
+ 6. **Batch operations carefully** - Zoho has rate limits per minute
@@ -0,0 +1,183 @@
1
+ # Zoho Projects API Reference
2
+
3
+ This project uses `@panoptic-it-solutions/zoho-projects-client` - a TypeScript client for the Zoho Projects V3 API.
4
+
5
+ ## Client Initialization
6
+
7
+ ```typescript
8
+ import { createZohoProjectsClient } from '@panoptic-it-solutions/zoho-projects-client';
9
+
10
+ const client = createZohoProjectsClient({
11
+ clientId: process.env.ZOHO_CLIENT_ID!,
12
+ clientSecret: process.env.ZOHO_CLIENT_SECRET!,
13
+ refreshToken: process.env.ZOHO_REFRESH_TOKEN!,
14
+ portalId: process.env.ZOHO_PORTAL_ID!,
15
+ // Optional: specify data center (default: 'com')
16
+ // dataCenterExtension: 'eu' | 'in' | 'com.au' | 'jp' | 'com'
17
+ });
18
+ ```
19
+
20
+ ## API Namespaces
21
+
22
+ ### Portal-Level APIs (no projectId required)
23
+
24
+ | Namespace | Description | Methods |
25
+ |-----------|-------------|---------|
26
+ | `client.projects` | Projects CRUD | `list`, `listAll`, `iterate`, `get`, `create`, `update`, `delete` |
27
+ | `client.users` | Users management | `list`, `listAll`, `iterate`, `get` |
28
+ | `client.tags` | Tags CRUD | `list`, `listAll`, `iterate`, `get`, `create`, `update`, `delete` |
29
+ | `client.roles` | Roles CRUD | `list`, `listAll`, `iterate`, `get`, `create`, `update`, `delete` |
30
+ | `client.profiles` | Profiles CRUD | `list`, `listAll`, `iterate`, `get`, `create`, `update`, `delete` |
31
+ | `client.clients` | Clients/Customers | `list`, `listAll`, `iterate`, `get`, `create`, `update`, `delete` |
32
+ | `client.contacts` | Contacts CRUD | `list`, `listAll`, `iterate`, `get`, `create`, `update`, `delete` |
33
+ | `client.groups` | Project Groups | `list`, `listAll`, `iterate`, `get`, `create`, `update`, `delete` |
34
+ | `client.leaves` | Leave management | `list`, `listAll`, `iterate`, `get`, `create`, `update`, `delete` |
35
+ | `client.teams` | Teams CRUD | `list`, `listAll`, `iterate`, `get`, `create`, `update`, `delete` |
36
+ | `client.dashboards` | Dashboards + widgets | `list`, `listAll`, `iterate`, `get`, `create`, `update`, `delete` |
37
+ | `client.reports` | Reports + execute | `list`, `listAll`, `iterate`, `get`, `execute` |
38
+ | `client.search` | Global search | `search` |
39
+ | `client.trash` | Trash management | `list`, `listAll`, `iterate`, `restore`, `deletePermanently` |
40
+
41
+ ### Project-Scoped APIs (require projectId as first argument)
42
+
43
+ | Namespace | Description | Methods |
44
+ |-----------|-------------|---------|
45
+ | `client.tasks` | Tasks CRUD | `list(projectId)`, `get(projectId, taskId)`, `create`, `update`, `delete` |
46
+ | `client.tasklists` | Task Lists | `list(projectId)`, `get(projectId, tasklistId)`, `create`, `update`, `delete` |
47
+ | `client.phases` | Milestones | `list(projectId)`, `get(projectId, phaseId)`, `create`, `update`, `delete` |
48
+ | `client.issues` | Bugs/Issues | `list(projectId)`, `get(projectId, issueId)`, `create`, `update`, `delete` |
49
+ | `client.forums` | Forums | `list(projectId)`, `get(projectId, forumId)`, `create`, `update`, `delete` |
50
+ | `client.events` | Events/Calendar | `list(projectId)`, `get(projectId, eventId)`, `create`, `update`, `delete` |
51
+ | `client.timelogs` | Time logs | `list(projectId)`, `get(projectId, timelogId)`, `create`, `update`, `delete` |
52
+ | `client.attachments` | File attachments | `list(projectId)`, `upload`, `download`, `delete` |
53
+ | `client.documents` | Documents + folders | `list(projectId)`, `get`, `create`, `update`, `delete`, `listFolders`, `createFolder` |
54
+
55
+ ### Polymorphic Sub-Resources
56
+
57
+ Comments and followers can be attached to different entity types:
58
+
59
+ ```typescript
60
+ // Comments on tasks
61
+ const taskComments = client.comments.forTask(projectId, taskId);
62
+ await taskComments.list();
63
+ await taskComments.create({ content: 'My comment' });
64
+
65
+ // Comments on issues/bugs
66
+ const issueComments = client.comments.forIssue(projectId, issueId);
67
+ await issueComments.list();
68
+
69
+ // Followers on tasks
70
+ const taskFollowers = client.followers.forTask(projectId, taskId);
71
+ await taskFollowers.list();
72
+ await taskFollowers.add({ users: ['userId1', 'userId2'] });
73
+ ```
74
+
75
+ ### Nested Resources
76
+
77
+ Widgets are nested under dashboards:
78
+
79
+ ```typescript
80
+ // List widgets for a dashboard
81
+ const widgets = await client.dashboards.listWidgets(dashboardId);
82
+
83
+ // Create a widget
84
+ await client.dashboards.createWidget(dashboardId, {
85
+ name: 'Task Summary',
86
+ type: 'chart',
87
+ });
88
+ ```
89
+
90
+ ## Common Patterns
91
+
92
+ ### Auto-Pagination
93
+
94
+ ```typescript
95
+ // Get all items (auto-paginate through all pages)
96
+ const allProjects = await client.projects.listAll();
97
+
98
+ // Memory-efficient iteration (fetches pages as needed)
99
+ for await (const project of client.projects.iterate()) {
100
+ console.log(project.name);
101
+ }
102
+
103
+ // With filters
104
+ const openTasks = await client.tasks.listAll(projectId, {
105
+ status: 'open',
106
+ });
107
+ ```
108
+
109
+ ### Error Handling
110
+
111
+ ```typescript
112
+ import {
113
+ ZohoProjectsError,
114
+ ZohoRateLimitError,
115
+ ZohoAuthError,
116
+ } from '@panoptic-it-solutions/zoho-projects-client';
117
+
118
+ try {
119
+ await client.projects.get('invalid-id');
120
+ } catch (error) {
121
+ if (error instanceof ZohoRateLimitError) {
122
+ // Rate limited - wait and retry
123
+ console.log(`Rate limited. Retry after ${error.retryAfter}ms`);
124
+ } else if (error instanceof ZohoAuthError) {
125
+ // Authentication failed - check credentials
126
+ console.log('Authentication failed:', error.message);
127
+ } else if (error instanceof ZohoProjectsError) {
128
+ // General API error
129
+ console.log('API error:', error.message, error.code);
130
+ }
131
+ }
132
+ ```
133
+
134
+ ### Pagination Parameters
135
+
136
+ ```typescript
137
+ // Manual pagination control
138
+ const page1 = await client.projects.list({
139
+ index: 0, // Start index (0-based)
140
+ range: 100, // Items per page (max usually 200)
141
+ });
142
+
143
+ // Access pagination info
144
+ console.log(page1.page_info?.has_next_page);
145
+ console.log(page1.page_info?.total_count);
146
+ ```
147
+
148
+ ## Type Exports
149
+
150
+ All types are exported from the main package:
151
+
152
+ ```typescript
153
+ import type {
154
+ // Projects
155
+ Project,
156
+ CreateProjectInput,
157
+ UpdateProjectInput,
158
+
159
+ // Tasks
160
+ Task,
161
+ CreateTaskInput,
162
+ UpdateTaskInput,
163
+
164
+ // Common
165
+ ZohoPageInfo,
166
+ OwnerRef,
167
+
168
+ // And many more...
169
+ } from '@panoptic-it-solutions/zoho-projects-client';
170
+ ```
171
+
172
+ ## Environment Variables
173
+
174
+ Required environment variables:
175
+
176
+ ```bash
177
+ ZOHO_CLIENT_ID=your_client_id
178
+ ZOHO_CLIENT_SECRET=your_client_secret
179
+ ZOHO_REFRESH_TOKEN=your_refresh_token
180
+ ZOHO_PORTAL_ID=your_portal_id
181
+ ```
182
+
183
+ See `/zoho-auth` for OAuth 2.0 setup instructions.