@interop/was-client 0.59.1 → 0.61.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 +66 -45
- package/dist/Collection.d.ts +140 -96
- package/dist/Collection.d.ts.map +1 -1
- package/dist/Collection.js +648 -194
- package/dist/Collection.js.map +1 -1
- package/dist/Resource.d.ts +1 -1
- package/dist/Resource.d.ts.map +1 -1
- package/dist/Resource.js +0 -3
- package/dist/Resource.js.map +1 -1
- package/dist/Space.d.ts +17 -16
- package/dist/Space.d.ts.map +1 -1
- package/dist/Space.js +41 -24
- package/dist/Space.js.map +1 -1
- package/dist/WasClient.d.ts.map +1 -1
- package/dist/WasClient.js +9 -3
- package/dist/WasClient.js.map +1 -1
- package/dist/codec.d.ts +3 -3
- package/dist/edv/EdvCodec.d.ts.map +1 -1
- package/dist/edv/EdvCodec.js +22 -46
- package/dist/edv/EdvCodec.js.map +1 -1
- package/dist/edv/descriptorStore.d.ts +16 -14
- package/dist/edv/descriptorStore.d.ts.map +1 -1
- package/dist/edv/descriptorStore.js +17 -14
- package/dist/edv/descriptorStore.js.map +1 -1
- package/dist/edv/didKeyRecipient.d.ts +6 -1
- package/dist/edv/didKeyRecipient.d.ts.map +1 -1
- package/dist/edv/didKeyRecipient.js +4 -0
- package/dist/edv/didKeyRecipient.js.map +1 -1
- package/dist/edv/epochKeys.d.ts +43 -3
- package/dist/edv/epochKeys.d.ts.map +1 -1
- package/dist/edv/epochKeys.js +90 -9
- package/dist/edv/epochKeys.js.map +1 -1
- package/dist/edv/epochRoster.d.ts +36 -26
- package/dist/edv/epochRoster.d.ts.map +1 -1
- package/dist/edv/epochRoster.js +61 -10
- package/dist/edv/epochRoster.js.map +1 -1
- package/dist/edv/hmacKey.d.ts +17 -5
- package/dist/edv/hmacKey.d.ts.map +1 -1
- package/dist/edv/hmacKey.js +19 -5
- package/dist/edv/hmacKey.js.map +1 -1
- package/dist/edv/index.d.ts +1 -1
- package/dist/edv/index.js +1 -1
- package/dist/edv/logGovernedDescriptorStore.d.ts +2 -2
- package/dist/edv/logGovernedDescriptorStore.d.ts.map +1 -1
- package/dist/edv/logGovernedDescriptorStore.js +10 -9
- package/dist/edv/logGovernedDescriptorStore.js.map +1 -1
- package/dist/edv/recipients.d.ts +1 -1
- package/dist/edv/recipients.d.ts.map +1 -1
- package/dist/edv/recipients.js +12 -4
- package/dist/edv/recipients.js.map +1 -1
- package/dist/edv/refresh.d.ts +6 -1
- package/dist/edv/refresh.d.ts.map +1 -1
- package/dist/edv/refresh.js +19 -2
- package/dist/edv/refresh.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.js +3 -3
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/internal/cas.d.ts.map +1 -1
- package/dist/internal/cas.js +7 -4
- package/dist/internal/cas.js.map +1 -1
- package/dist/internal/codec.d.ts +22 -1
- package/dist/internal/codec.d.ts.map +1 -1
- package/dist/internal/codec.js +117 -46
- package/dist/internal/codec.js.map +1 -1
- package/dist/internal/content.d.ts.map +1 -1
- package/dist/internal/content.js +12 -1
- package/dist/internal/content.js.map +1 -1
- package/dist/internal/describe.d.ts +98 -24
- package/dist/internal/describe.d.ts.map +1 -1
- package/dist/internal/describe.js +125 -18
- package/dist/internal/describe.js.map +1 -1
- package/dist/internal/meta.d.ts +32 -17
- package/dist/internal/meta.d.ts.map +1 -1
- package/dist/internal/meta.js +64 -35
- package/dist/internal/meta.js.map +1 -1
- package/dist/internal/paths.d.ts +33 -17
- package/dist/internal/paths.d.ts.map +1 -1
- package/dist/internal/paths.js +92 -40
- package/dist/internal/paths.js.map +1 -1
- package/dist/internal/reserved.d.ts +14 -0
- package/dist/internal/reserved.d.ts.map +1 -1
- package/dist/internal/reserved.js +23 -4
- package/dist/internal/reserved.js.map +1 -1
- package/dist/internal/write.js +30 -1
- package/dist/internal/write.js.map +1 -1
- package/dist/paths.d.ts +8 -5
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +8 -5
- package/dist/paths.js.map +1 -1
- package/dist/sync/port.d.ts.map +1 -1
- package/dist/sync/port.js +14 -1
- package/dist/sync/port.js.map +1 -1
- package/dist/sync/provisioning.d.ts +7 -7
- package/dist/sync/provisioning.d.ts.map +1 -1
- package/dist/sync/provisioning.js +27 -15
- package/dist/sync/provisioning.js.map +1 -1
- package/dist/types.d.ts +16 -9
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/internal/meta.js
CHANGED
|
@@ -2,13 +2,18 @@
|
|
|
2
2
|
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
* Shared
|
|
6
|
-
*
|
|
7
|
-
* the
|
|
8
|
-
*
|
|
9
|
-
*
|
|
5
|
+
* Shared `meta` I/O for the Collection and Resource handles. `readMeta` serves
|
|
6
|
+
* both: the two read the same metadata document shape and differ only in the
|
|
7
|
+
* metadata type and the slot the `custom` envelope is bound to.
|
|
8
|
+
*
|
|
9
|
+
* `writeMeta` is the Resource side alone. A Collection's `meta` write is a full
|
|
10
|
+
* replacement of the merged Collection Metadata object -- configuration
|
|
11
|
+
* members included -- so it is composed against a fresh read of that object in
|
|
12
|
+
* `Collection`, and `patchCustom` below drives both handles' read-modify-write
|
|
13
|
+
* helpers through a bounded compare-and-swap.
|
|
10
14
|
*/
|
|
11
15
|
import { WasServerError } from '../errors.js';
|
|
16
|
+
import { compareAndSwap } from './cas.js';
|
|
12
17
|
import { send } from './request.js';
|
|
13
18
|
import { readEtag, writeHeaders } from './conditional.js';
|
|
14
19
|
import { withCodec } from './withCodec.js';
|
|
@@ -27,9 +32,13 @@ import { withCodec } from './withCodec.js';
|
|
|
27
32
|
* @param options.slot {MetaReadSlot} the `/meta` slot being read, for an
|
|
28
33
|
* encrypting codec's envelope-binding check
|
|
29
34
|
* @param [options.capability] {IZcap}
|
|
35
|
+
* @param [options.onStored] {function} receives the document as served, with
|
|
36
|
+
* its validator and its `custom` still undecoded, before the decode -- so a
|
|
37
|
+
* caller whose next step is a full-replacement write of the same document
|
|
38
|
+
* can compose that write against the read it just paid for
|
|
30
39
|
* @returns {Promise<(Metadata & { etag?: string }) | null>}
|
|
31
40
|
*/
|
|
32
|
-
export async function readMeta(context, { metaPath, codec: codecPromise, subject, slot, capability }) {
|
|
41
|
+
export async function readMeta(context, { metaPath, codec: codecPromise, subject, slot, capability, onStored }) {
|
|
33
42
|
// The metadata GET does not depend on the codec (only its `custom` decode
|
|
34
43
|
// below does), so the two overlap.
|
|
35
44
|
const [codec, response] = await withCodec(codecPromise, send(context, {
|
|
@@ -54,54 +63,49 @@ export async function readMeta(context, { metaPath, codec: codecPromise, subject
|
|
|
54
63
|
`"${response.headers.get('content-type') ?? 'unknown'}").`);
|
|
55
64
|
}
|
|
56
65
|
const metadata = response.data;
|
|
66
|
+
const etagBeforeDecode = readEtag(response);
|
|
67
|
+
onStored?.({
|
|
68
|
+
metadata: metadata,
|
|
69
|
+
...(etagBeforeDecode !== undefined && { etag: etagBeforeDecode })
|
|
70
|
+
});
|
|
57
71
|
// Decode the user-writable `custom` (decrypting it on an encrypted
|
|
58
72
|
// collection) so callers uniformly see plaintext `{ name, tags }`. The
|
|
59
73
|
// stated slot drives the encrypting codec's binding check: in the
|
|
60
74
|
// Collection slot it refuses a resource-bound envelope served there.
|
|
61
75
|
const custom = await codec.decodeMeta({ custom: metadata.custom }, slot);
|
|
62
76
|
const decoded = { ...metadata, custom };
|
|
63
|
-
|
|
64
|
-
|
|
77
|
+
return etagBeforeDecode !== undefined
|
|
78
|
+
? { ...decoded, etag: etagBeforeDecode }
|
|
79
|
+
: decoded;
|
|
65
80
|
}
|
|
66
81
|
/**
|
|
67
|
-
* Replaces a metadata document's user-writable `custom`, encoding it
|
|
68
|
-
* the codec first (which seals it into an opaque envelope on an
|
|
69
|
-
* collection).
|
|
82
|
+
* Replaces a Resource metadata document's user-writable `custom`, encoding it
|
|
83
|
+
* through the codec first (which seals it into an opaque envelope on an
|
|
84
|
+
* encrypted collection). A key epoch the codec surfaces is deliberately
|
|
85
|
+
* dropped: a Resource's epoch stamps its *content* write through the
|
|
86
|
+
* `Key-Epoch` header, not its metadata.
|
|
70
87
|
*
|
|
71
88
|
* @param context {ClientContext}
|
|
72
89
|
* @param options {object}
|
|
73
|
-
* @param options.metaPath {string} the
|
|
90
|
+
* @param options.metaPath {string} the `meta` sub-resource path
|
|
74
91
|
* @param options.codec {Promise<ResourceCodec>} the resolving codec
|
|
75
92
|
* @param options.custom {ResourceMetadataCustomInput} the user-writable
|
|
76
93
|
* properties, as a full replacement
|
|
77
|
-
* @param options.
|
|
78
|
-
* a top-level member of this PUT body. True at Collection level, where the
|
|
79
|
-
* stamp describes the `custom` envelope itself; false at Resource level,
|
|
80
|
-
* where a Resource's epoch instead stamps its content write via the
|
|
81
|
-
* `Key-Epoch` header, so an epoch surfaced here is deliberately dropped.
|
|
82
|
-
* @param options.slot {MetaWriteSlot} the `/meta` slot being written, which
|
|
94
|
+
* @param options.slot {MetaWriteSlot} the `meta` slot being written, which
|
|
83
95
|
* an encrypting codec binds into the envelope
|
|
84
|
-
* @param [options.ifMatch] {string} update only if the
|
|
96
|
+
* @param [options.ifMatch] {string} update only if the `meta` ETag matches
|
|
85
97
|
* @param [options.ifNoneMatch] {boolean} write only if no metadata is set
|
|
86
98
|
* @param [options.capability] {IZcap}
|
|
87
99
|
* @returns {Promise<{ etag?: string }>} the metadata's new ETag
|
|
88
100
|
*/
|
|
89
|
-
export async function writeMeta(context, { metaPath, codec: codecPromise, custom,
|
|
101
|
+
export async function writeMeta(context, { metaPath, codec: codecPromise, custom, slot, ifMatch, ifNoneMatch, capability }) {
|
|
90
102
|
const codec = await codecPromise;
|
|
91
|
-
const { custom: encoded
|
|
103
|
+
const { custom: encoded } = await codec.encodeMeta({ custom, slot });
|
|
92
104
|
const response = await send(context, {
|
|
93
105
|
path: metaPath,
|
|
94
106
|
method: 'PUT',
|
|
95
107
|
capability,
|
|
96
|
-
|
|
97
|
-
// the header channel stamps a Resource's *content* write, while the
|
|
98
|
-
// Collection metadata stamp describes the `custom` envelope itself and is
|
|
99
|
-
// a top-level member of this PUT body. The server clears the stored stamp
|
|
100
|
-
// when the member is omitted -- which is exactly right on a plaintext
|
|
101
|
-
// collection, whose codec surfaces no epoch.
|
|
102
|
-
json: sendEpoch && epoch !== undefined
|
|
103
|
-
? { custom: encoded, epoch }
|
|
104
|
-
: { custom: encoded },
|
|
108
|
+
json: { custom: encoded },
|
|
105
109
|
headers: writeHeaders({ precondition: { ifMatch, ifNoneMatch } })
|
|
106
110
|
});
|
|
107
111
|
return { etag: readEtag(response) };
|
|
@@ -110,16 +114,41 @@ export async function writeMeta(context, { metaPath, codec: codecPromise, custom
|
|
|
110
114
|
* The shared read-then-CAS body of the handles' `setName` / `setTags`: reads
|
|
111
115
|
* the current metadata, merges `patch` over its `custom`, and writes it back
|
|
112
116
|
* pinned to the read's `etag` (when the backend supports `conditional-writes`),
|
|
113
|
-
* so a concurrent metadata write
|
|
114
|
-
*
|
|
117
|
+
* so a concurrent metadata write is rebased on rather than silently erased by
|
|
118
|
+
* the full-replacement write.
|
|
119
|
+
*
|
|
120
|
+
* A lost race (`412`) re-reads and re-applies the patch, up to the shared
|
|
121
|
+
* compare-and-swap attempt limit. A handle whose metadata cannot be read at
|
|
122
|
+
* all patches nothing onto an empty object: the write it drives is the one
|
|
123
|
+
* that refuses (`Collection.setMeta` throws `NotFoundError`), so a masked 404
|
|
124
|
+
* cannot turn a rename into a create. At Collection level that is not a rare event:
|
|
125
|
+
* one `metaVersion` covers the configuration members and the annotations
|
|
126
|
+
* alike, so a concurrent `configure` -- or an epoch rotation -- legitimately
|
|
127
|
+
* invalidates an in-flight annotation write.
|
|
115
128
|
*
|
|
116
129
|
* @param handle {object} the Collection or Resource handle to patch
|
|
117
130
|
* @param patch {ResourceMetadataCustom} the properties to merge over the
|
|
118
131
|
* current `custom`
|
|
132
|
+
* @param operation {string} what the caller is doing, for the exhaustion
|
|
133
|
+
* error (e.g. `Metadata update`)
|
|
119
134
|
* @returns {Promise<void>}
|
|
120
135
|
*/
|
|
121
|
-
export async function patchCustom(handle, patch) {
|
|
122
|
-
|
|
123
|
-
|
|
136
|
+
export async function patchCustom(handle, patch, operation = 'Metadata update') {
|
|
137
|
+
await compareAndSwap({
|
|
138
|
+
store: {
|
|
139
|
+
read: async () => {
|
|
140
|
+
const current = await handle.meta();
|
|
141
|
+
return {
|
|
142
|
+
value: current?.custom ?? {},
|
|
143
|
+
...(current?.etag !== undefined && { etag: current.etag })
|
|
144
|
+
};
|
|
145
|
+
},
|
|
146
|
+
replace: async (custom, { ifMatch }) => {
|
|
147
|
+
await handle.setMeta({ custom }, { ifMatch });
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
operation,
|
|
151
|
+
mutate: custom => ({ ...custom, ...patch })
|
|
152
|
+
});
|
|
124
153
|
}
|
|
125
154
|
//# sourceMappingURL=meta.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../../src/internal/meta.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../../src/internal/meta.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;GAUG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAGzC,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAO1C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAG5B,OAAsB,EACtB,EACE,QAAQ,EACR,KAAK,EAAE,YAAY,EACnB,OAAO,EACP,IAAI,EACJ,UAAU,EACV,QAAQ,EAWT;IAED,0EAA0E;IAC1E,mCAAmC;IACnC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,MAAM,SAAS,CACvC,YAAY,EACZ,IAAI,CAAC,OAAO,EAAE;QACZ,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,KAAK;QACb,UAAU;QACV,IAAI,EAAE,IAAI;KACX,CAAC,CACH,CAAA;IACD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAChC,yEAAyE;QACzE,uEAAuE;QACvE,yEAAyE;QACzE,+DAA+D;QAC/D,wEAAwE;QACxE,2EAA2E;QAC3E,6DAA6D;QAC7D,MAAM,IAAI,cAAc,CACtB,yBAAyB,OAAO,wBAAwB;YACtD,gBAAgB;YAChB,IAAI,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,SAAS,KAAK,CAC7D,CAAA;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAgB,CAAA;IAC1C,MAAM,gBAAgB,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAA;IAC3C,QAAQ,EAAE,CAAC;QACT,QAAQ,EAAE,QAAmC;QAC7C,GAAG,CAAC,gBAAgB,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;KAClE,CAAC,CAAA;IACF,mEAAmE;IACnE,uEAAuE;IACvE,kEAAkE;IAClE,qEAAqE;IACrE,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAA;IACxE,MAAM,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,CAAA;IACvC,OAAO,gBAAgB,KAAK,SAAS;QACnC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE;QACxC,CAAC,CAAC,OAAO,CAAA;AACb,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,OAAsB,EACtB,EACE,QAAQ,EACR,KAAK,EAAE,YAAY,EACnB,MAAM,EACN,IAAI,EACJ,OAAO,EACP,WAAW,EACX,UAAU,EASX;IAED,MAAM,KAAK,GAAG,MAAM,YAAY,CAAA;IAChC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;IACpE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE;QACnC,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,KAAK;QACb,UAAU;QACV,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE;QACzB,OAAO,EAAE,YAAY,CAAC,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;KAClE,CAAC,CAAA;IACF,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAA;AACrC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAMC,EACD,KAA6B,EAC7B,SAAS,GAAG,iBAAiB;IAE7B,MAAM,cAAc,CAAyB;QAC3C,KAAK,EAAE;YACL,IAAI,EAAE,KAAK,IAAI,EAAE;gBACf,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;gBACnC,OAAO;oBACL,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,EAAE;oBAC5B,GAAG,CAAC,OAAO,EAAE,IAAI,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;iBAC3D,CAAA;YACH,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;gBACrC,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;YAC/C,CAAC;SACF;QACD,SAAS;QACT,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;KAC5C,CAAC,CAAA;AACJ,CAAC"}
|
package/dist/internal/paths.d.ts
CHANGED
|
@@ -3,17 +3,24 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export declare function spacesRoot(): string;
|
|
5
5
|
/**
|
|
6
|
-
* `/space/:spaceId
|
|
6
|
+
* `/space/:spaceId/` -- the Space container in canonical form: the target a
|
|
7
|
+
* Space root capability names, the URL whose `GET` lists the Space's
|
|
8
|
+
* Collections, whose `POST` creates one, and whose `DELETE` removes the Space.
|
|
9
|
+
* The Space is an ordinary container, so its members are listed and created at
|
|
10
|
+
* the container itself -- there is no second builder for that.
|
|
11
|
+
*
|
|
12
|
+
* @param spaceId {string}
|
|
13
|
+
* @returns {string}
|
|
7
14
|
*/
|
|
8
15
|
export declare function spacePath(spaceId: string): string;
|
|
9
16
|
/**
|
|
10
|
-
* `/space/:spaceId
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
*
|
|
17
|
+
* `/space/:spaceId/meta` -- the Space Metadata object: the Space's description
|
|
18
|
+
* (`name`, `controller`, `type`), read with `GET` and replaced with `PUT`.
|
|
19
|
+
*
|
|
20
|
+
* @param spaceId {string}
|
|
21
|
+
* @returns {string}
|
|
15
22
|
*/
|
|
16
|
-
export declare function
|
|
23
|
+
export declare function spaceMeta(spaceId: string): string;
|
|
17
24
|
/**
|
|
18
25
|
* `/space/:spaceId/export` -- export a space as a tar archive.
|
|
19
26
|
*/
|
|
@@ -54,15 +61,16 @@ export declare function spaceLinkset(spaceId: string): string;
|
|
|
54
61
|
*/
|
|
55
62
|
export declare function spaceRevocation(spaceId: string, capabilityId: string): string;
|
|
56
63
|
/**
|
|
57
|
-
* `/space/:spaceId/:collectionId
|
|
58
|
-
*
|
|
64
|
+
* `/space/:spaceId/:collectionId/` -- the Collection container in canonical
|
|
65
|
+
* form: the target a "share this collection" capability names, the URL whose
|
|
66
|
+
* `GET` lists its Resources, whose `POST` adds one, and whose `DELETE` removes
|
|
67
|
+
* the Collection.
|
|
68
|
+
*
|
|
69
|
+
* @param spaceId {string}
|
|
70
|
+
* @param collectionId {string}
|
|
71
|
+
* @returns {string}
|
|
59
72
|
*/
|
|
60
73
|
export declare function collectionPath(spaceId: string, collectionId: string): string;
|
|
61
|
-
/**
|
|
62
|
-
* `/space/:spaceId/:collectionId/` -- list items / add a resource
|
|
63
|
-
* (trailing slash).
|
|
64
|
-
*/
|
|
65
|
-
export declare function collectionItems(spaceId: string, collectionId: string): string;
|
|
66
74
|
/**
|
|
67
75
|
* `/space/:spaceId/:collectionId/policy` -- the collection-level access-control
|
|
68
76
|
* policy resource.
|
|
@@ -84,9 +92,10 @@ export declare function collectionBackend(spaceId: string, collectionId: string)
|
|
|
84
92
|
*/
|
|
85
93
|
export declare function collectionQuota(spaceId: string, collectionId: string): string;
|
|
86
94
|
/**
|
|
87
|
-
* `/space/:spaceId/:collectionId/meta` -- the Collection
|
|
88
|
-
*
|
|
89
|
-
*
|
|
95
|
+
* `/space/:spaceId/:collectionId/meta` -- the Collection Metadata object: the
|
|
96
|
+
* Collection's configuration (`name`, `backend`, `encryption`, `generator`)
|
|
97
|
+
* together with the server-managed timestamps / `createdBy` and the
|
|
98
|
+
* user-writable `custom` and `epoch`, as one object under one validator.
|
|
90
99
|
*/
|
|
91
100
|
export declare function collectionMeta(spaceId: string, collectionId: string): string;
|
|
92
101
|
/**
|
|
@@ -209,6 +218,13 @@ export declare function parseSpaceTarget({ serverUrl, target }: {
|
|
|
209
218
|
* or any 5-segment target like `/space/s/c/r/meta` -- is classified
|
|
210
219
|
* `sub-resource`, never silently truncated to the nearest handle.
|
|
211
220
|
*
|
|
221
|
+
* Empty segments are dropped, so a container addressed in either form
|
|
222
|
+
* classifies the same: `/space/s` and `/space/s/` are both the Space, and
|
|
223
|
+
* `/space/s/c` and `/space/s/c/` both the Collection. That is deliberate. The
|
|
224
|
+
* builders emit only the canonical trailing-slash form, but the targets parsed
|
|
225
|
+
* here come from capabilities minted elsewhere, and a client that reads only
|
|
226
|
+
* one spelling would refuse valid ones.
|
|
227
|
+
*
|
|
212
228
|
* @param pathname {string} a URL pathname (e.g. from `new URL(...).pathname`)
|
|
213
229
|
* @returns {ParsedSpacePath | null}
|
|
214
230
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/internal/paths.ts"],"names":[],"mappings":"AA+
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/internal/paths.ts"],"names":[],"mappings":"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"}
|
package/dist/internal/paths.js
CHANGED
|
@@ -3,9 +3,25 @@
|
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
5
|
* URL path builders for the WAS server, encoding the trailing-slash
|
|
6
|
-
* canonicalization once.
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* canonicalization once. The convention: a trailing slash marks a container in
|
|
7
|
+
* canonical form (`/spaces/`, `/space/{s}/`, `/space/{s}/{c}/`), everything
|
|
8
|
+
* else has none, and no two paths differ only by a trailing slash. Path
|
|
9
|
+
* segments are percent-encoded so ids never break out of their slot.
|
|
10
|
+
*
|
|
11
|
+
* A container's own description is not at its URL: it lives at the reserved
|
|
12
|
+
* `meta` segment (`spaceMeta`, `collectionMeta`), beside the Resource-level
|
|
13
|
+
* `resourceMeta`. The bare (slash-less) form of a container URL only
|
|
14
|
+
* 308-redirects, and a signed invocation covers the target it was signed for,
|
|
15
|
+
* so no builder here emits the bare form -- a redirect would have to be signed
|
|
16
|
+
* again.
|
|
17
|
+
*
|
|
18
|
+
* The parser is deliberately laxer than the builders. `parseSpacePath` accepts
|
|
19
|
+
* the bare form too, because the targets it classifies are not this client's
|
|
20
|
+
* own URLs: they are the `invocationTarget` strings of delegated capabilities
|
|
21
|
+
* a third party minted, and those name containers in either form. Reading one
|
|
22
|
+
* as the Space or Collection it addresses is what `WasClient.fromCapability`
|
|
23
|
+
* and the revocation route's `spaceIdOf` do; refusing the bare form there would
|
|
24
|
+
* reject valid capabilities over a spelling this client does not control.
|
|
9
25
|
*
|
|
10
26
|
* The zcap `invocationTarget` is derived from the request URL, so these
|
|
11
27
|
* trailing-slash rules must match the server's per-operation `allowedTarget`
|
|
@@ -16,9 +32,8 @@
|
|
|
16
32
|
* resource / sub-resource), so `WasClient.fromCapability` and the builders stay
|
|
17
33
|
* in lockstep.
|
|
18
34
|
*/
|
|
19
|
-
import { RESERVED_COLLECTION_IDS, RESERVED_RESOURCE_IDS } from '@interop/storage-core';
|
|
20
35
|
import { ValidationError } from '../errors.js';
|
|
21
|
-
import { assertNotReserved } from './reserved.js';
|
|
36
|
+
import { assertNotReserved, isReservedCollectionId, isReservedResourceId } from './reserved.js';
|
|
22
37
|
/**
|
|
23
38
|
* Rejects an id that would escape its path slot even after percent-encoding:
|
|
24
39
|
* `encodeURIComponent` leaves `.` and `..` intact, and WHATWG URL resolution
|
|
@@ -74,41 +89,59 @@ export function spacesRoot() {
|
|
|
74
89
|
return '/spaces/';
|
|
75
90
|
}
|
|
76
91
|
/**
|
|
77
|
-
* `/space/:spaceId` --
|
|
92
|
+
* `/space/:spaceId` -- the slash-less prefix the space-level sub-endpoints hang
|
|
93
|
+
* off. Module-private: the bare form is not a path this client ever requests
|
|
94
|
+
* (the server only 308-redirects it), so it is a prefix here and never a
|
|
95
|
+
* builder's return value. It is still a form the parser below reads, since a
|
|
96
|
+
* third party's capability target may be written that way.
|
|
97
|
+
*
|
|
98
|
+
* @param spaceId {string}
|
|
99
|
+
* @returns {string}
|
|
78
100
|
*/
|
|
79
|
-
|
|
101
|
+
function spacePrefix(spaceId) {
|
|
80
102
|
return `/space/${encode(spaceId)}`;
|
|
81
103
|
}
|
|
82
104
|
/**
|
|
83
|
-
* `/space/:spaceId/` --
|
|
105
|
+
* `/space/:spaceId/` -- the Space container in canonical form: the target a
|
|
106
|
+
* Space root capability names, the URL whose `GET` lists the Space's
|
|
107
|
+
* Collections, whose `POST` creates one, and whose `DELETE` removes the Space.
|
|
108
|
+
* The Space is an ordinary container, so its members are listed and created at
|
|
109
|
+
* the container itself -- there is no second builder for that.
|
|
110
|
+
*
|
|
111
|
+
* @param spaceId {string}
|
|
112
|
+
* @returns {string}
|
|
84
113
|
*/
|
|
85
|
-
export function
|
|
86
|
-
return `${
|
|
114
|
+
export function spacePath(spaceId) {
|
|
115
|
+
return `${spacePrefix(spaceId)}/`;
|
|
87
116
|
}
|
|
88
117
|
/**
|
|
89
|
-
* `/space/:spaceId/
|
|
118
|
+
* `/space/:spaceId/meta` -- the Space Metadata object: the Space's description
|
|
119
|
+
* (`name`, `controller`, `type`), read with `GET` and replaced with `PUT`.
|
|
120
|
+
*
|
|
121
|
+
* @param spaceId {string}
|
|
122
|
+
* @returns {string}
|
|
90
123
|
*/
|
|
91
|
-
export function
|
|
92
|
-
return `${
|
|
124
|
+
export function spaceMeta(spaceId) {
|
|
125
|
+
return `${spacePrefix(spaceId)}/meta`;
|
|
93
126
|
}
|
|
94
127
|
/**
|
|
95
128
|
* `/space/:spaceId/export` -- export a space as a tar archive.
|
|
96
129
|
*/
|
|
97
130
|
export function spaceExport(spaceId) {
|
|
98
|
-
return `${
|
|
131
|
+
return `${spacePrefix(spaceId)}/export`;
|
|
99
132
|
}
|
|
100
133
|
/**
|
|
101
134
|
* `/space/:spaceId/import` -- import a tar archive into a space.
|
|
102
135
|
*/
|
|
103
136
|
export function spaceImport(spaceId) {
|
|
104
|
-
return `${
|
|
137
|
+
return `${spacePrefix(spaceId)}/import`;
|
|
105
138
|
}
|
|
106
139
|
/**
|
|
107
140
|
* `/space/:spaceId/backends` -- the backends available within a space (list, and
|
|
108
141
|
* register a new `external` backend).
|
|
109
142
|
*/
|
|
110
143
|
export function spaceBackends(spaceId) {
|
|
111
|
-
return `${
|
|
144
|
+
return `${spacePrefix(spaceId)}/backends`;
|
|
112
145
|
}
|
|
113
146
|
/**
|
|
114
147
|
* `/space/:spaceId/backends/:backendId` -- a single registered `external`
|
|
@@ -121,19 +154,19 @@ export function registeredBackend(spaceId, backendId) {
|
|
|
121
154
|
* `/space/:spaceId/quotas` -- the space-level storage quota report.
|
|
122
155
|
*/
|
|
123
156
|
export function spaceQuotas(spaceId) {
|
|
124
|
-
return `${
|
|
157
|
+
return `${spacePrefix(spaceId)}/quotas`;
|
|
125
158
|
}
|
|
126
159
|
/**
|
|
127
160
|
* `/space/:spaceId/policy` -- the space-level access-control policy resource.
|
|
128
161
|
*/
|
|
129
162
|
export function spacePolicy(spaceId) {
|
|
130
|
-
return `${
|
|
163
|
+
return `${spacePrefix(spaceId)}/policy`;
|
|
131
164
|
}
|
|
132
165
|
/**
|
|
133
166
|
* `/space/:spaceId/linkset` -- the space-level linkset (policy discovery).
|
|
134
167
|
*/
|
|
135
168
|
export function spaceLinkset(spaceId) {
|
|
136
|
-
return `${
|
|
169
|
+
return `${spacePrefix(spaceId)}/linkset`;
|
|
137
170
|
}
|
|
138
171
|
/**
|
|
139
172
|
* `/space/:spaceId/zcaps/revocations/:capabilityId` -- submit a revocation of a
|
|
@@ -144,57 +177,69 @@ export function spaceLinkset(spaceId) {
|
|
|
144
177
|
* deeper than any Collection or Resource route, so it shadows nothing.
|
|
145
178
|
*/
|
|
146
179
|
export function spaceRevocation(spaceId, capabilityId) {
|
|
147
|
-
return `${
|
|
180
|
+
return `${spacePrefix(spaceId)}/zcaps/revocations/${encode(capabilityId)}`;
|
|
148
181
|
}
|
|
149
182
|
/**
|
|
150
|
-
* `/space/:spaceId/:collectionId` --
|
|
151
|
-
*
|
|
183
|
+
* `/space/:spaceId/:collectionId` -- the slash-less prefix the collection-level
|
|
184
|
+
* sub-endpoints and the Resource ids hang off. Module-private, like
|
|
185
|
+
* {@link spacePrefix}.
|
|
186
|
+
*
|
|
187
|
+
* @param spaceId {string}
|
|
188
|
+
* @param collectionId {string}
|
|
189
|
+
* @returns {string}
|
|
152
190
|
*/
|
|
153
|
-
|
|
154
|
-
return `${
|
|
191
|
+
function collectionPrefix(spaceId, collectionId) {
|
|
192
|
+
return `${spacePrefix(spaceId)}/${encodeCollectionId(collectionId)}`;
|
|
155
193
|
}
|
|
156
194
|
/**
|
|
157
|
-
* `/space/:spaceId/:collectionId/` --
|
|
158
|
-
*
|
|
195
|
+
* `/space/:spaceId/:collectionId/` -- the Collection container in canonical
|
|
196
|
+
* form: the target a "share this collection" capability names, the URL whose
|
|
197
|
+
* `GET` lists its Resources, whose `POST` adds one, and whose `DELETE` removes
|
|
198
|
+
* the Collection.
|
|
199
|
+
*
|
|
200
|
+
* @param spaceId {string}
|
|
201
|
+
* @param collectionId {string}
|
|
202
|
+
* @returns {string}
|
|
159
203
|
*/
|
|
160
|
-
export function
|
|
161
|
-
return `${
|
|
204
|
+
export function collectionPath(spaceId, collectionId) {
|
|
205
|
+
return `${collectionPrefix(spaceId, collectionId)}/`;
|
|
162
206
|
}
|
|
163
207
|
/**
|
|
164
208
|
* `/space/:spaceId/:collectionId/policy` -- the collection-level access-control
|
|
165
209
|
* policy resource.
|
|
166
210
|
*/
|
|
167
211
|
export function collectionPolicy(spaceId, collectionId) {
|
|
168
|
-
return `${
|
|
212
|
+
return `${collectionPrefix(spaceId, collectionId)}/policy`;
|
|
169
213
|
}
|
|
170
214
|
/**
|
|
171
215
|
* `/space/:spaceId/:collectionId/linkset` -- the collection-level linkset
|
|
172
216
|
* (policy discovery).
|
|
173
217
|
*/
|
|
174
218
|
export function collectionLinkset(spaceId, collectionId) {
|
|
175
|
-
return `${
|
|
219
|
+
return `${collectionPrefix(spaceId, collectionId)}/linkset`;
|
|
176
220
|
}
|
|
177
221
|
/**
|
|
178
222
|
* `/space/:spaceId/:collectionId/backend` -- the "Collection Backend Selected"
|
|
179
223
|
* descriptor (the backend this collection is stored on).
|
|
180
224
|
*/
|
|
181
225
|
export function collectionBackend(spaceId, collectionId) {
|
|
182
|
-
return `${
|
|
226
|
+
return `${collectionPrefix(spaceId, collectionId)}/backend`;
|
|
183
227
|
}
|
|
184
228
|
/**
|
|
185
229
|
* `/space/:spaceId/:collectionId/quota` -- the per-collection storage quota
|
|
186
230
|
* report (spec "Quotas").
|
|
187
231
|
*/
|
|
188
232
|
export function collectionQuota(spaceId, collectionId) {
|
|
189
|
-
return `${
|
|
233
|
+
return `${collectionPrefix(spaceId, collectionId)}/quota`;
|
|
190
234
|
}
|
|
191
235
|
/**
|
|
192
|
-
* `/space/:spaceId/:collectionId/meta` -- the Collection
|
|
193
|
-
*
|
|
194
|
-
*
|
|
236
|
+
* `/space/:spaceId/:collectionId/meta` -- the Collection Metadata object: the
|
|
237
|
+
* Collection's configuration (`name`, `backend`, `encryption`, `generator`)
|
|
238
|
+
* together with the server-managed timestamps / `createdBy` and the
|
|
239
|
+
* user-writable `custom` and `epoch`, as one object under one validator.
|
|
195
240
|
*/
|
|
196
241
|
export function collectionMeta(spaceId, collectionId) {
|
|
197
|
-
return `${
|
|
242
|
+
return `${collectionPrefix(spaceId, collectionId)}/meta`;
|
|
198
243
|
}
|
|
199
244
|
/**
|
|
200
245
|
* `/space/:spaceId/:collectionId/meta/log` -- the Collection's governing
|
|
@@ -209,14 +254,14 @@ export function collectionLog(spaceId, collectionId) {
|
|
|
209
254
|
* whose body's `profile` selects the query (e.g. `changes`, `blinded-index`).
|
|
210
255
|
*/
|
|
211
256
|
export function collectionQuery(spaceId, collectionId) {
|
|
212
|
-
return `${
|
|
257
|
+
return `${collectionPrefix(spaceId, collectionId)}/query`;
|
|
213
258
|
}
|
|
214
259
|
/**
|
|
215
260
|
* `/space/:spaceId/:collectionId/:resourceId` -- get / put / delete a resource
|
|
216
261
|
* (no trailing slash).
|
|
217
262
|
*/
|
|
218
263
|
export function resourcePath(spaceId, collectionId, resourceId) {
|
|
219
|
-
return `${
|
|
264
|
+
return `${collectionPrefix(spaceId, collectionId)}/${encodeResourceId(resourceId)}`;
|
|
220
265
|
}
|
|
221
266
|
/**
|
|
222
267
|
* `/space/:spaceId/:collectionId/:resourceId/meta` -- the resource metadata
|
|
@@ -322,6 +367,13 @@ export function parseSpaceTarget({ serverUrl, target }) {
|
|
|
322
367
|
* or any 5-segment target like `/space/s/c/r/meta` -- is classified
|
|
323
368
|
* `sub-resource`, never silently truncated to the nearest handle.
|
|
324
369
|
*
|
|
370
|
+
* Empty segments are dropped, so a container addressed in either form
|
|
371
|
+
* classifies the same: `/space/s` and `/space/s/` are both the Space, and
|
|
372
|
+
* `/space/s/c` and `/space/s/c/` both the Collection. That is deliberate. The
|
|
373
|
+
* builders emit only the canonical trailing-slash form, but the targets parsed
|
|
374
|
+
* here come from capabilities minted elsewhere, and a client that reads only
|
|
375
|
+
* one spelling would refuse valid ones.
|
|
376
|
+
*
|
|
325
377
|
* @param pathname {string} a URL pathname (e.g. from `new URL(...).pathname`)
|
|
326
378
|
* @returns {ParsedSpacePath | null}
|
|
327
379
|
*/
|
|
@@ -346,7 +398,7 @@ export function parseSpacePath(pathname) {
|
|
|
346
398
|
// A reserved segment directly under the space (`policy`, `backends`,
|
|
347
399
|
// `export`, ...) addresses a space-level sub-endpoint, as does anything
|
|
348
400
|
// nested beneath one (`/space/s/backends/:backendId`).
|
|
349
|
-
if (
|
|
401
|
+
if (isReservedCollectionId(rest[0])) {
|
|
350
402
|
return { kind: 'sub-resource', spaceId, segments: rest };
|
|
351
403
|
}
|
|
352
404
|
if (rest.length === 1) {
|
|
@@ -354,7 +406,7 @@ export function parseSpacePath(pathname) {
|
|
|
354
406
|
}
|
|
355
407
|
// A reserved segment under the collection (`policy`, `backend`, `quota`,
|
|
356
408
|
// ...) addresses a collection-level sub-endpoint.
|
|
357
|
-
if (
|
|
409
|
+
if (isReservedResourceId(rest[1])) {
|
|
358
410
|
return { kind: 'sub-resource', spaceId, segments: rest };
|
|
359
411
|
}
|
|
360
412
|
if (rest.length === 2) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/internal/paths.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/internal/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether `id` is a reserved Collection-id path segment.
|
|
3
|
+
*
|
|
4
|
+
* @param id {string}
|
|
5
|
+
* @returns {boolean}
|
|
6
|
+
*/
|
|
7
|
+
export declare function isReservedCollectionId(id: string): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Whether `id` is a reserved Resource-id path segment.
|
|
10
|
+
*
|
|
11
|
+
* @param id {string}
|
|
12
|
+
* @returns {boolean}
|
|
13
|
+
*/
|
|
14
|
+
export declare function isReservedResourceId(id: string): boolean;
|
|
1
15
|
/**
|
|
2
16
|
* Throws a `ValidationError` if the given id collides with a reserved path
|
|
3
17
|
* segment for its kind.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reserved.d.ts","sourceRoot":"","sources":["../../src/internal/reserved.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"reserved.d.ts","sourceRoot":"","sources":["../../src/internal/reserved.ts"],"names":[],"mappings":"AAoBA;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,EAAE,EACF,IAAI,EACL,EAAE;IACD,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,YAAY,GAAG,UAAU,CAAA;CAChC,GAAG,IAAI,CAQP"}
|