@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.
- package/dist/__tests__/fixtures/attachments.d.ts +126 -0
- package/dist/__tests__/fixtures/attachments.d.ts.map +1 -0
- package/dist/__tests__/fixtures/attachments.js +60 -0
- package/dist/__tests__/fixtures/attachments.js.map +1 -0
- package/dist/__tests__/fixtures/blueprints.d.ts +114 -0
- package/dist/__tests__/fixtures/blueprints.d.ts.map +1 -0
- package/dist/__tests__/fixtures/blueprints.js +102 -0
- package/dist/__tests__/fixtures/blueprints.js.map +1 -0
- package/dist/__tests__/fixtures/comments.d.ts +92 -0
- package/dist/__tests__/fixtures/comments.d.ts.map +1 -0
- package/dist/__tests__/fixtures/comments.js +42 -0
- package/dist/__tests__/fixtures/comments.js.map +1 -0
- package/dist/__tests__/fixtures/customviews.d.ts +5 -0
- package/dist/__tests__/fixtures/customviews.d.ts.map +1 -0
- package/dist/__tests__/fixtures/customviews.js +55 -0
- package/dist/__tests__/fixtures/customviews.js.map +1 -0
- package/dist/__tests__/fixtures/events.d.ts +133 -0
- package/dist/__tests__/fixtures/events.d.ts.map +1 -0
- package/dist/__tests__/fixtures/events.js +75 -0
- package/dist/__tests__/fixtures/events.js.map +1 -0
- package/dist/__tests__/fixtures/forums.d.ts +114 -0
- package/dist/__tests__/fixtures/forums.d.ts.map +1 -0
- package/dist/__tests__/fixtures/forums.js +53 -0
- package/dist/__tests__/fixtures/forums.js.map +1 -0
- package/dist/__tests__/fixtures/groups.d.ts +25 -0
- package/dist/__tests__/fixtures/groups.d.ts.map +1 -0
- package/dist/__tests__/fixtures/groups.js +36 -0
- package/dist/__tests__/fixtures/groups.js.map +1 -0
- package/dist/__tests__/fixtures/index.d.ts +22 -0
- package/dist/__tests__/fixtures/index.d.ts.map +1 -0
- package/dist/__tests__/fixtures/index.js +22 -0
- package/dist/__tests__/fixtures/index.js.map +1 -0
- package/dist/__tests__/fixtures/issues.d.ts +196 -0
- package/dist/__tests__/fixtures/issues.d.ts.map +1 -0
- package/dist/__tests__/fixtures/issues.js +80 -0
- package/dist/__tests__/fixtures/issues.js.map +1 -0
- package/dist/__tests__/fixtures/modules.d.ts +6 -0
- package/dist/__tests__/fixtures/modules.d.ts.map +1 -0
- package/dist/__tests__/fixtures/modules.js +103 -0
- package/dist/__tests__/fixtures/modules.js.map +1 -0
- package/dist/__tests__/fixtures/phases.d.ts +123 -0
- package/dist/__tests__/fixtures/phases.d.ts.map +1 -0
- package/dist/__tests__/fixtures/phases.js +68 -0
- package/dist/__tests__/fixtures/phases.js.map +1 -0
- package/dist/__tests__/fixtures/portals.d.ts +4 -0
- package/dist/__tests__/fixtures/portals.d.ts.map +1 -0
- package/dist/__tests__/fixtures/portals.js +48 -0
- package/dist/__tests__/fixtures/portals.js.map +1 -0
- package/dist/__tests__/fixtures/projects.d.ts +298 -0
- package/dist/__tests__/fixtures/projects.d.ts.map +1 -0
- package/dist/__tests__/fixtures/projects.js +44 -0
- package/dist/__tests__/fixtures/projects.js.map +1 -0
- package/dist/__tests__/fixtures/tags.d.ts +22 -0
- package/dist/__tests__/fixtures/tags.d.ts.map +1 -0
- package/dist/__tests__/fixtures/tags.js +33 -0
- package/dist/__tests__/fixtures/tags.js.map +1 -0
- package/dist/__tests__/fixtures/tasklists.d.ts +107 -0
- package/dist/__tests__/fixtures/tasklists.d.ts.map +1 -0
- package/dist/__tests__/fixtures/tasklists.js +31 -0
- package/dist/__tests__/fixtures/tasklists.js.map +1 -0
- package/dist/__tests__/fixtures/tasks.d.ts +209 -0
- package/dist/__tests__/fixtures/tasks.d.ts.map +1 -0
- package/dist/__tests__/fixtures/tasks.js +69 -0
- package/dist/__tests__/fixtures/tasks.js.map +1 -0
- package/dist/__tests__/fixtures/timelogs.d.ts +151 -0
- package/dist/__tests__/fixtures/timelogs.d.ts.map +1 -0
- package/dist/__tests__/fixtures/timelogs.js +79 -0
- package/dist/__tests__/fixtures/timelogs.js.map +1 -0
- package/dist/__tests__/fixtures/timers.d.ts +5 -0
- package/dist/__tests__/fixtures/timers.d.ts.map +1 -0
- package/dist/__tests__/fixtures/timers.js +50 -0
- package/dist/__tests__/fixtures/timers.js.map +1 -0
- package/dist/__tests__/fixtures/users.d.ts +55 -0
- package/dist/__tests__/fixtures/users.d.ts.map +1 -0
- package/dist/__tests__/fixtures/users.js +47 -0
- package/dist/__tests__/fixtures/users.js.map +1 -0
- package/dist/__tests__/integration/setup.d.ts +14 -0
- package/dist/__tests__/integration/setup.d.ts.map +1 -0
- package/dist/__tests__/integration/setup.js +52 -0
- package/dist/__tests__/integration/setup.js.map +1 -0
- package/dist/__tests__/mocks/handlers.d.ts +34 -0
- package/dist/__tests__/mocks/handlers.d.ts.map +1 -0
- package/dist/__tests__/mocks/handlers.js +49 -0
- package/dist/__tests__/mocks/handlers.js.map +1 -0
- package/dist/__tests__/mocks/server.d.ts +2 -0
- package/dist/__tests__/mocks/server.d.ts.map +1 -0
- package/dist/__tests__/mocks/server.js +7 -0
- package/dist/__tests__/mocks/server.js.map +1 -0
- package/dist/__tests__/setup.d.ts +2 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/setup.js +18 -0
- package/dist/__tests__/setup.js.map +1 -0
- package/dist/__tests__/unit/client/attachments.test.d.ts +2 -0
- package/dist/__tests__/unit/client/attachments.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/attachments.test.js +55 -0
- package/dist/__tests__/unit/client/attachments.test.js.map +1 -0
- package/dist/__tests__/unit/client/blueprints.test.d.ts +2 -0
- package/dist/__tests__/unit/client/blueprints.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/blueprints.test.js +127 -0
- package/dist/__tests__/unit/client/blueprints.test.js.map +1 -0
- package/dist/__tests__/unit/client/comments.test.d.ts +2 -0
- package/dist/__tests__/unit/client/comments.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/comments.test.js +95 -0
- package/dist/__tests__/unit/client/comments.test.js.map +1 -0
- package/dist/__tests__/unit/client/customviews.test.d.ts +2 -0
- package/dist/__tests__/unit/client/customviews.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/customviews.test.js +112 -0
- package/dist/__tests__/unit/client/customviews.test.js.map +1 -0
- package/dist/__tests__/unit/client/events.test.d.ts +2 -0
- package/dist/__tests__/unit/client/events.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/events.test.js +79 -0
- package/dist/__tests__/unit/client/events.test.js.map +1 -0
- package/dist/__tests__/unit/client/forums.test.d.ts +2 -0
- package/dist/__tests__/unit/client/forums.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/forums.test.js +75 -0
- package/dist/__tests__/unit/client/forums.test.js.map +1 -0
- package/dist/__tests__/unit/client/groups.test.d.ts +2 -0
- package/dist/__tests__/unit/client/groups.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/groups.test.js +74 -0
- package/dist/__tests__/unit/client/groups.test.js.map +1 -0
- package/dist/__tests__/unit/client/issues.test.d.ts +2 -0
- package/dist/__tests__/unit/client/issues.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/issues.test.js +75 -0
- package/dist/__tests__/unit/client/issues.test.js.map +1 -0
- package/dist/__tests__/unit/client/modules.test.d.ts +2 -0
- package/dist/__tests__/unit/client/modules.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/modules.test.js +92 -0
- package/dist/__tests__/unit/client/modules.test.js.map +1 -0
- package/dist/__tests__/unit/client/phases.test.d.ts +2 -0
- package/dist/__tests__/unit/client/phases.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/phases.test.js +79 -0
- package/dist/__tests__/unit/client/phases.test.js.map +1 -0
- package/dist/__tests__/unit/client/portals.test.d.ts +2 -0
- package/dist/__tests__/unit/client/portals.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/portals.test.js +54 -0
- package/dist/__tests__/unit/client/portals.test.js.map +1 -0
- package/dist/__tests__/unit/client/projects.test.d.ts +2 -0
- package/dist/__tests__/unit/client/projects.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/projects.test.js +171 -0
- package/dist/__tests__/unit/client/projects.test.js.map +1 -0
- package/dist/__tests__/unit/client/tags.test.d.ts +2 -0
- package/dist/__tests__/unit/client/tags.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/tags.test.js +99 -0
- package/dist/__tests__/unit/client/tags.test.js.map +1 -0
- package/dist/__tests__/unit/client/tasklists.test.d.ts +2 -0
- package/dist/__tests__/unit/client/tasklists.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/tasklists.test.js +75 -0
- package/dist/__tests__/unit/client/tasklists.test.js.map +1 -0
- package/dist/__tests__/unit/client/tasks.test.d.ts +2 -0
- package/dist/__tests__/unit/client/tasks.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/tasks.test.js +157 -0
- package/dist/__tests__/unit/client/tasks.test.js.map +1 -0
- package/dist/__tests__/unit/client/timers.test.d.ts +2 -0
- package/dist/__tests__/unit/client/timers.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/timers.test.js +122 -0
- package/dist/__tests__/unit/client/timers.test.js.map +1 -0
- package/dist/__tests__/unit/client/users.test.d.ts +2 -0
- package/dist/__tests__/unit/client/users.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/users.test.js +89 -0
- package/dist/__tests__/unit/client/users.test.js.map +1 -0
- package/dist/cli/init.d.ts +3 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +130 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/client.d.ts +2613 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +1623 -1
- package/dist/client.js.map +1 -1
- package/dist/types/attachments.d.ts +1545 -0
- package/dist/types/attachments.d.ts.map +1 -0
- package/dist/types/attachments.js +78 -0
- package/dist/types/attachments.js.map +1 -0
- package/dist/types/blueprints.d.ts +5070 -0
- package/dist/types/blueprints.d.ts.map +1 -0
- package/dist/types/blueprints.js +111 -0
- package/dist/types/blueprints.js.map +1 -0
- package/dist/types/clients.d.ts +384 -0
- package/dist/types/clients.d.ts.map +1 -0
- package/dist/types/clients.js +77 -0
- package/dist/types/clients.js.map +1 -0
- package/dist/types/comments.d.ts +1111 -0
- package/dist/types/comments.d.ts.map +1 -0
- package/dist/types/comments.js +73 -0
- package/dist/types/comments.js.map +1 -0
- package/dist/types/contacts.d.ts +444 -0
- package/dist/types/contacts.d.ts.map +1 -0
- package/dist/types/contacts.js +86 -0
- package/dist/types/contacts.js.map +1 -0
- package/dist/types/customviews.d.ts +1593 -0
- package/dist/types/customviews.d.ts.map +1 -0
- package/dist/types/customviews.js +117 -0
- package/dist/types/customviews.js.map +1 -0
- package/dist/types/dashboards.d.ts +1675 -0
- package/dist/types/dashboards.d.ts.map +1 -0
- package/dist/types/dashboards.js +77 -0
- package/dist/types/dashboards.js.map +1 -0
- package/dist/types/documents.d.ts +2322 -0
- package/dist/types/documents.d.ts.map +1 -0
- package/dist/types/documents.js +121 -0
- package/dist/types/documents.js.map +1 -0
- package/dist/types/events.d.ts +1747 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +122 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/followers.d.ts +198 -0
- package/dist/types/followers.d.ts.map +1 -0
- package/dist/types/followers.js +44 -0
- package/dist/types/followers.js.map +1 -0
- package/dist/types/forums.d.ts +1443 -0
- package/dist/types/forums.d.ts.map +1 -0
- package/dist/types/forums.js +89 -0
- package/dist/types/forums.js.map +1 -0
- package/dist/types/groups.d.ts +237 -0
- package/dist/types/groups.d.ts.map +1 -0
- package/dist/types/groups.js +52 -0
- package/dist/types/groups.js.map +1 -0
- package/dist/types/index.d.ts +31 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +58 -4
- package/dist/types/index.js.map +1 -1
- package/dist/types/issues.d.ts +2600 -0
- package/dist/types/issues.d.ts.map +1 -0
- package/dist/types/issues.js +147 -0
- package/dist/types/issues.js.map +1 -0
- package/dist/types/leaves.d.ts +435 -0
- package/dist/types/leaves.d.ts.map +1 -0
- package/dist/types/leaves.js +92 -0
- package/dist/types/leaves.js.map +1 -0
- package/dist/types/modules.d.ts +469 -0
- package/dist/types/modules.d.ts.map +1 -0
- package/dist/types/modules.js +91 -0
- package/dist/types/modules.js.map +1 -0
- package/dist/types/phases.d.ts +1564 -0
- package/dist/types/phases.d.ts.map +1 -0
- package/dist/types/phases.js +98 -0
- package/dist/types/phases.js.map +1 -0
- package/dist/types/portals.d.ts +1050 -0
- package/dist/types/portals.d.ts.map +1 -0
- package/dist/types/portals.js +58 -0
- package/dist/types/portals.js.map +1 -0
- package/dist/types/profiles.d.ts +243 -0
- package/dist/types/profiles.d.ts.map +1 -0
- package/dist/types/profiles.js +59 -0
- package/dist/types/profiles.js.map +1 -0
- package/dist/types/projects.d.ts +128 -0
- package/dist/types/projects.d.ts.map +1 -1
- package/dist/types/projects.js +44 -0
- package/dist/types/projects.js.map +1 -1
- package/dist/types/reports.d.ts +2010 -0
- package/dist/types/reports.d.ts.map +1 -0
- package/dist/types/reports.js +110 -0
- package/dist/types/reports.js.map +1 -0
- package/dist/types/roles.d.ts +243 -0
- package/dist/types/roles.d.ts.map +1 -0
- package/dist/types/roles.js +59 -0
- package/dist/types/roles.js.map +1 -0
- package/dist/types/search.d.ts +1091 -0
- package/dist/types/search.d.ts.map +1 -0
- package/dist/types/search.js +83 -0
- package/dist/types/search.js.map +1 -0
- package/dist/types/tags.d.ts +198 -0
- package/dist/types/tags.d.ts.map +1 -0
- package/dist/types/tags.js +49 -0
- package/dist/types/tags.js.map +1 -0
- package/dist/types/tasklists.d.ts +1317 -0
- package/dist/types/tasklists.d.ts.map +1 -0
- package/dist/types/tasklists.js +78 -0
- package/dist/types/tasklists.js.map +1 -0
- package/dist/types/tasks.d.ts +182 -0
- package/dist/types/tasks.d.ts.map +1 -1
- package/dist/types/tasks.js +52 -0
- package/dist/types/tasks.js.map +1 -1
- package/dist/types/teams.d.ts +504 -0
- package/dist/types/teams.d.ts.map +1 -0
- package/dist/types/teams.js +75 -0
- package/dist/types/teams.js.map +1 -0
- package/dist/types/timelogs.d.ts +245 -0
- package/dist/types/timelogs.d.ts.map +1 -1
- package/dist/types/timelogs.js +53 -0
- package/dist/types/timelogs.js.map +1 -1
- package/dist/types/timers.d.ts +1334 -0
- package/dist/types/timers.d.ts.map +1 -0
- package/dist/types/timers.js +108 -0
- package/dist/types/timers.js.map +1 -0
- package/dist/types/trash.d.ts +1447 -0
- package/dist/types/trash.d.ts.map +1 -0
- package/dist/types/trash.js +77 -0
- package/dist/types/trash.js.map +1 -0
- package/dist/types/users.d.ts +100 -0
- package/dist/types/users.d.ts.map +1 -1
- package/dist/types/users.js +56 -0
- package/dist/types/users.js.map +1 -1
- package/dist/types/widgets.d.ts +1083 -0
- package/dist/types/widgets.d.ts.map +1 -0
- package/dist/types/widgets.js +87 -0
- package/dist/types/widgets.js.map +1 -0
- package/package.json +15 -3
- package/templates/CLAUDE.md +66 -0
- package/templates/commands/zoho-auth.md +195 -0
- package/templates/commands/zoho-examples.md +375 -0
- package/templates/commands/zoho-projects.md +183 -0
- 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.
|