@37signals/basecamp 0.15.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/client.d.ts +5 -2
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +4 -2
  4. package/dist/client.js.map +1 -1
  5. package/dist/download.d.ts.map +1 -1
  6. package/dist/download.js +70 -19
  7. package/dist/download.js.map +1 -1
  8. package/dist/errors.d.ts +14 -0
  9. package/dist/errors.d.ts.map +1 -1
  10. package/dist/errors.js +88 -3
  11. package/dist/errors.js.map +1 -1
  12. package/dist/generated/metadata.d.ts.map +1 -1
  13. package/dist/generated/metadata.js +156 -1
  14. package/dist/generated/metadata.js.map +1 -1
  15. package/dist/generated/metadata.ts +156 -1
  16. package/dist/generated/openapi-stripped.json +2055 -623
  17. package/dist/generated/path-mapping.d.ts.map +1 -1
  18. package/dist/generated/path-mapping.js +12 -0
  19. package/dist/generated/path-mapping.js.map +1 -1
  20. package/dist/generated/path-mapping.ts +12 -0
  21. package/dist/generated/schema.d.ts +1190 -36
  22. package/dist/generated/services/bubble-ups.d.ts +48 -0
  23. package/dist/generated/services/bubble-ups.d.ts.map +1 -0
  24. package/dist/generated/services/bubble-ups.js +67 -0
  25. package/dist/generated/services/bubble-ups.js.map +1 -0
  26. package/dist/generated/services/bubble-ups.ts +98 -0
  27. package/dist/generated/services/index.d.ts +1 -0
  28. package/dist/generated/services/index.d.ts.map +1 -1
  29. package/dist/generated/services/index.js +1 -0
  30. package/dist/generated/services/index.js.map +1 -1
  31. package/dist/generated/services/index.ts +1 -0
  32. package/dist/generated/services/people.d.ts +48 -0
  33. package/dist/generated/services/people.d.ts.map +1 -1
  34. package/dist/generated/services/people.js +81 -0
  35. package/dist/generated/services/people.js.map +1 -1
  36. package/dist/generated/services/people.ts +108 -0
  37. package/dist/generated/services/projects.d.ts +22 -0
  38. package/dist/generated/services/projects.d.ts.map +1 -1
  39. package/dist/generated/services/projects.js +42 -0
  40. package/dist/generated/services/projects.js.map +1 -1
  41. package/dist/generated/services/projects.ts +53 -0
  42. package/dist/generated/services/recordings.d.ts +24 -0
  43. package/dist/generated/services/recordings.d.ts.map +1 -1
  44. package/dist/generated/services/recordings.js +49 -0
  45. package/dist/generated/services/recordings.js.map +1 -1
  46. package/dist/generated/services/recordings.ts +59 -0
  47. package/dist/generated/services/templates.d.ts +46 -0
  48. package/dist/generated/services/templates.d.ts.map +1 -1
  49. package/dist/generated/services/templates.js +70 -0
  50. package/dist/generated/services/templates.js.map +1 -1
  51. package/dist/generated/services/templates.ts +98 -0
  52. package/dist/index.d.ts +4 -3
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +2 -1
  55. package/dist/index.js.map +1 -1
  56. package/dist/oauth/device.d.ts.map +1 -1
  57. package/dist/oauth/device.js +9 -71
  58. package/dist/oauth/device.js.map +1 -1
  59. package/dist/oauth/exchange.d.ts.map +1 -1
  60. package/dist/oauth/exchange.js +55 -16
  61. package/dist/oauth/exchange.js.map +1 -1
  62. package/dist/oauth/limits.d.ts +33 -2
  63. package/dist/oauth/limits.d.ts.map +1 -1
  64. package/dist/oauth/limits.js +76 -2
  65. package/dist/oauth/limits.js.map +1 -1
  66. package/package.json +3 -3
  67. package/src/generated/metadata.ts +156 -1
  68. package/src/generated/openapi-stripped.json +2055 -623
  69. package/src/generated/path-mapping.ts +12 -0
  70. package/src/generated/schema.d.ts +1190 -36
  71. package/src/generated/services/bubble-ups.ts +98 -0
  72. package/src/generated/services/index.ts +1 -0
  73. package/src/generated/services/people.ts +108 -0
  74. package/src/generated/services/projects.ts +53 -0
  75. package/src/generated/services/recordings.ts +59 -0
  76. package/src/generated/services/templates.ts +98 -0
@@ -0,0 +1,98 @@
1
+ /**
2
+ * BubbleUps service for the Basecamp API.
3
+ *
4
+ * @generated from OpenAPI spec - do not edit directly
5
+ */
6
+
7
+ import { BaseService } from "../../services/base.js";
8
+ import type { components } from "../schema.js";
9
+
10
+ // =============================================================================
11
+ // Types
12
+ // =============================================================================
13
+
14
+
15
+ /**
16
+ * Request parameters for createBubbleUp.
17
+ */
18
+ export interface CreateBubbleUpBubbleUpRequest {
19
+ /** Timing for the bubble-up. `"now"` bubbles up immediately; a scheduling
20
+ keyword (`"today"`, `"tomorrow"`, `"weekend"`, `"next_week"`) or an ISO8601
21
+ date (e.g. `"2026-09-10"`) schedules it to resurface later. bc3 requires a
22
+ value — omitting `at` errors server-side (`Date.iso8601(nil)`) — so send
23
+ `"now"` for the immediate case. */
24
+ at?: string;
25
+ }
26
+
27
+
28
+ // =============================================================================
29
+ // Service
30
+ // =============================================================================
31
+
32
+ /**
33
+ * Service for BubbleUps operations.
34
+ */
35
+ export class BubbleUpsService extends BaseService {
36
+
37
+ /**
38
+ * Bubble up a recording for the current user, resurfacing it in the current
39
+ * @param recordingId - The recording ID
40
+ * @param req - Bubble_up creation parameters
41
+ * @returns void
42
+ * @throws {BasecampError} If required fields are missing or invalid
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * await client.bubbleUps.createBubbleUp(123, { });
47
+ * ```
48
+ */
49
+ async createBubbleUp(recordingId: number, req: CreateBubbleUpBubbleUpRequest): Promise<void> {
50
+ await this.request(
51
+ {
52
+ service: "BubbleUps",
53
+ operation: "CreateBubbleUp",
54
+ resourceType: "bubble_up",
55
+ isMutation: true,
56
+ resourceId: recordingId,
57
+ },
58
+ () =>
59
+ this.client.POST("/recordings/{recordingId}/bubble_up.json", {
60
+ params: {
61
+ path: { recordingId },
62
+ },
63
+ body: {
64
+ at: req.at,
65
+ },
66
+ })
67
+ );
68
+ }
69
+
70
+ /**
71
+ * Remove the current user's bubble-up from a recording.
72
+ * @param recordingId - The recording ID
73
+ * @returns void
74
+ * @throws {BasecampError} If the request fails
75
+ *
76
+ * @example
77
+ * ```ts
78
+ * await client.bubbleUps.deleteBubbleUp(123);
79
+ * ```
80
+ */
81
+ async deleteBubbleUp(recordingId: number): Promise<void> {
82
+ await this.request(
83
+ {
84
+ service: "BubbleUps",
85
+ operation: "DeleteBubbleUp",
86
+ resourceType: "bubble_up",
87
+ isMutation: true,
88
+ resourceId: recordingId,
89
+ },
90
+ () =>
91
+ this.client.DELETE("/recordings/{recordingId}/bubble_up.json", {
92
+ params: {
93
+ path: { recordingId },
94
+ },
95
+ })
96
+ );
97
+ }
98
+ }
@@ -37,6 +37,7 @@ export { ProjectsService } from "./projects.js";
37
37
  export { RecordingsService } from "./recordings.js";
38
38
  export { TimelineService } from "./timeline.js";
39
39
  export { TimesheetsService } from "./timesheets.js";
40
+ export { BubbleUpsService } from "./bubble-ups.js";
40
41
  export { ClientVisibilityService } from "./client-visibility.js";
41
42
  export { EventsService } from "./events.js";
42
43
  export { SubscriptionsService } from "./subscriptions.js";
@@ -77,6 +77,18 @@ export interface ListForProjectPeopleOptions extends PaginationOptions {
77
77
  page?: number;
78
78
  }
79
79
 
80
+ /**
81
+ * Request parameters for updateProjectClientAccess.
82
+ */
83
+ export interface UpdateProjectClientAccessPeopleRequest {
84
+ /** Existing client people IDs to add to the project. */
85
+ grant?: number[];
86
+ /** Client people IDs to remove from the project. */
87
+ revoke?: number[];
88
+ /** New clients to invite by email. */
89
+ create?: components["schemas"]["CreateClientRequest"][];
90
+ }
91
+
80
92
  /**
81
93
  * Request parameters for updateProjectAccess.
82
94
  */
@@ -395,6 +407,66 @@ export class PeopleService extends BaseService {
395
407
  );
396
408
  }
397
409
 
410
+ /**
411
+ * Enable clients on a project so client users can be added to it
412
+ * @param projectId - The project ID
413
+ * @returns The project
414
+ * @throws {BasecampError} If the request fails
415
+ *
416
+ * @example
417
+ * ```ts
418
+ * const result = await client.people.enableProjectClients(123);
419
+ * ```
420
+ */
421
+ async enableProjectClients(projectId: number): Promise<components["schemas"]["EnableProjectClientsResponseContent"]> {
422
+ const response = await this.request(
423
+ {
424
+ service: "People",
425
+ operation: "EnableProjectClients",
426
+ resourceType: "project",
427
+ isMutation: true,
428
+ projectId,
429
+ },
430
+ () =>
431
+ this.client.POST("/projects/{projectId}/client_enablement.json", {
432
+ params: {
433
+ path: { projectId },
434
+ },
435
+ })
436
+ );
437
+ return response;
438
+ }
439
+
440
+ /**
441
+ * Disable clients on a project
442
+ * @param projectId - The project ID
443
+ * @returns The project
444
+ * @throws {BasecampError} If the request fails
445
+ *
446
+ * @example
447
+ * ```ts
448
+ * const result = await client.people.disableProjectClients(123);
449
+ * ```
450
+ */
451
+ async disableProjectClients(projectId: number): Promise<components["schemas"]["DisableProjectClientsResponseContent"]> {
452
+ const response = await this.request(
453
+ {
454
+ service: "People",
455
+ operation: "DisableProjectClients",
456
+ resourceType: "project",
457
+ isMutation: true,
458
+ projectId,
459
+ },
460
+ () =>
461
+ this.client.DELETE("/projects/{projectId}/client_enablement.json", {
462
+ params: {
463
+ path: { projectId },
464
+ },
465
+ })
466
+ );
467
+ return response;
468
+ }
469
+
398
470
  /**
399
471
  * List all active people on a project
400
472
  * @param projectId - The project ID
@@ -429,6 +501,42 @@ export class PeopleService extends BaseService {
429
501
  );
430
502
  }
431
503
 
504
+ /**
505
+ * Update project client access (grant/revoke/create client users)
506
+ * @param projectId - The project ID
507
+ * @param req - Project_access update parameters
508
+ * @returns The project_access
509
+ * @throws {BasecampError} If the resource is not found or fields are invalid
510
+ *
511
+ * @example
512
+ * ```ts
513
+ * const result = await client.people.updateProjectClientAccess(123, { });
514
+ * ```
515
+ */
516
+ async updateProjectClientAccess(projectId: number, req: UpdateProjectClientAccessPeopleRequest): Promise<components["schemas"]["UpdateProjectClientAccessResponseContent"]> {
517
+ const response = await this.request(
518
+ {
519
+ service: "People",
520
+ operation: "UpdateProjectClientAccess",
521
+ resourceType: "project_access",
522
+ isMutation: true,
523
+ projectId,
524
+ },
525
+ () =>
526
+ this.client.PUT("/projects/{projectId}/people/client_users.json", {
527
+ params: {
528
+ path: { projectId },
529
+ },
530
+ body: {
531
+ grant: req.grant,
532
+ revoke: req.revoke,
533
+ create: req.create,
534
+ },
535
+ })
536
+ );
537
+ return response;
538
+ }
539
+
432
540
  /**
433
541
  * Update project access (grant/revoke/create people)
434
542
  * @param projectId - The project ID
@@ -61,6 +61,30 @@ export interface UpdateProjectRequest {
61
61
  */
62
62
  export class ProjectsService extends BaseService {
63
63
 
64
+ /**
65
+ * List the projects the current user has most recently visited, most recent visit first.
66
+ * @returns Array of Project
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * const result = await client.projects.listRecentProjects();
71
+ * ```
72
+ */
73
+ async listRecentProjects(): Promise<Project[]> {
74
+ const response = await this.request(
75
+ {
76
+ service: "Projects",
77
+ operation: "ListRecentProjects",
78
+ resourceType: "project",
79
+ isMutation: false,
80
+ },
81
+ () =>
82
+ this.client.GET("/my/recent_projects.json", {
83
+ })
84
+ );
85
+ return response ?? [];
86
+ }
87
+
64
88
  /**
65
89
  * List projects (active by default; optionally archived/trashed)
66
90
  * @param options - Optional query parameters
@@ -224,6 +248,35 @@ export class ProjectsService extends BaseService {
224
248
  );
225
249
  }
226
250
 
251
+ /**
252
+ * Record that the current user visited a project, moving it to the front of ListRecentProjects.
253
+ * @param projectId - The project ID
254
+ * @returns void
255
+ * @throws {BasecampError} If the request fails
256
+ *
257
+ * @example
258
+ * ```ts
259
+ * await client.projects.recordProjectVisit(123);
260
+ * ```
261
+ */
262
+ async recordProjectVisit(projectId: number): Promise<void> {
263
+ await this.request(
264
+ {
265
+ service: "Projects",
266
+ operation: "RecordProjectVisit",
267
+ resourceType: "project",
268
+ isMutation: true,
269
+ projectId,
270
+ },
271
+ () =>
272
+ this.client.POST("/projects/{projectId}/recent_visit.json", {
273
+ params: {
274
+ path: { projectId },
275
+ },
276
+ })
277
+ );
278
+ }
279
+
227
280
  /**
228
281
  * Restore a project to active status from trash as well as from the archive.
229
282
  * @param projectId - The project ID
@@ -74,6 +74,65 @@ export class RecordingsService extends BaseService {
74
74
  );
75
75
  }
76
76
 
77
+ /**
78
+ * Put a recording's card in the spotlight area on its project or template home page.
79
+ * @param recordingId - The recording ID
80
+ * @returns The Recording
81
+ * @throws {BasecampError} If the request fails
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * const result = await client.recordings.spotlight(123);
86
+ * ```
87
+ */
88
+ async spotlight(recordingId: number): Promise<Recording> {
89
+ const response = await this.request(
90
+ {
91
+ service: "Recordings",
92
+ operation: "SpotlightRecording",
93
+ resourceType: "recording",
94
+ isMutation: true,
95
+ resourceId: recordingId,
96
+ },
97
+ () =>
98
+ this.client.POST("/recordings/{recordingId}/spotlight.json", {
99
+ params: {
100
+ path: { recordingId },
101
+ },
102
+ })
103
+ );
104
+ return response;
105
+ }
106
+
107
+ /**
108
+ * Remove a recording from the spotlight area.
109
+ * @param recordingId - The recording ID
110
+ * @returns void
111
+ * @throws {BasecampError} If the request fails
112
+ *
113
+ * @example
114
+ * ```ts
115
+ * await client.recordings.unspotlight(123);
116
+ * ```
117
+ */
118
+ async unspotlight(recordingId: number): Promise<void> {
119
+ await this.request(
120
+ {
121
+ service: "Recordings",
122
+ operation: "UnspotlightRecording",
123
+ resourceType: "recording",
124
+ isMutation: true,
125
+ resourceId: recordingId,
126
+ },
127
+ () =>
128
+ this.client.DELETE("/recordings/{recordingId}/spotlight.json", {
129
+ params: {
130
+ path: { recordingId },
131
+ },
132
+ })
133
+ );
134
+ }
135
+
77
136
  /**
78
137
  * Unarchive a recording (restore to active status)
79
138
  * @param recordingId - The recording ID
@@ -17,6 +17,18 @@ import { Errors } from "../../errors.js";
17
17
  /** Template entity from the Basecamp API. */
18
18
  export type Template = components["schemas"]["Template"];
19
19
 
20
+ /**
21
+ * Request parameters for createLibraryCopy.
22
+ */
23
+ export interface CreateLibraryCopyTemplateRequest {
24
+ /** Template recording id */
25
+ templateRecordingId: number;
26
+ /** Destination parent id */
27
+ destinationParentId: number;
28
+ /** Confirm granting destination-project access to people referenced by the template. */
29
+ addingPeopleConfirmed?: boolean;
30
+ }
31
+
20
32
  /**
21
33
  * Options for list.
22
34
  */
@@ -65,6 +77,92 @@ export interface CreateProjectTemplateRequest {
65
77
  */
66
78
  export class TemplatesService extends BaseService {
67
79
 
80
+ /**
81
+ * Get the account's to-do list template library
82
+ * @returns The template_library
83
+ * @throws {BasecampError} If the resource is not found
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * const result = await client.templates.getLibrary();
88
+ * ```
89
+ */
90
+ async getLibrary(): Promise<components["schemas"]["GetTemplateLibraryResponseContent"]> {
91
+ const response = await this.request(
92
+ {
93
+ service: "Templates",
94
+ operation: "GetTemplateLibrary",
95
+ resourceType: "template_library",
96
+ isMutation: false,
97
+ },
98
+ () =>
99
+ this.client.GET("/template_library.json", {
100
+ })
101
+ );
102
+ return response;
103
+ }
104
+
105
+ /**
106
+ * Start copying a to-do list template into a project
107
+ * @param req - Template_library_copy creation parameters
108
+ * @returns The template_library_copy
109
+ * @throws {BasecampError} If required fields are missing or invalid
110
+ *
111
+ * @example
112
+ * ```ts
113
+ * const result = await client.templates.createLibraryCopy({ templateRecordingId: 1, destinationParentId: 1 });
114
+ * ```
115
+ */
116
+ async createLibraryCopy(req: CreateLibraryCopyTemplateRequest): Promise<components["schemas"]["CreateTemplateLibraryCopyResponseContent"]> {
117
+ const response = await this.request(
118
+ {
119
+ service: "Templates",
120
+ operation: "CreateTemplateLibraryCopy",
121
+ resourceType: "template_library_copy",
122
+ isMutation: true,
123
+ },
124
+ () =>
125
+ this.client.POST("/template_library/copies.json", {
126
+ body: {
127
+ template_recording_id: req.templateRecordingId,
128
+ destination_parent_id: req.destinationParentId,
129
+ adding_people_confirmed: req.addingPeopleConfirmed,
130
+ },
131
+ })
132
+ );
133
+ return response;
134
+ }
135
+
136
+ /**
137
+ * Get the current status of a to-do list template copy
138
+ * @param copyId - The copy ID
139
+ * @returns The template_library_copy
140
+ * @throws {BasecampError} If the resource is not found
141
+ *
142
+ * @example
143
+ * ```ts
144
+ * const result = await client.templates.getLibraryCopy(123);
145
+ * ```
146
+ */
147
+ async getLibraryCopy(copyId: number): Promise<components["schemas"]["GetTemplateLibraryCopyResponseContent"]> {
148
+ const response = await this.request(
149
+ {
150
+ service: "Templates",
151
+ operation: "GetTemplateLibraryCopy",
152
+ resourceType: "template_library_copy",
153
+ isMutation: false,
154
+ resourceId: copyId,
155
+ },
156
+ () =>
157
+ this.client.GET("/template_library/copies/{copyId}", {
158
+ params: {
159
+ path: { copyId },
160
+ },
161
+ })
162
+ );
163
+ return response;
164
+ }
165
+
68
166
  /**
69
167
  * List all templates visible to the current user
70
168
  * @param options - Optional query parameters