@37signals/basecamp 0.7.3 → 0.9.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 +82 -2
- package/dist/client.d.ts +7 -4
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +32 -23
- package/dist/client.js.map +1 -1
- package/dist/download.d.ts.map +1 -1
- package/dist/errors.d.ts +10 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +7 -1
- package/dist/errors.js.map +1 -1
- package/dist/generated/metadata.d.ts +32 -0
- package/dist/generated/metadata.d.ts.map +1 -0
- package/dist/generated/metadata.js +2723 -0
- package/dist/generated/metadata.js.map +1 -0
- package/dist/generated/{metadata.json → metadata.ts} +141 -35
- package/dist/generated/openapi-stripped.json +1713 -478
- package/dist/generated/path-mapping.d.ts.map +1 -1
- package/dist/generated/path-mapping.js +10 -5
- package/dist/generated/path-mapping.js.map +1 -1
- package/dist/generated/path-mapping.ts +10 -5
- package/dist/generated/schema.d.ts +1027 -265
- package/dist/generated/services/campfires.d.ts +22 -1
- package/dist/generated/services/campfires.d.ts.map +1 -1
- package/dist/generated/services/campfires.js +33 -1
- package/dist/generated/services/campfires.js.map +1 -1
- package/dist/generated/services/campfires.ts +46 -1
- package/dist/generated/services/card-columns.d.ts +31 -28
- package/dist/generated/services/card-columns.d.ts.map +1 -1
- package/dist/generated/services/card-columns.js +57 -51
- package/dist/generated/services/card-columns.js.map +1 -1
- package/dist/generated/services/card-columns.ts +65 -59
- package/dist/generated/services/checkins.d.ts +3 -1
- package/dist/generated/services/checkins.d.ts.map +1 -1
- package/dist/generated/services/checkins.js +2 -1
- package/dist/generated/services/checkins.js.map +1 -1
- package/dist/generated/services/checkins.ts +4 -1
- package/dist/generated/services/documents.d.ts +2 -0
- package/dist/generated/services/documents.d.ts.map +1 -1
- package/dist/generated/services/documents.js +1 -0
- package/dist/generated/services/documents.js.map +1 -1
- package/dist/generated/services/documents.ts +3 -0
- package/dist/generated/services/gauges.d.ts +2 -2
- package/dist/generated/services/gauges.js +2 -2
- package/dist/generated/services/gauges.ts +2 -2
- package/dist/generated/services/index.d.ts +3 -2
- package/dist/generated/services/index.d.ts.map +1 -1
- package/dist/generated/services/index.js +3 -2
- package/dist/generated/services/index.js.map +1 -1
- package/dist/generated/services/index.ts +3 -2
- package/dist/generated/services/messages.d.ts +2 -0
- package/dist/generated/services/messages.d.ts.map +1 -1
- package/dist/generated/services/messages.js +1 -0
- package/dist/generated/services/messages.js.map +1 -1
- package/dist/generated/services/messages.ts +3 -0
- package/dist/generated/services/people.d.ts +2 -2
- package/dist/generated/services/people.js +2 -2
- package/dist/generated/services/people.ts +2 -2
- package/dist/generated/services/reports.d.ts +1 -1
- package/dist/generated/services/reports.js +1 -1
- package/dist/generated/services/reports.ts +1 -1
- package/dist/generated/services/schedules.d.ts +2 -0
- package/dist/generated/services/schedules.d.ts.map +1 -1
- package/dist/generated/services/schedules.js +1 -0
- package/dist/generated/services/schedules.js.map +1 -1
- package/dist/generated/services/schedules.ts +3 -0
- package/dist/generated/services/search.d.ts +30 -1
- package/dist/generated/services/search.d.ts.map +1 -1
- package/dist/generated/services/search.js +1 -1
- package/dist/generated/services/search.js.map +1 -1
- package/dist/generated/services/search.ts +31 -2
- package/dist/generated/services/templates.d.ts +3 -5
- package/dist/generated/services/templates.d.ts.map +1 -1
- package/dist/generated/services/templates.js +4 -5
- package/dist/generated/services/templates.js.map +1 -1
- package/dist/generated/services/templates.ts +6 -9
- package/dist/generated/services/todolists.d.ts +22 -0
- package/dist/generated/services/todolists.d.ts.map +1 -1
- package/dist/generated/services/todolists.js +31 -0
- package/dist/generated/services/todolists.js.map +1 -1
- package/dist/generated/services/todolists.ts +46 -0
- package/dist/generated/services/todos.d.ts +8 -8
- package/dist/generated/services/todos.d.ts.map +1 -1
- package/dist/generated/services/todos.js +9 -6
- package/dist/generated/services/todos.js.map +1 -1
- package/dist/generated/services/todos.ts +12 -9
- package/dist/generated/services/tools.d.ts +11 -10
- package/dist/generated/services/tools.d.ts.map +1 -1
- package/dist/generated/services/tools.js +16 -8
- package/dist/generated/services/tools.js.map +1 -1
- package/dist/generated/services/tools.ts +21 -13
- package/dist/generated/services/uploads.d.ts +2 -0
- package/dist/generated/services/uploads.d.ts.map +1 -1
- package/dist/generated/services/uploads.js +1 -0
- package/dist/generated/services/uploads.js.map +1 -1
- package/dist/generated/services/uploads.ts +3 -0
- package/dist/generated/services/webhooks.js +2 -2
- package/dist/generated/services/webhooks.js.map +1 -1
- package/dist/generated/services/webhooks.ts +2 -2
- package/dist/generated/services/wormholes.d.ts +70 -0
- package/dist/generated/services/wormholes.d.ts.map +1 -0
- package/dist/generated/services/wormholes.js +103 -0
- package/dist/generated/services/wormholes.js.map +1 -0
- package/dist/generated/services/wormholes.ts +145 -0
- package/dist/index.d.ts +8 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/oauth/discovery.d.ts +105 -23
- package/dist/oauth/discovery.d.ts.map +1 -1
- package/dist/oauth/discovery.js +453 -61
- package/dist/oauth/discovery.js.map +1 -1
- package/dist/oauth/index.d.ts +2 -2
- package/dist/oauth/index.d.ts.map +1 -1
- package/dist/oauth/index.js +1 -1
- package/dist/oauth/index.js.map +1 -1
- package/dist/oauth/interactive-login.d.ts +20 -2
- package/dist/oauth/interactive-login.d.ts.map +1 -1
- package/dist/oauth/interactive-login.js +58 -4
- package/dist/oauth/interactive-login.js.map +1 -1
- package/dist/oauth/types.d.ts +54 -2
- package/dist/oauth/types.d.ts.map +1 -1
- package/dist/security.d.ts +22 -0
- package/dist/security.d.ts.map +1 -1
- package/dist/security.js +56 -1
- package/dist/security.js.map +1 -1
- package/dist/services/authorization.d.ts.map +1 -1
- package/dist/services/authorization.js +3 -0
- package/dist/services/authorization.js.map +1 -1
- package/dist/services/base.d.ts.map +1 -1
- package/dist/services/base.js +1 -3
- package/dist/services/base.js.map +1 -1
- package/dist/services/todos-extensions.d.ts +118 -0
- package/dist/services/todos-extensions.d.ts.map +1 -0
- package/dist/services/todos-extensions.js +113 -0
- package/dist/services/todos-extensions.js.map +1 -0
- package/dist/services/uploads-extensions.d.ts +33 -0
- package/dist/services/uploads-extensions.d.ts.map +1 -0
- package/dist/services/uploads-extensions.js +48 -0
- package/dist/services/uploads-extensions.js.map +1 -0
- package/package.json +7 -4
- package/src/generated/{metadata.json → metadata.ts} +141 -35
- package/src/generated/openapi-stripped.json +1713 -478
- package/src/generated/path-mapping.ts +10 -5
- package/src/generated/schema.d.ts +1027 -265
- package/src/generated/services/campfires.ts +46 -1
- package/src/generated/services/card-columns.ts +65 -59
- package/src/generated/services/checkins.ts +4 -1
- package/src/generated/services/documents.ts +3 -0
- package/src/generated/services/gauges.ts +2 -2
- package/src/generated/services/index.ts +3 -2
- package/src/generated/services/messages.ts +3 -0
- package/src/generated/services/people.ts +2 -2
- package/src/generated/services/reports.ts +1 -1
- package/src/generated/services/schedules.ts +3 -0
- package/src/generated/services/search.ts +31 -2
- package/src/generated/services/templates.ts +6 -9
- package/src/generated/services/todolists.ts +46 -0
- package/src/generated/services/todos.ts +12 -9
- package/src/generated/services/tools.ts +21 -13
- package/src/generated/services/uploads.ts +3 -0
- package/src/generated/services/webhooks.ts +2 -2
- package/src/generated/services/wormholes.ts +145 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { TodosService as GeneratedTodosService } from "../generated/services/todos.js";
|
|
2
|
+
/**
|
|
3
|
+
* TodosService with merge-safe `update` and read-modify-write `edit` on
|
|
4
|
+
* top of the generated surface (`get`, `replace`, ...).
|
|
5
|
+
*
|
|
6
|
+
* Both compose the public `get` and `replace` methods, so hooks observe
|
|
7
|
+
* the two wire operations (`GetTodo` then `ReplaceTodo`), not a synthetic
|
|
8
|
+
* composite.
|
|
9
|
+
*/
|
|
10
|
+
export class TodosService extends GeneratedTodosService {
|
|
11
|
+
/**
|
|
12
|
+
* Sets the given fields on a todo and preserves everything else: GETs
|
|
13
|
+
* the current todo, overlays the explicitly-set request fields, and PUTs
|
|
14
|
+
* the full representation back. An omitted (`undefined`) field is
|
|
15
|
+
* untouched, guaranteed; an explicitly-passed empty array clears.
|
|
16
|
+
*
|
|
17
|
+
* Not atomic: there is no conditional-update signal on this endpoint, so
|
|
18
|
+
* a concurrent write between the GET and PUT is overwritten — last write
|
|
19
|
+
* wins for the whole representation. The window is one round-trip. Use
|
|
20
|
+
* `replace` to overwrite deliberately.
|
|
21
|
+
*
|
|
22
|
+
* @param todoId - The todo ID
|
|
23
|
+
* @param req - Fields to set; omitted fields are preserved
|
|
24
|
+
* @returns The updated Todo
|
|
25
|
+
* @throws {BasecampError} If the request fails
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* // Retitle without touching description, dates, or assignees.
|
|
30
|
+
* await client.todos.update(123, { content: "New title" });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
async update(todoId, req) {
|
|
34
|
+
const fields = await this.currentFields(todoId);
|
|
35
|
+
if (req.content !== undefined)
|
|
36
|
+
fields.content = req.content;
|
|
37
|
+
if (req.description !== undefined)
|
|
38
|
+
fields.description = req.description;
|
|
39
|
+
if (req.assigneeIds !== undefined)
|
|
40
|
+
fields.assigneeIds = req.assigneeIds;
|
|
41
|
+
if (req.completionSubscriberIds !== undefined) {
|
|
42
|
+
fields.completionSubscriberIds = req.completionSubscriberIds;
|
|
43
|
+
}
|
|
44
|
+
if (req.dueOn !== undefined)
|
|
45
|
+
fields.dueOn = req.dueOn;
|
|
46
|
+
if (req.startsOn !== undefined)
|
|
47
|
+
fields.startsOn = req.startsOn;
|
|
48
|
+
if (req.notify !== undefined)
|
|
49
|
+
fields.notify = req.notify;
|
|
50
|
+
return this.putFields(todoId, fields);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Applies a read-modify-write callback to a todo: GETs the current todo,
|
|
54
|
+
* hands the callback the full writable representation, and PUTs the
|
|
55
|
+
* whole thing back. Clearing a field means setting it empty (`""` or
|
|
56
|
+
* `[]`) — an untouched field keeps its current value. If the callback
|
|
57
|
+
* throws (or rejects), the edit aborts and nothing is written.
|
|
58
|
+
*
|
|
59
|
+
* Not atomic: there is no conditional-update signal on this endpoint, so
|
|
60
|
+
* a concurrent write between the GET and PUT is overwritten — last write
|
|
61
|
+
* wins for the whole representation. The window is one round-trip. Use
|
|
62
|
+
* `replace` to overwrite deliberately.
|
|
63
|
+
*
|
|
64
|
+
* @param todoId - The todo ID
|
|
65
|
+
* @param fn - Callback that mutates the todo's writable fields in place
|
|
66
|
+
* @returns The updated Todo
|
|
67
|
+
* @throws {BasecampError} If the request fails
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* await client.todos.edit(123, (t) => {
|
|
72
|
+
* t.content = `🚨 ${t.content}`;
|
|
73
|
+
* t.dueOn = ""; // clearing = setting empty on a full object
|
|
74
|
+
* });
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
async edit(todoId, fn) {
|
|
78
|
+
const fields = await this.currentFields(todoId);
|
|
79
|
+
await fn(fields);
|
|
80
|
+
return this.putFields(todoId, fields);
|
|
81
|
+
}
|
|
82
|
+
/** Fetches the todo and derives its full writable state. */
|
|
83
|
+
async currentFields(todoId) {
|
|
84
|
+
const current = await this.get(todoId);
|
|
85
|
+
return {
|
|
86
|
+
content: current.content ?? "",
|
|
87
|
+
description: current.description ?? "",
|
|
88
|
+
assigneeIds: (current.assignees ?? []).map((p) => p.id),
|
|
89
|
+
completionSubscriberIds: (current.completion_subscribers ?? []).map((p) => p.id),
|
|
90
|
+
dueOn: current.due_on ?? "",
|
|
91
|
+
startsOn: current.starts_on ?? "",
|
|
92
|
+
notify: false,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* PUTs the full writable state via `replace`: content, description, and
|
|
97
|
+
* both ID lists are always sent (empties included, so clears survive);
|
|
98
|
+
* dates are sent only when non-empty (the server clears an omitted date,
|
|
99
|
+
* and `""` is a format error); notify is sent only when true.
|
|
100
|
+
*/
|
|
101
|
+
putFields(todoId, f) {
|
|
102
|
+
return this.replace(todoId, {
|
|
103
|
+
content: f.content,
|
|
104
|
+
description: f.description,
|
|
105
|
+
assigneeIds: f.assigneeIds,
|
|
106
|
+
completionSubscriberIds: f.completionSubscriberIds,
|
|
107
|
+
dueOn: f.dueOn === "" ? undefined : f.dueOn,
|
|
108
|
+
startsOn: f.startsOn === "" ? undefined : f.startsOn,
|
|
109
|
+
notify: f.notify ? true : undefined,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=todos-extensions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"todos-extensions.js","sourceRoot":"","sources":["../../src/services/todos-extensions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { BasecampHooks } from "../hooks.js";
|
|
2
|
+
import type { DownloadResult } from "../download.js";
|
|
3
|
+
import { UploadsService as GeneratedUploadsService } from "../generated/services/uploads.js";
|
|
4
|
+
import type { RawClient } from "./base.js";
|
|
5
|
+
/** Function signature for the client-level `downloadURL` primitive. */
|
|
6
|
+
type DownloadURLFn = (rawURL: string) => Promise<DownloadResult>;
|
|
7
|
+
/**
|
|
8
|
+
* UploadsService with a hand-written `download(uploadId)` convenience.
|
|
9
|
+
*
|
|
10
|
+
* The subclass injects the client-level `downloadURL` function so the
|
|
11
|
+
* convenience method can delegate to it — the authenticated-hop + 302-follow
|
|
12
|
+
* flow stays in one place (`createDownloadURL` in `download.ts`).
|
|
13
|
+
*/
|
|
14
|
+
export declare class UploadsService extends GeneratedUploadsService {
|
|
15
|
+
private readonly downloadURLFn?;
|
|
16
|
+
constructor(client: RawClient, hooks?: BasecampHooks, fetchPage?: (url: string) => Promise<Response>, maxPages?: number, authenticatedFetch?: (url: string, init: RequestInit) => Promise<Response>, baseUrl?: string, downloadURLFn?: DownloadURLFn);
|
|
17
|
+
/**
|
|
18
|
+
* Downloads an upload's file content in one call.
|
|
19
|
+
*
|
|
20
|
+
* Fetches the upload metadata to retrieve `download_url`, then delegates to
|
|
21
|
+
* the client-level `downloadURL` primitive (authenticated-hop + 302-follow).
|
|
22
|
+
*
|
|
23
|
+
* @param uploadId - The upload's numeric id.
|
|
24
|
+
* @returns A `DownloadResult` whose `filename` prefers `upload.filename`
|
|
25
|
+
* from metadata, falling back to the URL-derived filename.
|
|
26
|
+
* @throws {BasecampError} `usage` if the upload has no `download_url`,
|
|
27
|
+
* or if the service was constructed without the injected download
|
|
28
|
+
* primitive (obtain the service through `createBasecampClient().uploads`).
|
|
29
|
+
*/
|
|
30
|
+
download(uploadId: number): Promise<DownloadResult>;
|
|
31
|
+
}
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=uploads-extensions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uploads-extensions.d.ts","sourceRoot":"","sources":["../../src/services/uploads-extensions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,EAAE,cAAc,IAAI,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC7F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,uEAAuE;AACvE,KAAK,aAAa,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;AAEjE;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,uBAAuB;IACzD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAgB;gBAS7C,MAAM,EAAE,SAAS,EACjB,KAAK,CAAC,EAAE,aAAa,EACrB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,EAC9C,QAAQ,CAAC,EAAE,MAAM,EACjB,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,EAC1E,OAAO,CAAC,EAAE,MAAM,EAChB,aAAa,CAAC,EAAE,aAAa;IAM/B;;;;;;;;;;;;OAYG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;CAc1D"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Errors } from "../errors.js";
|
|
2
|
+
import { UploadsService as GeneratedUploadsService } from "../generated/services/uploads.js";
|
|
3
|
+
/**
|
|
4
|
+
* UploadsService with a hand-written `download(uploadId)` convenience.
|
|
5
|
+
*
|
|
6
|
+
* The subclass injects the client-level `downloadURL` function so the
|
|
7
|
+
* convenience method can delegate to it — the authenticated-hop + 302-follow
|
|
8
|
+
* flow stays in one place (`createDownloadURL` in `download.ts`).
|
|
9
|
+
*/
|
|
10
|
+
export class UploadsService extends GeneratedUploadsService {
|
|
11
|
+
downloadURLFn;
|
|
12
|
+
// Preserve BaseService's full positional signature (authenticatedFetch, baseUrl),
|
|
13
|
+
// then append downloadURLFn — otherwise existing `new UploadsService(client, hooks,
|
|
14
|
+
// fetchPage, maxPages, authenticatedFetch, baseUrl)` callers would silently miswire
|
|
15
|
+
// authenticatedFetch into the 5th slot. All params optional for direct-construction
|
|
16
|
+
// back-compat; `download()` throws a clear usage error if the primitive wasn't
|
|
17
|
+
// injected (i.e. the service was constructed outside createBasecampClient).
|
|
18
|
+
constructor(client, hooks, fetchPage, maxPages, authenticatedFetch, baseUrl, downloadURLFn) {
|
|
19
|
+
super(client, hooks, fetchPage, maxPages, authenticatedFetch, baseUrl);
|
|
20
|
+
this.downloadURLFn = downloadURLFn;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Downloads an upload's file content in one call.
|
|
24
|
+
*
|
|
25
|
+
* Fetches the upload metadata to retrieve `download_url`, then delegates to
|
|
26
|
+
* the client-level `downloadURL` primitive (authenticated-hop + 302-follow).
|
|
27
|
+
*
|
|
28
|
+
* @param uploadId - The upload's numeric id.
|
|
29
|
+
* @returns A `DownloadResult` whose `filename` prefers `upload.filename`
|
|
30
|
+
* from metadata, falling back to the URL-derived filename.
|
|
31
|
+
* @throws {BasecampError} `usage` if the upload has no `download_url`,
|
|
32
|
+
* or if the service was constructed without the injected download
|
|
33
|
+
* primitive (obtain the service through `createBasecampClient().uploads`).
|
|
34
|
+
*/
|
|
35
|
+
async download(uploadId) {
|
|
36
|
+
if (!this.downloadURLFn) {
|
|
37
|
+
throw Errors.usage("uploads.download requires the download primitive — obtain UploadsService via createBasecampClient(...).uploads rather than instantiating it directly");
|
|
38
|
+
}
|
|
39
|
+
const upload = await this.get(uploadId);
|
|
40
|
+
const url = upload.download_url;
|
|
41
|
+
if (!url) {
|
|
42
|
+
throw Errors.usage(`upload ${uploadId} has no download_url`);
|
|
43
|
+
}
|
|
44
|
+
const result = await this.downloadURLFn(url);
|
|
45
|
+
return upload.filename ? { ...result, filename: upload.filename } : result;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=uploads-extensions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uploads-extensions.js","sourceRoot":"","sources":["../../src/services/uploads-extensions.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,cAAc,IAAI,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAM7F;;;;;;GAMG;AACH,MAAM,OAAO,cAAe,SAAQ,uBAAuB;IACxC,aAAa,CAAiB;IAE/C,kFAAkF;IAClF,oFAAoF;IACpF,oFAAoF;IACpF,oFAAoF;IACpF,+EAA+E;IAC/E,4EAA4E;IAC5E,YACE,MAAiB,EACjB,KAAqB,EACrB,SAA8C,EAC9C,QAAiB,EACjB,kBAA0E,EAC1E,OAAgB,EAChB,aAA6B;QAE7B,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,kBAAkB,EAAE,OAAO,CAAC,CAAC;QACvE,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACrC,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,QAAQ,CAAC,QAAgB;QAC7B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,MAAM,MAAM,CAAC,KAAK,CAChB,sJAAsJ,CACvJ,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC;QAChC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,QAAQ,sBAAsB,CAAC,CAAC;QAC/D,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAC7C,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IAC7E,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@37signals/basecamp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "TypeScript SDK for the Basecamp API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"src/generated"
|
|
21
21
|
],
|
|
22
22
|
"scripts": {
|
|
23
|
-
"generate": "tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/patch-flexible-ids.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.
|
|
23
|
+
"generate": "tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/patch-flexible-ids.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.ts && tsx scripts/generate-path-mapping.ts",
|
|
24
24
|
"build": "tsc",
|
|
25
25
|
"postbuild": "node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});\"",
|
|
26
26
|
"prepublishOnly": "npm run build",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"openapi-fetch": "^0.17.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@types/node": "^
|
|
56
|
+
"@types/node": "^26.1.0",
|
|
57
57
|
"@vitest/coverage-v8": "^4.0.18",
|
|
58
58
|
"msw": "^2.12.10",
|
|
59
59
|
"openapi-typescript": "^7.13.0",
|
|
@@ -66,6 +66,9 @@
|
|
|
66
66
|
"typescript": ">=5.0.0"
|
|
67
67
|
},
|
|
68
68
|
"overrides": {
|
|
69
|
-
"minimatch": ">=10.2.1"
|
|
69
|
+
"minimatch": ">=10.2.1",
|
|
70
|
+
"brace-expansion": ">=5.0.7",
|
|
71
|
+
"fast-uri": ">=3.1.3",
|
|
72
|
+
"js-yaml": "^4.3.0"
|
|
70
73
|
}
|
|
71
74
|
}
|
|
@@ -1,7 +1,43 @@
|
|
|
1
|
-
|
|
1
|
+
// Generated from OpenAPI x-basecamp-* extensions. Do not edit by hand.
|
|
2
|
+
|
|
3
|
+
export interface RetryConfig {
|
|
4
|
+
maxAttempts: number;
|
|
5
|
+
baseDelayMs: number;
|
|
6
|
+
backoff: "exponential" | "linear" | "constant";
|
|
7
|
+
retryOn: number[];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface PaginationConfig {
|
|
11
|
+
style: "link" | "cursor" | "page";
|
|
12
|
+
pageParam?: string;
|
|
13
|
+
totalCountHeader?: string;
|
|
14
|
+
maxPageSize?: number;
|
|
15
|
+
key?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface IdempotentConfig {
|
|
19
|
+
keySupported?: boolean;
|
|
20
|
+
keyHeader?: string;
|
|
21
|
+
natural?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface OperationMetadata {
|
|
25
|
+
retry?: RetryConfig;
|
|
26
|
+
pagination?: PaginationConfig;
|
|
27
|
+
idempotent?: IdempotentConfig;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface MetadataOutput {
|
|
31
|
+
$schema: string;
|
|
32
|
+
version: string;
|
|
33
|
+
generated: string;
|
|
34
|
+
operations: Record<string, OperationMetadata>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const metadata: MetadataOutput = {
|
|
2
38
|
"$schema": "https://basecamp.com/schemas/sdk-metadata.json",
|
|
3
39
|
"version": "1.0.0",
|
|
4
|
-
"generated": "2026-
|
|
40
|
+
"generated": "2026-07-23T19:34:22.062Z",
|
|
5
41
|
"operations": {
|
|
6
42
|
"GetAccount": {
|
|
7
43
|
"retry": {
|
|
@@ -92,7 +128,7 @@
|
|
|
92
128
|
"natural": true
|
|
93
129
|
}
|
|
94
130
|
},
|
|
95
|
-
"
|
|
131
|
+
"SetCardColumnColor": {
|
|
96
132
|
"retry": {
|
|
97
133
|
"maxAttempts": 3,
|
|
98
134
|
"baseDelayMs": 1000,
|
|
@@ -102,13 +138,11 @@
|
|
|
102
138
|
503
|
|
103
139
|
]
|
|
104
140
|
},
|
|
105
|
-
"
|
|
106
|
-
"
|
|
107
|
-
"totalCountHeader": "X-Total-Count",
|
|
108
|
-
"maxPageSize": 50
|
|
141
|
+
"idempotent": {
|
|
142
|
+
"natural": true
|
|
109
143
|
}
|
|
110
144
|
},
|
|
111
|
-
"
|
|
145
|
+
"EnableCardColumnOnHold": {
|
|
112
146
|
"retry": {
|
|
113
147
|
"maxAttempts": 2,
|
|
114
148
|
"baseDelayMs": 1000,
|
|
@@ -119,7 +153,7 @@
|
|
|
119
153
|
]
|
|
120
154
|
}
|
|
121
155
|
},
|
|
122
|
-
"
|
|
156
|
+
"DisableCardColumnOnHold": {
|
|
123
157
|
"retry": {
|
|
124
158
|
"maxAttempts": 3,
|
|
125
159
|
"baseDelayMs": 1000,
|
|
@@ -128,9 +162,12 @@
|
|
|
128
162
|
429,
|
|
129
163
|
503
|
|
130
164
|
]
|
|
165
|
+
},
|
|
166
|
+
"idempotent": {
|
|
167
|
+
"natural": true
|
|
131
168
|
}
|
|
132
169
|
},
|
|
133
|
-
"
|
|
170
|
+
"UpdateWormhole": {
|
|
134
171
|
"retry": {
|
|
135
172
|
"maxAttempts": 3,
|
|
136
173
|
"baseDelayMs": 1000,
|
|
@@ -144,18 +181,21 @@
|
|
|
144
181
|
"natural": true
|
|
145
182
|
}
|
|
146
183
|
},
|
|
147
|
-
"
|
|
184
|
+
"DeleteWormhole": {
|
|
148
185
|
"retry": {
|
|
149
|
-
"maxAttempts":
|
|
186
|
+
"maxAttempts": 3,
|
|
150
187
|
"baseDelayMs": 1000,
|
|
151
188
|
"backoff": "exponential",
|
|
152
189
|
"retryOn": [
|
|
153
190
|
429,
|
|
154
191
|
503
|
|
155
192
|
]
|
|
193
|
+
},
|
|
194
|
+
"idempotent": {
|
|
195
|
+
"natural": true
|
|
156
196
|
}
|
|
157
197
|
},
|
|
158
|
-
"
|
|
198
|
+
"CreateWormhole": {
|
|
159
199
|
"retry": {
|
|
160
200
|
"maxAttempts": 2,
|
|
161
201
|
"baseDelayMs": 1000,
|
|
@@ -166,7 +206,7 @@
|
|
|
166
206
|
]
|
|
167
207
|
}
|
|
168
208
|
},
|
|
169
|
-
"
|
|
209
|
+
"CreateTool": {
|
|
170
210
|
"retry": {
|
|
171
211
|
"maxAttempts": 2,
|
|
172
212
|
"baseDelayMs": 1000,
|
|
@@ -177,7 +217,7 @@
|
|
|
177
217
|
]
|
|
178
218
|
}
|
|
179
219
|
},
|
|
180
|
-
"
|
|
220
|
+
"ListWebhooks": {
|
|
181
221
|
"retry": {
|
|
182
222
|
"maxAttempts": 3,
|
|
183
223
|
"baseDelayMs": 1000,
|
|
@@ -186,9 +226,25 @@
|
|
|
186
226
|
429,
|
|
187
227
|
503
|
|
188
228
|
]
|
|
229
|
+
},
|
|
230
|
+
"pagination": {
|
|
231
|
+
"style": "link",
|
|
232
|
+
"totalCountHeader": "X-Total-Count",
|
|
233
|
+
"maxPageSize": 50
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
"CreateWebhook": {
|
|
237
|
+
"retry": {
|
|
238
|
+
"maxAttempts": 2,
|
|
239
|
+
"baseDelayMs": 1000,
|
|
240
|
+
"backoff": "exponential",
|
|
241
|
+
"retryOn": [
|
|
242
|
+
429,
|
|
243
|
+
503
|
|
244
|
+
]
|
|
189
245
|
}
|
|
190
246
|
},
|
|
191
|
-
"
|
|
247
|
+
"GetCard": {
|
|
192
248
|
"retry": {
|
|
193
249
|
"maxAttempts": 3,
|
|
194
250
|
"baseDelayMs": 1000,
|
|
@@ -197,12 +253,9 @@
|
|
|
197
253
|
429,
|
|
198
254
|
503
|
|
199
255
|
]
|
|
200
|
-
},
|
|
201
|
-
"idempotent": {
|
|
202
|
-
"natural": true
|
|
203
256
|
}
|
|
204
257
|
},
|
|
205
|
-
"
|
|
258
|
+
"UpdateCard": {
|
|
206
259
|
"retry": {
|
|
207
260
|
"maxAttempts": 3,
|
|
208
261
|
"baseDelayMs": 1000,
|
|
@@ -216,7 +269,7 @@
|
|
|
216
269
|
"natural": true
|
|
217
270
|
}
|
|
218
271
|
},
|
|
219
|
-
"
|
|
272
|
+
"MoveCard": {
|
|
220
273
|
"retry": {
|
|
221
274
|
"maxAttempts": 2,
|
|
222
275
|
"baseDelayMs": 1000,
|
|
@@ -227,7 +280,40 @@
|
|
|
227
280
|
]
|
|
228
281
|
}
|
|
229
282
|
},
|
|
230
|
-
"
|
|
283
|
+
"RepositionCardStep": {
|
|
284
|
+
"retry": {
|
|
285
|
+
"maxAttempts": 2,
|
|
286
|
+
"baseDelayMs": 1000,
|
|
287
|
+
"backoff": "exponential",
|
|
288
|
+
"retryOn": [
|
|
289
|
+
429,
|
|
290
|
+
503
|
|
291
|
+
]
|
|
292
|
+
}
|
|
293
|
+
},
|
|
294
|
+
"CreateCardStep": {
|
|
295
|
+
"retry": {
|
|
296
|
+
"maxAttempts": 2,
|
|
297
|
+
"baseDelayMs": 1000,
|
|
298
|
+
"backoff": "exponential",
|
|
299
|
+
"retryOn": [
|
|
300
|
+
429,
|
|
301
|
+
503
|
|
302
|
+
]
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
"GetCardColumn": {
|
|
306
|
+
"retry": {
|
|
307
|
+
"maxAttempts": 3,
|
|
308
|
+
"baseDelayMs": 1000,
|
|
309
|
+
"backoff": "exponential",
|
|
310
|
+
"retryOn": [
|
|
311
|
+
429,
|
|
312
|
+
503
|
|
313
|
+
]
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
"UpdateCardColumn": {
|
|
231
317
|
"retry": {
|
|
232
318
|
"maxAttempts": 3,
|
|
233
319
|
"baseDelayMs": 1000,
|
|
@@ -565,6 +651,20 @@
|
|
|
565
651
|
]
|
|
566
652
|
}
|
|
567
653
|
},
|
|
654
|
+
"UpdateCampfireLine": {
|
|
655
|
+
"retry": {
|
|
656
|
+
"maxAttempts": 3,
|
|
657
|
+
"baseDelayMs": 1000,
|
|
658
|
+
"backoff": "exponential",
|
|
659
|
+
"retryOn": [
|
|
660
|
+
429,
|
|
661
|
+
503
|
|
662
|
+
]
|
|
663
|
+
},
|
|
664
|
+
"idempotent": {
|
|
665
|
+
"natural": true
|
|
666
|
+
}
|
|
667
|
+
},
|
|
568
668
|
"DeleteCampfireLine": {
|
|
569
669
|
"retry": {
|
|
570
670
|
"maxAttempts": 3,
|
|
@@ -728,17 +828,6 @@
|
|
|
728
828
|
"natural": true
|
|
729
829
|
}
|
|
730
830
|
},
|
|
731
|
-
"CloneTool": {
|
|
732
|
-
"retry": {
|
|
733
|
-
"maxAttempts": 2,
|
|
734
|
-
"baseDelayMs": 1000,
|
|
735
|
-
"backoff": "exponential",
|
|
736
|
-
"retryOn": [
|
|
737
|
-
429,
|
|
738
|
-
503
|
|
739
|
-
]
|
|
740
|
-
}
|
|
741
|
-
},
|
|
742
831
|
"GetTool": {
|
|
743
832
|
"retry": {
|
|
744
833
|
"maxAttempts": 3,
|
|
@@ -2330,7 +2419,7 @@
|
|
|
2330
2419
|
]
|
|
2331
2420
|
}
|
|
2332
2421
|
},
|
|
2333
|
-
"
|
|
2422
|
+
"ReplaceTodo": {
|
|
2334
2423
|
"retry": {
|
|
2335
2424
|
"maxAttempts": 3,
|
|
2336
2425
|
"baseDelayMs": 1000,
|
|
@@ -2400,6 +2489,20 @@
|
|
|
2400
2489
|
"natural": true
|
|
2401
2490
|
}
|
|
2402
2491
|
},
|
|
2492
|
+
"RepositionTodolist": {
|
|
2493
|
+
"retry": {
|
|
2494
|
+
"maxAttempts": 3,
|
|
2495
|
+
"baseDelayMs": 1000,
|
|
2496
|
+
"backoff": "exponential",
|
|
2497
|
+
"retryOn": [
|
|
2498
|
+
429,
|
|
2499
|
+
503
|
|
2500
|
+
]
|
|
2501
|
+
},
|
|
2502
|
+
"idempotent": {
|
|
2503
|
+
"natural": true
|
|
2504
|
+
}
|
|
2505
|
+
},
|
|
2403
2506
|
"GetTodoset": {
|
|
2404
2507
|
"retry": {
|
|
2405
2508
|
"maxAttempts": 3,
|
|
@@ -2650,4 +2753,7 @@
|
|
|
2650
2753
|
}
|
|
2651
2754
|
}
|
|
2652
2755
|
}
|
|
2653
|
-
}
|
|
2756
|
+
};
|
|
2757
|
+
|
|
2758
|
+
export default metadata;
|
|
2759
|
+
|