@truenas/api-client 1.0.13 → 2.0.1
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 +87 -0
- package/dist/index.cjs +306 -210
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12218 -13575
- package/dist/index.d.ts +12218 -13575
- package/dist/index.js +306 -211
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,6 +11,93 @@ Framework-agnostic TypeScript client for the TrueNAS JSON-RPC 2.0 WebSocket API.
|
|
|
11
11
|
implementation (e.g. the [`ws`](https://www.npmjs.com/package/ws) package) via the socket config.
|
|
12
12
|
- **`rxjs` ^7.8** is a peer dependency — the consuming project provides it.
|
|
13
13
|
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
import { createTrueNasClient } from '@truenas/api-client';
|
|
18
|
+
|
|
19
|
+
const client = await createTrueNasClient({
|
|
20
|
+
uuid: 'system-uuid',
|
|
21
|
+
hostnames: ['truenas.local'],
|
|
22
|
+
enabled: true,
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`createTrueNasClient` does not take credentials, so log in before calling
|
|
27
|
+
anything — middleware refuses an unauthenticated call, and `authenticated$`
|
|
28
|
+
only turns true once one of these resolves:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
await firstValueFrom(
|
|
32
|
+
client.authenticator.loginWithApiKey({ username, key })
|
|
33
|
+
);
|
|
34
|
+
// or client.authenticator.loginWithUserPass(username, password)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Everything below hangs off `client.api`, and every method name it accepts comes
|
|
38
|
+
from types generated from `middlewared --dump-api`. A name the declared version
|
|
39
|
+
does not have is a compile error, and params and responses come from the same
|
|
40
|
+
source — there is no list of endpoint constants to import.
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
client.api.call('system.info'); // SystemInfoResult
|
|
44
|
+
client.api.call('alert.dismiss', ['uuid-1']); // params required
|
|
45
|
+
client.api.call('nope.nope'); // ✗ compile error
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Queries.** Middleware's `.query` methods are polymorphic in their options —
|
|
49
|
+
the same endpoint returns a list, one entry, or a count. Which you get is
|
|
50
|
+
chosen by the verb, so there is nothing to narrow:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
client.api.query('user.query', [['uid', '>', 1000]]); // UserEntry[]
|
|
54
|
+
client.api.queryOne('user.query', [['id', '=', 1]]); // UserEntry
|
|
55
|
+
client.api.queryCount('user.query'); // number
|
|
56
|
+
|
|
57
|
+
client.api.query('user.query', [], { select: ['id', 'username'] });
|
|
58
|
+
// Pick<UserEntry, 'id' | 'username'>[]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Use `satisfies` rather than an annotation when building options into a
|
|
62
|
+
variable — an annotated `QueryListOptions<E>` widens `select`, and the result
|
|
63
|
+
degrades to `Partial<E>[]`.
|
|
64
|
+
|
|
65
|
+
**Jobs.** A separate key space from `call`: `app.start` runs as a job and does
|
|
66
|
+
not appear in the call directory. `job` starts one and follows it to
|
|
67
|
+
completion, typing the result from the job directory:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
client.api.job('pool.dataset.export_key', ['tank/enc'])
|
|
71
|
+
.subscribe(job => report(job.progress.percent)); // Job<string | null>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Events.** Emits the change as a union discriminated on `msg`. Narrowing is
|
|
75
|
+
load-bearing: a removal carries an `id` and no `fields` in almost every
|
|
76
|
+
collection.
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
client.api.events('app.query').subscribe(event => {
|
|
80
|
+
if (event.msg === 'removed') return drop(event.id);
|
|
81
|
+
render(event.fields);
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Naming a version
|
|
86
|
+
|
|
87
|
+
The version is discovered at runtime; the types are fixed at compile time.
|
|
88
|
+
`createTrueNasClient` defaults to the oldest supported version, which
|
|
89
|
+
understates a newer server rather than promising methods it lacks. Name a
|
|
90
|
+
version to reach the rest:
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
const client = await createTrueNasClient<ApiDirectoryV26_0_0>(opts);
|
|
94
|
+
client.api.query('container.query'); // v26-only, reachable
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
That is a claim about the server, not a guarantee — the client you get is
|
|
98
|
+
whichever version discovery found. Operations that must work across versions
|
|
99
|
+
belong on `client.ops`, which resolves them at runtime.
|
|
100
|
+
|
|
14
101
|
## Documentation
|
|
15
102
|
|
|
16
103
|
The API reference is generated from the TSDoc comments in the source with
|