@panoptic-it-solutions/zoho-projects-client 0.1.4 → 0.2.1
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/clients.d.ts +4 -0
- package/dist/__tests__/fixtures/clients.d.ts.map +1 -0
- package/dist/__tests__/fixtures/clients.js +38 -0
- package/dist/__tests__/fixtures/clients.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/contacts.d.ts +4 -0
- package/dist/__tests__/fixtures/contacts.d.ts.map +1 -0
- package/dist/__tests__/fixtures/contacts.js +40 -0
- package/dist/__tests__/fixtures/contacts.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/dashboards.d.ts +4 -0
- package/dist/__tests__/fixtures/dashboards.d.ts.map +1 -0
- package/dist/__tests__/fixtures/dashboards.js +42 -0
- package/dist/__tests__/fixtures/dashboards.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/followers.d.ts +4 -0
- package/dist/__tests__/fixtures/followers.d.ts.map +1 -0
- package/dist/__tests__/fixtures/followers.js +33 -0
- package/dist/__tests__/fixtures/followers.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 +34 -0
- package/dist/__tests__/fixtures/index.d.ts.map +1 -0
- package/dist/__tests__/fixtures/index.js +34 -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/leaves.d.ts +4 -0
- package/dist/__tests__/fixtures/leaves.d.ts.map +1 -0
- package/dist/__tests__/fixtures/leaves.js +45 -0
- package/dist/__tests__/fixtures/leaves.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/profiles.d.ts +4 -0
- package/dist/__tests__/fixtures/profiles.d.ts.map +1 -0
- package/dist/__tests__/fixtures/profiles.js +35 -0
- package/dist/__tests__/fixtures/profiles.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/reports.d.ts +5 -0
- package/dist/__tests__/fixtures/reports.d.ts.map +1 -0
- package/dist/__tests__/fixtures/reports.js +70 -0
- package/dist/__tests__/fixtures/reports.js.map +1 -0
- package/dist/__tests__/fixtures/roles.d.ts +4 -0
- package/dist/__tests__/fixtures/roles.d.ts.map +1 -0
- package/dist/__tests__/fixtures/roles.js +38 -0
- package/dist/__tests__/fixtures/roles.js.map +1 -0
- package/dist/__tests__/fixtures/search.d.ts +5 -0
- package/dist/__tests__/fixtures/search.d.ts.map +1 -0
- package/dist/__tests__/fixtures/search.js +61 -0
- package/dist/__tests__/fixtures/search.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/teams.d.ts +5 -0
- package/dist/__tests__/fixtures/teams.d.ts.map +1 -0
- package/dist/__tests__/fixtures/teams.js +40 -0
- package/dist/__tests__/fixtures/teams.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/trash.d.ts +5 -0
- package/dist/__tests__/fixtures/trash.d.ts.map +1 -0
- package/dist/__tests__/fixtures/trash.js +62 -0
- package/dist/__tests__/fixtures/trash.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__/fixtures/widgets.d.ts +4 -0
- package/dist/__tests__/fixtures/widgets.d.ts.map +1 -0
- package/dist/__tests__/fixtures/widgets.js +51 -0
- package/dist/__tests__/fixtures/widgets.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/clients.test.d.ts +2 -0
- package/dist/__tests__/unit/client/clients.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/clients.test.js +87 -0
- package/dist/__tests__/unit/client/clients.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/contacts.test.d.ts +2 -0
- package/dist/__tests__/unit/client/contacts.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/contacts.test.js +89 -0
- package/dist/__tests__/unit/client/contacts.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/dashboards.test.d.ts +2 -0
- package/dist/__tests__/unit/client/dashboards.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/dashboards.test.js +87 -0
- package/dist/__tests__/unit/client/dashboards.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/followers.test.d.ts +2 -0
- package/dist/__tests__/unit/client/followers.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/followers.test.js +109 -0
- package/dist/__tests__/unit/client/followers.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/leaves.test.d.ts +2 -0
- package/dist/__tests__/unit/client/leaves.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/leaves.test.js +91 -0
- package/dist/__tests__/unit/client/leaves.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/profiles.test.d.ts +2 -0
- package/dist/__tests__/unit/client/profiles.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/profiles.test.js +86 -0
- package/dist/__tests__/unit/client/profiles.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/reports.test.d.ts +2 -0
- package/dist/__tests__/unit/client/reports.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/reports.test.js +86 -0
- package/dist/__tests__/unit/client/reports.test.js.map +1 -0
- package/dist/__tests__/unit/client/roles.test.d.ts +2 -0
- package/dist/__tests__/unit/client/roles.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/roles.test.js +86 -0
- package/dist/__tests__/unit/client/roles.test.js.map +1 -0
- package/dist/__tests__/unit/client/search.test.d.ts +2 -0
- package/dist/__tests__/unit/client/search.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/search.test.js +106 -0
- package/dist/__tests__/unit/client/search.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/teams.test.d.ts +2 -0
- package/dist/__tests__/unit/client/teams.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/teams.test.js +115 -0
- package/dist/__tests__/unit/client/teams.test.js.map +1 -0
- package/dist/__tests__/unit/client/timelogs.test.d.ts +2 -0
- package/dist/__tests__/unit/client/timelogs.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/timelogs.test.js +112 -0
- package/dist/__tests__/unit/client/timelogs.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/trash.test.d.ts +2 -0
- package/dist/__tests__/unit/client/trash.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/trash.test.js +103 -0
- package/dist/__tests__/unit/client/trash.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/__tests__/unit/client/widgets.test.d.ts +2 -0
- package/dist/__tests__/unit/client/widgets.test.d.ts.map +1 -0
- package/dist/__tests__/unit/client/widgets.test.js +91 -0
- package/dist/__tests__/unit/client/widgets.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
package/dist/client.js
CHANGED
|
@@ -2,7 +2,7 @@ import axios from "axios";
|
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { TokenManager } from "./auth/token-manager.js";
|
|
4
4
|
import { parseAxiosError, ZohoProjectsError, ZohoResponseValidationError, } from "./errors.js";
|
|
5
|
-
import { ProjectSchema, ProjectListResponseSchema, TaskSchema, TaskListResponseSchema, TimeLogListResponseSchema, UserSchema, UserListResponseSchema, } from "./types/index.js";
|
|
5
|
+
import { ProjectSchema, ProjectListResponseSchema, TaskSchema, TaskListResponseSchema, TimeLogSchema, TimeLogListResponseSchema, UserSchema, UserListResponseSchema, TagSchema, TagListResponseSchema, RoleSchema, RoleListResponseSchema, ProfileSchema, ProfileListResponseSchema, ClientSchema, ClientListResponseSchema, ContactSchema, ContactListResponseSchema, ProjectGroupSchema, ProjectGroupListResponseSchema, LeaveSchema, LeaveListResponseSchema, TeamSchema, TeamListResponseSchema, TaskListSchema, TaskListListResponseSchema, PhaseSchema, PhaseListResponseSchema, IssueSchema, IssueListResponseSchema, ForumSchema, ForumListResponseSchema, EventSchema, EventListResponseSchema, AttachmentSchema, AttachmentListResponseSchema, DocumentSchema, DocumentListResponseSchema, DocumentFolderSchema, DocumentFolderListResponseSchema, CommentSchema, CommentListResponseSchema, FollowerSchema, FollowerListResponseSchema, DashboardSchema, DashboardListResponseSchema, WidgetSchema, WidgetListResponseSchema, ReportSchema, ReportListResponseSchema, ReportDataResponseSchema, SearchResponseSchema, TrashListResponseSchema, TrashRestoreResponseSchema, PortalSchema, PortalListResponseSchema, ModuleSchema, ModuleListResponseSchema, ModuleFieldSchema, ModuleFieldListResponseSchema, TimerResponseSchema, TimerListResponseSchema, CustomViewSchema, CustomViewListResponseSchema, BlueprintSchema, BlueprintListResponseSchema, NextTransitionsResponseSchema, DuringActionsResponseSchema, } from "./types/index.js";
|
|
6
6
|
import { createRateLimiter } from "./utils/rate-limiter.js";
|
|
7
7
|
import { autoPaginate, collectAll, DEFAULT_PAGE_SIZE, } from "./utils/pagination.js";
|
|
8
8
|
/**
|
|
@@ -142,6 +142,28 @@ export function createZohoProjectsClient(config) {
|
|
|
142
142
|
}
|
|
143
143
|
return response.projects[0];
|
|
144
144
|
},
|
|
145
|
+
/**
|
|
146
|
+
* Create a new project
|
|
147
|
+
*/
|
|
148
|
+
async create(data) {
|
|
149
|
+
const response = await requestWithValidation(`${basePath}/projects/`, z.object({ projects: z.array(ProjectSchema) }), { method: "POST", data });
|
|
150
|
+
return response.projects[0];
|
|
151
|
+
},
|
|
152
|
+
/**
|
|
153
|
+
* Update an existing project
|
|
154
|
+
*/
|
|
155
|
+
async update(projectId, data) {
|
|
156
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/`, z.object({ projects: z.array(ProjectSchema) }), { method: "PUT", data });
|
|
157
|
+
return response.projects[0];
|
|
158
|
+
},
|
|
159
|
+
/**
|
|
160
|
+
* Delete a project (moves to trash)
|
|
161
|
+
*/
|
|
162
|
+
async delete(projectId) {
|
|
163
|
+
await request(`${basePath}/projects/${projectId}/`, {
|
|
164
|
+
method: "DELETE",
|
|
165
|
+
});
|
|
166
|
+
},
|
|
145
167
|
},
|
|
146
168
|
/**
|
|
147
169
|
* Tasks API
|
|
@@ -199,6 +221,28 @@ export function createZohoProjectsClient(config) {
|
|
|
199
221
|
}
|
|
200
222
|
return allTasks;
|
|
201
223
|
},
|
|
224
|
+
/**
|
|
225
|
+
* Create a new task in a project
|
|
226
|
+
*/
|
|
227
|
+
async create(projectId, data) {
|
|
228
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/tasks/`, z.object({ tasks: z.array(TaskSchema) }), { method: "POST", data });
|
|
229
|
+
return response.tasks[0];
|
|
230
|
+
},
|
|
231
|
+
/**
|
|
232
|
+
* Update an existing task
|
|
233
|
+
*/
|
|
234
|
+
async update(projectId, taskId, data) {
|
|
235
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/tasks/${taskId}/`, z.object({ tasks: z.array(TaskSchema) }), { method: "PUT", data });
|
|
236
|
+
return response.tasks[0];
|
|
237
|
+
},
|
|
238
|
+
/**
|
|
239
|
+
* Delete a task (moves to trash)
|
|
240
|
+
*/
|
|
241
|
+
async delete(projectId, taskId) {
|
|
242
|
+
await request(`${basePath}/projects/${projectId}/tasks/${taskId}/`, {
|
|
243
|
+
method: "DELETE",
|
|
244
|
+
});
|
|
245
|
+
},
|
|
202
246
|
// Internal reference to projects API
|
|
203
247
|
_getProjectsRef: () => client.projects,
|
|
204
248
|
},
|
|
@@ -280,6 +324,44 @@ export function createZohoProjectsClient(config) {
|
|
|
280
324
|
}
|
|
281
325
|
return allLogs;
|
|
282
326
|
},
|
|
327
|
+
/**
|
|
328
|
+
* Create a time log for a task
|
|
329
|
+
*/
|
|
330
|
+
async createForTask(projectId, data) {
|
|
331
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/logs/`, z.object({ timelogs: z.object({ tasklogs: z.array(TimeLogSchema) }) }), { method: "POST", data });
|
|
332
|
+
return response.timelogs.tasklogs[0];
|
|
333
|
+
},
|
|
334
|
+
/**
|
|
335
|
+
* Create a time log for a bug
|
|
336
|
+
*/
|
|
337
|
+
async createForBug(projectId, data) {
|
|
338
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/logs/`, z.object({ timelogs: z.object({ buglogs: z.array(TimeLogSchema) }) }), { method: "POST", data });
|
|
339
|
+
return response.timelogs.buglogs[0];
|
|
340
|
+
},
|
|
341
|
+
/**
|
|
342
|
+
* Create a general time log (not tied to task or bug)
|
|
343
|
+
*/
|
|
344
|
+
async createGeneral(projectId, data) {
|
|
345
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/logs/`, z.object({ timelogs: z.object({ generallogs: z.array(TimeLogSchema) }) }), { method: "POST", data });
|
|
346
|
+
return response.timelogs.generallogs[0];
|
|
347
|
+
},
|
|
348
|
+
/**
|
|
349
|
+
* Update a time log
|
|
350
|
+
*/
|
|
351
|
+
async update(projectId, logId, data) {
|
|
352
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/logs/${logId}/`, z.object({ timelogs: z.object({ tasklogs: z.array(TimeLogSchema).optional(), buglogs: z.array(TimeLogSchema).optional(), generallogs: z.array(TimeLogSchema).optional() }) }), { method: "PUT", data });
|
|
353
|
+
// Return whichever type was updated
|
|
354
|
+
const logs = response.timelogs.tasklogs || response.timelogs.buglogs || response.timelogs.generallogs || [];
|
|
355
|
+
return logs[0];
|
|
356
|
+
},
|
|
357
|
+
/**
|
|
358
|
+
* Delete a time log
|
|
359
|
+
*/
|
|
360
|
+
async delete(projectId, logId) {
|
|
361
|
+
await request(`${basePath}/projects/${projectId}/logs/${logId}/`, {
|
|
362
|
+
method: "DELETE",
|
|
363
|
+
});
|
|
364
|
+
},
|
|
283
365
|
// Internal reference to projects API
|
|
284
366
|
_getProjectsRef: () => client.projects,
|
|
285
367
|
},
|
|
@@ -339,6 +421,1546 @@ export function createZohoProjectsClient(config) {
|
|
|
339
421
|
pageInfo: response.page_info,
|
|
340
422
|
};
|
|
341
423
|
},
|
|
424
|
+
/**
|
|
425
|
+
* Invite a new user to the portal
|
|
426
|
+
*/
|
|
427
|
+
async invite(data) {
|
|
428
|
+
const response = await requestWithValidation(`${basePath}/users/`, z.object({ users: z.array(UserSchema) }), { method: "POST", data });
|
|
429
|
+
return response.users[0];
|
|
430
|
+
},
|
|
431
|
+
/**
|
|
432
|
+
* Add a user to a project
|
|
433
|
+
*/
|
|
434
|
+
async addToProject(projectId, data) {
|
|
435
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/users/`, z.object({ users: z.array(UserSchema) }), { method: "POST", data });
|
|
436
|
+
return response.users[0];
|
|
437
|
+
},
|
|
438
|
+
/**
|
|
439
|
+
* Update a user's details
|
|
440
|
+
*/
|
|
441
|
+
async update(userId, data) {
|
|
442
|
+
const response = await requestWithValidation(`${basePath}/users/${userId}/`, z.object({ users: z.array(UserSchema) }), { method: "PUT", data });
|
|
443
|
+
return response.users[0];
|
|
444
|
+
},
|
|
445
|
+
/**
|
|
446
|
+
* Remove a user from the portal
|
|
447
|
+
*/
|
|
448
|
+
async delete(userId) {
|
|
449
|
+
await request(`${basePath}/users/${userId}/`, {
|
|
450
|
+
method: "DELETE",
|
|
451
|
+
});
|
|
452
|
+
},
|
|
453
|
+
/**
|
|
454
|
+
* Remove a user from a project
|
|
455
|
+
*/
|
|
456
|
+
async removeFromProject(projectId, userId) {
|
|
457
|
+
await request(`${basePath}/projects/${projectId}/users/${userId}/`, {
|
|
458
|
+
method: "DELETE",
|
|
459
|
+
});
|
|
460
|
+
},
|
|
461
|
+
},
|
|
462
|
+
/**
|
|
463
|
+
* Tags API
|
|
464
|
+
*/
|
|
465
|
+
tags: {
|
|
466
|
+
async list(params) {
|
|
467
|
+
const response = await requestWithValidation(`${basePath}/tags/`, TagListResponseSchema, {
|
|
468
|
+
params: {
|
|
469
|
+
index: params?.index ?? 0,
|
|
470
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
471
|
+
},
|
|
472
|
+
});
|
|
473
|
+
return { data: response.tags, pageInfo: response.page_info };
|
|
474
|
+
},
|
|
475
|
+
async listAll(options) {
|
|
476
|
+
return collectAll(this.iterate(options));
|
|
477
|
+
},
|
|
478
|
+
iterate(options) {
|
|
479
|
+
return autoPaginate((index, range) => this.list({ index, range }), options);
|
|
480
|
+
},
|
|
481
|
+
async get(tagId) {
|
|
482
|
+
const response = await requestWithValidation(`${basePath}/tags/${tagId}/`, z.object({ tags: z.array(TagSchema) }));
|
|
483
|
+
if (response.tags.length === 0) {
|
|
484
|
+
throw new ZohoProjectsError(`Tag not found: ${tagId}`, 404);
|
|
485
|
+
}
|
|
486
|
+
return response.tags[0];
|
|
487
|
+
},
|
|
488
|
+
async create(data) {
|
|
489
|
+
const response = await requestWithValidation(`${basePath}/tags/`, z.object({ tags: z.array(TagSchema) }), { method: "POST", data });
|
|
490
|
+
return response.tags[0];
|
|
491
|
+
},
|
|
492
|
+
async update(tagId, data) {
|
|
493
|
+
const response = await requestWithValidation(`${basePath}/tags/${tagId}/`, z.object({ tags: z.array(TagSchema) }), { method: "PUT", data });
|
|
494
|
+
return response.tags[0];
|
|
495
|
+
},
|
|
496
|
+
async delete(tagId) {
|
|
497
|
+
await request(`${basePath}/tags/${tagId}/`, { method: "DELETE" });
|
|
498
|
+
},
|
|
499
|
+
},
|
|
500
|
+
/**
|
|
501
|
+
* Roles API
|
|
502
|
+
*/
|
|
503
|
+
roles: {
|
|
504
|
+
async list(params) {
|
|
505
|
+
const response = await requestWithValidation(`${basePath}/roles/`, RoleListResponseSchema, {
|
|
506
|
+
params: {
|
|
507
|
+
index: params?.index ?? 0,
|
|
508
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
509
|
+
},
|
|
510
|
+
});
|
|
511
|
+
return { data: response.roles, pageInfo: response.page_info };
|
|
512
|
+
},
|
|
513
|
+
async listAll(options) {
|
|
514
|
+
return collectAll(this.iterate(options));
|
|
515
|
+
},
|
|
516
|
+
iterate(options) {
|
|
517
|
+
return autoPaginate((index, range) => this.list({ index, range }), options);
|
|
518
|
+
},
|
|
519
|
+
async get(roleId) {
|
|
520
|
+
const response = await requestWithValidation(`${basePath}/roles/${roleId}/`, z.object({ roles: z.array(RoleSchema) }));
|
|
521
|
+
if (response.roles.length === 0) {
|
|
522
|
+
throw new ZohoProjectsError(`Role not found: ${roleId}`, 404);
|
|
523
|
+
}
|
|
524
|
+
return response.roles[0];
|
|
525
|
+
},
|
|
526
|
+
async create(data) {
|
|
527
|
+
const response = await requestWithValidation(`${basePath}/roles/`, z.object({ roles: z.array(RoleSchema) }), { method: "POST", data });
|
|
528
|
+
return response.roles[0];
|
|
529
|
+
},
|
|
530
|
+
async update(roleId, data) {
|
|
531
|
+
const response = await requestWithValidation(`${basePath}/roles/${roleId}/`, z.object({ roles: z.array(RoleSchema) }), { method: "PUT", data });
|
|
532
|
+
return response.roles[0];
|
|
533
|
+
},
|
|
534
|
+
async delete(roleId) {
|
|
535
|
+
await request(`${basePath}/roles/${roleId}/`, { method: "DELETE" });
|
|
536
|
+
},
|
|
537
|
+
},
|
|
538
|
+
/**
|
|
539
|
+
* Profiles API
|
|
540
|
+
*/
|
|
541
|
+
profiles: {
|
|
542
|
+
async list(params) {
|
|
543
|
+
const response = await requestWithValidation(`${basePath}/profiles/`, ProfileListResponseSchema, {
|
|
544
|
+
params: {
|
|
545
|
+
index: params?.index ?? 0,
|
|
546
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
547
|
+
},
|
|
548
|
+
});
|
|
549
|
+
return { data: response.profiles, pageInfo: response.page_info };
|
|
550
|
+
},
|
|
551
|
+
async listAll(options) {
|
|
552
|
+
return collectAll(this.iterate(options));
|
|
553
|
+
},
|
|
554
|
+
iterate(options) {
|
|
555
|
+
return autoPaginate((index, range) => this.list({ index, range }), options);
|
|
556
|
+
},
|
|
557
|
+
async get(profileId) {
|
|
558
|
+
const response = await requestWithValidation(`${basePath}/profiles/${profileId}/`, z.object({ profiles: z.array(ProfileSchema) }));
|
|
559
|
+
if (response.profiles.length === 0) {
|
|
560
|
+
throw new ZohoProjectsError(`Profile not found: ${profileId}`, 404);
|
|
561
|
+
}
|
|
562
|
+
return response.profiles[0];
|
|
563
|
+
},
|
|
564
|
+
async create(data) {
|
|
565
|
+
const response = await requestWithValidation(`${basePath}/profiles/`, z.object({ profiles: z.array(ProfileSchema) }), { method: "POST", data });
|
|
566
|
+
return response.profiles[0];
|
|
567
|
+
},
|
|
568
|
+
async update(profileId, data) {
|
|
569
|
+
const response = await requestWithValidation(`${basePath}/profiles/${profileId}/`, z.object({ profiles: z.array(ProfileSchema) }), { method: "PUT", data });
|
|
570
|
+
return response.profiles[0];
|
|
571
|
+
},
|
|
572
|
+
async delete(profileId) {
|
|
573
|
+
await request(`${basePath}/profiles/${profileId}/`, { method: "DELETE" });
|
|
574
|
+
},
|
|
575
|
+
},
|
|
576
|
+
/**
|
|
577
|
+
* Clients API
|
|
578
|
+
*/
|
|
579
|
+
clients: {
|
|
580
|
+
async list(params) {
|
|
581
|
+
const response = await requestWithValidation(`${basePath}/clients/`, ClientListResponseSchema, {
|
|
582
|
+
params: {
|
|
583
|
+
index: params?.index ?? 0,
|
|
584
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
585
|
+
},
|
|
586
|
+
});
|
|
587
|
+
return { data: response.clients, pageInfo: response.page_info };
|
|
588
|
+
},
|
|
589
|
+
async listAll(options) {
|
|
590
|
+
return collectAll(this.iterate(options));
|
|
591
|
+
},
|
|
592
|
+
iterate(options) {
|
|
593
|
+
return autoPaginate((index, range) => this.list({ index, range }), options);
|
|
594
|
+
},
|
|
595
|
+
async get(clientId) {
|
|
596
|
+
const response = await requestWithValidation(`${basePath}/clients/${clientId}/`, z.object({ clients: z.array(ClientSchema) }));
|
|
597
|
+
if (response.clients.length === 0) {
|
|
598
|
+
throw new ZohoProjectsError(`Client not found: ${clientId}`, 404);
|
|
599
|
+
}
|
|
600
|
+
return response.clients[0];
|
|
601
|
+
},
|
|
602
|
+
async create(data) {
|
|
603
|
+
const response = await requestWithValidation(`${basePath}/clients/`, z.object({ clients: z.array(ClientSchema) }), { method: "POST", data });
|
|
604
|
+
return response.clients[0];
|
|
605
|
+
},
|
|
606
|
+
async update(clientId, data) {
|
|
607
|
+
const response = await requestWithValidation(`${basePath}/clients/${clientId}/`, z.object({ clients: z.array(ClientSchema) }), { method: "PUT", data });
|
|
608
|
+
return response.clients[0];
|
|
609
|
+
},
|
|
610
|
+
async delete(clientId) {
|
|
611
|
+
await request(`${basePath}/clients/${clientId}/`, { method: "DELETE" });
|
|
612
|
+
},
|
|
613
|
+
},
|
|
614
|
+
/**
|
|
615
|
+
* Contacts API
|
|
616
|
+
*/
|
|
617
|
+
contacts: {
|
|
618
|
+
async list(params) {
|
|
619
|
+
const response = await requestWithValidation(`${basePath}/contacts/`, ContactListResponseSchema, {
|
|
620
|
+
params: {
|
|
621
|
+
index: params?.index ?? 0,
|
|
622
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
623
|
+
},
|
|
624
|
+
});
|
|
625
|
+
return { data: response.contacts, pageInfo: response.page_info };
|
|
626
|
+
},
|
|
627
|
+
async listAll(options) {
|
|
628
|
+
return collectAll(this.iterate(options));
|
|
629
|
+
},
|
|
630
|
+
iterate(options) {
|
|
631
|
+
return autoPaginate((index, range) => this.list({ index, range }), options);
|
|
632
|
+
},
|
|
633
|
+
async get(contactId) {
|
|
634
|
+
const response = await requestWithValidation(`${basePath}/contacts/${contactId}/`, z.object({ contacts: z.array(ContactSchema) }));
|
|
635
|
+
if (response.contacts.length === 0) {
|
|
636
|
+
throw new ZohoProjectsError(`Contact not found: ${contactId}`, 404);
|
|
637
|
+
}
|
|
638
|
+
return response.contacts[0];
|
|
639
|
+
},
|
|
640
|
+
async create(data) {
|
|
641
|
+
const response = await requestWithValidation(`${basePath}/contacts/`, z.object({ contacts: z.array(ContactSchema) }), { method: "POST", data });
|
|
642
|
+
return response.contacts[0];
|
|
643
|
+
},
|
|
644
|
+
async update(contactId, data) {
|
|
645
|
+
const response = await requestWithValidation(`${basePath}/contacts/${contactId}/`, z.object({ contacts: z.array(ContactSchema) }), { method: "PUT", data });
|
|
646
|
+
return response.contacts[0];
|
|
647
|
+
},
|
|
648
|
+
async delete(contactId) {
|
|
649
|
+
await request(`${basePath}/contacts/${contactId}/`, { method: "DELETE" });
|
|
650
|
+
},
|
|
651
|
+
},
|
|
652
|
+
/**
|
|
653
|
+
* Project Groups API
|
|
654
|
+
*/
|
|
655
|
+
groups: {
|
|
656
|
+
async list(params) {
|
|
657
|
+
const response = await requestWithValidation(`${basePath}/groups/`, ProjectGroupListResponseSchema, {
|
|
658
|
+
params: {
|
|
659
|
+
index: params?.index ?? 0,
|
|
660
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
661
|
+
},
|
|
662
|
+
});
|
|
663
|
+
return { data: response.groups, pageInfo: response.page_info };
|
|
664
|
+
},
|
|
665
|
+
async listAll(options) {
|
|
666
|
+
return collectAll(this.iterate(options));
|
|
667
|
+
},
|
|
668
|
+
iterate(options) {
|
|
669
|
+
return autoPaginate((index, range) => this.list({ index, range }), options);
|
|
670
|
+
},
|
|
671
|
+
async get(groupId) {
|
|
672
|
+
const response = await requestWithValidation(`${basePath}/groups/${groupId}/`, z.object({ groups: z.array(ProjectGroupSchema) }));
|
|
673
|
+
if (response.groups.length === 0) {
|
|
674
|
+
throw new ZohoProjectsError(`Project group not found: ${groupId}`, 404);
|
|
675
|
+
}
|
|
676
|
+
return response.groups[0];
|
|
677
|
+
},
|
|
678
|
+
async create(data) {
|
|
679
|
+
const response = await requestWithValidation(`${basePath}/groups/`, z.object({ groups: z.array(ProjectGroupSchema) }), { method: "POST", data });
|
|
680
|
+
return response.groups[0];
|
|
681
|
+
},
|
|
682
|
+
async update(groupId, data) {
|
|
683
|
+
const response = await requestWithValidation(`${basePath}/groups/${groupId}/`, z.object({ groups: z.array(ProjectGroupSchema) }), { method: "PUT", data });
|
|
684
|
+
return response.groups[0];
|
|
685
|
+
},
|
|
686
|
+
async delete(groupId) {
|
|
687
|
+
await request(`${basePath}/groups/${groupId}/`, { method: "DELETE" });
|
|
688
|
+
},
|
|
689
|
+
},
|
|
690
|
+
/**
|
|
691
|
+
* Leaves API
|
|
692
|
+
*/
|
|
693
|
+
leaves: {
|
|
694
|
+
async list(params) {
|
|
695
|
+
const response = await requestWithValidation(`${basePath}/leaves/`, LeaveListResponseSchema, {
|
|
696
|
+
params: {
|
|
697
|
+
index: params?.index ?? 0,
|
|
698
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
699
|
+
},
|
|
700
|
+
});
|
|
701
|
+
return { data: response.leaves, pageInfo: response.page_info };
|
|
702
|
+
},
|
|
703
|
+
async listAll(options) {
|
|
704
|
+
return collectAll(this.iterate(options));
|
|
705
|
+
},
|
|
706
|
+
iterate(options) {
|
|
707
|
+
return autoPaginate((index, range) => this.list({ index, range }), options);
|
|
708
|
+
},
|
|
709
|
+
async get(leaveId) {
|
|
710
|
+
const response = await requestWithValidation(`${basePath}/leaves/${leaveId}/`, z.object({ leaves: z.array(LeaveSchema) }));
|
|
711
|
+
if (response.leaves.length === 0) {
|
|
712
|
+
throw new ZohoProjectsError(`Leave not found: ${leaveId}`, 404);
|
|
713
|
+
}
|
|
714
|
+
return response.leaves[0];
|
|
715
|
+
},
|
|
716
|
+
async create(data) {
|
|
717
|
+
const response = await requestWithValidation(`${basePath}/leaves/`, z.object({ leaves: z.array(LeaveSchema) }), { method: "POST", data });
|
|
718
|
+
return response.leaves[0];
|
|
719
|
+
},
|
|
720
|
+
async update(leaveId, data) {
|
|
721
|
+
const response = await requestWithValidation(`${basePath}/leaves/${leaveId}/`, z.object({ leaves: z.array(LeaveSchema) }), { method: "PUT", data });
|
|
722
|
+
return response.leaves[0];
|
|
723
|
+
},
|
|
724
|
+
async delete(leaveId) {
|
|
725
|
+
await request(`${basePath}/leaves/${leaveId}/`, { method: "DELETE" });
|
|
726
|
+
},
|
|
727
|
+
},
|
|
728
|
+
/**
|
|
729
|
+
* Teams API
|
|
730
|
+
*/
|
|
731
|
+
teams: {
|
|
732
|
+
async list(params) {
|
|
733
|
+
const response = await requestWithValidation(`${basePath}/teams/`, TeamListResponseSchema, {
|
|
734
|
+
params: {
|
|
735
|
+
index: params?.index ?? 0,
|
|
736
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
737
|
+
},
|
|
738
|
+
});
|
|
739
|
+
return { data: response.teams, pageInfo: response.page_info };
|
|
740
|
+
},
|
|
741
|
+
async listAll(options) {
|
|
742
|
+
return collectAll(this.iterate(options));
|
|
743
|
+
},
|
|
744
|
+
iterate(options) {
|
|
745
|
+
return autoPaginate((index, range) => this.list({ index, range }), options);
|
|
746
|
+
},
|
|
747
|
+
async get(teamId) {
|
|
748
|
+
const response = await requestWithValidation(`${basePath}/teams/${teamId}/`, z.object({ teams: z.array(TeamSchema) }));
|
|
749
|
+
if (response.teams.length === 0) {
|
|
750
|
+
throw new ZohoProjectsError(`Team not found: ${teamId}`, 404);
|
|
751
|
+
}
|
|
752
|
+
return response.teams[0];
|
|
753
|
+
},
|
|
754
|
+
async create(data) {
|
|
755
|
+
const response = await requestWithValidation(`${basePath}/teams/`, z.object({ teams: z.array(TeamSchema) }), { method: "POST", data });
|
|
756
|
+
return response.teams[0];
|
|
757
|
+
},
|
|
758
|
+
async update(teamId, data) {
|
|
759
|
+
const response = await requestWithValidation(`${basePath}/teams/${teamId}/`, z.object({ teams: z.array(TeamSchema) }), { method: "PUT", data });
|
|
760
|
+
return response.teams[0];
|
|
761
|
+
},
|
|
762
|
+
async delete(teamId) {
|
|
763
|
+
await request(`${basePath}/teams/${teamId}/`, { method: "DELETE" });
|
|
764
|
+
},
|
|
765
|
+
async addMembers(teamId, data) {
|
|
766
|
+
const response = await requestWithValidation(`${basePath}/teams/${teamId}/members/`, z.object({ teams: z.array(TeamSchema) }), { method: "POST", data });
|
|
767
|
+
return response.teams[0];
|
|
768
|
+
},
|
|
769
|
+
async removeMember(teamId, userId) {
|
|
770
|
+
await request(`${basePath}/teams/${teamId}/members/${userId}/`, {
|
|
771
|
+
method: "DELETE",
|
|
772
|
+
});
|
|
773
|
+
},
|
|
774
|
+
},
|
|
775
|
+
/**
|
|
776
|
+
* Task Lists API (project-scoped)
|
|
777
|
+
*/
|
|
778
|
+
tasklists: {
|
|
779
|
+
async list(projectId, params) {
|
|
780
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/tasklists/`, TaskListListResponseSchema, {
|
|
781
|
+
params: {
|
|
782
|
+
index: params?.index ?? 0,
|
|
783
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
784
|
+
},
|
|
785
|
+
});
|
|
786
|
+
return { data: response.tasklists, pageInfo: response.page_info };
|
|
787
|
+
},
|
|
788
|
+
async listAll(projectId, options) {
|
|
789
|
+
return collectAll(this.iterate(projectId, options));
|
|
790
|
+
},
|
|
791
|
+
iterate(projectId, options) {
|
|
792
|
+
return autoPaginate((index, range) => this.list(projectId, { index, range }), options);
|
|
793
|
+
},
|
|
794
|
+
async get(projectId, tasklistId) {
|
|
795
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/tasklists/${tasklistId}/`, z.object({ tasklists: z.array(TaskListSchema) }));
|
|
796
|
+
if (response.tasklists.length === 0) {
|
|
797
|
+
throw new ZohoProjectsError(`Task list not found: ${tasklistId}`, 404);
|
|
798
|
+
}
|
|
799
|
+
return response.tasklists[0];
|
|
800
|
+
},
|
|
801
|
+
async create(projectId, data) {
|
|
802
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/tasklists/`, z.object({ tasklists: z.array(TaskListSchema) }), { method: "POST", data });
|
|
803
|
+
return response.tasklists[0];
|
|
804
|
+
},
|
|
805
|
+
async update(projectId, tasklistId, data) {
|
|
806
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/tasklists/${tasklistId}/`, z.object({ tasklists: z.array(TaskListSchema) }), { method: "PUT", data });
|
|
807
|
+
return response.tasklists[0];
|
|
808
|
+
},
|
|
809
|
+
async delete(projectId, tasklistId) {
|
|
810
|
+
await request(`${basePath}/projects/${projectId}/tasklists/${tasklistId}/`, { method: "DELETE" });
|
|
811
|
+
},
|
|
812
|
+
},
|
|
813
|
+
/**
|
|
814
|
+
* Phases (Milestones) API (project-scoped)
|
|
815
|
+
* Note: Zoho calls these "milestones" in the API
|
|
816
|
+
*/
|
|
817
|
+
phases: {
|
|
818
|
+
async list(projectId, params) {
|
|
819
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/milestones/`, PhaseListResponseSchema, {
|
|
820
|
+
params: {
|
|
821
|
+
index: params?.index ?? 0,
|
|
822
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
823
|
+
},
|
|
824
|
+
});
|
|
825
|
+
return { data: response.milestones, pageInfo: response.page_info };
|
|
826
|
+
},
|
|
827
|
+
async listAll(projectId, options) {
|
|
828
|
+
return collectAll(this.iterate(projectId, options));
|
|
829
|
+
},
|
|
830
|
+
iterate(projectId, options) {
|
|
831
|
+
return autoPaginate((index, range) => this.list(projectId, { index, range }), options);
|
|
832
|
+
},
|
|
833
|
+
async get(projectId, phaseId) {
|
|
834
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/milestones/${phaseId}/`, z.object({ milestones: z.array(PhaseSchema) }));
|
|
835
|
+
if (response.milestones.length === 0) {
|
|
836
|
+
throw new ZohoProjectsError(`Phase not found: ${phaseId}`, 404);
|
|
837
|
+
}
|
|
838
|
+
return response.milestones[0];
|
|
839
|
+
},
|
|
840
|
+
async create(projectId, data) {
|
|
841
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/milestones/`, z.object({ milestones: z.array(PhaseSchema) }), { method: "POST", data });
|
|
842
|
+
return response.milestones[0];
|
|
843
|
+
},
|
|
844
|
+
async update(projectId, phaseId, data) {
|
|
845
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/milestones/${phaseId}/`, z.object({ milestones: z.array(PhaseSchema) }), { method: "PUT", data });
|
|
846
|
+
return response.milestones[0];
|
|
847
|
+
},
|
|
848
|
+
async delete(projectId, phaseId) {
|
|
849
|
+
await request(`${basePath}/projects/${projectId}/milestones/${phaseId}/`, { method: "DELETE" });
|
|
850
|
+
},
|
|
851
|
+
},
|
|
852
|
+
/**
|
|
853
|
+
* Issues (Bugs) API (project-scoped)
|
|
854
|
+
* Note: Zoho calls these "bugs" in the API
|
|
855
|
+
*/
|
|
856
|
+
issues: {
|
|
857
|
+
async list(projectId, params) {
|
|
858
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/bugs/`, IssueListResponseSchema, {
|
|
859
|
+
params: {
|
|
860
|
+
index: params?.index ?? 0,
|
|
861
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
862
|
+
},
|
|
863
|
+
});
|
|
864
|
+
return { data: response.bugs, pageInfo: response.page_info };
|
|
865
|
+
},
|
|
866
|
+
async listAll(projectId, options) {
|
|
867
|
+
return collectAll(this.iterate(projectId, options));
|
|
868
|
+
},
|
|
869
|
+
iterate(projectId, options) {
|
|
870
|
+
return autoPaginate((index, range) => this.list(projectId, { index, range }), options);
|
|
871
|
+
},
|
|
872
|
+
async get(projectId, issueId) {
|
|
873
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/bugs/${issueId}/`, z.object({ bugs: z.array(IssueSchema) }));
|
|
874
|
+
if (response.bugs.length === 0) {
|
|
875
|
+
throw new ZohoProjectsError(`Issue not found: ${issueId}`, 404);
|
|
876
|
+
}
|
|
877
|
+
return response.bugs[0];
|
|
878
|
+
},
|
|
879
|
+
async create(projectId, data) {
|
|
880
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/bugs/`, z.object({ bugs: z.array(IssueSchema) }), { method: "POST", data });
|
|
881
|
+
return response.bugs[0];
|
|
882
|
+
},
|
|
883
|
+
async update(projectId, issueId, data) {
|
|
884
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/bugs/${issueId}/`, z.object({ bugs: z.array(IssueSchema) }), { method: "PUT", data });
|
|
885
|
+
return response.bugs[0];
|
|
886
|
+
},
|
|
887
|
+
async delete(projectId, issueId) {
|
|
888
|
+
await request(`${basePath}/projects/${projectId}/bugs/${issueId}/`, {
|
|
889
|
+
method: "DELETE",
|
|
890
|
+
});
|
|
891
|
+
},
|
|
892
|
+
},
|
|
893
|
+
/**
|
|
894
|
+
* Forums (Discussions) API (project-scoped)
|
|
895
|
+
*/
|
|
896
|
+
forums: {
|
|
897
|
+
async list(projectId, params) {
|
|
898
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/forums/`, ForumListResponseSchema, {
|
|
899
|
+
params: {
|
|
900
|
+
index: params?.index ?? 0,
|
|
901
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
902
|
+
},
|
|
903
|
+
});
|
|
904
|
+
return { data: response.forums, pageInfo: response.page_info };
|
|
905
|
+
},
|
|
906
|
+
async listAll(projectId, options) {
|
|
907
|
+
return collectAll(this.iterate(projectId, options));
|
|
908
|
+
},
|
|
909
|
+
iterate(projectId, options) {
|
|
910
|
+
return autoPaginate((index, range) => this.list(projectId, { index, range }), options);
|
|
911
|
+
},
|
|
912
|
+
async get(projectId, forumId) {
|
|
913
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/forums/${forumId}/`, z.object({ forums: z.array(ForumSchema) }));
|
|
914
|
+
if (response.forums.length === 0) {
|
|
915
|
+
throw new ZohoProjectsError(`Forum not found: ${forumId}`, 404);
|
|
916
|
+
}
|
|
917
|
+
return response.forums[0];
|
|
918
|
+
},
|
|
919
|
+
async create(projectId, data) {
|
|
920
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/forums/`, z.object({ forums: z.array(ForumSchema) }), { method: "POST", data });
|
|
921
|
+
return response.forums[0];
|
|
922
|
+
},
|
|
923
|
+
async update(projectId, forumId, data) {
|
|
924
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/forums/${forumId}/`, z.object({ forums: z.array(ForumSchema) }), { method: "PUT", data });
|
|
925
|
+
return response.forums[0];
|
|
926
|
+
},
|
|
927
|
+
async delete(projectId, forumId) {
|
|
928
|
+
await request(`${basePath}/projects/${projectId}/forums/${forumId}/`, {
|
|
929
|
+
method: "DELETE",
|
|
930
|
+
});
|
|
931
|
+
},
|
|
932
|
+
},
|
|
933
|
+
/**
|
|
934
|
+
* Events (Calendar) API (project-scoped)
|
|
935
|
+
*/
|
|
936
|
+
events: {
|
|
937
|
+
async list(projectId, params) {
|
|
938
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/events/`, EventListResponseSchema, {
|
|
939
|
+
params: {
|
|
940
|
+
index: params?.index ?? 0,
|
|
941
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
942
|
+
},
|
|
943
|
+
});
|
|
944
|
+
return { data: response.events, pageInfo: response.page_info };
|
|
945
|
+
},
|
|
946
|
+
async listAll(projectId, options) {
|
|
947
|
+
return collectAll(this.iterate(projectId, options));
|
|
948
|
+
},
|
|
949
|
+
iterate(projectId, options) {
|
|
950
|
+
return autoPaginate((index, range) => this.list(projectId, { index, range }), options);
|
|
951
|
+
},
|
|
952
|
+
async get(projectId, eventId) {
|
|
953
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/events/${eventId}/`, z.object({ events: z.array(EventSchema) }));
|
|
954
|
+
if (response.events.length === 0) {
|
|
955
|
+
throw new ZohoProjectsError(`Event not found: ${eventId}`, 404);
|
|
956
|
+
}
|
|
957
|
+
return response.events[0];
|
|
958
|
+
},
|
|
959
|
+
async create(projectId, data) {
|
|
960
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/events/`, z.object({ events: z.array(EventSchema) }), { method: "POST", data });
|
|
961
|
+
return response.events[0];
|
|
962
|
+
},
|
|
963
|
+
async update(projectId, eventId, data) {
|
|
964
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/events/${eventId}/`, z.object({ events: z.array(EventSchema) }), { method: "PUT", data });
|
|
965
|
+
return response.events[0];
|
|
966
|
+
},
|
|
967
|
+
async delete(projectId, eventId) {
|
|
968
|
+
await request(`${basePath}/projects/${projectId}/events/${eventId}/`, {
|
|
969
|
+
method: "DELETE",
|
|
970
|
+
});
|
|
971
|
+
},
|
|
972
|
+
},
|
|
973
|
+
/**
|
|
974
|
+
* Attachments API (project-scoped)
|
|
975
|
+
* Note: Upload requires multipart/form-data
|
|
976
|
+
*/
|
|
977
|
+
attachments: {
|
|
978
|
+
async list(projectId, params) {
|
|
979
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/attachments/`, AttachmentListResponseSchema, {
|
|
980
|
+
params: {
|
|
981
|
+
index: params?.index ?? 0,
|
|
982
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
983
|
+
},
|
|
984
|
+
});
|
|
985
|
+
return { data: response.attachments, pageInfo: response.page_info };
|
|
986
|
+
},
|
|
987
|
+
async listAll(projectId, options) {
|
|
988
|
+
return collectAll(this.iterate(projectId, options));
|
|
989
|
+
},
|
|
990
|
+
iterate(projectId, options) {
|
|
991
|
+
return autoPaginate((index, range) => this.list(projectId, { index, range }), options);
|
|
992
|
+
},
|
|
993
|
+
async get(projectId, attachmentId) {
|
|
994
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/attachments/${attachmentId}/`, z.object({ attachments: z.array(AttachmentSchema) }));
|
|
995
|
+
if (response.attachments.length === 0) {
|
|
996
|
+
throw new ZohoProjectsError(`Attachment not found: ${attachmentId}`, 404);
|
|
997
|
+
}
|
|
998
|
+
return response.attachments[0];
|
|
999
|
+
},
|
|
1000
|
+
/**
|
|
1001
|
+
* Upload an attachment
|
|
1002
|
+
* @param projectId - Project ID
|
|
1003
|
+
* @param file - File buffer or stream
|
|
1004
|
+
* @param filename - Original filename
|
|
1005
|
+
* @param options - Additional options
|
|
1006
|
+
*/
|
|
1007
|
+
async upload(projectId, file, filename, options) {
|
|
1008
|
+
const FormData = (await import("form-data")).default;
|
|
1009
|
+
const formData = new FormData();
|
|
1010
|
+
formData.append("uploaddoc", file, filename);
|
|
1011
|
+
if (options?.name)
|
|
1012
|
+
formData.append("name", options.name);
|
|
1013
|
+
if (options?.description)
|
|
1014
|
+
formData.append("description", options.description);
|
|
1015
|
+
if (options?.entity_type)
|
|
1016
|
+
formData.append("entity_type", options.entity_type);
|
|
1017
|
+
if (options?.entity_id)
|
|
1018
|
+
formData.append("entity_id", options.entity_id);
|
|
1019
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/attachments/`, z.object({ attachments: z.array(AttachmentSchema) }), {
|
|
1020
|
+
method: "POST",
|
|
1021
|
+
data: formData,
|
|
1022
|
+
headers: formData.getHeaders(),
|
|
1023
|
+
});
|
|
1024
|
+
return response.attachments[0];
|
|
1025
|
+
},
|
|
1026
|
+
async delete(projectId, attachmentId) {
|
|
1027
|
+
await request(`${basePath}/projects/${projectId}/attachments/${attachmentId}/`, { method: "DELETE" });
|
|
1028
|
+
},
|
|
1029
|
+
},
|
|
1030
|
+
/**
|
|
1031
|
+
* Documents API (project-scoped)
|
|
1032
|
+
*/
|
|
1033
|
+
documents: {
|
|
1034
|
+
async list(projectId, params) {
|
|
1035
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/documents/`, DocumentListResponseSchema, {
|
|
1036
|
+
params: {
|
|
1037
|
+
index: params?.index ?? 0,
|
|
1038
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
1039
|
+
folder_id: params?.folder_id,
|
|
1040
|
+
},
|
|
1041
|
+
});
|
|
1042
|
+
return { data: response.documents, pageInfo: response.page_info };
|
|
1043
|
+
},
|
|
1044
|
+
async listAll(projectId, options) {
|
|
1045
|
+
return collectAll(this.iterate(projectId, options));
|
|
1046
|
+
},
|
|
1047
|
+
iterate(projectId, options) {
|
|
1048
|
+
return autoPaginate((index, range) => this.list(projectId, { index, range }), options);
|
|
1049
|
+
},
|
|
1050
|
+
async get(projectId, documentId) {
|
|
1051
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/documents/${documentId}/`, z.object({ documents: z.array(DocumentSchema) }));
|
|
1052
|
+
if (response.documents.length === 0) {
|
|
1053
|
+
throw new ZohoProjectsError(`Document not found: ${documentId}`, 404);
|
|
1054
|
+
}
|
|
1055
|
+
return response.documents[0];
|
|
1056
|
+
},
|
|
1057
|
+
/**
|
|
1058
|
+
* Upload a document
|
|
1059
|
+
*/
|
|
1060
|
+
async upload(projectId, file, filename, options) {
|
|
1061
|
+
const FormData = (await import("form-data")).default;
|
|
1062
|
+
const formData = new FormData();
|
|
1063
|
+
formData.append("uploaddoc", file, filename);
|
|
1064
|
+
if (options?.name)
|
|
1065
|
+
formData.append("name", options.name);
|
|
1066
|
+
if (options?.description)
|
|
1067
|
+
formData.append("description", options.description);
|
|
1068
|
+
if (options?.folder_id)
|
|
1069
|
+
formData.append("folder_id", options.folder_id);
|
|
1070
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/documents/`, z.object({ documents: z.array(DocumentSchema) }), {
|
|
1071
|
+
method: "POST",
|
|
1072
|
+
data: formData,
|
|
1073
|
+
headers: formData.getHeaders(),
|
|
1074
|
+
});
|
|
1075
|
+
return response.documents[0];
|
|
1076
|
+
},
|
|
1077
|
+
async update(projectId, documentId, data) {
|
|
1078
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/documents/${documentId}/`, z.object({ documents: z.array(DocumentSchema) }), { method: "PUT", data });
|
|
1079
|
+
return response.documents[0];
|
|
1080
|
+
},
|
|
1081
|
+
async delete(projectId, documentId) {
|
|
1082
|
+
await request(`${basePath}/projects/${projectId}/documents/${documentId}/`, { method: "DELETE" });
|
|
1083
|
+
},
|
|
1084
|
+
// Folder operations
|
|
1085
|
+
folders: {
|
|
1086
|
+
async list(projectId, params) {
|
|
1087
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/folders/`, DocumentFolderListResponseSchema, {
|
|
1088
|
+
params: {
|
|
1089
|
+
index: params?.index ?? 0,
|
|
1090
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
1091
|
+
},
|
|
1092
|
+
});
|
|
1093
|
+
return { data: response.folders, pageInfo: response.page_info };
|
|
1094
|
+
},
|
|
1095
|
+
async get(projectId, folderId) {
|
|
1096
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/folders/${folderId}/`, z.object({ folders: z.array(DocumentFolderSchema) }));
|
|
1097
|
+
if (response.folders.length === 0) {
|
|
1098
|
+
throw new ZohoProjectsError(`Folder not found: ${folderId}`, 404);
|
|
1099
|
+
}
|
|
1100
|
+
return response.folders[0];
|
|
1101
|
+
},
|
|
1102
|
+
async create(projectId, data) {
|
|
1103
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/folders/`, z.object({ folders: z.array(DocumentFolderSchema) }), { method: "POST", data });
|
|
1104
|
+
return response.folders[0];
|
|
1105
|
+
},
|
|
1106
|
+
async update(projectId, folderId, data) {
|
|
1107
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/folders/${folderId}/`, z.object({ folders: z.array(DocumentFolderSchema) }), { method: "PUT", data });
|
|
1108
|
+
return response.folders[0];
|
|
1109
|
+
},
|
|
1110
|
+
async delete(projectId, folderId) {
|
|
1111
|
+
await request(`${basePath}/projects/${projectId}/folders/${folderId}/`, { method: "DELETE" });
|
|
1112
|
+
},
|
|
1113
|
+
},
|
|
1114
|
+
},
|
|
1115
|
+
/**
|
|
1116
|
+
* Comments API (polymorphic - attaches to multiple entity types)
|
|
1117
|
+
* Supports: tasks, bugs, forums, milestones, events
|
|
1118
|
+
*/
|
|
1119
|
+
comments: {
|
|
1120
|
+
/**
|
|
1121
|
+
* Get comments for a task
|
|
1122
|
+
*/
|
|
1123
|
+
forTask(projectId, taskId) {
|
|
1124
|
+
return this._forEntity("tasks", projectId, taskId);
|
|
1125
|
+
},
|
|
1126
|
+
/**
|
|
1127
|
+
* Get comments for an issue (bug)
|
|
1128
|
+
*/
|
|
1129
|
+
forIssue(projectId, issueId) {
|
|
1130
|
+
return this._forEntity("bugs", projectId, issueId);
|
|
1131
|
+
},
|
|
1132
|
+
/**
|
|
1133
|
+
* Get comments for a forum
|
|
1134
|
+
*/
|
|
1135
|
+
forForum(projectId, forumId) {
|
|
1136
|
+
return this._forEntity("forums", projectId, forumId);
|
|
1137
|
+
},
|
|
1138
|
+
/**
|
|
1139
|
+
* Get comments for a phase (milestone)
|
|
1140
|
+
*/
|
|
1141
|
+
forPhase(projectId, phaseId) {
|
|
1142
|
+
return this._forEntity("milestones", projectId, phaseId);
|
|
1143
|
+
},
|
|
1144
|
+
/**
|
|
1145
|
+
* Get comments for an event
|
|
1146
|
+
*/
|
|
1147
|
+
forEvent(projectId, eventId) {
|
|
1148
|
+
return this._forEntity("events", projectId, eventId);
|
|
1149
|
+
},
|
|
1150
|
+
/**
|
|
1151
|
+
* Internal method to create comment operations for any entity type
|
|
1152
|
+
*/
|
|
1153
|
+
_forEntity(entityType, projectId, entityId) {
|
|
1154
|
+
const commentsPath = `${basePath}/projects/${projectId}/${entityType}/${entityId}/comments`;
|
|
1155
|
+
return {
|
|
1156
|
+
async list(params) {
|
|
1157
|
+
const response = await requestWithValidation(`${commentsPath}/`, CommentListResponseSchema, {
|
|
1158
|
+
params: {
|
|
1159
|
+
index: params?.index ?? 0,
|
|
1160
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
1161
|
+
},
|
|
1162
|
+
});
|
|
1163
|
+
return { data: response.comments, pageInfo: response.page_info };
|
|
1164
|
+
},
|
|
1165
|
+
async listAll(options) {
|
|
1166
|
+
return collectAll(this.iterate(options));
|
|
1167
|
+
},
|
|
1168
|
+
iterate(options) {
|
|
1169
|
+
return autoPaginate((index, range) => this.list({ index, range }), options);
|
|
1170
|
+
},
|
|
1171
|
+
async get(commentId) {
|
|
1172
|
+
const response = await requestWithValidation(`${commentsPath}/${commentId}/`, z.object({ comments: z.array(CommentSchema) }));
|
|
1173
|
+
if (response.comments.length === 0) {
|
|
1174
|
+
throw new ZohoProjectsError(`Comment not found: ${commentId}`, 404);
|
|
1175
|
+
}
|
|
1176
|
+
return response.comments[0];
|
|
1177
|
+
},
|
|
1178
|
+
async create(data) {
|
|
1179
|
+
const response = await requestWithValidation(`${commentsPath}/`, z.object({ comments: z.array(CommentSchema) }), { method: "POST", data });
|
|
1180
|
+
return response.comments[0];
|
|
1181
|
+
},
|
|
1182
|
+
async update(commentId, data) {
|
|
1183
|
+
const response = await requestWithValidation(`${commentsPath}/${commentId}/`, z.object({ comments: z.array(CommentSchema) }), { method: "PUT", data });
|
|
1184
|
+
return response.comments[0];
|
|
1185
|
+
},
|
|
1186
|
+
async delete(commentId) {
|
|
1187
|
+
await request(`${commentsPath}/${commentId}/`, {
|
|
1188
|
+
method: "DELETE",
|
|
1189
|
+
});
|
|
1190
|
+
},
|
|
1191
|
+
};
|
|
1192
|
+
},
|
|
1193
|
+
},
|
|
1194
|
+
/**
|
|
1195
|
+
* Followers API (polymorphic - attaches to multiple entity types)
|
|
1196
|
+
* Supports: tasks, bugs, forums, milestones, events
|
|
1197
|
+
*/
|
|
1198
|
+
followers: {
|
|
1199
|
+
/**
|
|
1200
|
+
* Get followers for a task
|
|
1201
|
+
*/
|
|
1202
|
+
forTask(projectId, taskId) {
|
|
1203
|
+
return this._forEntity("tasks", projectId, taskId);
|
|
1204
|
+
},
|
|
1205
|
+
/**
|
|
1206
|
+
* Get followers for an issue (bug)
|
|
1207
|
+
*/
|
|
1208
|
+
forIssue(projectId, issueId) {
|
|
1209
|
+
return this._forEntity("bugs", projectId, issueId);
|
|
1210
|
+
},
|
|
1211
|
+
/**
|
|
1212
|
+
* Get followers for a forum
|
|
1213
|
+
*/
|
|
1214
|
+
forForum(projectId, forumId) {
|
|
1215
|
+
return this._forEntity("forums", projectId, forumId);
|
|
1216
|
+
},
|
|
1217
|
+
/**
|
|
1218
|
+
* Get followers for a phase (milestone)
|
|
1219
|
+
*/
|
|
1220
|
+
forPhase(projectId, phaseId) {
|
|
1221
|
+
return this._forEntity("milestones", projectId, phaseId);
|
|
1222
|
+
},
|
|
1223
|
+
/**
|
|
1224
|
+
* Get followers for an event
|
|
1225
|
+
*/
|
|
1226
|
+
forEvent(projectId, eventId) {
|
|
1227
|
+
return this._forEntity("events", projectId, eventId);
|
|
1228
|
+
},
|
|
1229
|
+
/**
|
|
1230
|
+
* Internal method to create follower operations for any entity type
|
|
1231
|
+
*/
|
|
1232
|
+
_forEntity(entityType, projectId, entityId) {
|
|
1233
|
+
const followersPath = `${basePath}/projects/${projectId}/${entityType}/${entityId}/followers`;
|
|
1234
|
+
return {
|
|
1235
|
+
async list(params) {
|
|
1236
|
+
const response = await requestWithValidation(`${followersPath}/`, FollowerListResponseSchema, {
|
|
1237
|
+
params: {
|
|
1238
|
+
index: params?.index ?? 0,
|
|
1239
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
1240
|
+
},
|
|
1241
|
+
});
|
|
1242
|
+
return { data: response.followers, pageInfo: response.page_info };
|
|
1243
|
+
},
|
|
1244
|
+
async listAll(options) {
|
|
1245
|
+
return collectAll(this.iterate(options));
|
|
1246
|
+
},
|
|
1247
|
+
iterate(options) {
|
|
1248
|
+
return autoPaginate((index, range) => this.list({ index, range }), options);
|
|
1249
|
+
},
|
|
1250
|
+
async add(data) {
|
|
1251
|
+
const response = await requestWithValidation(`${followersPath}/`, z.object({ followers: z.array(FollowerSchema) }), { method: "POST", data });
|
|
1252
|
+
return response.followers;
|
|
1253
|
+
},
|
|
1254
|
+
async remove(userId) {
|
|
1255
|
+
await request(`${followersPath}/${userId}/`, {
|
|
1256
|
+
method: "DELETE",
|
|
1257
|
+
});
|
|
1258
|
+
},
|
|
1259
|
+
/**
|
|
1260
|
+
* Follow this entity as the current user
|
|
1261
|
+
*/
|
|
1262
|
+
async follow() {
|
|
1263
|
+
await request(`${followersPath}/me/`, {
|
|
1264
|
+
method: "POST",
|
|
1265
|
+
});
|
|
1266
|
+
},
|
|
1267
|
+
/**
|
|
1268
|
+
* Unfollow this entity as the current user
|
|
1269
|
+
*/
|
|
1270
|
+
async unfollow() {
|
|
1271
|
+
await request(`${followersPath}/me/`, {
|
|
1272
|
+
method: "DELETE",
|
|
1273
|
+
});
|
|
1274
|
+
},
|
|
1275
|
+
};
|
|
1276
|
+
},
|
|
1277
|
+
},
|
|
1278
|
+
/**
|
|
1279
|
+
* Dashboards API
|
|
1280
|
+
*/
|
|
1281
|
+
dashboards: {
|
|
1282
|
+
async list(params) {
|
|
1283
|
+
const response = await requestWithValidation(`${basePath}/dashboards/`, DashboardListResponseSchema, {
|
|
1284
|
+
params: {
|
|
1285
|
+
index: params?.index ?? 0,
|
|
1286
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
1287
|
+
},
|
|
1288
|
+
});
|
|
1289
|
+
return { data: response.dashboards, pageInfo: response.page_info };
|
|
1290
|
+
},
|
|
1291
|
+
async listAll(options) {
|
|
1292
|
+
return collectAll(this.iterate(options));
|
|
1293
|
+
},
|
|
1294
|
+
iterate(options) {
|
|
1295
|
+
return autoPaginate((index, range) => this.list({ index, range }), options);
|
|
1296
|
+
},
|
|
1297
|
+
async get(dashboardId) {
|
|
1298
|
+
const response = await requestWithValidation(`${basePath}/dashboards/${dashboardId}/`, z.object({ dashboards: z.array(DashboardSchema) }));
|
|
1299
|
+
if (response.dashboards.length === 0) {
|
|
1300
|
+
throw new ZohoProjectsError(`Dashboard not found: ${dashboardId}`, 404);
|
|
1301
|
+
}
|
|
1302
|
+
return response.dashboards[0];
|
|
1303
|
+
},
|
|
1304
|
+
async create(data) {
|
|
1305
|
+
const response = await requestWithValidation(`${basePath}/dashboards/`, z.object({ dashboards: z.array(DashboardSchema) }), { method: "POST", data });
|
|
1306
|
+
return response.dashboards[0];
|
|
1307
|
+
},
|
|
1308
|
+
async update(dashboardId, data) {
|
|
1309
|
+
const response = await requestWithValidation(`${basePath}/dashboards/${dashboardId}/`, z.object({ dashboards: z.array(DashboardSchema) }), { method: "PUT", data });
|
|
1310
|
+
return response.dashboards[0];
|
|
1311
|
+
},
|
|
1312
|
+
async delete(dashboardId) {
|
|
1313
|
+
await request(`${basePath}/dashboards/${dashboardId}/`, {
|
|
1314
|
+
method: "DELETE",
|
|
1315
|
+
});
|
|
1316
|
+
},
|
|
1317
|
+
/**
|
|
1318
|
+
* Widget operations for a specific dashboard
|
|
1319
|
+
*/
|
|
1320
|
+
widgets(dashboardId) {
|
|
1321
|
+
const widgetsPath = `${basePath}/dashboards/${dashboardId}/widgets`;
|
|
1322
|
+
return {
|
|
1323
|
+
async list(params) {
|
|
1324
|
+
const response = await requestWithValidation(`${widgetsPath}/`, WidgetListResponseSchema, {
|
|
1325
|
+
params: {
|
|
1326
|
+
index: params?.index ?? 0,
|
|
1327
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
1328
|
+
},
|
|
1329
|
+
});
|
|
1330
|
+
return { data: response.widgets, pageInfo: response.page_info };
|
|
1331
|
+
},
|
|
1332
|
+
async listAll(options) {
|
|
1333
|
+
return collectAll(this.iterate(options));
|
|
1334
|
+
},
|
|
1335
|
+
iterate(options) {
|
|
1336
|
+
return autoPaginate((index, range) => this.list({ index, range }), options);
|
|
1337
|
+
},
|
|
1338
|
+
async get(widgetId) {
|
|
1339
|
+
const response = await requestWithValidation(`${widgetsPath}/${widgetId}/`, z.object({ widgets: z.array(WidgetSchema) }));
|
|
1340
|
+
if (response.widgets.length === 0) {
|
|
1341
|
+
throw new ZohoProjectsError(`Widget not found: ${widgetId}`, 404);
|
|
1342
|
+
}
|
|
1343
|
+
return response.widgets[0];
|
|
1344
|
+
},
|
|
1345
|
+
async create(data) {
|
|
1346
|
+
const response = await requestWithValidation(`${widgetsPath}/`, z.object({ widgets: z.array(WidgetSchema) }), { method: "POST", data });
|
|
1347
|
+
return response.widgets[0];
|
|
1348
|
+
},
|
|
1349
|
+
async update(widgetId, data) {
|
|
1350
|
+
const response = await requestWithValidation(`${widgetsPath}/${widgetId}/`, z.object({ widgets: z.array(WidgetSchema) }), { method: "PUT", data });
|
|
1351
|
+
return response.widgets[0];
|
|
1352
|
+
},
|
|
1353
|
+
async delete(widgetId) {
|
|
1354
|
+
await request(`${widgetsPath}/${widgetId}/`, {
|
|
1355
|
+
method: "DELETE",
|
|
1356
|
+
});
|
|
1357
|
+
},
|
|
1358
|
+
};
|
|
1359
|
+
},
|
|
1360
|
+
},
|
|
1361
|
+
/**
|
|
1362
|
+
* Reports API
|
|
1363
|
+
* Reports are typically read-only with specialized query parameters
|
|
1364
|
+
*/
|
|
1365
|
+
reports: {
|
|
1366
|
+
async list(params) {
|
|
1367
|
+
const response = await requestWithValidation(`${basePath}/reports/`, ReportListResponseSchema, {
|
|
1368
|
+
params: {
|
|
1369
|
+
index: params?.index ?? 0,
|
|
1370
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
1371
|
+
},
|
|
1372
|
+
});
|
|
1373
|
+
return { data: response.reports, pageInfo: response.page_info };
|
|
1374
|
+
},
|
|
1375
|
+
async listAll(options) {
|
|
1376
|
+
return collectAll(this.iterate(options));
|
|
1377
|
+
},
|
|
1378
|
+
iterate(options) {
|
|
1379
|
+
return autoPaginate((index, range) => this.list({ index, range }), options);
|
|
1380
|
+
},
|
|
1381
|
+
async get(reportId) {
|
|
1382
|
+
const response = await requestWithValidation(`${basePath}/reports/${reportId}/`, z.object({ reports: z.array(ReportSchema) }));
|
|
1383
|
+
if (response.reports.length === 0) {
|
|
1384
|
+
throw new ZohoProjectsError(`Report not found: ${reportId}`, 404);
|
|
1385
|
+
}
|
|
1386
|
+
return response.reports[0];
|
|
1387
|
+
},
|
|
1388
|
+
/**
|
|
1389
|
+
* Execute a report and get its data
|
|
1390
|
+
*/
|
|
1391
|
+
async execute(reportId, query) {
|
|
1392
|
+
const response = await requestWithValidation(`${basePath}/reports/${reportId}/data/`, ReportDataResponseSchema, {
|
|
1393
|
+
params: {
|
|
1394
|
+
index: query?.index ?? 0,
|
|
1395
|
+
range: query?.range ?? DEFAULT_PAGE_SIZE,
|
|
1396
|
+
sort_by: query?.sort_by,
|
|
1397
|
+
sort_order: query?.sort_order,
|
|
1398
|
+
group_by: query?.group_by,
|
|
1399
|
+
start_date: query?.start_date,
|
|
1400
|
+
end_date: query?.end_date,
|
|
1401
|
+
},
|
|
1402
|
+
});
|
|
1403
|
+
return response;
|
|
1404
|
+
},
|
|
1405
|
+
/**
|
|
1406
|
+
* List reports for a specific project
|
|
1407
|
+
*/
|
|
1408
|
+
async listForProject(projectId, params) {
|
|
1409
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/reports/`, ReportListResponseSchema, {
|
|
1410
|
+
params: {
|
|
1411
|
+
index: params?.index ?? 0,
|
|
1412
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
1413
|
+
},
|
|
1414
|
+
});
|
|
1415
|
+
return { data: response.reports, pageInfo: response.page_info };
|
|
1416
|
+
},
|
|
1417
|
+
},
|
|
1418
|
+
/**
|
|
1419
|
+
* Search API
|
|
1420
|
+
* Global search across entities
|
|
1421
|
+
*/
|
|
1422
|
+
search: {
|
|
1423
|
+
/**
|
|
1424
|
+
* Search across all entities
|
|
1425
|
+
*/
|
|
1426
|
+
async query(query) {
|
|
1427
|
+
const response = await requestWithValidation(`${basePath}/search/`, SearchResponseSchema, {
|
|
1428
|
+
params: {
|
|
1429
|
+
search_term: query.search_term,
|
|
1430
|
+
entity_type: query.entity_type,
|
|
1431
|
+
project_id: query.project_id,
|
|
1432
|
+
status: query.status,
|
|
1433
|
+
owner: query.owner,
|
|
1434
|
+
start_date: query.start_date,
|
|
1435
|
+
end_date: query.end_date,
|
|
1436
|
+
index: query.index ?? 0,
|
|
1437
|
+
range: query.range ?? DEFAULT_PAGE_SIZE,
|
|
1438
|
+
},
|
|
1439
|
+
});
|
|
1440
|
+
const results = response.results || response.search_results || [];
|
|
1441
|
+
return { data: results, pageInfo: response.page_info };
|
|
1442
|
+
},
|
|
1443
|
+
/**
|
|
1444
|
+
* Search within a specific project
|
|
1445
|
+
*/
|
|
1446
|
+
async inProject(projectId, query) {
|
|
1447
|
+
return this.query({ ...query, project_id: projectId });
|
|
1448
|
+
},
|
|
1449
|
+
/**
|
|
1450
|
+
* Search for tasks
|
|
1451
|
+
*/
|
|
1452
|
+
async tasks(searchTerm, params) {
|
|
1453
|
+
return this.query({
|
|
1454
|
+
search_term: searchTerm,
|
|
1455
|
+
entity_type: "task",
|
|
1456
|
+
...params,
|
|
1457
|
+
});
|
|
1458
|
+
},
|
|
1459
|
+
/**
|
|
1460
|
+
* Search for issues (bugs)
|
|
1461
|
+
*/
|
|
1462
|
+
async issues(searchTerm, params) {
|
|
1463
|
+
return this.query({
|
|
1464
|
+
search_term: searchTerm,
|
|
1465
|
+
entity_type: "bug",
|
|
1466
|
+
...params,
|
|
1467
|
+
});
|
|
1468
|
+
},
|
|
1469
|
+
/**
|
|
1470
|
+
* Search for projects
|
|
1471
|
+
*/
|
|
1472
|
+
async projects(searchTerm, params) {
|
|
1473
|
+
return this.query({
|
|
1474
|
+
search_term: searchTerm,
|
|
1475
|
+
entity_type: "project",
|
|
1476
|
+
...params,
|
|
1477
|
+
});
|
|
1478
|
+
},
|
|
1479
|
+
},
|
|
1480
|
+
/**
|
|
1481
|
+
* Trash API
|
|
1482
|
+
* Manage deleted items
|
|
1483
|
+
*/
|
|
1484
|
+
trash: {
|
|
1485
|
+
/**
|
|
1486
|
+
* List items in trash
|
|
1487
|
+
*/
|
|
1488
|
+
async list(params) {
|
|
1489
|
+
const response = await requestWithValidation(`${basePath}/trash/`, TrashListResponseSchema, {
|
|
1490
|
+
params: {
|
|
1491
|
+
entity_type: params?.entity_type,
|
|
1492
|
+
project_id: params?.project_id,
|
|
1493
|
+
deleted_by: params?.deleted_by,
|
|
1494
|
+
index: params?.index ?? 0,
|
|
1495
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
1496
|
+
},
|
|
1497
|
+
});
|
|
1498
|
+
const items = response.trash || response.deleted_items || [];
|
|
1499
|
+
return { data: items, pageInfo: response.page_info };
|
|
1500
|
+
},
|
|
1501
|
+
/**
|
|
1502
|
+
* List all items in trash with auto-pagination
|
|
1503
|
+
*/
|
|
1504
|
+
async listAll(params, options) {
|
|
1505
|
+
return collectAll(this.iterate(params, options));
|
|
1506
|
+
},
|
|
1507
|
+
/**
|
|
1508
|
+
* Iterate over all trash items with auto-pagination
|
|
1509
|
+
*/
|
|
1510
|
+
iterate(params, options) {
|
|
1511
|
+
return autoPaginate((index, range) => this.list({ ...params, index, range }), options);
|
|
1512
|
+
},
|
|
1513
|
+
/**
|
|
1514
|
+
* Restore an item from trash
|
|
1515
|
+
*/
|
|
1516
|
+
async restore(entityType, itemId) {
|
|
1517
|
+
const response = await requestWithValidation(`${basePath}/trash/${entityType}/${itemId}/restore/`, TrashRestoreResponseSchema, { method: "POST" });
|
|
1518
|
+
return response;
|
|
1519
|
+
},
|
|
1520
|
+
/**
|
|
1521
|
+
* Permanently delete an item from trash
|
|
1522
|
+
*/
|
|
1523
|
+
async permanentDelete(entityType, itemId) {
|
|
1524
|
+
await request(`${basePath}/trash/${entityType}/${itemId}/`, {
|
|
1525
|
+
method: "DELETE",
|
|
1526
|
+
});
|
|
1527
|
+
},
|
|
1528
|
+
/**
|
|
1529
|
+
* Empty trash (permanently delete all items)
|
|
1530
|
+
*/
|
|
1531
|
+
async empty(entityType) {
|
|
1532
|
+
const path = entityType
|
|
1533
|
+
? `${basePath}/trash/${entityType}/`
|
|
1534
|
+
: `${basePath}/trash/`;
|
|
1535
|
+
await request(path, { method: "DELETE" });
|
|
1536
|
+
},
|
|
1537
|
+
/**
|
|
1538
|
+
* List trash for a specific project
|
|
1539
|
+
*/
|
|
1540
|
+
async listForProject(projectId, params) {
|
|
1541
|
+
return this.list({ ...params, project_id: projectId });
|
|
1542
|
+
},
|
|
1543
|
+
},
|
|
1544
|
+
/**
|
|
1545
|
+
* Portals API
|
|
1546
|
+
* Note: Portals are accessed at a higher level than portal-specific endpoints
|
|
1547
|
+
*/
|
|
1548
|
+
portals: {
|
|
1549
|
+
/**
|
|
1550
|
+
* List all portals accessible to the authenticated user
|
|
1551
|
+
*/
|
|
1552
|
+
async list() {
|
|
1553
|
+
const response = await requestWithValidation(`/restapi/portals/`, PortalListResponseSchema);
|
|
1554
|
+
return response.portals;
|
|
1555
|
+
},
|
|
1556
|
+
/**
|
|
1557
|
+
* Get a specific portal by ID
|
|
1558
|
+
*/
|
|
1559
|
+
async get(portalId) {
|
|
1560
|
+
const response = await requestWithValidation(`/restapi/portals/${portalId}/`, z.object({ portals: z.array(PortalSchema) }));
|
|
1561
|
+
if (response.portals.length === 0) {
|
|
1562
|
+
throw new ZohoProjectsError(`Portal not found: ${portalId}`, 404);
|
|
1563
|
+
}
|
|
1564
|
+
return response.portals[0];
|
|
1565
|
+
},
|
|
1566
|
+
/**
|
|
1567
|
+
* Get the current portal (the one configured in the client)
|
|
1568
|
+
*/
|
|
1569
|
+
async getCurrent() {
|
|
1570
|
+
return this.get(portalId);
|
|
1571
|
+
},
|
|
1572
|
+
},
|
|
1573
|
+
/**
|
|
1574
|
+
* Modules API
|
|
1575
|
+
* Get module definitions and field metadata
|
|
1576
|
+
*/
|
|
1577
|
+
modules: {
|
|
1578
|
+
/**
|
|
1579
|
+
* List all modules in the portal
|
|
1580
|
+
*/
|
|
1581
|
+
async list(params) {
|
|
1582
|
+
const response = await requestWithValidation(`${basePath}/settings/modules/`, ModuleListResponseSchema, {
|
|
1583
|
+
params: {
|
|
1584
|
+
is_customized: params?.is_customized,
|
|
1585
|
+
is_default: params?.is_default,
|
|
1586
|
+
is_web_tab: params?.is_web_tab,
|
|
1587
|
+
},
|
|
1588
|
+
});
|
|
1589
|
+
return response.modules;
|
|
1590
|
+
},
|
|
1591
|
+
/**
|
|
1592
|
+
* Get a specific module by ID
|
|
1593
|
+
*/
|
|
1594
|
+
async get(moduleId) {
|
|
1595
|
+
const response = await requestWithValidation(`${basePath}/settings/modules/${moduleId}/`, z.object({ modules: z.array(ModuleSchema) }));
|
|
1596
|
+
if (response.modules.length === 0) {
|
|
1597
|
+
throw new ZohoProjectsError(`Module not found: ${moduleId}`, 404);
|
|
1598
|
+
}
|
|
1599
|
+
return response.modules[0];
|
|
1600
|
+
},
|
|
1601
|
+
/**
|
|
1602
|
+
* Get fields for a module
|
|
1603
|
+
*/
|
|
1604
|
+
async getFields(moduleId) {
|
|
1605
|
+
const response = await requestWithValidation(`${basePath}/settings/modules/${moduleId}/fields/`, ModuleFieldListResponseSchema);
|
|
1606
|
+
return response.fields;
|
|
1607
|
+
},
|
|
1608
|
+
/**
|
|
1609
|
+
* Get a specific field definition
|
|
1610
|
+
*/
|
|
1611
|
+
async getField(moduleId, fieldId) {
|
|
1612
|
+
const response = await requestWithValidation(`${basePath}/settings/modules/${moduleId}/fields/${fieldId}/`, z.object({ fields: z.array(ModuleFieldSchema) }));
|
|
1613
|
+
if (response.fields.length === 0) {
|
|
1614
|
+
throw new ZohoProjectsError(`Field not found: ${fieldId}`, 404);
|
|
1615
|
+
}
|
|
1616
|
+
return response.fields[0];
|
|
1617
|
+
},
|
|
1618
|
+
/**
|
|
1619
|
+
* Get project-specific field values (custom field options specific to a project)
|
|
1620
|
+
*/
|
|
1621
|
+
async getProjectFields(projectId, moduleId) {
|
|
1622
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/settings/modules/${moduleId}/fields/`, ModuleFieldListResponseSchema);
|
|
1623
|
+
return response.fields;
|
|
1624
|
+
},
|
|
1625
|
+
},
|
|
1626
|
+
/**
|
|
1627
|
+
* Timers API
|
|
1628
|
+
* Start, stop, pause, and resume time tracking
|
|
1629
|
+
*/
|
|
1630
|
+
timers: {
|
|
1631
|
+
/**
|
|
1632
|
+
* Get current running timer for the authenticated user
|
|
1633
|
+
*/
|
|
1634
|
+
async getCurrent() {
|
|
1635
|
+
const rawResponse = await request(`${basePath}/mytimers/`);
|
|
1636
|
+
if (!rawResponse || rawResponse === "") {
|
|
1637
|
+
return null;
|
|
1638
|
+
}
|
|
1639
|
+
const result = TimerListResponseSchema.safeParse(rawResponse);
|
|
1640
|
+
if (!result.success || result.data.timers.length === 0) {
|
|
1641
|
+
return null;
|
|
1642
|
+
}
|
|
1643
|
+
return result.data.timers[0];
|
|
1644
|
+
},
|
|
1645
|
+
/**
|
|
1646
|
+
* List all running timers
|
|
1647
|
+
*/
|
|
1648
|
+
async list() {
|
|
1649
|
+
const rawResponse = await request(`${basePath}/mytimers/`);
|
|
1650
|
+
if (!rawResponse || rawResponse === "") {
|
|
1651
|
+
return [];
|
|
1652
|
+
}
|
|
1653
|
+
const result = TimerListResponseSchema.safeParse(rawResponse);
|
|
1654
|
+
if (!result.success) {
|
|
1655
|
+
return [];
|
|
1656
|
+
}
|
|
1657
|
+
return result.data.timers;
|
|
1658
|
+
},
|
|
1659
|
+
/**
|
|
1660
|
+
* Start a timer for a task or issue
|
|
1661
|
+
*/
|
|
1662
|
+
async start(data) {
|
|
1663
|
+
const response = await requestWithValidation(`${basePath}/projects/${data.project_id}/${data.type.toLowerCase()}s/${data.entity_id}/timer/start/`, TimerResponseSchema, {
|
|
1664
|
+
method: "POST",
|
|
1665
|
+
data: {
|
|
1666
|
+
notes: data.notes,
|
|
1667
|
+
bill_status: data.bill_status,
|
|
1668
|
+
},
|
|
1669
|
+
});
|
|
1670
|
+
return response.timer || response.timers?.[0];
|
|
1671
|
+
},
|
|
1672
|
+
/**
|
|
1673
|
+
* Stop a running timer
|
|
1674
|
+
*/
|
|
1675
|
+
async stop(data) {
|
|
1676
|
+
let path;
|
|
1677
|
+
if (data.project_id && data.type && data.entity_id) {
|
|
1678
|
+
path = `${basePath}/projects/${data.project_id}/${data.type.toLowerCase()}s/${data.entity_id}/timer/stop/`;
|
|
1679
|
+
}
|
|
1680
|
+
else {
|
|
1681
|
+
path = `${basePath}/mytimers/stop/`;
|
|
1682
|
+
}
|
|
1683
|
+
const response = await requestWithValidation(path, TimerResponseSchema, {
|
|
1684
|
+
method: "POST",
|
|
1685
|
+
data: {
|
|
1686
|
+
log_name: data.log_name,
|
|
1687
|
+
date: data.date,
|
|
1688
|
+
hours: data.hours,
|
|
1689
|
+
start_time: data.start_time,
|
|
1690
|
+
end_time: data.end_time,
|
|
1691
|
+
bill_status: data.bill_status,
|
|
1692
|
+
notes: data.notes,
|
|
1693
|
+
},
|
|
1694
|
+
});
|
|
1695
|
+
return response.timer || response.timers?.[0];
|
|
1696
|
+
},
|
|
1697
|
+
/**
|
|
1698
|
+
* Pause a running timer
|
|
1699
|
+
*/
|
|
1700
|
+
async pause(data) {
|
|
1701
|
+
let path;
|
|
1702
|
+
if (data?.type && data?.entity_id) {
|
|
1703
|
+
path = `${basePath}/projects/${data.log_id}/${data.type.toLowerCase()}s/${data.entity_id}/timer/pause/`;
|
|
1704
|
+
}
|
|
1705
|
+
else {
|
|
1706
|
+
path = `${basePath}/mytimers/pause/`;
|
|
1707
|
+
}
|
|
1708
|
+
const response = await requestWithValidation(path, TimerResponseSchema, {
|
|
1709
|
+
method: "POST",
|
|
1710
|
+
data: {
|
|
1711
|
+
notes: data?.notes,
|
|
1712
|
+
},
|
|
1713
|
+
});
|
|
1714
|
+
return response.timer || response.timers?.[0];
|
|
1715
|
+
},
|
|
1716
|
+
/**
|
|
1717
|
+
* Resume a paused timer
|
|
1718
|
+
*/
|
|
1719
|
+
async resume(data) {
|
|
1720
|
+
let path;
|
|
1721
|
+
if (data?.type && data?.entity_id) {
|
|
1722
|
+
path = `${basePath}/projects/${data.log_id}/${data.type.toLowerCase()}s/${data.entity_id}/timer/resume/`;
|
|
1723
|
+
}
|
|
1724
|
+
else {
|
|
1725
|
+
path = `${basePath}/mytimers/resume/`;
|
|
1726
|
+
}
|
|
1727
|
+
const response = await requestWithValidation(path, TimerResponseSchema, {
|
|
1728
|
+
method: "POST",
|
|
1729
|
+
data: {
|
|
1730
|
+
notes: data?.notes,
|
|
1731
|
+
},
|
|
1732
|
+
});
|
|
1733
|
+
return response.timer || response.timers?.[0];
|
|
1734
|
+
},
|
|
1735
|
+
/**
|
|
1736
|
+
* Start timer for a task
|
|
1737
|
+
*/
|
|
1738
|
+
async startForTask(projectId, taskId, options) {
|
|
1739
|
+
return this.start({
|
|
1740
|
+
entity_id: taskId,
|
|
1741
|
+
type: "Task",
|
|
1742
|
+
project_id: projectId,
|
|
1743
|
+
notes: options?.notes,
|
|
1744
|
+
bill_status: options?.bill_status,
|
|
1745
|
+
});
|
|
1746
|
+
},
|
|
1747
|
+
/**
|
|
1748
|
+
* Start timer for an issue
|
|
1749
|
+
*/
|
|
1750
|
+
async startForIssue(projectId, issueId, options) {
|
|
1751
|
+
return this.start({
|
|
1752
|
+
entity_id: issueId,
|
|
1753
|
+
type: "Issue",
|
|
1754
|
+
project_id: projectId,
|
|
1755
|
+
notes: options?.notes,
|
|
1756
|
+
bill_status: options?.bill_status,
|
|
1757
|
+
});
|
|
1758
|
+
},
|
|
1759
|
+
},
|
|
1760
|
+
/**
|
|
1761
|
+
* Custom Views API
|
|
1762
|
+
* Manage saved filters and views for tasks, issues, etc.
|
|
1763
|
+
*/
|
|
1764
|
+
customViews: {
|
|
1765
|
+
/**
|
|
1766
|
+
* List custom views for a specific entity type
|
|
1767
|
+
*/
|
|
1768
|
+
async list(entityType, params) {
|
|
1769
|
+
const response = await requestWithValidation(`${basePath}/${entityType}/customviews/`, CustomViewListResponseSchema, {
|
|
1770
|
+
params: {
|
|
1771
|
+
index: params?.index ?? 0,
|
|
1772
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
1773
|
+
},
|
|
1774
|
+
});
|
|
1775
|
+
return { data: response.customviews, pageInfo: response.page_info };
|
|
1776
|
+
},
|
|
1777
|
+
/**
|
|
1778
|
+
* Get all custom views with auto-pagination
|
|
1779
|
+
*/
|
|
1780
|
+
async listAll(entityType, options) {
|
|
1781
|
+
return collectAll(this.iterate(entityType, options));
|
|
1782
|
+
},
|
|
1783
|
+
/**
|
|
1784
|
+
* Iterate over all custom views with auto-pagination
|
|
1785
|
+
*/
|
|
1786
|
+
iterate(entityType, options) {
|
|
1787
|
+
return autoPaginate((index, range) => this.list(entityType, { index, range }), options);
|
|
1788
|
+
},
|
|
1789
|
+
/**
|
|
1790
|
+
* Get a specific custom view
|
|
1791
|
+
*/
|
|
1792
|
+
async get(entityType, viewId) {
|
|
1793
|
+
const response = await requestWithValidation(`${basePath}/${entityType}/customviews/${viewId}/`, z.object({ customviews: z.array(CustomViewSchema) }));
|
|
1794
|
+
if (response.customviews.length === 0) {
|
|
1795
|
+
throw new ZohoProjectsError(`Custom view not found: ${viewId}`, 404);
|
|
1796
|
+
}
|
|
1797
|
+
return response.customviews[0];
|
|
1798
|
+
},
|
|
1799
|
+
/**
|
|
1800
|
+
* Create a custom view
|
|
1801
|
+
*/
|
|
1802
|
+
async create(entityType, data) {
|
|
1803
|
+
const response = await requestWithValidation(`${basePath}/${entityType}/customviews/`, z.object({ customviews: z.array(CustomViewSchema) }), { method: "POST", data });
|
|
1804
|
+
return response.customviews[0];
|
|
1805
|
+
},
|
|
1806
|
+
/**
|
|
1807
|
+
* Update a custom view
|
|
1808
|
+
*/
|
|
1809
|
+
async update(entityType, viewId, data) {
|
|
1810
|
+
const response = await requestWithValidation(`${basePath}/${entityType}/customviews/${viewId}/`, z.object({ customviews: z.array(CustomViewSchema) }), { method: "PUT", data });
|
|
1811
|
+
return response.customviews[0];
|
|
1812
|
+
},
|
|
1813
|
+
/**
|
|
1814
|
+
* Delete a custom view
|
|
1815
|
+
*/
|
|
1816
|
+
async delete(entityType, viewId) {
|
|
1817
|
+
await request(`${basePath}/${entityType}/customviews/${viewId}/`, {
|
|
1818
|
+
method: "DELETE",
|
|
1819
|
+
});
|
|
1820
|
+
},
|
|
1821
|
+
/**
|
|
1822
|
+
* List task custom views
|
|
1823
|
+
*/
|
|
1824
|
+
forTasks() {
|
|
1825
|
+
return {
|
|
1826
|
+
list: (params) => this.list("tasks", params),
|
|
1827
|
+
listAll: (options) => this.listAll("tasks", options),
|
|
1828
|
+
iterate: (options) => this.iterate("tasks", options),
|
|
1829
|
+
get: (viewId) => this.get("tasks", viewId),
|
|
1830
|
+
create: (data) => this.create("tasks", data),
|
|
1831
|
+
update: (viewId, data) => this.update("tasks", viewId, data),
|
|
1832
|
+
delete: (viewId) => this.delete("tasks", viewId),
|
|
1833
|
+
};
|
|
1834
|
+
},
|
|
1835
|
+
/**
|
|
1836
|
+
* List issue custom views
|
|
1837
|
+
*/
|
|
1838
|
+
forIssues() {
|
|
1839
|
+
return {
|
|
1840
|
+
list: (params) => this.list("issues", params),
|
|
1841
|
+
listAll: (options) => this.listAll("issues", options),
|
|
1842
|
+
iterate: (options) => this.iterate("issues", options),
|
|
1843
|
+
get: (viewId) => this.get("issues", viewId),
|
|
1844
|
+
create: (data) => this.create("issues", data),
|
|
1845
|
+
update: (viewId, data) => this.update("issues", viewId, data),
|
|
1846
|
+
delete: (viewId) => this.delete("issues", viewId),
|
|
1847
|
+
};
|
|
1848
|
+
},
|
|
1849
|
+
/**
|
|
1850
|
+
* List milestone custom views
|
|
1851
|
+
*/
|
|
1852
|
+
forMilestones() {
|
|
1853
|
+
return {
|
|
1854
|
+
list: (params) => this.list("milestones", params),
|
|
1855
|
+
listAll: (options) => this.listAll("milestones", options),
|
|
1856
|
+
iterate: (options) => this.iterate("milestones", options),
|
|
1857
|
+
get: (viewId) => this.get("milestones", viewId),
|
|
1858
|
+
create: (data) => this.create("milestones", data),
|
|
1859
|
+
update: (viewId, data) => this.update("milestones", viewId, data),
|
|
1860
|
+
delete: (viewId) => this.delete("milestones", viewId),
|
|
1861
|
+
};
|
|
1862
|
+
},
|
|
1863
|
+
},
|
|
1864
|
+
/**
|
|
1865
|
+
* Blueprints API
|
|
1866
|
+
* Workflow automation and status transitions
|
|
1867
|
+
*/
|
|
1868
|
+
blueprints: {
|
|
1869
|
+
/**
|
|
1870
|
+
* List all blueprints
|
|
1871
|
+
*/
|
|
1872
|
+
async list(params) {
|
|
1873
|
+
const response = await requestWithValidation(`${basePath}/settings/blueprints/`, BlueprintListResponseSchema, {
|
|
1874
|
+
params: {
|
|
1875
|
+
index: params?.index ?? 0,
|
|
1876
|
+
range: params?.range ?? DEFAULT_PAGE_SIZE,
|
|
1877
|
+
},
|
|
1878
|
+
});
|
|
1879
|
+
return { data: response.blueprints, pageInfo: response.page_info };
|
|
1880
|
+
},
|
|
1881
|
+
/**
|
|
1882
|
+
* Get all blueprints with auto-pagination
|
|
1883
|
+
*/
|
|
1884
|
+
async listAll(options) {
|
|
1885
|
+
return collectAll(this.iterate(options));
|
|
1886
|
+
},
|
|
1887
|
+
/**
|
|
1888
|
+
* Iterate over all blueprints with auto-pagination
|
|
1889
|
+
*/
|
|
1890
|
+
iterate(options) {
|
|
1891
|
+
return autoPaginate((index, range) => this.list({ index, range }), options);
|
|
1892
|
+
},
|
|
1893
|
+
/**
|
|
1894
|
+
* Get a specific blueprint
|
|
1895
|
+
*/
|
|
1896
|
+
async get(blueprintId) {
|
|
1897
|
+
const response = await requestWithValidation(`${basePath}/settings/blueprints/${blueprintId}/`, z.object({ blueprints: z.array(BlueprintSchema) }));
|
|
1898
|
+
if (response.blueprints.length === 0) {
|
|
1899
|
+
throw new ZohoProjectsError(`Blueprint not found: ${blueprintId}`, 404);
|
|
1900
|
+
}
|
|
1901
|
+
return response.blueprints[0];
|
|
1902
|
+
},
|
|
1903
|
+
/**
|
|
1904
|
+
* Get available transitions for an entity (task or issue)
|
|
1905
|
+
*/
|
|
1906
|
+
async getNextTransitions(projectId, moduleType, entityId) {
|
|
1907
|
+
const modulePath = moduleType === "Task" ? "tasks" : "bugs";
|
|
1908
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/${modulePath}/${entityId}/transitions/`, NextTransitionsResponseSchema);
|
|
1909
|
+
return response;
|
|
1910
|
+
},
|
|
1911
|
+
/**
|
|
1912
|
+
* Get required actions (fields) for a specific transition
|
|
1913
|
+
*/
|
|
1914
|
+
async getDuringActions(projectId, moduleType, entityId, transitionId) {
|
|
1915
|
+
const modulePath = moduleType === "Task" ? "tasks" : "bugs";
|
|
1916
|
+
const response = await requestWithValidation(`${basePath}/projects/${projectId}/${modulePath}/${entityId}/transitions/${transitionId}/actions/`, DuringActionsResponseSchema);
|
|
1917
|
+
return response;
|
|
1918
|
+
},
|
|
1919
|
+
/**
|
|
1920
|
+
* Execute a blueprint transition
|
|
1921
|
+
*/
|
|
1922
|
+
async executeTransition(projectId, moduleType, transitionId, data) {
|
|
1923
|
+
const modulePath = moduleType === "Task" ? "tasks" : "bugs";
|
|
1924
|
+
await request(`${basePath}/projects/${projectId}/${modulePath}/${data.entity_id}/transitions/${transitionId}/`, {
|
|
1925
|
+
method: "POST",
|
|
1926
|
+
data: {
|
|
1927
|
+
skip_bug_validation: data.skip_bug_validation,
|
|
1928
|
+
field_values: data.field_values,
|
|
1929
|
+
},
|
|
1930
|
+
});
|
|
1931
|
+
},
|
|
1932
|
+
/**
|
|
1933
|
+
* Get transitions for a task
|
|
1934
|
+
*/
|
|
1935
|
+
async getTaskTransitions(projectId, taskId) {
|
|
1936
|
+
const response = await this.getNextTransitions(projectId, "Task", taskId);
|
|
1937
|
+
return response.transitions;
|
|
1938
|
+
},
|
|
1939
|
+
/**
|
|
1940
|
+
* Get transitions for an issue
|
|
1941
|
+
*/
|
|
1942
|
+
async getIssueTransitions(projectId, issueId) {
|
|
1943
|
+
const response = await this.getNextTransitions(projectId, "Issue", issueId);
|
|
1944
|
+
return response.transitions;
|
|
1945
|
+
},
|
|
1946
|
+
/**
|
|
1947
|
+
* Execute a task transition
|
|
1948
|
+
*/
|
|
1949
|
+
async executeTaskTransition(projectId, taskId, transitionId, data) {
|
|
1950
|
+
return this.executeTransition(projectId, "Task", transitionId, {
|
|
1951
|
+
entity_id: taskId,
|
|
1952
|
+
...data,
|
|
1953
|
+
});
|
|
1954
|
+
},
|
|
1955
|
+
/**
|
|
1956
|
+
* Execute an issue transition
|
|
1957
|
+
*/
|
|
1958
|
+
async executeIssueTransition(projectId, issueId, transitionId, data) {
|
|
1959
|
+
return this.executeTransition(projectId, "Issue", transitionId, {
|
|
1960
|
+
entity_id: issueId,
|
|
1961
|
+
...data,
|
|
1962
|
+
});
|
|
1963
|
+
},
|
|
342
1964
|
},
|
|
343
1965
|
/**
|
|
344
1966
|
* Get the underlying token manager for advanced use cases
|