@37signals/basecamp 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +600 -0
- package/dist/auth-strategy.d.ts +36 -0
- package/dist/auth-strategy.d.ts.map +1 -0
- package/dist/auth-strategy.js +33 -0
- package/dist/auth-strategy.js.map +1 -0
- package/dist/client.d.ts +224 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +715 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +137 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +269 -0
- package/dist/errors.js.map +1 -0
- package/dist/generated/metadata.json +2281 -0
- package/dist/generated/openapi-stripped.json +21268 -0
- package/dist/generated/path-mapping.d.ts +8 -0
- package/dist/generated/path-mapping.d.ts.map +1 -0
- package/dist/generated/path-mapping.js +192 -0
- package/dist/generated/path-mapping.js.map +1 -0
- package/dist/generated/path-mapping.ts +199 -0
- package/dist/generated/schema.d.ts +14883 -0
- package/dist/generated/services/attachments.d.ts +27 -0
- package/dist/generated/services/attachments.d.ts.map +1 -0
- package/dist/generated/services/attachments.js +49 -0
- package/dist/generated/services/attachments.js.map +1 -0
- package/dist/generated/services/attachments.ts +59 -0
- package/dist/generated/services/boosts.d.ts +114 -0
- package/dist/generated/services/boosts.d.ts.map +1 -0
- package/dist/generated/services/boosts.js +179 -0
- package/dist/generated/services/boosts.js.map +1 -0
- package/dist/generated/services/boosts.ts +250 -0
- package/dist/generated/services/campfires.d.ts +202 -0
- package/dist/generated/services/campfires.d.ts.map +1 -0
- package/dist/generated/services/campfires.js +309 -0
- package/dist/generated/services/campfires.js.map +1 -0
- package/dist/generated/services/campfires.ts +433 -0
- package/dist/generated/services/card-columns.d.ts +163 -0
- package/dist/generated/services/card-columns.d.ts.map +1 -0
- package/dist/generated/services/card-columns.js +264 -0
- package/dist/generated/services/card-columns.js.map +1 -0
- package/dist/generated/services/card-columns.ts +360 -0
- package/dist/generated/services/card-steps.d.ts +105 -0
- package/dist/generated/services/card-steps.d.ts.map +1 -0
- package/dist/generated/services/card-steps.js +148 -0
- package/dist/generated/services/card-steps.js.map +1 -0
- package/dist/generated/services/card-steps.ts +221 -0
- package/dist/generated/services/card-tables.d.ts +27 -0
- package/dist/generated/services/card-tables.d.ts.map +1 -0
- package/dist/generated/services/card-tables.js +40 -0
- package/dist/generated/services/card-tables.js.map +1 -0
- package/dist/generated/services/card-tables.ts +55 -0
- package/dist/generated/services/cards.d.ts +118 -0
- package/dist/generated/services/cards.d.ts.map +1 -0
- package/dist/generated/services/cards.js +166 -0
- package/dist/generated/services/cards.js.map +1 -0
- package/dist/generated/services/cards.ts +247 -0
- package/dist/generated/services/checkins.d.ts +278 -0
- package/dist/generated/services/checkins.d.ts.map +1 -0
- package/dist/generated/services/checkins.js +420 -0
- package/dist/generated/services/checkins.js.map +1 -0
- package/dist/generated/services/checkins.ts +600 -0
- package/dist/generated/services/client-approvals.d.ts +45 -0
- package/dist/generated/services/client-approvals.d.ts.map +1 -0
- package/dist/generated/services/client-approvals.js +58 -0
- package/dist/generated/services/client-approvals.js.map +1 -0
- package/dist/generated/services/client-approvals.ts +89 -0
- package/dist/generated/services/client-correspondences.d.ts +45 -0
- package/dist/generated/services/client-correspondences.d.ts.map +1 -0
- package/dist/generated/services/client-correspondences.js +58 -0
- package/dist/generated/services/client-correspondences.js.map +1 -0
- package/dist/generated/services/client-correspondences.ts +89 -0
- package/dist/generated/services/client-replies.d.ts +47 -0
- package/dist/generated/services/client-replies.d.ts.map +1 -0
- package/dist/generated/services/client-replies.js +65 -0
- package/dist/generated/services/client-replies.js.map +1 -0
- package/dist/generated/services/client-replies.ts +95 -0
- package/dist/generated/services/client-visibility.d.ts +35 -0
- package/dist/generated/services/client-visibility.d.ts.map +1 -0
- package/dist/generated/services/client-visibility.js +44 -0
- package/dist/generated/services/client-visibility.js.map +1 -0
- package/dist/generated/services/client-visibility.ts +68 -0
- package/dist/generated/services/comments.d.ts +86 -0
- package/dist/generated/services/comments.d.ts.map +1 -0
- package/dist/generated/services/comments.js +129 -0
- package/dist/generated/services/comments.js.map +1 -0
- package/dist/generated/services/comments.ts +185 -0
- package/dist/generated/services/documents.d.ts +92 -0
- package/dist/generated/services/documents.d.ts.map +1 -0
- package/dist/generated/services/documents.js +129 -0
- package/dist/generated/services/documents.js.map +1 -0
- package/dist/generated/services/documents.ts +191 -0
- package/dist/generated/services/events.d.ts +34 -0
- package/dist/generated/services/events.d.ts.map +1 -0
- package/dist/generated/services/events.js +39 -0
- package/dist/generated/services/events.js.map +1 -0
- package/dist/generated/services/events.ts +64 -0
- package/dist/generated/services/forwards.d.ts +112 -0
- package/dist/generated/services/forwards.d.ts.map +1 -0
- package/dist/generated/services/forwards.js +172 -0
- package/dist/generated/services/forwards.js.map +1 -0
- package/dist/generated/services/forwards.ts +241 -0
- package/dist/generated/services/index.d.ts +39 -0
- package/dist/generated/services/index.d.ts.map +1 -0
- package/dist/generated/services/index.js +39 -0
- package/dist/generated/services/index.js.map +1 -0
- package/dist/generated/services/index.ts +38 -0
- package/dist/generated/services/lineup.d.ts +67 -0
- package/dist/generated/services/lineup.d.ts.map +1 -0
- package/dist/generated/services/lineup.js +99 -0
- package/dist/generated/services/lineup.js.map +1 -0
- package/dist/generated/services/lineup.ts +143 -0
- package/dist/generated/services/message-boards.d.ts +27 -0
- package/dist/generated/services/message-boards.d.ts.map +1 -0
- package/dist/generated/services/message-boards.js +40 -0
- package/dist/generated/services/message-boards.js.map +1 -0
- package/dist/generated/services/message-boards.ts +55 -0
- package/dist/generated/services/message-types.d.ts +100 -0
- package/dist/generated/services/message-types.d.ts.map +1 -0
- package/dist/generated/services/message-types.js +144 -0
- package/dist/generated/services/message-types.js.map +1 -0
- package/dist/generated/services/message-types.ts +210 -0
- package/dist/generated/services/messages.d.ts +122 -0
- package/dist/generated/services/messages.d.ts.map +1 -0
- package/dist/generated/services/messages.js +180 -0
- package/dist/generated/services/messages.js.map +1 -0
- package/dist/generated/services/messages.ts +258 -0
- package/dist/generated/services/people.d.ts +122 -0
- package/dist/generated/services/people.d.ts.map +1 -0
- package/dist/generated/services/people.js +167 -0
- package/dist/generated/services/people.js.map +1 -0
- package/dist/generated/services/people.ts +252 -0
- package/dist/generated/services/projects.d.ts +109 -0
- package/dist/generated/services/projects.d.ts.map +1 -0
- package/dist/generated/services/projects.js +153 -0
- package/dist/generated/services/projects.js.map +1 -0
- package/dist/generated/services/projects.ts +224 -0
- package/dist/generated/services/recordings.d.ts +93 -0
- package/dist/generated/services/recordings.d.ts.map +1 -0
- package/dist/generated/services/recordings.js +138 -0
- package/dist/generated/services/recordings.js.map +1 -0
- package/dist/generated/services/recordings.ts +191 -0
- package/dist/generated/services/reports.d.ts +90 -0
- package/dist/generated/services/reports.d.ts.map +1 -0
- package/dist/generated/services/reports.js +124 -0
- package/dist/generated/services/reports.js.map +1 -0
- package/dist/generated/services/reports.ts +187 -0
- package/dist/generated/services/schedules.d.ts +162 -0
- package/dist/generated/services/schedules.d.ts.map +1 -0
- package/dist/generated/services/schedules.js +228 -0
- package/dist/generated/services/schedules.js.map +1 -0
- package/dist/generated/services/schedules.ts +335 -0
- package/dist/generated/services/search.d.ts +45 -0
- package/dist/generated/services/search.d.ts.map +1 -0
- package/dist/generated/services/search.js +56 -0
- package/dist/generated/services/search.js.map +1 -0
- package/dist/generated/services/search.ts +89 -0
- package/dist/generated/services/subscriptions.d.ts +73 -0
- package/dist/generated/services/subscriptions.d.ts.map +1 -0
- package/dist/generated/services/subscriptions.js +119 -0
- package/dist/generated/services/subscriptions.js.map +1 -0
- package/dist/generated/services/subscriptions.ts +160 -0
- package/dist/generated/services/templates.d.ts +140 -0
- package/dist/generated/services/templates.d.ts.map +1 -0
- package/dist/generated/services/templates.js +207 -0
- package/dist/generated/services/templates.js.map +1 -0
- package/dist/generated/services/templates.ts +294 -0
- package/dist/generated/services/timeline.d.ts +31 -0
- package/dist/generated/services/timeline.d.ts.map +1 -0
- package/dist/generated/services/timeline.js +39 -0
- package/dist/generated/services/timeline.js.map +1 -0
- package/dist/generated/services/timeline.ts +62 -0
- package/dist/generated/services/timesheets.d.ts +145 -0
- package/dist/generated/services/timesheets.d.ts.map +1 -0
- package/dist/generated/services/timesheets.js +186 -0
- package/dist/generated/services/timesheets.js.map +1 -0
- package/dist/generated/services/timesheets.ts +289 -0
- package/dist/generated/services/todolist-groups.d.ts +74 -0
- package/dist/generated/services/todolist-groups.d.ts.map +1 -0
- package/dist/generated/services/todolist-groups.js +100 -0
- package/dist/generated/services/todolist-groups.js.map +1 -0
- package/dist/generated/services/todolist-groups.ts +151 -0
- package/dist/generated/services/todolists.d.ts +95 -0
- package/dist/generated/services/todolists.d.ts.map +1 -0
- package/dist/generated/services/todolists.js +130 -0
- package/dist/generated/services/todolists.js.map +1 -0
- package/dist/generated/services/todolists.ts +192 -0
- package/dist/generated/services/todos.d.ts +175 -0
- package/dist/generated/services/todos.d.ts.map +1 -0
- package/dist/generated/services/todos.js +255 -0
- package/dist/generated/services/todos.js.map +1 -0
- package/dist/generated/services/todos.ts +369 -0
- package/dist/generated/services/todosets.d.ts +27 -0
- package/dist/generated/services/todosets.d.ts.map +1 -0
- package/dist/generated/services/todosets.js +40 -0
- package/dist/generated/services/todosets.js.map +1 -0
- package/dist/generated/services/todosets.ts +55 -0
- package/dist/generated/services/tools.d.ts +122 -0
- package/dist/generated/services/tools.d.ts.map +1 -0
- package/dist/generated/services/tools.js +197 -0
- package/dist/generated/services/tools.js.map +1 -0
- package/dist/generated/services/tools.ts +267 -0
- package/dist/generated/services/uploads.d.ts +109 -0
- package/dist/generated/services/uploads.d.ts.map +1 -0
- package/dist/generated/services/uploads.js +153 -0
- package/dist/generated/services/uploads.js.map +1 -0
- package/dist/generated/services/uploads.ts +227 -0
- package/dist/generated/services/vaults.d.ts +86 -0
- package/dist/generated/services/vaults.d.ts.map +1 -0
- package/dist/generated/services/vaults.js +126 -0
- package/dist/generated/services/vaults.js.map +1 -0
- package/dist/generated/services/vaults.ts +182 -0
- package/dist/generated/services/webhooks.d.ts +106 -0
- package/dist/generated/services/webhooks.d.ts.map +1 -0
- package/dist/generated/services/webhooks.js +157 -0
- package/dist/generated/services/webhooks.js.map +1 -0
- package/dist/generated/services/webhooks.ts +226 -0
- package/dist/hooks/otel.d.ts +136 -0
- package/dist/hooks/otel.d.ts.map +1 -0
- package/dist/hooks/otel.js +240 -0
- package/dist/hooks/otel.js.map +1 -0
- package/dist/hooks.d.ts +171 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +196 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +122 -0
- package/dist/index.js.map +1 -0
- package/dist/oauth/authorize.d.ts +48 -0
- package/dist/oauth/authorize.d.ts.map +1 -0
- package/dist/oauth/authorize.js +56 -0
- package/dist/oauth/authorize.js.map +1 -0
- package/dist/oauth/callback-server.d.ts +56 -0
- package/dist/oauth/callback-server.d.ts.map +1 -0
- package/dist/oauth/callback-server.js +150 -0
- package/dist/oauth/callback-server.js.map +1 -0
- package/dist/oauth/discovery.d.ts +54 -0
- package/dist/oauth/discovery.d.ts.map +1 -0
- package/dist/oauth/discovery.js +116 -0
- package/dist/oauth/discovery.js.map +1 -0
- package/dist/oauth/exchange.d.ts +96 -0
- package/dist/oauth/exchange.d.ts.map +1 -0
- package/dist/oauth/exchange.js +324 -0
- package/dist/oauth/exchange.js.map +1 -0
- package/dist/oauth/identity.d.ts +30 -0
- package/dist/oauth/identity.d.ts.map +1 -0
- package/dist/oauth/identity.js +82 -0
- package/dist/oauth/identity.js.map +1 -0
- package/dist/oauth/index.d.ts +50 -0
- package/dist/oauth/index.d.ts.map +1 -0
- package/dist/oauth/index.js +58 -0
- package/dist/oauth/index.js.map +1 -0
- package/dist/oauth/interactive-login.d.ts +62 -0
- package/dist/oauth/interactive-login.d.ts.map +1 -0
- package/dist/oauth/interactive-login.js +106 -0
- package/dist/oauth/interactive-login.js.map +1 -0
- package/dist/oauth/pkce.d.ts +68 -0
- package/dist/oauth/pkce.d.ts.map +1 -0
- package/dist/oauth/pkce.js +80 -0
- package/dist/oauth/pkce.js.map +1 -0
- package/dist/oauth/token-manager.d.ts +92 -0
- package/dist/oauth/token-manager.d.ts.map +1 -0
- package/dist/oauth/token-manager.js +126 -0
- package/dist/oauth/token-manager.js.map +1 -0
- package/dist/oauth/token-store.d.ts +45 -0
- package/dist/oauth/token-store.d.ts.map +1 -0
- package/dist/oauth/token-store.js +105 -0
- package/dist/oauth/token-store.js.map +1 -0
- package/dist/oauth/types.d.ts +98 -0
- package/dist/oauth/types.d.ts.map +1 -0
- package/dist/oauth/types.js +8 -0
- package/dist/oauth/types.js.map +1 -0
- package/dist/pagination-utils.d.ts +27 -0
- package/dist/pagination-utils.d.ts.map +1 -0
- package/dist/pagination-utils.js +54 -0
- package/dist/pagination-utils.js.map +1 -0
- package/dist/pagination.d.ts +56 -0
- package/dist/pagination.d.ts.map +1 -0
- package/dist/pagination.js +57 -0
- package/dist/pagination.js.map +1 -0
- package/dist/security.d.ts +68 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +107 -0
- package/dist/security.js.map +1 -0
- package/dist/services/authorization.d.ts +124 -0
- package/dist/services/authorization.d.ts.map +1 -0
- package/dist/services/authorization.js +117 -0
- package/dist/services/authorization.js.map +1 -0
- package/dist/services/base.d.ts +102 -0
- package/dist/services/base.d.ts.map +1 -0
- package/dist/services/base.js +230 -0
- package/dist/services/base.js.map +1 -0
- package/dist/webhooks/adapters/node-http.d.ts +14 -0
- package/dist/webhooks/adapters/node-http.d.ts.map +1 -0
- package/dist/webhooks/adapters/node-http.js +60 -0
- package/dist/webhooks/adapters/node-http.js.map +1 -0
- package/dist/webhooks/events.d.ts +52 -0
- package/dist/webhooks/events.d.ts.map +1 -0
- package/dist/webhooks/events.js +52 -0
- package/dist/webhooks/events.js.map +1 -0
- package/dist/webhooks/handler.d.ts +62 -0
- package/dist/webhooks/handler.d.ts.map +1 -0
- package/dist/webhooks/handler.js +226 -0
- package/dist/webhooks/handler.js.map +1 -0
- package/dist/webhooks/index.d.ts +5 -0
- package/dist/webhooks/index.d.ts.map +1 -0
- package/dist/webhooks/index.js +5 -0
- package/dist/webhooks/index.js.map +1 -0
- package/dist/webhooks/verify.d.ts +11 -0
- package/dist/webhooks/verify.d.ts.map +1 -0
- package/dist/webhooks/verify.js +25 -0
- package/dist/webhooks/verify.js.map +1 -0
- package/package.json +70 -0
- package/src/generated/metadata.json +2281 -0
- package/src/generated/openapi-stripped.json +21268 -0
- package/src/generated/path-mapping.ts +199 -0
- package/src/generated/schema.d.ts +14883 -0
- package/src/generated/services/attachments.ts +59 -0
- package/src/generated/services/boosts.ts +250 -0
- package/src/generated/services/campfires.ts +433 -0
- package/src/generated/services/card-columns.ts +360 -0
- package/src/generated/services/card-steps.ts +221 -0
- package/src/generated/services/card-tables.ts +55 -0
- package/src/generated/services/cards.ts +247 -0
- package/src/generated/services/checkins.ts +600 -0
- package/src/generated/services/client-approvals.ts +89 -0
- package/src/generated/services/client-correspondences.ts +89 -0
- package/src/generated/services/client-replies.ts +95 -0
- package/src/generated/services/client-visibility.ts +68 -0
- package/src/generated/services/comments.ts +185 -0
- package/src/generated/services/documents.ts +191 -0
- package/src/generated/services/events.ts +64 -0
- package/src/generated/services/forwards.ts +241 -0
- package/src/generated/services/index.ts +38 -0
- package/src/generated/services/lineup.ts +143 -0
- package/src/generated/services/message-boards.ts +55 -0
- package/src/generated/services/message-types.ts +210 -0
- package/src/generated/services/messages.ts +258 -0
- package/src/generated/services/people.ts +252 -0
- package/src/generated/services/projects.ts +224 -0
- package/src/generated/services/recordings.ts +191 -0
- package/src/generated/services/reports.ts +187 -0
- package/src/generated/services/schedules.ts +335 -0
- package/src/generated/services/search.ts +89 -0
- package/src/generated/services/subscriptions.ts +160 -0
- package/src/generated/services/templates.ts +294 -0
- package/src/generated/services/timeline.ts +62 -0
- package/src/generated/services/timesheets.ts +289 -0
- package/src/generated/services/todolist-groups.ts +151 -0
- package/src/generated/services/todolists.ts +192 -0
- package/src/generated/services/todos.ts +369 -0
- package/src/generated/services/todosets.ts +55 -0
- package/src/generated/services/tools.ts +267 -0
- package/src/generated/services/uploads.ts +227 -0
- package/src/generated/services/vaults.ts +182 -0
- package/src/generated/services/webhooks.ts +226 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authorization service for Basecamp SDK.
|
|
3
|
+
*
|
|
4
|
+
* Provides functionality to fetch authorization information including
|
|
5
|
+
* the authenticated user's identity and list of accessible accounts.
|
|
6
|
+
*/
|
|
7
|
+
import { BaseService } from "./base.js";
|
|
8
|
+
const DEFAULT_AUTHORIZATION_ENDPOINT = "https://launchpad.37signals.com/authorization.json";
|
|
9
|
+
/**
|
|
10
|
+
* Service for authorization-related operations.
|
|
11
|
+
*
|
|
12
|
+
* This service communicates with the Launchpad authorization endpoint
|
|
13
|
+
* rather than the standard Basecamp API.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { createBasecampClient } from "@37signals/basecamp";
|
|
18
|
+
*
|
|
19
|
+
* const client = createBasecampClient({
|
|
20
|
+
* accountId: "12345",
|
|
21
|
+
* accessToken: "your-token",
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* // Get all accounts
|
|
25
|
+
* const info = await client.authorization.getInfo();
|
|
26
|
+
* console.log(`Logged in as ${info.identity.firstName}`);
|
|
27
|
+
*
|
|
28
|
+
* // Filter to only Basecamp 3 accounts
|
|
29
|
+
* const bc3Info = await client.authorization.getInfo({ filterProduct: "bc3" });
|
|
30
|
+
* for (const account of bc3Info.accounts) {
|
|
31
|
+
* console.log(account.name);
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export class AuthorizationService extends BaseService {
|
|
36
|
+
authStrategy;
|
|
37
|
+
userAgent;
|
|
38
|
+
constructor(client, hooks, authStrategy, userAgent) {
|
|
39
|
+
super(client, hooks);
|
|
40
|
+
this.authStrategy = authStrategy;
|
|
41
|
+
this.userAgent = userAgent;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Fetches authorization information for the current access token.
|
|
45
|
+
*
|
|
46
|
+
* Returns the authenticated user's identity and list of accounts
|
|
47
|
+
* they have access to.
|
|
48
|
+
*
|
|
49
|
+
* @param options - Optional configuration
|
|
50
|
+
* @returns Authorization information including identity and accounts
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* const info = await authService.getInfo();
|
|
55
|
+
*
|
|
56
|
+
* console.log(`User: ${info.identity.firstName} ${info.identity.lastName}`);
|
|
57
|
+
* console.log(`Email: ${info.identity.emailAddress}`);
|
|
58
|
+
* console.log(`Token expires: ${info.expiresAt}`);
|
|
59
|
+
*
|
|
60
|
+
* for (const account of info.accounts) {
|
|
61
|
+
* console.log(`${account.name} (${account.product})`);
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
async getInfo(options = {}) {
|
|
66
|
+
const endpoint = options.endpoint ?? DEFAULT_AUTHORIZATION_ENDPOINT;
|
|
67
|
+
return this.request({
|
|
68
|
+
service: "Authorization",
|
|
69
|
+
operation: "GetInfo",
|
|
70
|
+
resourceType: "authorization",
|
|
71
|
+
isMutation: false,
|
|
72
|
+
}, async () => {
|
|
73
|
+
// Build headers with auth strategy
|
|
74
|
+
const headers = new Headers({
|
|
75
|
+
"User-Agent": this.userAgent,
|
|
76
|
+
Accept: "application/json",
|
|
77
|
+
});
|
|
78
|
+
await this.authStrategy.authenticate(headers);
|
|
79
|
+
// Make direct fetch request to Launchpad endpoint
|
|
80
|
+
const response = await fetch(endpoint, {
|
|
81
|
+
method: "GET",
|
|
82
|
+
headers,
|
|
83
|
+
});
|
|
84
|
+
if (!response.ok) {
|
|
85
|
+
return { data: undefined, error: undefined, response };
|
|
86
|
+
}
|
|
87
|
+
const raw = (await response.json());
|
|
88
|
+
// Transform to our clean types
|
|
89
|
+
let accounts = raw.accounts.map((a) => ({
|
|
90
|
+
id: a.id,
|
|
91
|
+
name: a.name,
|
|
92
|
+
product: a.product,
|
|
93
|
+
href: a.href,
|
|
94
|
+
appHref: a.app_href,
|
|
95
|
+
hidden: a.hidden,
|
|
96
|
+
expired: a.expired,
|
|
97
|
+
featured: a.featured,
|
|
98
|
+
}));
|
|
99
|
+
// Filter by product if requested
|
|
100
|
+
if (options.filterProduct) {
|
|
101
|
+
accounts = accounts.filter((a) => a.product === options.filterProduct);
|
|
102
|
+
}
|
|
103
|
+
const data = {
|
|
104
|
+
expiresAt: new Date(raw.expires_at),
|
|
105
|
+
identity: {
|
|
106
|
+
id: raw.identity.id,
|
|
107
|
+
firstName: raw.identity.first_name,
|
|
108
|
+
lastName: raw.identity.last_name,
|
|
109
|
+
emailAddress: raw.identity.email_address,
|
|
110
|
+
},
|
|
111
|
+
accounts,
|
|
112
|
+
};
|
|
113
|
+
return { data, error: undefined, response };
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=authorization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorization.js","sourceRoot":"","sources":["../../src/services/authorization.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base service class for Basecamp API services.
|
|
3
|
+
*
|
|
4
|
+
* Provides shared functionality for all service classes including:
|
|
5
|
+
* - Error handling with typed BasecampError
|
|
6
|
+
* - Hooks integration for observability
|
|
7
|
+
* - Request/response processing
|
|
8
|
+
* - Automatic pagination via Link headers
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* export class TodosService extends BaseService {
|
|
13
|
+
* async list(projectId: number, todolistId: number): Promise<ListResult<Todo>> {
|
|
14
|
+
* return this.requestPaginated(
|
|
15
|
+
* { service: "Todos", operation: "List", resourceType: "todo", isMutation: false, projectId },
|
|
16
|
+
* () => this.client.GET("/buckets/{projectId}/todolists/{todolistId}/todos.json", {
|
|
17
|
+
* params: { path: { projectId, todolistId } },
|
|
18
|
+
* })
|
|
19
|
+
* );
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
import type { BasecampHooks, OperationInfo } from "../hooks.js";
|
|
25
|
+
import { BasecampError } from "../errors.js";
|
|
26
|
+
import { ListResult, type PaginationOptions } from "../pagination.js";
|
|
27
|
+
import type { paths } from "../generated/schema.js";
|
|
28
|
+
import type createClient from "openapi-fetch";
|
|
29
|
+
/**
|
|
30
|
+
* Raw client type from openapi-fetch.
|
|
31
|
+
*/
|
|
32
|
+
export type RawClient = ReturnType<typeof createClient<paths>>;
|
|
33
|
+
/**
|
|
34
|
+
* Response type from openapi-fetch methods.
|
|
35
|
+
*/
|
|
36
|
+
export interface FetchResponse<T> {
|
|
37
|
+
data?: T;
|
|
38
|
+
error?: unknown;
|
|
39
|
+
response: Response;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Abstract base class for all Basecamp API services.
|
|
43
|
+
*
|
|
44
|
+
* Services extend this class to inherit common functionality
|
|
45
|
+
* for making API requests, handling errors, and integrating
|
|
46
|
+
* with the hooks system.
|
|
47
|
+
*/
|
|
48
|
+
export declare abstract class BaseService {
|
|
49
|
+
/** The underlying openapi-fetch client */
|
|
50
|
+
protected readonly client: RawClient;
|
|
51
|
+
/** Optional hooks for observability */
|
|
52
|
+
protected readonly hooks?: BasecampHooks;
|
|
53
|
+
/**
|
|
54
|
+
* Authenticated fetch for pagination follow-up requests.
|
|
55
|
+
*
|
|
56
|
+
* Note: Subsequent pages use this raw fetch rather than the openapi-fetch
|
|
57
|
+
* middleware stack (retry, cache, hooks). This is intentional — Link header
|
|
58
|
+
* URLs are absolute and don't map to openapi-fetch path patterns. The
|
|
59
|
+
* createBasecampClient() factory provides an authenticated fetchPage closure
|
|
60
|
+
* with Bearer token and User-Agent. When services are instantiated directly
|
|
61
|
+
* (without the factory), the fallback is unauthenticated — page 1 will
|
|
62
|
+
* succeed via the authenticated raw client, but page 2+ may 401.
|
|
63
|
+
*/
|
|
64
|
+
protected readonly fetchPage: (url: string) => Promise<Response>;
|
|
65
|
+
constructor(client: RawClient, hooks?: BasecampHooks, fetchPage?: (url: string) => Promise<Response>);
|
|
66
|
+
/**
|
|
67
|
+
* Executes an API request with error handling and hooks integration.
|
|
68
|
+
*
|
|
69
|
+
* @param info - Operation metadata for hooks
|
|
70
|
+
* @param fn - The function that performs the actual API call
|
|
71
|
+
* @returns The response data
|
|
72
|
+
* @throws BasecampError on API errors
|
|
73
|
+
*/
|
|
74
|
+
protected request<T>(info: OperationInfo, fn: () => Promise<FetchResponse<T>>): Promise<T>;
|
|
75
|
+
/**
|
|
76
|
+
* Executes a paginated API request, automatically following Link headers.
|
|
77
|
+
*
|
|
78
|
+
* Returns a ListResult<T> which extends Array<T> — fully backwards-compatible
|
|
79
|
+
* with array operations, plus `.meta.totalCount` for total item count.
|
|
80
|
+
*
|
|
81
|
+
* @param info - Operation metadata for hooks
|
|
82
|
+
* @param fn - The function that performs the initial API call
|
|
83
|
+
* @param paginationOpts - Optional pagination control (maxItems)
|
|
84
|
+
* @returns A ListResult containing all items across pages
|
|
85
|
+
* @throws BasecampError on API errors or cross-origin Link headers
|
|
86
|
+
*/
|
|
87
|
+
protected requestPaginated<T>(info: OperationInfo, fn: () => Promise<FetchResponse<T[]>>, paginationOpts?: PaginationOptions): Promise<ListResult<T>>;
|
|
88
|
+
/**
|
|
89
|
+
* Follows Link header pagination, accumulating items across pages.
|
|
90
|
+
* Returns items and whether results were truncated (by maxItems or page cap).
|
|
91
|
+
*/
|
|
92
|
+
private followPagination;
|
|
93
|
+
/**
|
|
94
|
+
* Converts an HTTP error response to a typed BasecampError.
|
|
95
|
+
*
|
|
96
|
+
* @param response - The HTTP response
|
|
97
|
+
* @param error - Optional error object from openapi-fetch
|
|
98
|
+
* @returns A BasecampError with appropriate code and metadata
|
|
99
|
+
*/
|
|
100
|
+
protected handleError(response: Response, error?: unknown): Promise<BasecampError>;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/services/base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAmB,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,aAAa,EAAqB,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,UAAU,EAAmB,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEvF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,KAAK,YAAY,MAAM,eAAe,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAKD;;;;;;GAMG;AACH,8BAAsB,WAAW;IAC/B,0CAA0C;IAC1C,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAErC,uCAAuC;IACvC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;IAEzC;;;;;;;;;;OAUG;IACH,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAG/D,MAAM,EAAE,SAAS,EACjB,KAAK,CAAC,EAAE,aAAa,EACrB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC;IAOhD;;;;;;;OAOG;cACa,OAAO,CAAC,CAAC,EACvB,IAAI,EAAE,aAAa,EACnB,EAAE,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAClC,OAAO,CAAC,CAAC,CAAC;IAgDb;;;;;;;;;;;OAWG;cACa,gBAAgB,CAAC,CAAC,EAChC,IAAI,EAAE,aAAa,EACnB,EAAE,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EACrC,cAAc,CAAC,EAAE,iBAAiB,GACjC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAkEzB;;;OAGG;YACW,gBAAgB;IA4C9B;;;;;;OAMG;cACa,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC;CAYzF"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base service class for Basecamp API services.
|
|
3
|
+
*
|
|
4
|
+
* Provides shared functionality for all service classes including:
|
|
5
|
+
* - Error handling with typed BasecampError
|
|
6
|
+
* - Hooks integration for observability
|
|
7
|
+
* - Request/response processing
|
|
8
|
+
* - Automatic pagination via Link headers
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* export class TodosService extends BaseService {
|
|
13
|
+
* async list(projectId: number, todolistId: number): Promise<ListResult<Todo>> {
|
|
14
|
+
* return this.requestPaginated(
|
|
15
|
+
* { service: "Todos", operation: "List", resourceType: "todo", isMutation: false, projectId },
|
|
16
|
+
* () => this.client.GET("/buckets/{projectId}/todolists/{todolistId}/todos.json", {
|
|
17
|
+
* params: { path: { projectId, todolistId } },
|
|
18
|
+
* })
|
|
19
|
+
* );
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
import { BasecampError, errorFromResponse } from "../errors.js";
|
|
25
|
+
import { ListResult, parseTotalCount } from "../pagination.js";
|
|
26
|
+
import { parseNextLink, resolveURL, isSameOrigin } from "../pagination-utils.js";
|
|
27
|
+
/** Maximum pages to follow as a safety cap against infinite loops. */
|
|
28
|
+
const MAX_PAGES = 10_000;
|
|
29
|
+
/**
|
|
30
|
+
* Abstract base class for all Basecamp API services.
|
|
31
|
+
*
|
|
32
|
+
* Services extend this class to inherit common functionality
|
|
33
|
+
* for making API requests, handling errors, and integrating
|
|
34
|
+
* with the hooks system.
|
|
35
|
+
*/
|
|
36
|
+
export class BaseService {
|
|
37
|
+
/** The underlying openapi-fetch client */
|
|
38
|
+
client;
|
|
39
|
+
/** Optional hooks for observability */
|
|
40
|
+
hooks;
|
|
41
|
+
/**
|
|
42
|
+
* Authenticated fetch for pagination follow-up requests.
|
|
43
|
+
*
|
|
44
|
+
* Note: Subsequent pages use this raw fetch rather than the openapi-fetch
|
|
45
|
+
* middleware stack (retry, cache, hooks). This is intentional — Link header
|
|
46
|
+
* URLs are absolute and don't map to openapi-fetch path patterns. The
|
|
47
|
+
* createBasecampClient() factory provides an authenticated fetchPage closure
|
|
48
|
+
* with Bearer token and User-Agent. When services are instantiated directly
|
|
49
|
+
* (without the factory), the fallback is unauthenticated — page 1 will
|
|
50
|
+
* succeed via the authenticated raw client, but page 2+ may 401.
|
|
51
|
+
*/
|
|
52
|
+
fetchPage;
|
|
53
|
+
constructor(client, hooks, fetchPage) {
|
|
54
|
+
this.client = client;
|
|
55
|
+
this.hooks = hooks;
|
|
56
|
+
this.fetchPage = fetchPage ?? ((url) => fetch(url, { headers: { Accept: "application/json" } }));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Executes an API request with error handling and hooks integration.
|
|
60
|
+
*
|
|
61
|
+
* @param info - Operation metadata for hooks
|
|
62
|
+
* @param fn - The function that performs the actual API call
|
|
63
|
+
* @returns The response data
|
|
64
|
+
* @throws BasecampError on API errors
|
|
65
|
+
*/
|
|
66
|
+
async request(info, fn) {
|
|
67
|
+
const start = performance.now();
|
|
68
|
+
let result = { durationMs: 0 };
|
|
69
|
+
// Notify hooks of operation start (wrapped to prevent hook failures from breaking operations)
|
|
70
|
+
try {
|
|
71
|
+
this.hooks?.onOperationStart?.(info);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// Hooks should not interrupt operations
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
const { data, error, response } = await fn();
|
|
78
|
+
result.durationMs = Math.round(performance.now() - start);
|
|
79
|
+
// Check for errors
|
|
80
|
+
if (!response.ok || error) {
|
|
81
|
+
const basecampError = await this.handleError(response, error);
|
|
82
|
+
result.error = basecampError;
|
|
83
|
+
throw basecampError;
|
|
84
|
+
}
|
|
85
|
+
// For void responses (204, etc.), return undefined as T
|
|
86
|
+
if (response.status === 204 || data === undefined) {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
return data;
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
result.durationMs = Math.round(performance.now() - start);
|
|
93
|
+
if (err instanceof BasecampError) {
|
|
94
|
+
result.error = err;
|
|
95
|
+
}
|
|
96
|
+
else if (err instanceof Error) {
|
|
97
|
+
result.error = err;
|
|
98
|
+
}
|
|
99
|
+
throw err;
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
// Always notify hooks of operation end (wrapped to prevent hook failures from breaking operations)
|
|
103
|
+
try {
|
|
104
|
+
this.hooks?.onOperationEnd?.(info, result);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// Hooks should not interrupt operations
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Executes a paginated API request, automatically following Link headers.
|
|
113
|
+
*
|
|
114
|
+
* Returns a ListResult<T> which extends Array<T> — fully backwards-compatible
|
|
115
|
+
* with array operations, plus `.meta.totalCount` for total item count.
|
|
116
|
+
*
|
|
117
|
+
* @param info - Operation metadata for hooks
|
|
118
|
+
* @param fn - The function that performs the initial API call
|
|
119
|
+
* @param paginationOpts - Optional pagination control (maxItems)
|
|
120
|
+
* @returns A ListResult containing all items across pages
|
|
121
|
+
* @throws BasecampError on API errors or cross-origin Link headers
|
|
122
|
+
*/
|
|
123
|
+
async requestPaginated(info, fn, paginationOpts) {
|
|
124
|
+
const start = performance.now();
|
|
125
|
+
let result = { durationMs: 0 };
|
|
126
|
+
// Notify hooks of operation start
|
|
127
|
+
try {
|
|
128
|
+
this.hooks?.onOperationStart?.(info);
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
// Hooks should not interrupt operations
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
const { data, error, response } = await fn();
|
|
135
|
+
result.durationMs = Math.round(performance.now() - start);
|
|
136
|
+
// Check for errors
|
|
137
|
+
if (!response.ok || error) {
|
|
138
|
+
const basecampError = await this.handleError(response, error);
|
|
139
|
+
result.error = basecampError;
|
|
140
|
+
throw basecampError;
|
|
141
|
+
}
|
|
142
|
+
const firstPageItems = data ?? [];
|
|
143
|
+
const totalCount = parseTotalCount(response);
|
|
144
|
+
const maxItems = paginationOpts?.maxItems;
|
|
145
|
+
// If maxItems is set and first page satisfies it, return early
|
|
146
|
+
if (maxItems && maxItems > 0 && firstPageItems.length >= maxItems) {
|
|
147
|
+
// Only mark truncated if there are actually more items beyond maxItems
|
|
148
|
+
// (either more items on this page than maxItems, or a Link header for more pages)
|
|
149
|
+
const hasMore = firstPageItems.length > maxItems
|
|
150
|
+
|| parseNextLink(response.headers.get("Link")) !== null;
|
|
151
|
+
result.durationMs = Math.round(performance.now() - start);
|
|
152
|
+
return new ListResult(firstPageItems.slice(0, maxItems), { totalCount, truncated: hasMore });
|
|
153
|
+
}
|
|
154
|
+
// Follow pagination
|
|
155
|
+
const { items: allItems, truncated } = await this.followPagination(response, firstPageItems, maxItems);
|
|
156
|
+
// Update duration to reflect total time across all pages
|
|
157
|
+
result.durationMs = Math.round(performance.now() - start);
|
|
158
|
+
return new ListResult(allItems, { totalCount, truncated });
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
result.durationMs = Math.round(performance.now() - start);
|
|
162
|
+
if (err instanceof BasecampError) {
|
|
163
|
+
result.error = err;
|
|
164
|
+
}
|
|
165
|
+
else if (err instanceof Error) {
|
|
166
|
+
result.error = err;
|
|
167
|
+
}
|
|
168
|
+
throw err;
|
|
169
|
+
}
|
|
170
|
+
finally {
|
|
171
|
+
try {
|
|
172
|
+
this.hooks?.onOperationEnd?.(info, result);
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// Hooks should not interrupt operations
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Follows Link header pagination, accumulating items across pages.
|
|
181
|
+
* Returns items and whether results were truncated (by maxItems or page cap).
|
|
182
|
+
*/
|
|
183
|
+
async followPagination(initialResponse, firstPageItems, maxItems) {
|
|
184
|
+
const allItems = [...firstPageItems];
|
|
185
|
+
let response = initialResponse;
|
|
186
|
+
const initialUrl = initialResponse.url;
|
|
187
|
+
for (let page = 1; page < MAX_PAGES; page++) {
|
|
188
|
+
const rawNextUrl = parseNextLink(response.headers.get("Link"));
|
|
189
|
+
if (!rawNextUrl)
|
|
190
|
+
break;
|
|
191
|
+
const nextUrl = resolveURL(response.url, rawNextUrl);
|
|
192
|
+
// Validate same-origin to prevent SSRF / token leakage
|
|
193
|
+
if (!isSameOrigin(nextUrl, initialUrl)) {
|
|
194
|
+
throw new BasecampError("api_error", `Pagination Link header points to different origin: ${nextUrl}`);
|
|
195
|
+
}
|
|
196
|
+
response = await this.fetchPage(nextUrl);
|
|
197
|
+
if (!response.ok) {
|
|
198
|
+
throw await errorFromResponse(response, response.headers.get("X-Request-Id") ?? undefined);
|
|
199
|
+
}
|
|
200
|
+
const pageItems = (await response.json());
|
|
201
|
+
allItems.push(...pageItems);
|
|
202
|
+
// Check maxItems cap
|
|
203
|
+
if (maxItems && maxItems > 0 && allItems.length >= maxItems) {
|
|
204
|
+
return { items: allItems.slice(0, maxItems), truncated: true };
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// If we exited the loop because page >= MAX_PAGES and there's still a next link,
|
|
208
|
+
// the results are truncated by the safety cap
|
|
209
|
+
const hasMore = parseNextLink(response.headers.get("Link")) !== null;
|
|
210
|
+
return { items: allItems, truncated: hasMore };
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Converts an HTTP error response to a typed BasecampError.
|
|
214
|
+
*
|
|
215
|
+
* @param response - The HTTP response
|
|
216
|
+
* @param error - Optional error object from openapi-fetch
|
|
217
|
+
* @returns A BasecampError with appropriate code and metadata
|
|
218
|
+
*/
|
|
219
|
+
async handleError(response, error) {
|
|
220
|
+
// If already a BasecampError, just return it
|
|
221
|
+
if (error instanceof BasecampError) {
|
|
222
|
+
return error;
|
|
223
|
+
}
|
|
224
|
+
// Extract request ID from response headers if available
|
|
225
|
+
const requestId = response.headers.get("X-Request-Id") ?? undefined;
|
|
226
|
+
// Use the errorFromResponse helper to create the appropriate error
|
|
227
|
+
return errorFromResponse(response, requestId);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/services/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { RequestListener } from "node:http";
|
|
2
|
+
import { WebhookReceiver } from "../handler.js";
|
|
3
|
+
export interface NodeHandlerOptions {
|
|
4
|
+
/** URL path to handle (default: "/webhooks/basecamp"). Requests to other paths get 404. */
|
|
5
|
+
path?: string;
|
|
6
|
+
/** Maximum request body size in bytes (default: 1MB). Requests exceeding this get 413. */
|
|
7
|
+
maxBodyBytes?: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Create a Node.js HTTP request listener that dispatches to a WebhookReceiver.
|
|
11
|
+
* Returns 200 on success, 401 on bad signature, 405 on non-POST, 404 on wrong path.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createNodeHandler(receiver: WebhookReceiver, options?: NodeHandlerOptions): RequestListener;
|
|
14
|
+
//# sourceMappingURL=node-http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-http.d.ts","sourceRoot":"","sources":["../../../src/webhooks/adapters/node-http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmC,eAAe,EAAE,MAAM,WAAW,CAAC;AAClF,OAAO,EAAE,eAAe,EAA4B,MAAM,eAAe,CAAC;AAE1E,MAAM,WAAW,kBAAkB;IACjC,2FAA2F;IAC3F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0FAA0F;IAC1F,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,eAAe,EACzB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,eAAe,CAyDjB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { WebhookVerificationError } from "../handler.js";
|
|
2
|
+
/**
|
|
3
|
+
* Create a Node.js HTTP request listener that dispatches to a WebhookReceiver.
|
|
4
|
+
* Returns 200 on success, 401 on bad signature, 405 on non-POST, 404 on wrong path.
|
|
5
|
+
*/
|
|
6
|
+
export function createNodeHandler(receiver, options) {
|
|
7
|
+
const targetPath = options?.path ?? "/webhooks/basecamp";
|
|
8
|
+
const maxBodyBytes = options?.maxBodyBytes ?? 1_048_576; // 1MB
|
|
9
|
+
return (req, res) => {
|
|
10
|
+
// Parse URL path (handles both origin-form and absolute-form request targets)
|
|
11
|
+
const { pathname } = new URL(req.url ?? "/", "http://localhost");
|
|
12
|
+
if (pathname !== targetPath) {
|
|
13
|
+
res.writeHead(404);
|
|
14
|
+
res.end("Not Found");
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (req.method !== "POST") {
|
|
18
|
+
res.writeHead(405);
|
|
19
|
+
res.end("Method Not Allowed");
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const chunks = [];
|
|
23
|
+
let totalBytes = 0;
|
|
24
|
+
req.on("data", (chunk) => {
|
|
25
|
+
totalBytes += chunk.length;
|
|
26
|
+
if (totalBytes <= maxBodyBytes) {
|
|
27
|
+
chunks.push(chunk);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
req.on("end", () => {
|
|
31
|
+
if (totalBytes > maxBodyBytes) {
|
|
32
|
+
res.writeHead(413);
|
|
33
|
+
res.end("Payload Too Large");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const body = Buffer.concat(chunks);
|
|
37
|
+
const headers = (name) => {
|
|
38
|
+
const val = req.headers[name.toLowerCase()];
|
|
39
|
+
return Array.isArray(val) ? val[0] : val;
|
|
40
|
+
};
|
|
41
|
+
receiver
|
|
42
|
+
.handleRequest(body, headers)
|
|
43
|
+
.then(() => {
|
|
44
|
+
res.writeHead(200);
|
|
45
|
+
res.end("OK");
|
|
46
|
+
})
|
|
47
|
+
.catch((err) => {
|
|
48
|
+
if (err instanceof WebhookVerificationError) {
|
|
49
|
+
res.writeHead(401);
|
|
50
|
+
res.end("Unauthorized");
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
res.writeHead(500);
|
|
54
|
+
res.end("Internal Server Error");
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=node-http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-http.js","sourceRoot":"","sources":["../../../src/webhooks/adapters/node-http.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAS1E;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAyB,EACzB,OAA4B;IAE5B,MAAM,UAAU,GAAG,OAAO,EAAE,IAAI,IAAI,oBAAoB,CAAC;IACzD,MAAM,YAAY,GAAG,OAAO,EAAE,YAAY,IAAI,SAAS,CAAC,CAAC,MAAM;IAE/D,OAAO,CAAC,GAAoB,EAAE,GAAmB,EAAE,EAAE;QACnD,8EAA8E;QAC9E,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC;QAEjE,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;YAC5B,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC1B,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YAC/B,UAAU,IAAI,KAAK,CAAC,MAAM,CAAC;YAC3B,IAAI,UAAU,IAAI,YAAY,EAAE,CAAC;gBAC/B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;QACH,CAAC,CAAC,CAAC;QACH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACjB,IAAI,UAAU,GAAG,YAAY,EAAE,CAAC;gBAC9B,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACnB,GAAG,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;gBAC7B,OAAO;YACT,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACnC,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE;gBAC/B,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;gBAC5C,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YAC3C,CAAC,CAAC;YAEF,QAAQ;iBACL,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC;iBAC5B,IAAI,CAAC,GAAG,EAAE;gBACT,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACnB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAChB,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;gBACtB,IAAI,GAAG,YAAY,wBAAwB,EAAE,CAAC;oBAC5C,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;oBACnB,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;gBAC1B,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;oBACnB,GAAG,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;gBACnC,CAAC;YACH,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { components } from "../generated/schema.js";
|
|
2
|
+
export type WebhookEvent = components["schemas"]["WebhookEvent"];
|
|
3
|
+
export type WebhookDelivery = components["schemas"]["WebhookDelivery"];
|
|
4
|
+
export type WebhookDeliveryRequest = components["schemas"]["WebhookDeliveryRequest"];
|
|
5
|
+
export type WebhookDeliveryResponse = components["schemas"]["WebhookDeliveryResponse"];
|
|
6
|
+
export type WebhookCopy = components["schemas"]["WebhookCopy"];
|
|
7
|
+
/**
|
|
8
|
+
* Parse "todo_created" → { type: "todo", action: "created" }.
|
|
9
|
+
* For compound types like "question_answer_created" → { type: "question_answer", action: "created" }.
|
|
10
|
+
* The action is always the last underscore-separated segment.
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseEventKind(kind: string): {
|
|
13
|
+
type: string;
|
|
14
|
+
action: string;
|
|
15
|
+
};
|
|
16
|
+
/** Known webhook event kind strings (convenience constants, not exhaustive). */
|
|
17
|
+
export declare const WebhookEventKind: {
|
|
18
|
+
readonly TodoCreated: "todo_created";
|
|
19
|
+
readonly TodoCompleted: "todo_completed";
|
|
20
|
+
readonly TodoUncompleted: "todo_uncompleted";
|
|
21
|
+
readonly TodoChanged: "todo_changed";
|
|
22
|
+
readonly TodolistCreated: "todolist_created";
|
|
23
|
+
readonly TodolistChanged: "todolist_changed";
|
|
24
|
+
readonly MessageCreated: "message_created";
|
|
25
|
+
readonly MessageChanged: "message_changed";
|
|
26
|
+
readonly CommentCreated: "comment_created";
|
|
27
|
+
readonly CommentChanged: "comment_changed";
|
|
28
|
+
readonly DocumentCreated: "document_created";
|
|
29
|
+
readonly DocumentChanged: "document_changed";
|
|
30
|
+
readonly UploadCreated: "upload_created";
|
|
31
|
+
readonly UploadChanged: "upload_changed";
|
|
32
|
+
readonly QuestionAnswerCreated: "question_answer_created";
|
|
33
|
+
readonly QuestionAnswerChanged: "question_answer_changed";
|
|
34
|
+
readonly ScheduleEntryCreated: "schedule_entry_created";
|
|
35
|
+
readonly ScheduleEntryChanged: "schedule_entry_changed";
|
|
36
|
+
readonly CloudFileCreated: "cloud_file_created";
|
|
37
|
+
readonly VaultCreated: "vault_created";
|
|
38
|
+
readonly InboxForwardCreated: "inbox_forward_created";
|
|
39
|
+
readonly ForwardReplyCreated: "forward_reply_created";
|
|
40
|
+
readonly ClientReplyCreated: "client_reply_created";
|
|
41
|
+
readonly ClientApprovalCreated: "client_approval_created";
|
|
42
|
+
readonly ClientApprovalChanged: "client_approval_changed";
|
|
43
|
+
readonly TodoCopied: "todo_copied";
|
|
44
|
+
readonly MessageCopied: "message_copied";
|
|
45
|
+
readonly TodoArchived: "todo_archived";
|
|
46
|
+
readonly TodoUnarchived: "todo_unarchived";
|
|
47
|
+
readonly TodoTrashed: "todo_trashed";
|
|
48
|
+
readonly MessageArchived: "message_archived";
|
|
49
|
+
readonly MessageUnarchived: "message_unarchived";
|
|
50
|
+
readonly MessageTrashed: "message_trashed";
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/webhooks/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGzD,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,cAAc,CAAC,CAAC;AACjE,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,iBAAiB,CAAC,CAAC;AACvE,MAAM,MAAM,sBAAsB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,wBAAwB,CAAC,CAAC;AACrF,MAAM,MAAM,uBAAuB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,yBAAyB,CAAC,CAAC;AACvF,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,CAAC;AAE/D;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAS7E;AAED,gFAAgF;AAChF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCnB,CAAC"}
|