@panoptic-it-solutions/zoho-projects-client 0.2.2 → 0.2.3

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 (2) hide show
  1. package/README.md +195 -26
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -88,7 +88,7 @@ Zoho requires OAuth 2.0 with a refresh token. Here's how to get one:
88
88
  1. In API Console, select your client → **Generate Code** → **Self Client**
89
89
  2. Enter scope:
90
90
  ```
91
- ZohoProjects.projects.READ,ZohoProjects.tasks.READ,ZohoProjects.timesheets.READ,ZohoProjects.users.READ,ZohoProjects.portals.READ
91
+ ZohoProjects.projects.ALL,ZohoProjects.tasks.ALL,ZohoProjects.timesheets.ALL,ZohoProjects.users.ALL,ZohoProjects.portals.ALL,ZohoProjects.bugs.ALL,ZohoProjects.events.ALL,ZohoProjects.forums.ALL,ZohoProjects.documents.ALL
92
92
  ```
93
93
  3. Click **Create** and copy the authorization code
94
94
  4. Exchange it for a refresh token (within 2 minutes):
@@ -134,6 +134,55 @@ const client = createZohoProjectsClient({
134
134
  | IN | `https://projectsapi.zoho.in` | `https://accounts.zoho.in` |
135
135
  | AU | `https://projectsapi.zoho.com.au` | `https://accounts.zoho.com.au` |
136
136
 
137
+ ## Available APIs
138
+
139
+ The client provides access to 26 API namespaces:
140
+
141
+ ### Portal-Level APIs (no projectId required)
142
+
143
+ | Namespace | Description |
144
+ |-----------|-------------|
145
+ | `projects` | Project management |
146
+ | `users` | Portal users |
147
+ | `tags` | Tags/labels |
148
+ | `roles` | User roles |
149
+ | `profiles` | Permission profiles |
150
+ | `clients` | Client companies |
151
+ | `contacts` | Client contacts |
152
+ | `groups` | Project groups |
153
+ | `leaves` | Leave requests |
154
+ | `teams` | Team management |
155
+ | `portals` | Portal information |
156
+ | `modules` | Portal modules |
157
+ | `dashboards` | Dashboards & widgets |
158
+ | `reports` | Report execution |
159
+ | `search` | Global search |
160
+ | `trash` | Deleted items |
161
+
162
+ ### Project-Scoped APIs (require projectId)
163
+
164
+ | Namespace | Description |
165
+ |-----------|-------------|
166
+ | `tasks` | Task management |
167
+ | `tasklists` | Task list management |
168
+ | `phases` | Project phases/milestones |
169
+ | `issues` | Bug/issue tracking |
170
+ | `forums` | Discussion forums |
171
+ | `events` | Calendar events |
172
+ | `timelogs` | Time tracking |
173
+ | `timers` | Active timers |
174
+ | `attachments` | File attachments |
175
+ | `documents` | Project documents |
176
+ | `blueprints` | Workflow blueprints |
177
+ | `customviews` | Custom views |
178
+
179
+ ### Polymorphic APIs
180
+
181
+ | Namespace | Description |
182
+ |-----------|-------------|
183
+ | `comments` | Comments on tasks, issues, forums |
184
+ | `followers` | Followers on tasks, issues, forums |
185
+
137
186
  ## API Reference
138
187
 
139
188
  ### Projects
@@ -142,16 +191,19 @@ const client = createZohoProjectsClient({
142
191
  // List with pagination
143
192
  const { data, pageInfo } = await client.projects.list({ index: 0, range: 100 });
144
193
 
145
- // Get all projects
194
+ // Get all projects (auto-pagination)
146
195
  const projects = await client.projects.listAll();
147
196
 
148
- // Get single project
149
- const project = await client.projects.get("project_id");
150
-
151
- // Iterate with auto-pagination
197
+ // Iterate (memory-efficient)
152
198
  for await (const project of client.projects.iterate()) {
153
199
  console.log(project.name);
154
200
  }
201
+
202
+ // CRUD operations
203
+ const project = await client.projects.get("project_id");
204
+ const newProject = await client.projects.create({ name: "My Project" });
205
+ await client.projects.update("project_id", { name: "Updated Name" });
206
+ await client.projects.delete("project_id");
155
207
  ```
156
208
 
157
209
  ### Tasks
@@ -163,11 +215,14 @@ const { data } = await client.tasks.list("project_id");
163
215
  // Get all tasks for a project
164
216
  const tasks = await client.tasks.listAll("project_id");
165
217
 
166
- // Get single task
167
- const task = await client.tasks.get("project_id", "task_id");
168
-
169
218
  // Get all tasks across all projects
170
219
  const allTasks = await client.tasks.listAllAcrossProjects();
220
+
221
+ // CRUD operations
222
+ const task = await client.tasks.get("project_id", "task_id");
223
+ await client.tasks.create("project_id", { name: "New Task", tasklist_id: "list_id" });
224
+ await client.tasks.update("project_id", "task_id", { status: "completed" });
225
+ await client.tasks.delete("project_id", "task_id");
171
226
  ```
172
227
 
173
228
  ### Time Logs
@@ -179,35 +234,149 @@ Time logs require specific parameters:
179
234
  const { data } = await client.timelogs.list("project_id", {
180
235
  users_list: "all", // "all" or comma-separated user IDs
181
236
  view_type: "month", // "day", "week", "month", or "custom_date"
182
- date: "12-14-2025", // MM-DD-YYYY format
237
+ date: "01-15-2025", // MM-DD-YYYY format
183
238
  bill_status: "All", // "All", "Billable", or "Non Billable"
184
239
  component_type: "task", // "task", "bug", or "general"
185
240
  });
186
241
 
187
- // Get all time logs for a project
188
- const logs = await client.timelogs.listAll("project_id", {
189
- users_list: "all",
190
- view_type: "month",
191
- date: "12-14-2025",
192
- bill_status: "All",
193
- component_type: "task",
242
+ // Create time logs
243
+ await client.timelogs.createForTask("project_id", {
244
+ task_id: "task_id",
245
+ date: "01-15-2025",
246
+ hours: "2",
247
+ bill_status: "Billable",
248
+ });
249
+
250
+ await client.timelogs.createForBug("project_id", {
251
+ bug_id: "bug_id",
252
+ date: "01-15-2025",
253
+ hours: "1",
254
+ bill_status: "Non Billable",
255
+ });
256
+
257
+ await client.timelogs.createGeneral("project_id", {
258
+ name: "Meeting",
259
+ date: "01-15-2025",
260
+ hours: "1",
261
+ bill_status: "Non Billable",
194
262
  });
195
263
  ```
196
264
 
197
- ### Users
265
+ ### Issues (Bugs)
266
+
267
+ ```typescript
268
+ const { data } = await client.issues.list("project_id");
269
+ const issue = await client.issues.get("project_id", "issue_id");
270
+ await client.issues.create("project_id", { title: "Bug report" });
271
+ await client.issues.update("project_id", "issue_id", { status: "fixed" });
272
+ await client.issues.delete("project_id", "issue_id");
273
+ ```
274
+
275
+ ### Comments (Polymorphic)
276
+
277
+ ```typescript
278
+ // Comments on tasks
279
+ const taskComments = client.comments.forTask("project_id", "task_id");
280
+ const { data } = await taskComments.list();
281
+ await taskComments.create({ content: "Great work!" });
282
+
283
+ // Comments on issues
284
+ const issueComments = client.comments.forIssue("project_id", "issue_id");
285
+ await issueComments.list();
286
+
287
+ // Comments on forums
288
+ const forumComments = client.comments.forForum("project_id", "forum_id");
289
+ await forumComments.list();
290
+ ```
291
+
292
+ ### Followers (Polymorphic)
198
293
 
199
294
  ```typescript
200
- // List portal users
201
- const { data } = await client.users.list();
295
+ // Followers on tasks
296
+ const taskFollowers = client.followers.forTask("project_id", "task_id");
297
+ const { data } = await taskFollowers.list();
298
+ await taskFollowers.add({ user_ids: ["user_1", "user_2"] });
299
+ await taskFollowers.remove("user_id");
300
+
301
+ // Followers on issues
302
+ const issueFollowers = client.followers.forIssue("project_id", "issue_id");
303
+ await issueFollowers.list();
304
+ ```
202
305
 
203
- // Get all users
204
- const users = await client.users.listAll();
306
+ ### Search
205
307
 
206
- // Get single user
207
- const user = await client.users.get("user_id");
308
+ ```typescript
309
+ // Global search
310
+ const results = await client.search.query({ search_term: "keyword" });
208
311
 
209
- // List users for a project
210
- const { data: projectUsers } = await client.users.listForProject("project_id");
312
+ // Search with filters
313
+ const taskResults = await client.search.query({
314
+ search_term: "keyword",
315
+ entity_type: "task",
316
+ });
317
+
318
+ // Convenience methods
319
+ await client.search.tasks("keyword");
320
+ await client.search.issues("keyword");
321
+ await client.search.projects("keyword");
322
+
323
+ // Search within a project
324
+ await client.search.inProject("project_id", { search_term: "keyword" });
325
+ ```
326
+
327
+ ### Trash
328
+
329
+ ```typescript
330
+ // List deleted items
331
+ const { data } = await client.trash.list();
332
+ const projectTrash = await client.trash.list({ entity_type: "task" });
333
+
334
+ // Restore from trash
335
+ await client.trash.restore("task", "item_id");
336
+
337
+ // Permanently delete
338
+ await client.trash.permanentDelete("task", "item_id");
339
+
340
+ // Empty trash
341
+ await client.trash.empty(); // All items
342
+ await client.trash.empty("task"); // Only tasks
343
+ ```
344
+
345
+ ### Timers
346
+
347
+ ```typescript
348
+ // Get active timer for current user
349
+ const timer = await client.timers.getActive("project_id");
350
+
351
+ // Start/stop timer on a task
352
+ await client.timers.startForTask("project_id", "task_id");
353
+ await client.timers.stop("project_id");
354
+
355
+ // Start/stop timer on a bug
356
+ await client.timers.startForBug("project_id", "bug_id");
357
+ ```
358
+
359
+ ### Teams
360
+
361
+ ```typescript
362
+ const { data } = await client.teams.list();
363
+ const team = await client.teams.get("team_id");
364
+ await client.teams.create({ name: "Engineering" });
365
+ await client.teams.addMembers("team_id", { user_ids: ["user_1", "user_2"] });
366
+ await client.teams.removeMember("team_id", "user_id");
367
+ ```
368
+
369
+ ### Dashboards & Widgets
370
+
371
+ ```typescript
372
+ // Dashboards
373
+ const { data } = await client.dashboards.list();
374
+ const dashboard = await client.dashboards.get("dashboard_id");
375
+
376
+ // Widgets within a dashboard
377
+ const widgets = client.dashboards.widgets("dashboard_id");
378
+ const { data: widgetList } = await widgets.list();
379
+ await widgets.create({ name: "Task Chart", type: "chart" });
211
380
  ```
212
381
 
213
382
  ## Rate Limiting
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panoptic-it-solutions/zoho-projects-client",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
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",