@37signals/basecamp 0.7.3 → 0.8.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 +80 -1
- package/dist/client.d.ts +4 -4
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +30 -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 +2670 -0
- package/dist/generated/metadata.js.map +1 -0
- package/dist/generated/{metadata.json → metadata.ts} +98 -45
- package/dist/generated/openapi-stripped.json +713 -440
- package/dist/generated/path-mapping.d.ts.map +1 -1
- package/dist/generated/path-mapping.js +6 -5
- package/dist/generated/path-mapping.js.map +1 -1
- package/dist/generated/path-mapping.ts +6 -5
- package/dist/generated/schema.d.ts +510 -297
- 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 +54 -51
- package/dist/generated/services/card-columns.js.map +1 -1
- package/dist/generated/services/card-columns.ts +62 -59
- package/dist/generated/services/index.d.ts +2 -2
- package/dist/generated/services/index.d.ts.map +1 -1
- package/dist/generated/services/index.js +2 -2
- package/dist/generated/services/index.js.map +1 -1
- package/dist/generated/services/index.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/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/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -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} +98 -45
- package/src/generated/openapi-stripped.json +713 -440
- package/src/generated/path-mapping.ts +6 -5
- package/src/generated/schema.d.ts +510 -297
- package/src/generated/services/campfires.ts +46 -1
- package/src/generated/services/card-columns.ts +62 -59
- package/src/generated/services/index.ts +2 -2
- package/src/generated/services/reports.ts +1 -1
- package/src/generated/services/todos.ts +12 -9
- package/src/generated/services/tools.ts +21 -13
|
@@ -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.8.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-22T08:32:59.805Z",
|
|
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,34 +162,39 @@
|
|
|
128
162
|
429,
|
|
129
163
|
503
|
|
130
164
|
]
|
|
165
|
+
},
|
|
166
|
+
"idempotent": {
|
|
167
|
+
"natural": true
|
|
131
168
|
}
|
|
132
169
|
},
|
|
133
|
-
"
|
|
170
|
+
"CreateTool": {
|
|
134
171
|
"retry": {
|
|
135
|
-
"maxAttempts":
|
|
172
|
+
"maxAttempts": 2,
|
|
136
173
|
"baseDelayMs": 1000,
|
|
137
174
|
"backoff": "exponential",
|
|
138
175
|
"retryOn": [
|
|
139
176
|
429,
|
|
140
177
|
503
|
|
141
178
|
]
|
|
142
|
-
},
|
|
143
|
-
"idempotent": {
|
|
144
|
-
"natural": true
|
|
145
179
|
}
|
|
146
180
|
},
|
|
147
|
-
"
|
|
181
|
+
"ListWebhooks": {
|
|
148
182
|
"retry": {
|
|
149
|
-
"maxAttempts":
|
|
183
|
+
"maxAttempts": 3,
|
|
150
184
|
"baseDelayMs": 1000,
|
|
151
185
|
"backoff": "exponential",
|
|
152
186
|
"retryOn": [
|
|
153
187
|
429,
|
|
154
188
|
503
|
|
155
189
|
]
|
|
190
|
+
},
|
|
191
|
+
"pagination": {
|
|
192
|
+
"style": "link",
|
|
193
|
+
"totalCountHeader": "X-Total-Count",
|
|
194
|
+
"maxPageSize": 50
|
|
156
195
|
}
|
|
157
196
|
},
|
|
158
|
-
"
|
|
197
|
+
"CreateWebhook": {
|
|
159
198
|
"retry": {
|
|
160
199
|
"maxAttempts": 2,
|
|
161
200
|
"baseDelayMs": 1000,
|
|
@@ -166,9 +205,9 @@
|
|
|
166
205
|
]
|
|
167
206
|
}
|
|
168
207
|
},
|
|
169
|
-
"
|
|
208
|
+
"GetCard": {
|
|
170
209
|
"retry": {
|
|
171
|
-
"maxAttempts":
|
|
210
|
+
"maxAttempts": 3,
|
|
172
211
|
"baseDelayMs": 1000,
|
|
173
212
|
"backoff": "exponential",
|
|
174
213
|
"retryOn": [
|
|
@@ -177,7 +216,7 @@
|
|
|
177
216
|
]
|
|
178
217
|
}
|
|
179
218
|
},
|
|
180
|
-
"
|
|
219
|
+
"UpdateCard": {
|
|
181
220
|
"retry": {
|
|
182
221
|
"maxAttempts": 3,
|
|
183
222
|
"baseDelayMs": 1000,
|
|
@@ -186,37 +225,34 @@
|
|
|
186
225
|
429,
|
|
187
226
|
503
|
|
188
227
|
]
|
|
228
|
+
},
|
|
229
|
+
"idempotent": {
|
|
230
|
+
"natural": true
|
|
189
231
|
}
|
|
190
232
|
},
|
|
191
|
-
"
|
|
233
|
+
"MoveCard": {
|
|
192
234
|
"retry": {
|
|
193
|
-
"maxAttempts":
|
|
235
|
+
"maxAttempts": 2,
|
|
194
236
|
"baseDelayMs": 1000,
|
|
195
237
|
"backoff": "exponential",
|
|
196
238
|
"retryOn": [
|
|
197
239
|
429,
|
|
198
240
|
503
|
|
199
241
|
]
|
|
200
|
-
},
|
|
201
|
-
"idempotent": {
|
|
202
|
-
"natural": true
|
|
203
242
|
}
|
|
204
243
|
},
|
|
205
|
-
"
|
|
244
|
+
"RepositionCardStep": {
|
|
206
245
|
"retry": {
|
|
207
|
-
"maxAttempts":
|
|
246
|
+
"maxAttempts": 2,
|
|
208
247
|
"baseDelayMs": 1000,
|
|
209
248
|
"backoff": "exponential",
|
|
210
249
|
"retryOn": [
|
|
211
250
|
429,
|
|
212
251
|
503
|
|
213
252
|
]
|
|
214
|
-
},
|
|
215
|
-
"idempotent": {
|
|
216
|
-
"natural": true
|
|
217
253
|
}
|
|
218
254
|
},
|
|
219
|
-
"
|
|
255
|
+
"CreateCardStep": {
|
|
220
256
|
"retry": {
|
|
221
257
|
"maxAttempts": 2,
|
|
222
258
|
"baseDelayMs": 1000,
|
|
@@ -227,7 +263,18 @@
|
|
|
227
263
|
]
|
|
228
264
|
}
|
|
229
265
|
},
|
|
230
|
-
"
|
|
266
|
+
"GetCardColumn": {
|
|
267
|
+
"retry": {
|
|
268
|
+
"maxAttempts": 3,
|
|
269
|
+
"baseDelayMs": 1000,
|
|
270
|
+
"backoff": "exponential",
|
|
271
|
+
"retryOn": [
|
|
272
|
+
429,
|
|
273
|
+
503
|
|
274
|
+
]
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
"UpdateCardColumn": {
|
|
231
278
|
"retry": {
|
|
232
279
|
"maxAttempts": 3,
|
|
233
280
|
"baseDelayMs": 1000,
|
|
@@ -565,6 +612,20 @@
|
|
|
565
612
|
]
|
|
566
613
|
}
|
|
567
614
|
},
|
|
615
|
+
"UpdateCampfireLine": {
|
|
616
|
+
"retry": {
|
|
617
|
+
"maxAttempts": 3,
|
|
618
|
+
"baseDelayMs": 1000,
|
|
619
|
+
"backoff": "exponential",
|
|
620
|
+
"retryOn": [
|
|
621
|
+
429,
|
|
622
|
+
503
|
|
623
|
+
]
|
|
624
|
+
},
|
|
625
|
+
"idempotent": {
|
|
626
|
+
"natural": true
|
|
627
|
+
}
|
|
628
|
+
},
|
|
568
629
|
"DeleteCampfireLine": {
|
|
569
630
|
"retry": {
|
|
570
631
|
"maxAttempts": 3,
|
|
@@ -728,17 +789,6 @@
|
|
|
728
789
|
"natural": true
|
|
729
790
|
}
|
|
730
791
|
},
|
|
731
|
-
"CloneTool": {
|
|
732
|
-
"retry": {
|
|
733
|
-
"maxAttempts": 2,
|
|
734
|
-
"baseDelayMs": 1000,
|
|
735
|
-
"backoff": "exponential",
|
|
736
|
-
"retryOn": [
|
|
737
|
-
429,
|
|
738
|
-
503
|
|
739
|
-
]
|
|
740
|
-
}
|
|
741
|
-
},
|
|
742
792
|
"GetTool": {
|
|
743
793
|
"retry": {
|
|
744
794
|
"maxAttempts": 3,
|
|
@@ -2330,7 +2380,7 @@
|
|
|
2330
2380
|
]
|
|
2331
2381
|
}
|
|
2332
2382
|
},
|
|
2333
|
-
"
|
|
2383
|
+
"ReplaceTodo": {
|
|
2334
2384
|
"retry": {
|
|
2335
2385
|
"maxAttempts": 3,
|
|
2336
2386
|
"baseDelayMs": 1000,
|
|
@@ -2650,4 +2700,7 @@
|
|
|
2650
2700
|
}
|
|
2651
2701
|
}
|
|
2652
2702
|
}
|
|
2653
|
-
}
|
|
2703
|
+
};
|
|
2704
|
+
|
|
2705
|
+
export default metadata;
|
|
2706
|
+
|