@interop/was-client 0.2.0 → 0.4.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 +245 -40
- package/dist/Collection.d.ts +9 -3
- package/dist/Collection.d.ts.map +1 -1
- package/dist/Collection.js +12 -1
- package/dist/Collection.js.map +1 -1
- package/dist/Resource.d.ts +47 -1
- package/dist/Resource.d.ts.map +1 -1
- package/dist/Resource.js +71 -1
- package/dist/Resource.js.map +1 -1
- package/dist/Space.d.ts +25 -3
- package/dist/Space.d.ts.map +1 -1
- package/dist/Space.js +46 -3
- package/dist/Space.js.map +1 -1
- package/dist/WasClient.d.ts +30 -4
- package/dist/WasClient.d.ts.map +1 -1
- package/dist/WasClient.js +44 -4
- package/dist/WasClient.js.map +1 -1
- package/dist/errors.d.ts +34 -10
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +101 -3
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/paths.d.ts +13 -0
- package/dist/internal/paths.d.ts.map +1 -1
- package/dist/internal/paths.js +19 -0
- package/dist/internal/paths.js.map +1 -1
- package/dist/internal/request.d.ts +20 -0
- package/dist/internal/request.d.ts.map +1 -1
- package/dist/internal/request.js +41 -0
- package/dist/internal/request.js.map +1 -1
- package/dist/types.d.ts +11 -131
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
# Wallet Attached Storage Client _(@interop/was-client)_
|
|
2
2
|
|
|
3
|
+
[](https://github.com/interop-alliance/was-client/actions?query=workflow%3A%22CI%22)
|
|
3
4
|
[](https://npm.im/@interop/was-client)
|
|
4
5
|
|
|
5
6
|
> A developer-friendly client for Wallet Attached Storage (WAS) servers, with a
|
|
6
|
-
>
|
|
7
|
+
> database-driver-inspired navigational API over zcap-authorized HTTP.
|
|
7
8
|
|
|
8
9
|
## Table of Contents
|
|
9
10
|
|
|
10
11
|
- [Background](#background)
|
|
11
12
|
- [Install](#install)
|
|
12
13
|
- [Usage](#usage)
|
|
13
|
-
- [
|
|
14
|
+
- [Creating a client (signer + zcapClient)](#creating-a-client-signer--zcapclient)
|
|
14
15
|
- [The handle model](#the-handle-model)
|
|
16
|
+
- [Spaces](#spaces)
|
|
17
|
+
- [Collections](#collections)
|
|
15
18
|
- [Resources: JSON and binary](#resources-json-and-binary)
|
|
16
19
|
- [Delegation and sharing](#delegation-and-sharing)
|
|
20
|
+
- [Public sharing and access-control policies](#public-sharing-and-access-control-policies)
|
|
21
|
+
- [Resource metadata](#resource-metadata)
|
|
22
|
+
- [Storage introspection: backends and quotas](#storage-introspection-backends-and-quotas)
|
|
17
23
|
- [Export and import](#export-and-import)
|
|
18
24
|
- [The manual-request escape hatch](#the-manual-request-escape-hatch)
|
|
19
25
|
- [Errors and the 404/null caveat](#errors-and-the-404null-caveat)
|
|
@@ -22,23 +28,19 @@
|
|
|
22
28
|
|
|
23
29
|
## Background
|
|
24
30
|
|
|
25
|
-
The WAS protocol exposes a
|
|
31
|
+
The WAS protocol exposes a general purpose database-like container model --
|
|
26
32
|
`SpacesRepository > Space > Collection > Resource` -- over HTTP, authorized with
|
|
27
|
-
[Authorization Capabilities (zcaps)](https://w3c-ccg.github.io/zcap-spec/).
|
|
28
|
-
low-level transport is an
|
|
29
|
-
[`@interop/ezcap`](https://www.npmjs.com/package/@interop/ezcap) `ZcapClient`,
|
|
30
|
-
where every operation hand-builds a URL, picks a trailing-slash variant, threads
|
|
31
|
-
JSON vs binary bodies, and reasons about delegation inline.
|
|
33
|
+
[Authorization Capabilities (zcaps)](https://w3c-ccg.github.io/zcap-spec/).
|
|
32
34
|
|
|
33
35
|
`@interop/was-client` wraps that `ZcapClient` and exposes the containment model
|
|
34
|
-
through cheap, lazy navigational handles modeled on
|
|
36
|
+
through cheap, lazy navigational handles modeled on a document store's DX
|
|
35
37
|
(`client > db > collection`), using WAS-specific verbs
|
|
36
38
|
(`add`/`get`/`put`/`list`/`delete`) rather than `insertOne`/`findOne` (WAS has
|
|
37
39
|
no query-by-filter yet).
|
|
38
40
|
|
|
39
|
-
|
|
|
41
|
+
| Document db driver | WAS client |
|
|
40
42
|
| ----------------------------------- | ------------------------------------------ |
|
|
41
|
-
| `new
|
|
43
|
+
| `new Client(url)` | `new WasClient({ serverUrl, zcapClient })` |
|
|
42
44
|
| `client.db('app')` | `was.space(spaceId)` |
|
|
43
45
|
| `db.collection('users')` | `space.collection(collectionId)` |
|
|
44
46
|
| `collection.insertOne(doc)` | `collection.add(doc)` |
|
|
@@ -57,34 +59,86 @@ pnpm install @interop/was-client
|
|
|
57
59
|
|
|
58
60
|
## Usage
|
|
59
61
|
|
|
60
|
-
###
|
|
62
|
+
### Creating a client (signer + zcapClient)
|
|
63
|
+
|
|
64
|
+
A `WasClient` signs every request with a key you control. The key is held by an
|
|
65
|
+
ezcap `ZcapClient`, which you build from a `did:key` identity. You will need two
|
|
66
|
+
companion packages alongside this one (this library already depends on
|
|
67
|
+
`@interop/ed25519-signature`):
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
pnpm install @interop/ezcap @interop/did-method-key @interop/ed25519-verification-key
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The primary form wraps a `ZcapClient` you build yourself. The `did:key` driver
|
|
74
|
+
generates a key pair and a matching DID document, wiring the signer's
|
|
75
|
+
`id`/`controller` correctly:
|
|
61
76
|
|
|
62
77
|
```ts
|
|
78
|
+
import { ZcapClient } from '@interop/ezcap'
|
|
79
|
+
import * as didKey from '@interop/did-method-key'
|
|
80
|
+
import { Ed25519Signature2020 } from '@interop/ed25519-signature'
|
|
81
|
+
import { Ed25519VerificationKey } from '@interop/ed25519-verification-key'
|
|
63
82
|
import { WasClient } from '@interop/was-client'
|
|
64
83
|
|
|
65
|
-
//
|
|
66
|
-
const
|
|
84
|
+
// 1. Generate a did:key identity (didDocument + keyPairs).
|
|
85
|
+
const didKeyDriver = didKey.driver()
|
|
86
|
+
didKeyDriver.use({ keyPairClass: Ed25519VerificationKey })
|
|
87
|
+
const { didDocument, keyPairs } = await didKeyDriver.generate()
|
|
67
88
|
|
|
68
|
-
//
|
|
69
|
-
|
|
70
|
-
|
|
89
|
+
// 2. Build the ezcap ZcapClient (it holds the signer and signs every request).
|
|
90
|
+
const zcapClient = new ZcapClient({
|
|
91
|
+
didDocument,
|
|
92
|
+
keyPairs,
|
|
93
|
+
SuiteClass: Ed25519Signature2020
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
// 3. Wrap it.
|
|
97
|
+
const was = new WasClient({ serverUrl: 'https://was.example', zcapClient })
|
|
71
98
|
```
|
|
72
99
|
|
|
100
|
+
If you already have a single signer, `WasClient.fromSigner()` builds the
|
|
101
|
+
`ZcapClient` internally (using the `Ed25519Signature2020` suite). A signer is
|
|
102
|
+
any object with `{ id, sign() }`; here we get one from a generated key. The
|
|
103
|
+
signer's `id` must be a `did:key` so the server can resolve and verify it:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { Ed25519VerificationKey } from '@interop/ed25519-verification-key'
|
|
107
|
+
import { WasClient } from '@interop/was-client'
|
|
108
|
+
|
|
109
|
+
// Pass a 32-byte `seed` for a deterministic key, or omit it for a random one.
|
|
110
|
+
const keyPair = await Ed25519VerificationKey.generate({ seed })
|
|
111
|
+
keyPair.controller = `did:key:${keyPair.fingerprint()}`
|
|
112
|
+
keyPair.id = `${keyPair.controller}#${keyPair.fingerprint()}`
|
|
113
|
+
|
|
114
|
+
const was = WasClient.fromSigner({
|
|
115
|
+
serverUrl: 'https://was.example',
|
|
116
|
+
signer: keyPair.signer()
|
|
117
|
+
})
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
The `seed` is where a passphrase-, stored-secret-, or KMS-derived key plugs in:
|
|
121
|
+
deriving the same 32-byte seed yields the same DID, and therefore access to the
|
|
122
|
+
same spaces. (Apps with user accounts often derive the signer from a passphrase
|
|
123
|
+
via `CapabilityAgent.fromSecret()` from `@digitalbazaar/webkms-client` -- not
|
|
124
|
+
required, just a common alternative.)
|
|
125
|
+
|
|
73
126
|
`serverUrl` is the base for both URL building and zcap `invocationTarget`s, so
|
|
74
127
|
the "server URL must equal the invocation target host:port" constraint holds by
|
|
75
128
|
construction.
|
|
76
129
|
|
|
77
130
|
### The handle model
|
|
78
131
|
|
|
132
|
+
The client exposes the WAS containment model
|
|
133
|
+
(`SpacesRepository > Space > Collection > Resource`) as navigational handles.
|
|
79
134
|
Handles are lazy and synchronous to obtain -- only the verb methods hit the
|
|
80
135
|
network. Lazy chains never throw: `was.space(x).collection(y)` does no I/O and
|
|
81
136
|
just accumulates URL context. Existence is checked on the first network verb.
|
|
82
137
|
|
|
83
138
|
```ts
|
|
84
|
-
const space = await was.createSpace({ name: 'Home' })
|
|
139
|
+
const space = await was.createSpace({ name: 'Home' })
|
|
85
140
|
|
|
86
141
|
const collection = await space.createCollection({
|
|
87
|
-
id: 'credentials',
|
|
88
142
|
name: 'Verifiable Credentials'
|
|
89
143
|
})
|
|
90
144
|
|
|
@@ -94,18 +148,99 @@ await collection.put('vc-1', {
|
|
|
94
148
|
})
|
|
95
149
|
const vc = await collection.get('vc-1') // parsed JSON object, or null on a miss
|
|
96
150
|
|
|
97
|
-
const listing = await collection.list() // { id, url, totalItems, items, ... }
|
|
98
|
-
|
|
99
151
|
await collection.resource('vc-1').delete() // delete one resource by id
|
|
100
152
|
await space.delete() // delete the whole space (idempotent)
|
|
101
153
|
```
|
|
102
154
|
|
|
103
155
|
`delete()` is uniform at every level, takes no argument, and always deletes the
|
|
104
156
|
thing the handle points at -- so there is no "delete the collection" vs "delete
|
|
105
|
-
one item" footgun.
|
|
157
|
+
one item" footgun. The next sections cover each level in turn.
|
|
158
|
+
|
|
159
|
+
### Spaces
|
|
160
|
+
|
|
161
|
+
A Space is the top-level container, created from the spaces repository. The
|
|
162
|
+
server requires a `name`; `controller` defaults to the client's own DID, and the
|
|
163
|
+
server generates the id unless you pass one.
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
const space = await was.createSpace({ name: 'Home' }) // POST /spaces/
|
|
167
|
+
|
|
168
|
+
// Lazy handle to an existing space by id -- no I/O until a verb runs.
|
|
169
|
+
const same = was.space(space.id)
|
|
170
|
+
|
|
171
|
+
// Read the Space Description (null if missing or not visible to you).
|
|
172
|
+
const desc = await space.describe() // { id, type: ['Space'], name, controller } | null
|
|
173
|
+
|
|
174
|
+
// Upsert: merges the given fields over the current description.
|
|
175
|
+
await space.configure({ name: 'Home (renamed)' })
|
|
176
|
+
|
|
177
|
+
await space.delete() // idempotent
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Listing every space in the repository (`was.listSpaces()`) is specified but not
|
|
181
|
+
yet implemented by the reference server, so it currently throws
|
|
182
|
+
`NotImplementedError`. To enumerate what is _inside_ a space, use
|
|
183
|
+
`space.collections()` (below).
|
|
184
|
+
|
|
185
|
+
### Collections
|
|
186
|
+
|
|
187
|
+
A Collection lives inside a Space and holds resources. WAS does not auto-create
|
|
188
|
+
parents, so `createCollection` throws `NotFoundError` if the space does not
|
|
189
|
+
exist. The server generates the id unless you pass one (a handful of reserved
|
|
190
|
+
ids are rejected).
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
// Create.
|
|
194
|
+
const collection = await space.createCollection({
|
|
195
|
+
name: 'Verifiable Credentials'
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
// Lazy handle to an existing collection by id.
|
|
199
|
+
const same = space.collection(collection.id)
|
|
200
|
+
|
|
201
|
+
// Read the Collection Description (null if missing or not visible).
|
|
202
|
+
const desc = await collection.describe() // { id, type: ['Collection'], name } | null
|
|
203
|
+
|
|
204
|
+
// Update (upsert; merges over the current description).
|
|
205
|
+
await collection.configure({ name: 'Credentials' })
|
|
206
|
+
|
|
207
|
+
// List the collections in a space.
|
|
208
|
+
const collections = await space.collections()
|
|
209
|
+
// { url, totalItems, items: [{ id, name, url }, ...] } | null
|
|
210
|
+
|
|
211
|
+
// List the resources inside this collection.
|
|
212
|
+
const resources = await collection.list()
|
|
213
|
+
// { id, url, totalItems, items: [{ id, url, contentType }, ...], ... } | null
|
|
214
|
+
|
|
215
|
+
await collection.delete() // deletes the whole collection; idempotent
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
To delete a single resource instead of the whole collection, use
|
|
219
|
+
`collection.resource(id).delete()`.
|
|
106
220
|
|
|
107
221
|
### Resources: JSON and binary
|
|
108
222
|
|
|
223
|
+
A Resource is a JSON object or binary blob keyed by id within a Collection. Use
|
|
224
|
+
`add()` for a server-generated id or `put(id, ...)` to create-or-replace at a
|
|
225
|
+
known id (both throw `NotFoundError` if the parent collection is missing):
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
// Server-generated id; returns { id, url, contentType? }.
|
|
229
|
+
const added = await collection.add({
|
|
230
|
+
type: ['VerifiableCredential'],
|
|
231
|
+
name: 'Diploma'
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
// Create or replace at a known id (upsert).
|
|
235
|
+
await collection.put('vc-1', {
|
|
236
|
+
type: ['VerifiableCredential'],
|
|
237
|
+
name: 'Diploma'
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
const vc = await collection.get('vc-1') // parsed JSON object, or null on a miss
|
|
241
|
+
await collection.resource('vc-1').delete() // idempotent
|
|
242
|
+
```
|
|
243
|
+
|
|
109
244
|
Writes detect the payload: a plain object/array is sent as JSON; a
|
|
110
245
|
`Blob`/`Uint8Array`/`Buffer` is sent as binary, with the content-type taken from
|
|
111
246
|
`options.contentType`, the `Blob.type`, or `application/octet-stream`.
|
|
@@ -168,6 +303,7 @@ const link = added.url // hand this URL out; a plain GET resolves it
|
|
|
168
303
|
|
|
169
304
|
// Inspect or revoke.
|
|
170
305
|
const policy = await collection.getPolicy() // { type: 'PublicCanRead' } | null
|
|
306
|
+
const isPublic = await collection.isPublic() // true if its own policy is PublicCanRead
|
|
171
307
|
await collection.clearPolicy() // revert to capability-only access (idempotent)
|
|
172
308
|
|
|
173
309
|
// setPolicy() is the generic, forward-compatible primitive; setPublic() is sugar.
|
|
@@ -176,10 +312,71 @@ await resource.setPublic() // a single public resource
|
|
|
176
312
|
```
|
|
177
313
|
|
|
178
314
|
Policies are resolved most-specific-first (Resource over Collection over Space)
|
|
179
|
-
and are permissive-only -- they broaden access, never restrict a valid
|
|
180
|
-
holder. Managing a policy is a controller-level operation. Discover a
|
|
181
|
-
`space.linkset()` / `collection.linkset()` (RFC9264) or the `linkset`
|
|
182
|
-
a description.
|
|
315
|
+
and are permissive-only -- they broaden access, never restrict a valid
|
|
316
|
+
capability holder. Managing a policy is a controller-level operation. Discover a
|
|
317
|
+
policy via `space.linkset()` / `collection.linkset()` (RFC9264) or the `linkset`
|
|
318
|
+
property on a description.
|
|
319
|
+
|
|
320
|
+
`isPublic()` is a read-only convenience that returns `true` when the Space,
|
|
321
|
+
Collection, or Resource has a `{ type: 'PublicCanRead' }` policy -- that is,
|
|
322
|
+
when it has been made public via `setPublic()` (or an equivalent `setPolicy()`
|
|
323
|
+
call). It's meant to drive data-browser style UI, to show a "This
|
|
324
|
+
space(/collection/resource) has been shared publicly" type of icon.
|
|
325
|
+
|
|
326
|
+
#### Consuming public links (unauthenticated reads)
|
|
327
|
+
|
|
328
|
+
The flip side of `setPublic()`: reading a `PublicCanRead` resource or collection
|
|
329
|
+
with no authorization, by its URL. These use an unsigned plain `fetch` (no
|
|
330
|
+
capability invocation), so they work for a consumer who only holds the link.
|
|
331
|
+
|
|
332
|
+
```ts
|
|
333
|
+
// Fetch a single public resource (auto-parses JSON, returns binary as a Blob).
|
|
334
|
+
const doc = await was.publicRead({
|
|
335
|
+
resourceUrl: 'https://was.example/space/s/c/r'
|
|
336
|
+
}) // Json | Blob | null
|
|
337
|
+
|
|
338
|
+
// List a public collection -- e.g. a blog published as a public-read collection.
|
|
339
|
+
const listing = await was.publicListCollection({
|
|
340
|
+
collectionUrl: 'https://was.example/space/s/c'
|
|
341
|
+
}) // ResourceListing | null
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
Both follow the read-method 404/null caveat: a missing or non-public target
|
|
345
|
+
resolves to `null`.
|
|
346
|
+
|
|
347
|
+
### Resource metadata
|
|
348
|
+
|
|
349
|
+
Each Resource has a metadata object at its reserved `/meta` path: server-managed
|
|
350
|
+
properties (`contentType`, `size`, optional `createdAt` / `updatedAt`) plus a
|
|
351
|
+
user-writable `custom` object (`name` and `tags`).
|
|
352
|
+
|
|
353
|
+
```ts
|
|
354
|
+
const resource = collection.resource('vc-1')
|
|
355
|
+
|
|
356
|
+
const meta = await resource.meta() // ResourceMetadata | null (null on a miss)
|
|
357
|
+
|
|
358
|
+
// setMeta() is a full replacement of `custom`; omitted properties are cleared.
|
|
359
|
+
await resource.setMeta({ custom: { name: 'Diploma', tags: { year: '2026' } } })
|
|
360
|
+
|
|
361
|
+
// setName() / setTags() are read-modify-write sugar that preserve the other.
|
|
362
|
+
await resource.setName('Renamed diploma') // keeps existing tags
|
|
363
|
+
await resource.setTags({ status: 'verified' }) // keeps existing name
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
The `custom.name` is the same value surfaced as a resource's `name` in
|
|
367
|
+
collection listings; updating one updates the other.
|
|
368
|
+
|
|
369
|
+
### Storage introspection: backends and quotas
|
|
370
|
+
|
|
371
|
+
A Space can report the storage backends available to it and a per-backend usage
|
|
372
|
+
report. Both are optional server features (a server without them surfaces a
|
|
373
|
+
`NotImplementedError`); both follow the read-method 404/null caveat.
|
|
374
|
+
|
|
375
|
+
```ts
|
|
376
|
+
const backends = await space.backends() // BackendDescriptor[] | null
|
|
377
|
+
const report = await space.quotas() // SpaceQuotaReport | null
|
|
378
|
+
// report.backends[i]: { id, state, usageBytes, limit, restrictedActions, ... }
|
|
379
|
+
```
|
|
183
380
|
|
|
184
381
|
### Export and import
|
|
185
382
|
|
|
@@ -208,20 +405,28 @@ MongoDB's `findOne` semantics. **WAS returns 404 for both not-found and
|
|
|
208
405
|
unauthorized**, so `null` means "not visible to you" rather than strictly "does
|
|
209
406
|
not exist". Write/delete methods throw a typed error instead.
|
|
210
407
|
|
|
211
|
-
| Status | Read methods
|
|
212
|
-
| ------ |
|
|
213
|
-
| 404 | `null`
|
|
214
|
-
| 400 | `ValidationError`
|
|
215
|
-
| 401 | `AuthRequiredError`
|
|
216
|
-
|
|
|
217
|
-
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
`
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
408
|
+
| Status | Read methods | Write / delete methods |
|
|
409
|
+
| ------ | ---------------------- | ---------------------- |
|
|
410
|
+
| 404 | `null` | `NotFoundError` |
|
|
411
|
+
| 400 | `ValidationError` | `ValidationError` |
|
|
412
|
+
| 401 | `AuthRequiredError` | `AuthRequiredError` |
|
|
413
|
+
| 409 | `ConflictError` | `ConflictError` |
|
|
414
|
+
| 413 | `PayloadTooLargeError` | `PayloadTooLargeError` |
|
|
415
|
+
| 501 | `NotImplementedError` | `NotImplementedError` |
|
|
416
|
+
| 507 | `QuotaExceededError` | `QuotaExceededError` |
|
|
417
|
+
| 5xx | `WasServerError` | `WasServerError` |
|
|
418
|
+
|
|
419
|
+
All error classes extend `WasError` (carrying `status`, the problem-kind `type`
|
|
420
|
+
URI, `title`, `details`, and `requestUrl`). When the server sends a
|
|
421
|
+
`problem+json` `type` (the spec's Error Type Registry), `mapError()` dispatches
|
|
422
|
+
on that kind first and falls back to the HTTP status -- so, for example, a 409
|
|
423
|
+
`id-conflict` from `createSpace({ id })` is catchable as a `ConflictError`, and
|
|
424
|
+
a 507 `quota-exceeded` (a client-actionable storage-full condition, not a server
|
|
425
|
+
fault) as a `QuotaExceededError`. `delete()` additionally treats a 404 as
|
|
426
|
+
success, so it is idempotent.
|
|
427
|
+
|
|
428
|
+
Some spec endpoints (`listSpaces()`, ...) are not yet implemented by the
|
|
429
|
+
reference server and currently surface `NotImplementedError`.
|
|
225
430
|
|
|
226
431
|
## Contribute
|
|
227
432
|
|
package/dist/Collection.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ClientContext } from './internal/request.js';
|
|
2
2
|
import { Resource } from './Resource.js';
|
|
3
|
-
import type { AddResult, BackendReference, CollectionDescription, GrantOptions, HandleOptions, IDelegatedZcap, IZcap, Json, LinkSet, PolicyDocument,
|
|
3
|
+
import type { AddResult, BackendReference, CollectionDescription, GrantOptions, HandleOptions, IDelegatedZcap, IZcap, Json, LinkSet, PolicyDocument, CollectionResourcesList } from './types.js';
|
|
4
4
|
export declare class Collection {
|
|
5
5
|
readonly spaceId: string;
|
|
6
6
|
readonly id: string;
|
|
@@ -97,9 +97,9 @@ export declare class Collection {
|
|
|
97
97
|
* Lists the items in the collection. Returns `null` if the collection is
|
|
98
98
|
* missing or not visible to you (404 conflation caveat).
|
|
99
99
|
*
|
|
100
|
-
* @returns {Promise<
|
|
100
|
+
* @returns {Promise<CollectionResourcesList | null>}
|
|
101
101
|
*/
|
|
102
|
-
list(): Promise<
|
|
102
|
+
list(): Promise<CollectionResourcesList | null>;
|
|
103
103
|
/**
|
|
104
104
|
* Delegates access to this collection. Prefills the grant `target` with this
|
|
105
105
|
* collection's URL (and the bound `capability`, if any, for re-delegation).
|
|
@@ -124,6 +124,12 @@ export declare class Collection {
|
|
|
124
124
|
* @returns {Promise<void>}
|
|
125
125
|
*/
|
|
126
126
|
setPolicy(policy: PolicyDocument): Promise<void>;
|
|
127
|
+
/**
|
|
128
|
+
* Returns `true` when this collection's policy is `PublicCanRead`.
|
|
129
|
+
*
|
|
130
|
+
* @returns {Promise<boolean>}
|
|
131
|
+
*/
|
|
132
|
+
isPublic(): Promise<boolean>;
|
|
127
133
|
/**
|
|
128
134
|
* Makes the collection world-readable: every resource in it becomes readable
|
|
129
135
|
* without authorization (unless overridden by a more specific policy). Sugar
|
package/dist/Collection.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Collection.d.ts","sourceRoot":"","sources":["../src/Collection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Collection.d.ts","sourceRoot":"","sources":["../src/Collection.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAE1D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAChB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,KAAK,EACL,IAAI,EACJ,OAAO,EACP,cAAc,EACd,uBAAuB,EACxB,MAAM,YAAY,CAAA;AAEnB,qBAAa,UAAU;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IAEnB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAO;IAEpC;;;;;;;OAOG;gBACS,EACV,OAAO,EACP,OAAO,EACP,YAAY,EACZ,UAAU,EACX,EAAE;QACD,OAAO,EAAE,aAAa,CAAA;QACtB,OAAO,EAAE,MAAM,CAAA;QACf,YAAY,EAAE,MAAM,CAAA;QACpB,UAAU,CAAC,EAAE,KAAK,CAAA;KACnB;IAOD,OAAO,KAAK,KAAK,GAEhB;IAED,OAAO,KAAK,UAAU,GAErB;IAED;;;;;;OAMG;IACG,QAAQ,IAAI,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IAUvD;;;;;;;;OAQG;IACG,SAAS,CAAC,IAAI,EAAE;QACpB,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,OAAO,CAAC,EAAE,gBAAgB,CAAA;KAC3B,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAqBlC;;;;;OAKG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAS7B;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,QAAQ;IAUnE;;;;;;;;;OASG;IACG,GAAG,CACP,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,UAAU,EAC9B,OAAO,GAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAO,GACrC,OAAO,CAAC,SAAS,CAAC;IAgCrB;;;;;;;OAOG;IACG,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAU1D;;;;;;;;OAQG;IACG,GAAG,CACP,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,UAAU,EAC9B,OAAO,GAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAO,GACrC,OAAO,CAAC,IAAI,CAAC;IAIhB;;;;;OAKG;IACG,IAAI,IAAI,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC;IAUrD;;;;;;OAMG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC;IAU3D;;;;;;;OAOG;IACG,SAAS,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAUjD;;;;;OAKG;IACG,SAAS,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAStD;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAKlC;;;;;;OAMG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAIhC;;;;;OAKG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IASlC;;;;;OAKG;IACG,OAAO,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;CASzC"}
|
package/dist/Collection.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { collectionPath, collectionItems, collectionPolicy, collectionLinkset, resourcePath, toUrl } from './internal/paths.js';
|
|
10
10
|
import { prepareBody, parseResource } from './internal/content.js';
|
|
11
|
+
import { assertNotReserved } from './internal/reserved.js';
|
|
11
12
|
import { delegateGrant } from './internal/grant.js';
|
|
12
13
|
import { send } from './internal/request.js';
|
|
13
14
|
import { Resource } from './Resource.js';
|
|
@@ -62,6 +63,7 @@ export class Collection {
|
|
|
62
63
|
* @returns {Promise<CollectionDescription>}
|
|
63
64
|
*/
|
|
64
65
|
async configure(desc) {
|
|
66
|
+
assertNotReserved(this.id, 'collection');
|
|
65
67
|
const current = await this.describe();
|
|
66
68
|
const name = desc.name ?? current?.name;
|
|
67
69
|
const body = { id: this.id, name };
|
|
@@ -179,7 +181,7 @@ export class Collection {
|
|
|
179
181
|
* Lists the items in the collection. Returns `null` if the collection is
|
|
180
182
|
* missing or not visible to you (404 conflation caveat).
|
|
181
183
|
*
|
|
182
|
-
* @returns {Promise<
|
|
184
|
+
* @returns {Promise<CollectionResourcesList | null>}
|
|
183
185
|
*/
|
|
184
186
|
async list() {
|
|
185
187
|
const response = await send(this._context, {
|
|
@@ -236,6 +238,15 @@ export class Collection {
|
|
|
236
238
|
json: policy
|
|
237
239
|
});
|
|
238
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* Returns `true` when this collection's policy is `PublicCanRead`.
|
|
243
|
+
*
|
|
244
|
+
* @returns {Promise<boolean>}
|
|
245
|
+
*/
|
|
246
|
+
async isPublic() {
|
|
247
|
+
const policy = await this.getPolicy();
|
|
248
|
+
return policy?.type === 'PublicCanRead';
|
|
249
|
+
}
|
|
239
250
|
/**
|
|
240
251
|
* Makes the collection world-readable: every resource in it becomes readable
|
|
241
252
|
* without authorization (unless overridden by a more specific policy). Sugar
|
package/dist/Collection.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Collection.js","sourceRoot":"","sources":["../src/Collection.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"Collection.js","sourceRoot":"","sources":["../src/Collection.ts"],"names":[],"mappings":"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"}
|
package/dist/Resource.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ClientContext } from './internal/request.js';
|
|
2
|
-
import type { IZcap, Json, PolicyDocument } from './types.js';
|
|
2
|
+
import type { IZcap, Json, PolicyDocument, ResourceMetadata, ResourceMetadataCustom } from './types.js';
|
|
3
3
|
export declare class Resource {
|
|
4
4
|
readonly spaceId: string;
|
|
5
5
|
readonly collectionId: string;
|
|
@@ -63,6 +63,46 @@ export declare class Resource {
|
|
|
63
63
|
* @returns {Promise<void>}
|
|
64
64
|
*/
|
|
65
65
|
delete(): Promise<void>;
|
|
66
|
+
private get _metaPath();
|
|
67
|
+
/**
|
|
68
|
+
* Reads the resource's metadata object (server-managed `contentType` / `size`
|
|
69
|
+
* / timestamps plus the user-writable `custom` object). Returns `null` if the
|
|
70
|
+
* resource is missing or not visible to you (404 conflation caveat). A server
|
|
71
|
+
* without metadata support surfaces its 501 as `NotImplementedError`.
|
|
72
|
+
*
|
|
73
|
+
* @returns {Promise<ResourceMetadata | null>}
|
|
74
|
+
*/
|
|
75
|
+
meta(): Promise<ResourceMetadata | null>;
|
|
76
|
+
/**
|
|
77
|
+
* Replaces the resource's user-writable metadata (`custom`). This is a full
|
|
78
|
+
* replacement: any property omitted from `custom` is cleared, and an omitted
|
|
79
|
+
* `custom` clears them all. Does not create the resource -- a `PUT` to the
|
|
80
|
+
* metadata of a nonexistent resource throws `NotFoundError`. Servers without
|
|
81
|
+
* metadata support surface their 501 as `NotImplementedError`.
|
|
82
|
+
*
|
|
83
|
+
* @param meta {object}
|
|
84
|
+
* @param [meta.custom] {ResourceMetadataCustom} the user-writable properties
|
|
85
|
+
* @returns {Promise<void>}
|
|
86
|
+
*/
|
|
87
|
+
setMeta(meta?: {
|
|
88
|
+
custom?: ResourceMetadataCustom;
|
|
89
|
+
}): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Sets the resource's human-readable `name` (the value surfaced in collection
|
|
92
|
+
* listings), preserving any existing `tags`. Convenience over `setMeta()`.
|
|
93
|
+
*
|
|
94
|
+
* @param name {string}
|
|
95
|
+
* @returns {Promise<void>}
|
|
96
|
+
*/
|
|
97
|
+
setName(name: string): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Sets the resource's `tags`, preserving any existing `name`. Convenience over
|
|
100
|
+
* `setMeta()`.
|
|
101
|
+
*
|
|
102
|
+
* @param tags {Record<string, string>}
|
|
103
|
+
* @returns {Promise<void>}
|
|
104
|
+
*/
|
|
105
|
+
setTags(tags: Record<string, string>): Promise<void>;
|
|
66
106
|
private get _policyPath();
|
|
67
107
|
/**
|
|
68
108
|
* Reads the resource's access-control policy. Returns `null` when no policy is
|
|
@@ -86,6 +126,12 @@ export declare class Resource {
|
|
|
86
126
|
* @returns {Promise<void>}
|
|
87
127
|
*/
|
|
88
128
|
setPublic(): Promise<void>;
|
|
129
|
+
/**
|
|
130
|
+
* Returns `true` when this resource policy is `PublicCanRead`.
|
|
131
|
+
*
|
|
132
|
+
* @returns {Promise<boolean>}
|
|
133
|
+
*/
|
|
134
|
+
isPublic(): Promise<boolean>;
|
|
89
135
|
/**
|
|
90
136
|
* Removes the resource's access-control policy, reverting it to
|
|
91
137
|
* capability-only access. Idempotent.
|
package/dist/Resource.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Resource.d.ts","sourceRoot":"","sources":["../src/Resource.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAE1D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"Resource.d.ts","sourceRoot":"","sources":["../src/Resource.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAE1D,OAAO,KAAK,EACV,KAAK,EACL,IAAI,EACJ,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,YAAY,CAAA;AAEnB,qBAAa,QAAQ;IACnB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IAEnB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAO;IAEpC;;;;;;;OAOG;gBACS,EACV,OAAO,EACP,OAAO,EACP,YAAY,EACZ,UAAU,EACV,UAAU,EACX,EAAE;QACD,OAAO,EAAE,aAAa,CAAA;QACtB,OAAO,EAAE,MAAM,CAAA;QACf,YAAY,EAAE,MAAM,CAAA;QACpB,UAAU,EAAE,MAAM,CAAA;QAClB,UAAU,CAAC,EAAE,KAAK,CAAA;KACnB;IAQD,OAAO,KAAK,KAAK,GAEhB;IAED;;;;;;OAMG;IACG,GAAG,IAAI,OAAO,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAUxC;;;;;OAKG;IACG,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAUvC;;;;;OAKG;IACG,QAAQ,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAa5C;;;;;;;;;OASG;IACG,GAAG,CACP,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,UAAU,EAC9B,OAAO,GAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAO,GACrC,OAAO,CAAC,IAAI,CAAC;IAehB;;;;OAIG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAS7B,OAAO,KAAK,SAAS,GAEpB;IAED;;;;;;;OAOG;IACG,IAAI,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAU9C;;;;;;;;;;OAUG;IACG,OAAO,CAAC,IAAI,GAAE;QAAE,MAAM,CAAC,EAAE,sBAAsB,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAS5E;;;;;;OAMG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK1C;;;;;;OAMG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAK1D,OAAO,KAAK,WAAW,GAEtB;IAED;;;;;;OAMG;IACG,SAAS,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAUjD;;;;;OAKG;IACG,SAAS,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAStD;;;;;OAKG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAIhC;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAKlC;;;;;OAKG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;CAQnC"}
|
package/dist/Resource.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* keyed by id within a Collection). Sugar over the Collection item operations,
|
|
7
7
|
* with explicit `getText()` / `getBytes()` escape hatches.
|
|
8
8
|
*/
|
|
9
|
-
import { resourcePath, resourcePolicy } from './internal/paths.js';
|
|
9
|
+
import { resourcePath, resourcePolicy, resourceMeta } from './internal/paths.js';
|
|
10
10
|
import { prepareBody, parseResource } from './internal/content.js';
|
|
11
11
|
import { assertNotReserved } from './internal/reserved.js';
|
|
12
12
|
import { send } from './internal/request.js';
|
|
@@ -120,6 +120,67 @@ export class Resource {
|
|
|
120
120
|
idempotent: true
|
|
121
121
|
});
|
|
122
122
|
}
|
|
123
|
+
get _metaPath() {
|
|
124
|
+
return resourceMeta(this.spaceId, this.collectionId, this.id);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Reads the resource's metadata object (server-managed `contentType` / `size`
|
|
128
|
+
* / timestamps plus the user-writable `custom` object). Returns `null` if the
|
|
129
|
+
* resource is missing or not visible to you (404 conflation caveat). A server
|
|
130
|
+
* without metadata support surfaces its 501 as `NotImplementedError`.
|
|
131
|
+
*
|
|
132
|
+
* @returns {Promise<ResourceMetadata | null>}
|
|
133
|
+
*/
|
|
134
|
+
async meta() {
|
|
135
|
+
const response = await send(this._context, {
|
|
136
|
+
path: this._metaPath,
|
|
137
|
+
method: 'GET',
|
|
138
|
+
capability: this._capability,
|
|
139
|
+
read: true
|
|
140
|
+
});
|
|
141
|
+
return response === null ? null : response.data;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Replaces the resource's user-writable metadata (`custom`). This is a full
|
|
145
|
+
* replacement: any property omitted from `custom` is cleared, and an omitted
|
|
146
|
+
* `custom` clears them all. Does not create the resource -- a `PUT` to the
|
|
147
|
+
* metadata of a nonexistent resource throws `NotFoundError`. Servers without
|
|
148
|
+
* metadata support surface their 501 as `NotImplementedError`.
|
|
149
|
+
*
|
|
150
|
+
* @param meta {object}
|
|
151
|
+
* @param [meta.custom] {ResourceMetadataCustom} the user-writable properties
|
|
152
|
+
* @returns {Promise<void>}
|
|
153
|
+
*/
|
|
154
|
+
async setMeta(meta = {}) {
|
|
155
|
+
await send(this._context, {
|
|
156
|
+
path: this._metaPath,
|
|
157
|
+
method: 'PUT',
|
|
158
|
+
capability: this._capability,
|
|
159
|
+
json: { custom: meta.custom ?? {} }
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Sets the resource's human-readable `name` (the value surfaced in collection
|
|
164
|
+
* listings), preserving any existing `tags`. Convenience over `setMeta()`.
|
|
165
|
+
*
|
|
166
|
+
* @param name {string}
|
|
167
|
+
* @returns {Promise<void>}
|
|
168
|
+
*/
|
|
169
|
+
async setName(name) {
|
|
170
|
+
const current = await this.meta();
|
|
171
|
+
await this.setMeta({ custom: { ...current?.custom, name } });
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Sets the resource's `tags`, preserving any existing `name`. Convenience over
|
|
175
|
+
* `setMeta()`.
|
|
176
|
+
*
|
|
177
|
+
* @param tags {Record<string, string>}
|
|
178
|
+
* @returns {Promise<void>}
|
|
179
|
+
*/
|
|
180
|
+
async setTags(tags) {
|
|
181
|
+
const current = await this.meta();
|
|
182
|
+
await this.setMeta({ custom: { ...current?.custom, tags } });
|
|
183
|
+
}
|
|
123
184
|
get _policyPath() {
|
|
124
185
|
return resourcePolicy(this.spaceId, this.collectionId, this.id);
|
|
125
186
|
}
|
|
@@ -162,6 +223,15 @@ export class Resource {
|
|
|
162
223
|
async setPublic() {
|
|
163
224
|
await this.setPolicy({ type: 'PublicCanRead' });
|
|
164
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Returns `true` when this resource policy is `PublicCanRead`.
|
|
228
|
+
*
|
|
229
|
+
* @returns {Promise<boolean>}
|
|
230
|
+
*/
|
|
231
|
+
async isPublic() {
|
|
232
|
+
const policy = await this.getPolicy();
|
|
233
|
+
return policy?.type === 'PublicCanRead';
|
|
234
|
+
}
|
|
165
235
|
/**
|
|
166
236
|
* Removes the resource's access-control policy, reverting it to
|
|
167
237
|
* capability-only access. Idempotent.
|