@workast/sdk 2.3.0 → 3.1.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 +156 -58
- package/dist/chunk-LR7MGXLV.js +1851 -0
- package/dist/chunk-LR7MGXLV.js.map +1 -0
- package/dist/index.cjs +1875 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +15911 -0
- package/dist/index.d.ts +15911 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/mock.cjs +4591 -0
- package/dist/mock.cjs.map +1 -0
- package/dist/mock.d.cts +115 -0
- package/dist/mock.d.ts +115 -0
- package/dist/mock.js +2736 -0
- package/dist/mock.js.map +1 -0
- package/package.json +44 -52
- package/CHANGELOG.md +0 -59
- package/dist/workast.min.js +0 -1
- package/index.d.ts +0 -163
- package/lib/workast.js +0 -1850
package/README.md
CHANGED
|
@@ -1,83 +1,181 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @workast/sdk
|
|
2
2
|
|
|
3
|
-
[](https://coveralls.io/github/workast/workast-sdk-js?branch=master)
|
|
6
|
-
[](https://snyk.io/test/github/workast/workast-sdk-js?targetFile=package.json)
|
|
7
|
-
[](https://david-dm.org/workast/workast-sdk-js)
|
|
8
|
-
[](https://david-dm.org/workast/workast-sdk-js?type=dev)
|
|
3
|
+
[](https://www.npmjs.com/package/@workast/sdk)
|
|
4
|
+
[](https://github.com/workast/sdk/actions/workflows/ci.yml)
|
|
9
5
|
|
|
10
|
-
|
|
6
|
+
TypeScript library for the [Workast API](https://developers.workast.com/). Works in Node.js 18+ and in browsers.
|
|
11
7
|
|
|
12
|
-
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
npm install @workast/sdk
|
|
12
|
+
```
|
|
13
13
|
|
|
14
|
-
##
|
|
15
|
-
- [Prerequisites](#prerequisites)
|
|
16
|
-
- [Installation](#installation)
|
|
17
|
-
- [Usage](#usage)
|
|
18
|
-
- [Releases](CHANGELOG.md)
|
|
19
|
-
- [Responsible disclosure](#responsible-disclosure)
|
|
14
|
+
## Usage
|
|
20
15
|
|
|
21
|
-
|
|
22
|
-
We use [browserslist](https://github.com/browserslist/browserslist) to handle our supported versions for both node and browsers. [You can see the updated list here.](https://browserl.ist/?q=%3E+1%25%2C+last+2+versions%2C+not+dead%2C+maintained+node+versions)
|
|
16
|
+
Create a token in Workast under **Preferences → API**. Secret API keys are server-only — passing `apiKey` in a browser throws.
|
|
23
17
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
```ts
|
|
19
|
+
import { Workast } from '@workast/sdk';
|
|
20
|
+
|
|
21
|
+
const workast = new Workast({ apiKey: process.env.WORKAST_API_KEY });
|
|
22
|
+
// shorthand: new Workast(process.env.WORKAST_API_KEY)
|
|
23
|
+
|
|
24
|
+
const task = await workast.tasks.create(listId, { text: 'Ship SDK' });
|
|
25
|
+
await workast.tasks.complete(task.id);
|
|
26
|
+
const page = await workast.tasks.list({
|
|
27
|
+
predicates: [{ type: 'status', attribute: 'status', comparison: 'eq', value: 'pending' }],
|
|
28
|
+
});
|
|
28
29
|
```
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
|
|
31
|
+
Browser / user session:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
const workast = new Workast({ token: sessionToken });
|
|
35
|
+
// or
|
|
36
|
+
const workast = new Workast({ getToken: () => auth.getAccessToken() });
|
|
32
37
|
```
|
|
33
38
|
|
|
34
|
-
|
|
39
|
+
### Configuration
|
|
40
|
+
|
|
41
|
+
| Option | Description |
|
|
42
|
+
| --- | --- |
|
|
43
|
+
| `apiKey` | Secret API token. Server-only. |
|
|
44
|
+
| `token` | User or session token. Allowed in browsers. |
|
|
45
|
+
| `getToken` | Function that returns a token (sync or async). |
|
|
46
|
+
| `baseUrl` | API host. Defaults to `https://api.workast.com`. |
|
|
47
|
+
| `headers` | Extra headers (for example `W-USER-ID`, `W-TEAM-ID`). `Authorization` is set by the client. |
|
|
48
|
+
| `fetch` | Custom `fetch` implementation. |
|
|
49
|
+
|
|
50
|
+
`withHeaders(h)` returns a cloned client. `setHeaders(h)` updates the current one.
|
|
35
51
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
52
|
+
```ts
|
|
53
|
+
const workast = new Workast({
|
|
54
|
+
apiKey: process.env.WORKAST_API_KEY,
|
|
55
|
+
headers: { 'W-USER-ID': userId },
|
|
56
|
+
});
|
|
39
57
|
|
|
40
|
-
|
|
58
|
+
await workast.withHeaders({ 'W-USER-ID': otherUserId }).tasks.create(listId, { text: 'Hi' });
|
|
59
|
+
workast.setHeaders({ 'W-TEAM-ID': teamId });
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Errors
|
|
63
|
+
|
|
64
|
+
Failed requests throw a subclass of `ApiError`:
|
|
41
65
|
|
|
42
|
-
|
|
66
|
+
| Status | Error |
|
|
67
|
+
| --- | --- |
|
|
68
|
+
| 400 | `ValidationError` |
|
|
69
|
+
| 401 | `AuthenticationError` |
|
|
70
|
+
| 403 | `PermissionError` |
|
|
71
|
+
| 404 | `NotFoundError` |
|
|
72
|
+
| other | `ApiError` |
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
import { NotFoundError } from '@workast/sdk';
|
|
43
76
|
|
|
44
77
|
try {
|
|
45
|
-
|
|
46
|
-
console.log('Task data: %O', task);
|
|
78
|
+
await workast.tasks.retrieve(taskId);
|
|
47
79
|
} catch (err) {
|
|
48
|
-
|
|
80
|
+
if (err instanceof NotFoundError) {
|
|
81
|
+
console.log(err.status, err.body);
|
|
82
|
+
}
|
|
49
83
|
}
|
|
50
84
|
```
|
|
51
85
|
|
|
52
|
-
|
|
53
|
-
```javascript
|
|
54
|
-
import Workast from '@workast/sdk';
|
|
86
|
+
## Resources
|
|
55
87
|
|
|
56
|
-
|
|
88
|
+
`tasks` · `lists` · `fields` · `users` · `searches` · `tags` · `notes` · `notifications` · `meetings` · `calendar.events` · `workflows` · `reactions` · `attachments` · `tokens`
|
|
57
89
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
90
|
+
Methods use `create` / `retrieve` / `update` / `list` / `del`, plus domain verbs like `complete` and `assign`. Path ids first, body second, request options last. Types match the [API reference](https://developers.workast.com/).
|
|
91
|
+
|
|
92
|
+
## Testing
|
|
93
|
+
|
|
94
|
+
`@workast/sdk/mock` stubs SDK methods on any `Workast` instance (including one your app already constructed). No real HTTP while a mock is active. It also exports `examples`: Public API response fixtures (`examples.task`, `examples.list`, `examples.userResource`, …) generated from the spec. Spread them in `.resolves()` and override the fields your test cares about.
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
import { Workast } from '@workast/sdk';
|
|
98
|
+
import { examples, mockWorkast } from '@workast/sdk/mock';
|
|
99
|
+
|
|
100
|
+
const workast = new Workast({ apiKey: process.env.WORKAST_API_KEY });
|
|
101
|
+
|
|
102
|
+
async function createShipTask() {
|
|
103
|
+
return workast.tasks.create(examples.list.id, { text: examples.task.text });
|
|
63
104
|
}
|
|
105
|
+
|
|
106
|
+
const mock = mockWorkast();
|
|
107
|
+
mock.tasks.create.on(examples.list.id, { text: examples.task.text }).resolves({
|
|
108
|
+
...examples.task,
|
|
109
|
+
text: 'Ship from my test',
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const created = await createShipTask();
|
|
113
|
+
|
|
114
|
+
expect(created.text).toBe('Ship from my test');
|
|
115
|
+
expect(mock.calls()).toEqual([
|
|
116
|
+
{ method: 'tasks.create', args: [examples.list.id, { text: examples.task.text }] },
|
|
117
|
+
]);
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
mock.users.me.on().resolves({ ...examples.userResource, name: 'Ada Lovelace' });
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`.on(...args)` is a prefix: extra trailing options on the real call still match. Nested objects match regardless of key order. Pass a function for a loose match (`true` → match):
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
mock.tasks.create.on(examples.list.id, (body) => body.text === examples.task.text).resolves({
|
|
128
|
+
...examples.task,
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Queue errors with `.rejects()`. `errors.*` are the same classes the client throws:
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
import { AuthenticationError } from '@workast/sdk';
|
|
136
|
+
import { errors } from '@workast/sdk/mock';
|
|
137
|
+
|
|
138
|
+
mock.users.me.on().rejects(errors.unauthorized);
|
|
139
|
+
await expect(workast.users.me()).rejects.toBeInstanceOf(AuthenticationError);
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
| Helper | Meaning |
|
|
143
|
+
| --- | --- |
|
|
144
|
+
| `mock.calls()` | Every SDK call while this mock is active (`{ method, args }`). |
|
|
145
|
+
| `mock.pending()` | Interceptors that were not used. |
|
|
146
|
+
| `interceptor.wasCalled()` | Whether that `.resolves()` / `.rejects()` fired. |
|
|
147
|
+
| `mock.reset()` | Clear queue and calls. Stay intercepting. |
|
|
148
|
+
| `mock.restore()` | Unpatch. Later SDK calls hit the real API. |
|
|
149
|
+
|
|
150
|
+
One mock per test, or one shared mock and `reset()` between tests:
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
const mock = mockWorkast();
|
|
154
|
+
|
|
155
|
+
afterEach(() => mock.reset());
|
|
156
|
+
afterAll(() => mock.restore());
|
|
64
157
|
```
|
|
65
158
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
});
|
|
79
|
-
</script>
|
|
159
|
+
`mockWorkast()` last-wins: a second call replaces the active queue. Unmatched SDK methods throw and list pending interceptors.
|
|
160
|
+
|
|
161
|
+
## Upgrading from v2
|
|
162
|
+
|
|
163
|
+
v3 is a rewrite. The v2 positional constructor, `apiCall`, and generated resource helpers are gone. A string argument is now a secret `apiKey` (server-only), not a session token.
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
// v2
|
|
167
|
+
const workast = new Workast(process.env.WORKAST_TOKEN);
|
|
168
|
+
|
|
169
|
+
// v3
|
|
170
|
+
const workast = new Workast({ apiKey: process.env.WORKAST_API_KEY });
|
|
80
171
|
```
|
|
81
172
|
|
|
82
|
-
|
|
83
|
-
|
|
173
|
+
What shipped in each version is on [Releases](https://github.com/workast/sdk/releases).
|
|
174
|
+
|
|
175
|
+
## Contributing
|
|
176
|
+
|
|
177
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md). To report a vulnerability, see [SECURITY.md](SECURITY.md).
|
|
178
|
+
|
|
179
|
+
## License
|
|
180
|
+
|
|
181
|
+
MIT
|