@interop/was-client 0.12.0 → 0.13.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 +21 -0
- package/dist/Collection.d.ts +13 -0
- package/dist/Collection.d.ts.map +1 -1
- package/dist/Collection.js +61 -52
- package/dist/Collection.js.map +1 -1
- package/dist/Resource.d.ts +39 -25
- package/dist/Resource.d.ts.map +1 -1
- package/dist/Resource.js +89 -74
- package/dist/Resource.js.map +1 -1
- package/dist/Space.d.ts +43 -0
- package/dist/Space.d.ts.map +1 -1
- package/dist/Space.js +98 -56
- package/dist/Space.js.map +1 -1
- package/dist/WasClient.d.ts.map +1 -1
- package/dist/WasClient.js +33 -32
- package/dist/WasClient.js.map +1 -1
- package/dist/edv/EdvCodec.d.ts +8 -3
- package/dist/edv/EdvCodec.d.ts.map +1 -1
- package/dist/edv/EdvCodec.js +43 -31
- package/dist/edv/EdvCodec.js.map +1 -1
- package/dist/edv/WasTransport.d.ts +28 -10
- package/dist/edv/WasTransport.d.ts.map +1 -1
- package/dist/edv/WasTransport.js +66 -16
- package/dist/edv/WasTransport.js.map +1 -1
- package/dist/edv/constants.d.ts +8 -0
- package/dist/edv/constants.d.ts.map +1 -1
- package/dist/edv/constants.js +10 -0
- package/dist/edv/constants.js.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +10 -7
- package/dist/errors.js.map +1 -1
- package/dist/internal/codec.d.ts +6 -43
- package/dist/internal/codec.d.ts.map +1 -1
- package/dist/internal/codec.js +19 -40
- package/dist/internal/codec.js.map +1 -1
- package/dist/internal/conditional.d.ts +8 -3
- package/dist/internal/conditional.d.ts.map +1 -1
- package/dist/internal/conditional.js +5 -3
- package/dist/internal/conditional.js.map +1 -1
- package/dist/internal/content.d.ts +42 -8
- package/dist/internal/content.d.ts.map +1 -1
- package/dist/internal/content.js +70 -21
- package/dist/internal/content.js.map +1 -1
- package/dist/internal/grant.d.ts +20 -2
- package/dist/internal/grant.d.ts.map +1 -1
- package/dist/internal/grant.js +22 -2
- package/dist/internal/grant.js.map +1 -1
- package/dist/internal/pagination.d.ts +16 -0
- package/dist/internal/pagination.d.ts.map +1 -1
- package/dist/internal/pagination.js +21 -1
- package/dist/internal/pagination.js.map +1 -1
- package/dist/internal/paths.d.ts +48 -17
- package/dist/internal/paths.d.ts.map +1 -1
- package/dist/internal/paths.js +85 -6
- package/dist/internal/paths.js.map +1 -1
- package/dist/internal/request.d.ts +21 -12
- package/dist/internal/request.d.ts.map +1 -1
- package/dist/internal/request.js +22 -0
- package/dist/internal/request.js.map +1 -1
- package/dist/internal/reserved.d.ts +8 -4
- package/dist/internal/reserved.d.ts.map +1 -1
- package/dist/internal/reserved.js +5 -4
- package/dist/internal/reserved.js.map +1 -1
- package/dist/internal/write.d.ts +47 -6
- package/dist/internal/write.d.ts.map +1 -1
- package/dist/internal/write.js +71 -1
- package/dist/internal/write.js.map +1 -1
- package/package.json +1 -1
package/dist/internal/content.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { ValidationError, WasServerError } from '../errors.js';
|
|
2
2
|
const OCTET_STREAM = 'application/octet-stream';
|
|
3
|
+
/**
|
|
4
|
+
* A shared `TextEncoder` for serializing an explicitly-typed JSON write to
|
|
5
|
+
* bytes (stateless, so one instance is reused).
|
|
6
|
+
*/
|
|
7
|
+
const ENCODER = new TextEncoder();
|
|
3
8
|
/**
|
|
4
9
|
* Whether a content-type denotes JSON -- `application/json` or any
|
|
5
10
|
* `application/<prefix>+json` structured-suffix variant (e.g.
|
|
@@ -103,40 +108,81 @@ export function toPlainBytes(bytes) {
|
|
|
103
108
|
return new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
104
109
|
}
|
|
105
110
|
/**
|
|
106
|
-
*
|
|
111
|
+
* Classifies write data as binary or JSON and resolves the binary
|
|
112
|
+
* content-type -- the single source of the detection and precedence rules
|
|
113
|
+
* shared by the plaintext `prepareBody` and the EDV codec's document builder.
|
|
107
114
|
*
|
|
108
115
|
* The binary content-type resolves in precedence order: an explicit
|
|
109
|
-
* `
|
|
110
|
-
* `
|
|
111
|
-
*
|
|
112
|
-
*
|
|
116
|
+
* `contentType`, then a non-empty `Blob.type`, then a guess from the resource
|
|
117
|
+
* `id`'s extension, then `application/octet-stream`. (Coalescing with `||`
|
|
118
|
+
* rather than `??` so an empty-string `Blob.type` -- a typeless Blob -- falls
|
|
119
|
+
* through to the guess instead of becoming an empty content-type.)
|
|
113
120
|
*
|
|
114
|
-
* @param data {ResourceData} the resource content
|
|
115
121
|
* @param options {object}
|
|
122
|
+
* @param options.data {ResourceData} the resource content
|
|
116
123
|
* @param [options.contentType] {string} overrides the inferred content-type
|
|
117
124
|
* for binary data
|
|
118
|
-
* @param [options.
|
|
125
|
+
* @param [options.id] {string} resource id used to guess a
|
|
119
126
|
* content-type by extension when none is given (binary data only)
|
|
120
|
-
* @returns {
|
|
127
|
+
* @returns {ResolvedPayload}
|
|
121
128
|
*/
|
|
122
|
-
export function
|
|
123
|
-
const guessed =
|
|
124
|
-
? guessContentTypeFromId(options.filename)
|
|
125
|
-
: undefined;
|
|
129
|
+
export function resolvePayload({ data, contentType, id }) {
|
|
130
|
+
const guessed = id ? guessContentTypeFromId(id) : undefined;
|
|
126
131
|
if (isBlob(data)) {
|
|
127
132
|
return {
|
|
128
|
-
|
|
129
|
-
|
|
133
|
+
kind: 'binary',
|
|
134
|
+
data,
|
|
135
|
+
contentType: contentType || data.type || guessed || OCTET_STREAM
|
|
130
136
|
};
|
|
131
137
|
}
|
|
132
138
|
if (data instanceof Uint8Array) {
|
|
133
139
|
return {
|
|
134
|
-
|
|
135
|
-
|
|
140
|
+
kind: 'binary',
|
|
141
|
+
data,
|
|
142
|
+
contentType: contentType || guessed || OCTET_STREAM
|
|
136
143
|
};
|
|
137
144
|
}
|
|
138
145
|
if (data !== null && typeof data === 'object') {
|
|
139
|
-
|
|
146
|
+
return { kind: 'json' };
|
|
147
|
+
}
|
|
148
|
+
return { kind: 'invalid' };
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Inspects write data and resolves it to a JSON or binary payload, using
|
|
152
|
+
* {@link resolvePayload} for the detection and content-type precedence rules.
|
|
153
|
+
*
|
|
154
|
+
* @param data {ResourceData} the resource content
|
|
155
|
+
* @param options {object}
|
|
156
|
+
* @param [options.contentType] {string} overrides the inferred content-type
|
|
157
|
+
* for binary data
|
|
158
|
+
* @param [options.filename] {string} resource id used to guess a
|
|
159
|
+
* content-type by extension when none is given (binary data only)
|
|
160
|
+
* @returns {PreparedBody}
|
|
161
|
+
*/
|
|
162
|
+
export function prepareBody(data, options = {}) {
|
|
163
|
+
const payload = resolvePayload({
|
|
164
|
+
data,
|
|
165
|
+
contentType: options.contentType,
|
|
166
|
+
id: options.filename
|
|
167
|
+
});
|
|
168
|
+
if (payload.kind === 'binary') {
|
|
169
|
+
return {
|
|
170
|
+
body: isBlob(payload.data) ? payload.data : toPlainBytes(payload.data),
|
|
171
|
+
contentType: payload.contentType
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
if (payload.kind === 'json') {
|
|
175
|
+
// Plain object or array -- send as JSON. An explicit `contentType` (e.g.
|
|
176
|
+
// `application/ld+json`) is honored by serializing the value ourselves and
|
|
177
|
+
// sending it with that content-type header; the bare `json` shorthand
|
|
178
|
+
// would silently store it as `application/json`, losing the declared media
|
|
179
|
+
// type (which the encrypted path preserves).
|
|
180
|
+
if (options.contentType !== undefined) {
|
|
181
|
+
return {
|
|
182
|
+
body: ENCODER.encode(JSON.stringify(data)),
|
|
183
|
+
contentType: options.contentType
|
|
184
|
+
};
|
|
185
|
+
}
|
|
140
186
|
return { json: data };
|
|
141
187
|
}
|
|
142
188
|
throw new ValidationError('Resource data must be a plain object/array (JSON) or a ' +
|
|
@@ -172,15 +218,18 @@ export function createdId(response) {
|
|
|
172
218
|
}
|
|
173
219
|
/**
|
|
174
220
|
* Unwraps a read response's pre-parsed JSON `data` as `T`, mapping a `null`
|
|
175
|
-
* response (a 404 that a `read` request resolved to `null`) to `null`.
|
|
176
|
-
*
|
|
177
|
-
*
|
|
221
|
+
* response (a 404 that a `read` request resolved to `null`) to `null`. The
|
|
222
|
+
* http-client leaves `data` undefined for a non-JSON content-type or a 204;
|
|
223
|
+
* that is also mapped to `null`, so the declared `T | null` is honest and a
|
|
224
|
+
* caller never dereferences `undefined` cast as `T`.
|
|
178
225
|
*
|
|
179
226
|
* @param response {HttpResponse | null}
|
|
180
227
|
* @returns {T | null}
|
|
181
228
|
*/
|
|
182
229
|
export function dataOrNull(response) {
|
|
183
|
-
return response === null
|
|
230
|
+
return response === null || response.data === undefined
|
|
231
|
+
? null
|
|
232
|
+
: response.data;
|
|
184
233
|
}
|
|
185
234
|
/**
|
|
186
235
|
* Reads a JSON response body, preferring the http-client's pre-parsed `data`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/internal/content.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAG9D,MAAM,YAAY,GAAG,0BAA0B,CAAA;AAE/C;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACnD,OAAO,4CAA4C,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;AACvE,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACnD,MAAM,IAAI,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IACnE,OAAO,CACL,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QACxB,IAAI,KAAK,iBAAiB;QAC1B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CACtB,CAAA;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,iBAAiB,GAA2B;IAChD,IAAI,EAAE,WAAW;IACjB,GAAG,EAAE,UAAU;IACf,EAAE,EAAE,iBAAiB;IACrB,GAAG,EAAE,iBAAiB;IACtB,IAAI,EAAE,kBAAkB;IACxB,GAAG,EAAE,eAAe;IACpB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,YAAY;IACjB,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,WAAW;IAChB,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,cAAc;IACnB,KAAK,EAAE,YAAY;IACnB,GAAG,EAAE,YAAY;IACjB,IAAI,EAAE,kBAAkB;CACzB,CAAA;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,sBAAsB,CAAC,EAAU;IAC/C,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;IACnC,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,MAAM,SAAS,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;IACrD,OAAO,iBAAiB,CAAC,SAAS,CAAC,CAAA;AACrC,CAAC;AAYD;;;;;;GAMG;AACH,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,OAAO,OAAO,IAAI,KAAK,WAAW,IAAI,KAAK,YAAY,IAAI,CAAA;AAC7D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,KAAiB;IAC5C,IAAI,KAAK,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;QACrC,OAAO,KAAK,CAAA;IACd,CAAC;IACD,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAA;AACzE,CAAC;
|
|
1
|
+
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/internal/content.ts"],"names":[],"mappings":"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"}
|
package/dist/internal/grant.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* the server (which matches actions case-sensitively against `'GET'`).
|
|
9
9
|
*/
|
|
10
10
|
import type { ClientContext } from './request.js';
|
|
11
|
-
import type { GrantOptions, IDelegatedZcap } from '../types.js';
|
|
11
|
+
import type { GrantOptions, IDelegatedZcap, IZcap } from '../types.js';
|
|
12
12
|
/**
|
|
13
13
|
* Delegates a capability per `GrantOptions`, returning the signed zcap to hand
|
|
14
14
|
* off out-of-band.
|
|
@@ -17,5 +17,23 @@ import type { GrantOptions, IDelegatedZcap } from '../types.js';
|
|
|
17
17
|
* @param options {GrantOptions}
|
|
18
18
|
* @returns {Promise<IDelegatedZcap>}
|
|
19
19
|
*/
|
|
20
|
-
export declare function delegateGrant(context: ClientContext,
|
|
20
|
+
export declare function delegateGrant(context: ClientContext, { to, actions, expires, target, capability }: GrantOptions): Promise<IDelegatedZcap>;
|
|
21
|
+
/**
|
|
22
|
+
* The scoped-grant sugar shared by `Space.grant` and `Collection.grant`:
|
|
23
|
+
* delegates per `GrantOptions` with the grant `target` prefilled from the
|
|
24
|
+
* handle's `path` (and the handle's bound `capability`, if any, as the parent
|
|
25
|
+
* for re-delegation). Explicit options win over both prefills.
|
|
26
|
+
*
|
|
27
|
+
* @param context {ClientContext}
|
|
28
|
+
* @param options {object}
|
|
29
|
+
* @param options.path {string} the handle's path (target fallback)
|
|
30
|
+
* @param options.options {GrantOptions} the caller's grant options
|
|
31
|
+
* @param [options.capability] {IZcap} the handle's bound capability
|
|
32
|
+
* @returns {Promise<IDelegatedZcap>}
|
|
33
|
+
*/
|
|
34
|
+
export declare function delegateGrantAt(context: ClientContext, { path, options, capability }: {
|
|
35
|
+
path: string;
|
|
36
|
+
options: GrantOptions;
|
|
37
|
+
capability?: IZcap;
|
|
38
|
+
}): Promise<IDelegatedZcap>;
|
|
21
39
|
//# sourceMappingURL=grant.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grant.d.ts","sourceRoot":"","sources":["../../src/internal/grant.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;GAKG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"grant.d.ts","sourceRoot":"","sources":["../../src/internal/grant.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;GAKG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAEtE;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,aAAa,EACtB,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,YAAY,GACzD,OAAO,CAAC,cAAc,CAAC,CAQzB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,aAAa,EACtB,EACE,IAAI,EACJ,OAAO,EACP,UAAU,EACX,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,YAAY,CAAC;IAAC,UAAU,CAAC,EAAE,KAAK,CAAA;CAAE,GAC7D,OAAO,CAAC,cAAc,CAAC,CAMzB"}
|
package/dist/internal/grant.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { toUrl } from './paths.js';
|
|
1
2
|
/**
|
|
2
3
|
* Delegates a capability per `GrantOptions`, returning the signed zcap to hand
|
|
3
4
|
* off out-of-band.
|
|
@@ -6,8 +7,7 @@
|
|
|
6
7
|
* @param options {GrantOptions}
|
|
7
8
|
* @returns {Promise<IDelegatedZcap>}
|
|
8
9
|
*/
|
|
9
|
-
export async function delegateGrant(context,
|
|
10
|
-
const { to, actions, expires, target, capability } = options;
|
|
10
|
+
export async function delegateGrant(context, { to, actions, expires, target, capability }) {
|
|
11
11
|
return context.zcapClient.delegate({
|
|
12
12
|
controller: to,
|
|
13
13
|
invocationTarget: target,
|
|
@@ -16,4 +16,24 @@ export async function delegateGrant(context, options) {
|
|
|
16
16
|
capability
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* The scoped-grant sugar shared by `Space.grant` and `Collection.grant`:
|
|
21
|
+
* delegates per `GrantOptions` with the grant `target` prefilled from the
|
|
22
|
+
* handle's `path` (and the handle's bound `capability`, if any, as the parent
|
|
23
|
+
* for re-delegation). Explicit options win over both prefills.
|
|
24
|
+
*
|
|
25
|
+
* @param context {ClientContext}
|
|
26
|
+
* @param options {object}
|
|
27
|
+
* @param options.path {string} the handle's path (target fallback)
|
|
28
|
+
* @param options.options {GrantOptions} the caller's grant options
|
|
29
|
+
* @param [options.capability] {IZcap} the handle's bound capability
|
|
30
|
+
* @returns {Promise<IDelegatedZcap>}
|
|
31
|
+
*/
|
|
32
|
+
export async function delegateGrantAt(context, { path, options, capability }) {
|
|
33
|
+
return delegateGrant(context, {
|
|
34
|
+
...options,
|
|
35
|
+
target: options.target ?? toUrl({ serverUrl: context.serverUrl, path }),
|
|
36
|
+
capability: options.capability ?? capability
|
|
37
|
+
});
|
|
38
|
+
}
|
|
19
39
|
//# sourceMappingURL=grant.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grant.js","sourceRoot":"","sources":["../../src/internal/grant.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"grant.js","sourceRoot":"","sources":["../../src/internal/grant.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAGlC;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAAsB,EACtB,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAgB;IAE1D,OAAO,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC;QACjC,UAAU,EAAE,EAAE;QACd,gBAAgB,EAAE,MAAM;QACxB,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAC3D,OAAO;QACP,UAAU;KACX,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAsB,EACtB,EACE,IAAI,EACJ,OAAO,EACP,UAAU,EACkD;IAE9D,OAAO,aAAa,CAAC,OAAO,EAAE;QAC5B,GAAG,OAAO;QACV,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC;QACvE,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,UAAU;KAC7C,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -21,6 +21,22 @@ export interface PageWalk {
|
|
|
21
21
|
firstUrl: string;
|
|
22
22
|
fetchPage: (url: string) => Promise<CollectionResourcesList | null>;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Builds a {@link PageWalk} by fetching the first page with the same
|
|
26
|
+
* `fetchPage` used for every following page -- the shared shape of the signed
|
|
27
|
+
* (`Collection._listWalk`) and unsigned (`WasClient._publicListWalk`) walks,
|
|
28
|
+
* which differ only in how a single page URL is fetched. Returns `null` when
|
|
29
|
+
* the first page is missing/unauthorized (404 conflation caveat).
|
|
30
|
+
*
|
|
31
|
+
* @param options {object}
|
|
32
|
+
* @param options.firstUrl {string} the absolute listing URL
|
|
33
|
+
* @param options.fetchPage {function} fetches one page by absolute URL
|
|
34
|
+
* @returns {Promise<PageWalk | null>}
|
|
35
|
+
*/
|
|
36
|
+
export declare function buildPageWalk({ firstUrl, fetchPage }: {
|
|
37
|
+
firstUrl: string;
|
|
38
|
+
fetchPage: PageWalk['fetchPage'];
|
|
39
|
+
}): Promise<PageWalk | null>;
|
|
24
40
|
/**
|
|
25
41
|
* Lazily walks a list response page by page, yielding the first page and then
|
|
26
42
|
* each page reached by following `next`. Each `next` is resolved relative to the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/internal/pagination.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAE1D;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,uBAAuB,CAAA;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAA;CACpE;AAED;;;;;;;;;GASG;AACH,wBAAuB,SAAS,CAC9B,IAAI,EAAE,QAAQ,GACb,cAAc,CAAC,uBAAuB,CAAC,
|
|
1
|
+
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/internal/pagination.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAE1D;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,uBAAuB,CAAA;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAA;CACpE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,EAClC,QAAQ,EACR,SAAS,EACV,EAAE;IACD,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAA;CACjC,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAG3B;AAED;;;;;;;;;GASG;AACH,wBAAuB,SAAS,CAC9B,IAAI,EAAE,QAAQ,GACb,cAAc,CAAC,uBAAuB,CAAC,CAwBzC;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,uBAAuB,CAAC,CAWlC"}
|
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds a {@link PageWalk} by fetching the first page with the same
|
|
3
|
+
* `fetchPage` used for every following page -- the shared shape of the signed
|
|
4
|
+
* (`Collection._listWalk`) and unsigned (`WasClient._publicListWalk`) walks,
|
|
5
|
+
* which differ only in how a single page URL is fetched. Returns `null` when
|
|
6
|
+
* the first page is missing/unauthorized (404 conflation caveat).
|
|
7
|
+
*
|
|
8
|
+
* @param options {object}
|
|
9
|
+
* @param options.firstUrl {string} the absolute listing URL
|
|
10
|
+
* @param options.fetchPage {function} fetches one page by absolute URL
|
|
11
|
+
* @returns {Promise<PageWalk | null>}
|
|
12
|
+
*/
|
|
13
|
+
export async function buildPageWalk({ firstUrl, fetchPage }) {
|
|
14
|
+
const first = await fetchPage(firstUrl);
|
|
15
|
+
return first === null ? null : { first, firstUrl, fetchPage };
|
|
16
|
+
}
|
|
1
17
|
/**
|
|
2
18
|
* Lazily walks a list response page by page, yielding the first page and then
|
|
3
19
|
* each page reached by following `next`. Each `next` is resolved relative to the
|
|
@@ -11,7 +27,11 @@
|
|
|
11
27
|
export async function* walkPages(walk) {
|
|
12
28
|
const { first, firstUrl, fetchPage } = walk;
|
|
13
29
|
yield first;
|
|
14
|
-
|
|
30
|
+
// Seed the cycle guard with the canonicalized first URL -- every followed
|
|
31
|
+
// `next` is canonicalized via `new URL(...)`, so an equivalent-but-unequal
|
|
32
|
+
// seed (e.g. an explicit default port) would let a next-link back to page 1
|
|
33
|
+
// defeat the guard and yield its items twice.
|
|
34
|
+
const seen = new Set([new URL(firstUrl).toString()]);
|
|
15
35
|
let baseUrl = firstUrl;
|
|
16
36
|
let next = first.next;
|
|
17
37
|
while (next) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/internal/pagination.ts"],"names":[],"mappings":"AAyBA;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,SAAS,CAC9B,IAAc;IAEd,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;IAC3C,MAAM,KAAK,CAAA;IACX,MAAM,IAAI,GAAG,IAAI,GAAG,CAAS,CAAC,QAAQ,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/internal/pagination.ts"],"names":[],"mappings":"AAyBA;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAClC,QAAQ,EACR,SAAS,EAIV;IACC,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAA;IACvC,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAA;AAC/D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,SAAS,CAC9B,IAAc;IAEd,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;IAC3C,MAAM,KAAK,CAAA;IACX,0EAA0E;IAC1E,2EAA2E;IAC3E,4EAA4E;IAC5E,8CAA8C;IAC9C,MAAM,IAAI,GAAG,IAAI,GAAG,CAAS,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;IAC5D,IAAI,OAAO,GAAG,QAAQ,CAAA;IACtB,IAAI,IAAI,GAAG,KAAK,CAAC,IAAI,CAAA;IACrB,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAA;QACjD,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACtB,MAAK;QACP,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACjB,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAA;QACrC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,MAAK;QACP,CAAC;QACD,MAAM,IAAI,CAAA;QACV,OAAO,GAAG,OAAO,CAAA;QACjB,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;IAClB,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAc;IAEd,IAAI,SAA8C,CAAA;IAClD,MAAM,KAAK,GAAqC,EAAE,CAAA;IAClD,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,SAAS,KAAK,IAAI,CAAA;QAClB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC;IACD,iEAAiE;IACjE,MAAM,MAAM,GAA4B,EAAE,GAAG,SAAU,EAAE,KAAK,EAAE,CAAA;IAChE,OAAO,MAAM,CAAC,IAAI,CAAA;IAClB,OAAO,MAAM,CAAA;AACf,CAAC"}
|
package/dist/internal/paths.d.ts
CHANGED
|
@@ -1,24 +1,7 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* URL path builders for the WAS server, encoding the trailing-slash
|
|
6
|
-
* canonicalization once. Item-create and listing endpoints use a trailing
|
|
7
|
-
* slash; get/put/delete-by-id endpoints do not. Path segments are
|
|
8
|
-
* percent-encoded so ids never break out of their slot.
|
|
9
|
-
*
|
|
10
|
-
* The zcap `invocationTarget` is derived from the request URL, so these
|
|
11
|
-
* trailing-slash rules must match the server's per-operation `allowedTarget`
|
|
12
|
-
* exactly or signature verification fails.
|
|
13
|
-
*/
|
|
14
1
|
/**
|
|
15
2
|
* `/spaces/` -- the SpacesRepository (create / list spaces).
|
|
16
3
|
*/
|
|
17
4
|
export declare function spacesRoot(): string;
|
|
18
|
-
/**
|
|
19
|
-
* `/spaces/:spaceId` -- canonical location of a created space (POST response).
|
|
20
|
-
*/
|
|
21
|
-
export declare function spaceLocation(spaceId: string): string;
|
|
22
5
|
/**
|
|
23
6
|
* `/space/:spaceId` -- get / update / delete a space (no trailing slash).
|
|
24
7
|
*/
|
|
@@ -123,4 +106,52 @@ export declare function toUrl({ serverUrl, path }: {
|
|
|
123
106
|
serverUrl: string;
|
|
124
107
|
path: string;
|
|
125
108
|
}): string;
|
|
109
|
+
/**
|
|
110
|
+
* Canonicalizes an absolute collection URL to its items/listing endpoint --
|
|
111
|
+
* the trailing-slash form (`/space/:id/:collectionId/`). This module owns the
|
|
112
|
+
* trailing-slash rules, so callers that receive a collection URL from outside
|
|
113
|
+
* (e.g. a public link) normalize it here rather than re-encoding the rule.
|
|
114
|
+
*
|
|
115
|
+
* @param collectionUrl {string} an absolute collection URL
|
|
116
|
+
* @returns {string}
|
|
117
|
+
*/
|
|
118
|
+
export declare function collectionItemsUrl(collectionUrl: string): string;
|
|
119
|
+
/**
|
|
120
|
+
* The classification of a WAS pathname by the depth it addresses. The three
|
|
121
|
+
* containment kinds map onto navigational handles; `sub-resource` covers every
|
|
122
|
+
* reserved sub-endpoint the builders above produce (`/space/:id/policy`,
|
|
123
|
+
* `/space/:id/:c/backend`, `/space/:id/:c/:r/meta`, ...), which has no handle of
|
|
124
|
+
* its own.
|
|
125
|
+
*/
|
|
126
|
+
export type ParsedSpacePath = {
|
|
127
|
+
kind: 'space';
|
|
128
|
+
spaceId: string;
|
|
129
|
+
} | {
|
|
130
|
+
kind: 'collection';
|
|
131
|
+
spaceId: string;
|
|
132
|
+
collectionId: string;
|
|
133
|
+
} | {
|
|
134
|
+
kind: 'resource';
|
|
135
|
+
spaceId: string;
|
|
136
|
+
collectionId: string;
|
|
137
|
+
resourceId: string;
|
|
138
|
+
} | {
|
|
139
|
+
kind: 'sub-resource';
|
|
140
|
+
spaceId: string;
|
|
141
|
+
segments: string[];
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Parses a server pathname back into the containment depth it addresses -- the
|
|
145
|
+
* inverse of the builders above, kept next to them so the grammar is owned in
|
|
146
|
+
* one place. Segments are percent-decoded (the builders re-encode them).
|
|
147
|
+
* Returns `null` for a pathname outside the `/space/...` tree; the caller
|
|
148
|
+
* chooses the error. A path that addresses a reserved sub-endpoint rather than
|
|
149
|
+
* a space/collection/resource -- e.g. `/space/s/policy`, `/space/s/c/backend`,
|
|
150
|
+
* or any 5-segment target like `/space/s/c/r/meta` -- is classified
|
|
151
|
+
* `sub-resource`, never silently truncated to the nearest handle.
|
|
152
|
+
*
|
|
153
|
+
* @param pathname {string} a URL pathname (e.g. from `new URL(...).pathname`)
|
|
154
|
+
* @returns {ParsedSpacePath | null}
|
|
155
|
+
*/
|
|
156
|
+
export declare function parseSpacePath(pathname: string): ParsedSpacePath | null;
|
|
126
157
|
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/internal/paths.ts"],"names":[],"mappings":"
|
|
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
|
@@ -10,8 +10,33 @@
|
|
|
10
10
|
* The zcap `invocationTarget` is derived from the request URL, so these
|
|
11
11
|
* trailing-slash rules must match the server's per-operation `allowedTarget`
|
|
12
12
|
* exactly or signature verification fails.
|
|
13
|
+
*
|
|
14
|
+
* This module also owns the inverse grammar: `parseSpacePath` classifies a
|
|
15
|
+
* server pathname back into the handle depth it addresses (space / collection /
|
|
16
|
+
* resource / sub-resource), so `WasClient.fromCapability` and the builders stay
|
|
17
|
+
* in lockstep.
|
|
18
|
+
*/
|
|
19
|
+
import { RESERVED_COLLECTION_IDS, RESERVED_RESOURCE_IDS } from '@interop/storage-core';
|
|
20
|
+
import { ValidationError } from '../errors.js';
|
|
21
|
+
/**
|
|
22
|
+
* Rejects an id that would escape its path slot even after percent-encoding:
|
|
23
|
+
* `encodeURIComponent` leaves `.` and `..` intact, and WHATWG URL resolution
|
|
24
|
+
* collapses dot segments -- so `resource('.').delete()` would target the
|
|
25
|
+
* collection items endpoint and `'..'` the parent space. An empty id likewise
|
|
26
|
+
* collapses into the parent's trailing-slash endpoint. One guard here covers
|
|
27
|
+
* every builder.
|
|
28
|
+
*
|
|
29
|
+
* @param segment {string} the proposed id
|
|
30
|
+
* @returns {void}
|
|
13
31
|
*/
|
|
32
|
+
function assertValidId(segment) {
|
|
33
|
+
if (segment === '' || segment === '.' || segment === '..') {
|
|
34
|
+
throw new ValidationError(`Invalid id ${JSON.stringify(segment)}: an empty or dot-segment id ` +
|
|
35
|
+
'would resolve to a different endpoint than its own.');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
14
38
|
function encode(segment) {
|
|
39
|
+
assertValidId(segment);
|
|
15
40
|
return encodeURIComponent(segment);
|
|
16
41
|
}
|
|
17
42
|
/**
|
|
@@ -20,12 +45,6 @@ function encode(segment) {
|
|
|
20
45
|
export function spacesRoot() {
|
|
21
46
|
return '/spaces/';
|
|
22
47
|
}
|
|
23
|
-
/**
|
|
24
|
-
* `/spaces/:spaceId` -- canonical location of a created space (POST response).
|
|
25
|
-
*/
|
|
26
|
-
export function spaceLocation(spaceId) {
|
|
27
|
-
return `/spaces/${encode(spaceId)}`;
|
|
28
|
-
}
|
|
29
48
|
/**
|
|
30
49
|
* `/space/:spaceId` -- get / update / delete a space (no trailing slash).
|
|
31
50
|
*/
|
|
@@ -172,4 +191,64 @@ export function toUrl({ serverUrl, path }) {
|
|
|
172
191
|
const relative = path.startsWith('/') ? path.slice(1) : path;
|
|
173
192
|
return new URL(relative, base).toString();
|
|
174
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Canonicalizes an absolute collection URL to its items/listing endpoint --
|
|
196
|
+
* the trailing-slash form (`/space/:id/:collectionId/`). This module owns the
|
|
197
|
+
* trailing-slash rules, so callers that receive a collection URL from outside
|
|
198
|
+
* (e.g. a public link) normalize it here rather than re-encoding the rule.
|
|
199
|
+
*
|
|
200
|
+
* @param collectionUrl {string} an absolute collection URL
|
|
201
|
+
* @returns {string}
|
|
202
|
+
*/
|
|
203
|
+
export function collectionItemsUrl(collectionUrl) {
|
|
204
|
+
return collectionUrl.endsWith('/') ? collectionUrl : `${collectionUrl}/`;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Parses a server pathname back into the containment depth it addresses -- the
|
|
208
|
+
* inverse of the builders above, kept next to them so the grammar is owned in
|
|
209
|
+
* one place. Segments are percent-decoded (the builders re-encode them).
|
|
210
|
+
* Returns `null` for a pathname outside the `/space/...` tree; the caller
|
|
211
|
+
* chooses the error. A path that addresses a reserved sub-endpoint rather than
|
|
212
|
+
* a space/collection/resource -- e.g. `/space/s/policy`, `/space/s/c/backend`,
|
|
213
|
+
* or any 5-segment target like `/space/s/c/r/meta` -- is classified
|
|
214
|
+
* `sub-resource`, never silently truncated to the nearest handle.
|
|
215
|
+
*
|
|
216
|
+
* @param pathname {string} a URL pathname (e.g. from `new URL(...).pathname`)
|
|
217
|
+
* @returns {ParsedSpacePath | null}
|
|
218
|
+
*/
|
|
219
|
+
export function parseSpacePath(pathname) {
|
|
220
|
+
const segments = pathname.split('/').filter(Boolean).map(decodeURIComponent);
|
|
221
|
+
if (segments[0] !== 'space' || segments[1] === undefined) {
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
const [, spaceId, ...rest] = segments;
|
|
225
|
+
if (rest.length === 0) {
|
|
226
|
+
return { kind: 'space', spaceId };
|
|
227
|
+
}
|
|
228
|
+
// A reserved segment directly under the space (`policy`, `backends`,
|
|
229
|
+
// `export`, ...) addresses a space-level sub-endpoint, as does anything
|
|
230
|
+
// nested beneath one (`/space/s/backends/:backendId`).
|
|
231
|
+
if (RESERVED_COLLECTION_IDS.has(rest[0])) {
|
|
232
|
+
return { kind: 'sub-resource', spaceId, segments: rest };
|
|
233
|
+
}
|
|
234
|
+
if (rest.length === 1) {
|
|
235
|
+
return { kind: 'collection', spaceId, collectionId: rest[0] };
|
|
236
|
+
}
|
|
237
|
+
// A reserved segment under the collection (`policy`, `backend`, `quota`,
|
|
238
|
+
// ...) addresses a collection-level sub-endpoint.
|
|
239
|
+
if (RESERVED_RESOURCE_IDS.has(rest[1])) {
|
|
240
|
+
return { kind: 'sub-resource', spaceId, segments: rest };
|
|
241
|
+
}
|
|
242
|
+
if (rest.length === 2) {
|
|
243
|
+
return {
|
|
244
|
+
kind: 'resource',
|
|
245
|
+
spaceId,
|
|
246
|
+
collectionId: rest[0],
|
|
247
|
+
resourceId: rest[1]
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
// Anything deeper (`/space/s/c/r/meta`, `/space/s/c/r/policy`, chunk
|
|
251
|
+
// sub-segments, ...) is a resource-level sub-endpoint.
|
|
252
|
+
return { kind: 'sub-resource', spaceId, segments: rest };
|
|
253
|
+
}
|
|
175
254
|
//# sourceMappingURL=paths.js.map
|
|
@@ -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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"}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import type { ZcapClient } from '@interop/ezcap';
|
|
12
12
|
import type { HttpResponse } from '@interop/http-client';
|
|
13
13
|
import type { EncryptionProvider } from '../codec.js';
|
|
14
|
-
import type { IZcap } from '../types.js';
|
|
14
|
+
import type { IZcap, RequestInput } from '../types.js';
|
|
15
15
|
/**
|
|
16
16
|
* The shared context threaded through every handle: the server base URL, the
|
|
17
17
|
* wrapped ezcap client, the cached controller DID of its signer, and the
|
|
@@ -25,18 +25,11 @@ export interface ClientContext {
|
|
|
25
25
|
encryption?: EncryptionProvider;
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
|
-
* A single signed request
|
|
29
|
-
* `url`
|
|
28
|
+
* A single signed request: the public `RequestInput` shape (either `path`,
|
|
29
|
+
* resolved against `serverUrl`, or an absolute `url` must be given) plus the
|
|
30
|
+
* `send()`-level 404 translations.
|
|
30
31
|
*/
|
|
31
|
-
export interface SendInput {
|
|
32
|
-
path?: string;
|
|
33
|
-
url?: string;
|
|
34
|
-
method?: string;
|
|
35
|
-
action?: string;
|
|
36
|
-
headers?: Record<string, string>;
|
|
37
|
-
json?: object;
|
|
38
|
-
body?: Blob | Uint8Array;
|
|
39
|
-
capability?: IZcap;
|
|
32
|
+
export interface SendInput extends RequestInput {
|
|
40
33
|
/**
|
|
41
34
|
* When true, a 404 response resolves to `null` instead of throwing.
|
|
42
35
|
*/
|
|
@@ -87,4 +80,20 @@ export declare function unsignedRequest(input: {
|
|
|
87
80
|
* @returns {Promise<HttpResponse | null>}
|
|
88
81
|
*/
|
|
89
82
|
export declare function send(context: ClientContext, input: SendInput): Promise<HttpResponse | null>;
|
|
83
|
+
/**
|
|
84
|
+
* The GET-a-JSON-description read shared across the handles: a signed
|
|
85
|
+
* null-on-404 `GET` of `path` whose pre-parsed body is unwrapped as `T`. Both
|
|
86
|
+
* a missing/unauthorized target (404) and a bodyless/non-JSON response resolve
|
|
87
|
+
* to `null` (see `dataOrNull`).
|
|
88
|
+
*
|
|
89
|
+
* @param context {ClientContext}
|
|
90
|
+
* @param options {object}
|
|
91
|
+
* @param options.path {string} the path to read
|
|
92
|
+
* @param [options.capability] {IZcap} capability attached to the request
|
|
93
|
+
* @returns {Promise<T | null>}
|
|
94
|
+
*/
|
|
95
|
+
export declare function readData<T>(context: ClientContext, { path, capability }: {
|
|
96
|
+
path: string;
|
|
97
|
+
capability?: IZcap;
|
|
98
|
+
}): Promise<T | null>;
|
|
90
99
|
//# sourceMappingURL=request.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/internal/request.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/internal/request.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAIxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAEtD;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,UAAU,CAAA;IACtB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,kBAAkB,CAAA;CAChC;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAU,SAAQ,YAAY;IAC7C;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IACd;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAYD;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,YAAY,CAAC,CAavB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE;IAC3C,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,IAAI,CAAC,EAAE,OAAO,CAAA;CACf,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAiC/B;AAED;;;;;;;;GAQG;AACH,wBAAsB,IAAI,CACxB,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAS9B;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,OAAO,EAAE,aAAa,EACtB,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,KAAK,CAAA;CAAE,GACzD,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAQnB"}
|
package/dist/internal/request.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { mapError, httpStatus } from '../errors.js';
|
|
2
2
|
import { toUrl } from './paths.js';
|
|
3
|
+
import { dataOrNull } from './content.js';
|
|
3
4
|
function resolveRequestUrl(context, input) {
|
|
4
5
|
if (input.url !== undefined) {
|
|
5
6
|
return input.url;
|
|
@@ -100,4 +101,25 @@ export async function send(context, input) {
|
|
|
100
101
|
throw mapError(err);
|
|
101
102
|
}
|
|
102
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* The GET-a-JSON-description read shared across the handles: a signed
|
|
106
|
+
* null-on-404 `GET` of `path` whose pre-parsed body is unwrapped as `T`. Both
|
|
107
|
+
* a missing/unauthorized target (404) and a bodyless/non-JSON response resolve
|
|
108
|
+
* to `null` (see `dataOrNull`).
|
|
109
|
+
*
|
|
110
|
+
* @param context {ClientContext}
|
|
111
|
+
* @param options {object}
|
|
112
|
+
* @param options.path {string} the path to read
|
|
113
|
+
* @param [options.capability] {IZcap} capability attached to the request
|
|
114
|
+
* @returns {Promise<T | null>}
|
|
115
|
+
*/
|
|
116
|
+
export async function readData(context, { path, capability }) {
|
|
117
|
+
const response = await send(context, {
|
|
118
|
+
path,
|
|
119
|
+
method: 'GET',
|
|
120
|
+
capability,
|
|
121
|
+
read: true
|
|
122
|
+
});
|
|
123
|
+
return dataOrNull(response);
|
|
124
|
+
}
|
|
103
125
|
//# sourceMappingURL=request.js.map
|