@interop/storage-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +20 -0
- package/README.md +94 -0
- package/dist/common.d.ts +187 -0
- package/dist/common.d.ts.map +1 -0
- package/dist/common.js +156 -0
- package/dist/common.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/was.d.ts +266 -0
- package/dist/was.d.ts.map +1 -0
- package/dist/was.js +2 -0
- package/dist/was.js.map +1 -0
- package/package.json +76 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Interop Alliance
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Storage Core _(@interop/storage-core)_
|
|
2
|
+
|
|
3
|
+
[](https://github.com/interop-alliance/storage-core/actions?query=workflow%3A%22CI%22)
|
|
4
|
+
[](https://npm.im/@interop/storage-core)
|
|
5
|
+
|
|
6
|
+
> Shared wire-model types and error vocabulary for Wallet Attached Storage (WAS)
|
|
7
|
+
> -- the single source of truth imported by both the WAS server and client.
|
|
8
|
+
|
|
9
|
+
## Table of Contents
|
|
10
|
+
|
|
11
|
+
- [Background](#background)
|
|
12
|
+
- [Security](#security)
|
|
13
|
+
- [Install](#install)
|
|
14
|
+
- [Usage](#usage)
|
|
15
|
+
- [Contribute](#contribute)
|
|
16
|
+
- [License](#license)
|
|
17
|
+
|
|
18
|
+
## Background
|
|
19
|
+
|
|
20
|
+
This package holds the **wire shapes** (the JSON a WAS server emits and a client
|
|
21
|
+
parses) and the **error vocabulary** (problem-type URIs plus their HTTP-status
|
|
22
|
+
mapping) shared between
|
|
23
|
+
[`was-teaching-server`](https://github.com/interop-alliance/was-teaching-server)
|
|
24
|
+
and [`was-client`](https://github.com/interop-alliance/was-client). Extracting
|
|
25
|
+
them here keeps the two repos from silently drifting apart.
|
|
26
|
+
|
|
27
|
+
It is named `storage-core` rather than `was-core` because the WAS and encrypted
|
|
28
|
+
data vault (EDV) data models are being aligned, and the shared EDV types will
|
|
29
|
+
live here too. The source is organized by domain to leave room for that:
|
|
30
|
+
|
|
31
|
+
- `src/common.ts` -- cross-spec primitives: the capability-action vocabulary,
|
|
32
|
+
the RFC9457 problem-type registry + `application/problem+json` body shapes +
|
|
33
|
+
canonical code-to-status map, the storage-limit shape, the RFC9264 linkset
|
|
34
|
+
shapes, and the reserved path-segment registry.
|
|
35
|
+
- `src/was.ts` -- the WAS data model: Space / Collection / Resource descriptions
|
|
36
|
+
and summaries, listing shapes, resource metadata, backend descriptor / usage,
|
|
37
|
+
the quota report, and the policy document.
|
|
38
|
+
- `src/edv.ts` -- (later) the EDV data model.
|
|
39
|
+
|
|
40
|
+
The package is **pure types plus a few `const` values** (`ProblemTypes`,
|
|
41
|
+
`ProblemStatusCodes`, the reserved-segment sets); it has no platform APIs and no
|
|
42
|
+
runtime dependency surface beyond a type-only reference to
|
|
43
|
+
`@interop/data-integrity-core` (`IDID`), which it uses but does not re-export.
|
|
44
|
+
|
|
45
|
+
## Install
|
|
46
|
+
|
|
47
|
+
- Node.js 22+ is recommended.
|
|
48
|
+
|
|
49
|
+
### PNPM
|
|
50
|
+
|
|
51
|
+
To install via PNPM:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
pnpm install @interop/storage-core
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Development
|
|
58
|
+
|
|
59
|
+
To install locally (for development):
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
git clone https://github.com/interop-alliance/storage-core.git
|
|
63
|
+
cd storage-core
|
|
64
|
+
pnpm install
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Usage
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import {
|
|
71
|
+
ProblemTypes,
|
|
72
|
+
ProblemStatusCodes,
|
|
73
|
+
type SpaceDescription,
|
|
74
|
+
type SpaceQuotaReport
|
|
75
|
+
} from '@interop/storage-core'
|
|
76
|
+
|
|
77
|
+
const status = ProblemStatusCodes[ProblemTypes.QUOTA_EXCEEDED] // 507
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Consumers that need `IDID` / `IZcap` / `ISigner` import them directly from
|
|
81
|
+
`@interop/data-integrity-core`; this package references but does not re-export
|
|
82
|
+
them.
|
|
83
|
+
|
|
84
|
+
## Contribute
|
|
85
|
+
|
|
86
|
+
PRs accepted. See [CONTRIBUTING.md](CONTRIBUTING.md) for editor setup (Prettier,
|
|
87
|
+
ESLint, and EditorConfig) and how it maps to CI.
|
|
88
|
+
|
|
89
|
+
If editing the Readme, please conform to the
|
|
90
|
+
[standard-readme](https://github.com/RichardLitt/standard-readme) specification.
|
|
91
|
+
|
|
92
|
+
## License
|
|
93
|
+
|
|
94
|
+
[MIT License](LICENSE.md) © 2026 Interop Alliance.
|
package/dist/common.d.ts
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Cross-spec primitives shared by the WAS (and, later, EDV) data models: the
|
|
6
|
+
* capability-action vocabulary, the RFC9457 problem-type registry plus its
|
|
7
|
+
* `application/problem+json` body shape and canonical code -> HTTP-status map,
|
|
8
|
+
* the storage-limit shape, the RFC9264 linkset shapes, and the reserved
|
|
9
|
+
* path-segment registry.
|
|
10
|
+
*
|
|
11
|
+
* This module is pure types plus a handful of `const` values; it has no runtime
|
|
12
|
+
* dependencies and is fully isomorphic.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* A capability action -- an HTTP verb in its canonical uppercase form, as it
|
|
16
|
+
* appears in the signed zcap. WAS servers match actions case-sensitively.
|
|
17
|
+
*/
|
|
18
|
+
export type Action = 'GET' | 'PUT' | 'POST' | 'DELETE';
|
|
19
|
+
/**
|
|
20
|
+
* The action input accepted by delegation helpers: canonical uppercase or
|
|
21
|
+
* lowercase. Lowercase is normalized to uppercase before the zcap is signed, so
|
|
22
|
+
* a grant of `'get'` still validates on the server (which expects `'GET'`).
|
|
23
|
+
*/
|
|
24
|
+
export type ActionInput = Action | Lowercase<Action>;
|
|
25
|
+
/**
|
|
26
|
+
* Catalog of `type` URIs emitted in `application/problem+json` error responses.
|
|
27
|
+
*
|
|
28
|
+
* Per [[RFC9457]], a problem `type` identifies the *kind* of problem and is
|
|
29
|
+
* reused across operations; the per-occurrence specifics live in the `errors`
|
|
30
|
+
* array (`detail` / `pointer`) and the human summary in `title`. So these URIs
|
|
31
|
+
* are keyed by problem-kind, not by operation -- a single `type` such as
|
|
32
|
+
* `INVALID_ID` is emitted by Create / Update / Read across Spaces, Collections,
|
|
33
|
+
* and Resources alike.
|
|
34
|
+
*
|
|
35
|
+
* **Privacy-merged kinds.** Under the spec's maximum-privacy principle, an
|
|
36
|
+
* unauthorized caller MUST NOT be able to tell a missing resource from one they
|
|
37
|
+
* simply cannot access. `NOT_FOUND` therefore deliberately covers both the
|
|
38
|
+
* "resource absent" and "invalid authorization" conditions (Space / Collection
|
|
39
|
+
* / Resource not found, and failed capability invocation) -- callers cannot use
|
|
40
|
+
* `type` to probe existence.
|
|
41
|
+
*
|
|
42
|
+
* Each URI is a fragment anchor into the WAS specification's Error Type
|
|
43
|
+
* Registry appendix.
|
|
44
|
+
*/
|
|
45
|
+
export declare const ProblemTypes: {
|
|
46
|
+
/**
|
|
47
|
+
* Privacy-merged -- the resource does not exist, OR the caller is not
|
|
48
|
+
* authorized to access it. The two conditions are intentionally
|
|
49
|
+
* indistinguishable; do not split this kind (see file header).
|
|
50
|
+
*/
|
|
51
|
+
readonly NOT_FOUND: "https://wallet.storage/spec#not-found";
|
|
52
|
+
/** A Space / Collection / Resource id is missing or not URL-safe. */
|
|
53
|
+
readonly INVALID_ID: "https://wallet.storage/spec#invalid-id";
|
|
54
|
+
/**
|
|
55
|
+
* A client-supplied `id` in a `POST` create operation already exists.
|
|
56
|
+
* (Create-or-replace at a chosen id is the idempotent `PUT` path, which does
|
|
57
|
+
* not conflict.) Typical status 409.
|
|
58
|
+
*/
|
|
59
|
+
readonly ID_CONFLICT: "https://wallet.storage/spec#id-conflict";
|
|
60
|
+
/**
|
|
61
|
+
* A client-supplied `id` collides with a segment from the spec's Reserved
|
|
62
|
+
* Path Segment Registry (e.g. a Collection named `export` would shadow
|
|
63
|
+
* `/space/{id}/export`). Typical status 409.
|
|
64
|
+
*/
|
|
65
|
+
readonly RESERVED_ID: "https://wallet.storage/spec#reserved-id";
|
|
66
|
+
/**
|
|
67
|
+
* A Collection create/update names a `backend` id that is not in the Space's
|
|
68
|
+
* backends-available list. Typical status 409.
|
|
69
|
+
*/
|
|
70
|
+
readonly UNSUPPORTED_BACKEND: "https://wallet.storage/spec#unsupported-backend";
|
|
71
|
+
/** The request body is missing or invalid (missing required fields, etc.). */
|
|
72
|
+
readonly INVALID_REQUEST_BODY: "https://wallet.storage/spec#invalid-request-body";
|
|
73
|
+
/** A required `Content-Type` header is missing. */
|
|
74
|
+
readonly MISSING_CONTENT_TYPE: "https://wallet.storage/spec#missing-content-type";
|
|
75
|
+
/** Required `Authorization` / `Capability-Invocation` headers are missing. */
|
|
76
|
+
readonly MISSING_AUTHORIZATION: "https://wallet.storage/spec#missing-authorization";
|
|
77
|
+
/**
|
|
78
|
+
* The `Authorization`, `Capability-Invocation`, or `Digest` header is
|
|
79
|
+
* malformed, unparseable, or failed verification.
|
|
80
|
+
*/
|
|
81
|
+
readonly INVALID_AUTHORIZATION_HEADER: "https://wallet.storage/spec#invalid-authorization-header";
|
|
82
|
+
/**
|
|
83
|
+
* The DID that signed the capability invocation does not match the
|
|
84
|
+
* `controller` supplied in a Create Space request body.
|
|
85
|
+
*/
|
|
86
|
+
readonly CONTROLLER_MISMATCH: "https://wallet.storage/spec#controller-mismatch";
|
|
87
|
+
/** An uploaded archive is not a valid WAS space export. */
|
|
88
|
+
readonly INVALID_IMPORT: "https://wallet.storage/spec#invalid-import";
|
|
89
|
+
/** An underlying storage operation failed (server-side fault). */
|
|
90
|
+
readonly STORAGE_ERROR: "https://wallet.storage/spec#storage-error";
|
|
91
|
+
/**
|
|
92
|
+
* A write was rejected because the target backend's per-Space storage quota
|
|
93
|
+
* is exhausted (see the spec "Quotas" section). Typical status 507.
|
|
94
|
+
*/
|
|
95
|
+
readonly QUOTA_EXCEEDED: "https://wallet.storage/spec#quota-exceeded";
|
|
96
|
+
/**
|
|
97
|
+
* An upload exceeds the target backend's `maxUploadBytes` constraint (see
|
|
98
|
+
* the spec "Quotas" section). Unlike `quota-exceeded`, this rejection is
|
|
99
|
+
* per-request, not cumulative: smaller uploads may still succeed. Typical
|
|
100
|
+
* status 413.
|
|
101
|
+
*/
|
|
102
|
+
readonly PAYLOAD_TOO_LARGE: "https://wallet.storage/spec#payload-too-large";
|
|
103
|
+
/**
|
|
104
|
+
* The server does not implement this OPTIONAL operation (e.g. updating
|
|
105
|
+
* Resource Metadata). Typical status 501.
|
|
106
|
+
*/
|
|
107
|
+
readonly UNSUPPORTED_OPERATION: "https://wallet.storage/spec#unsupported-operation";
|
|
108
|
+
/** Fallback for an unexpected server-side fault with no more specific kind. */
|
|
109
|
+
readonly INTERNAL_ERROR: "https://wallet.storage/spec#internal-error";
|
|
110
|
+
};
|
|
111
|
+
/** One of the problem-type URIs in {@link ProblemTypes}. */
|
|
112
|
+
export type ProblemType = (typeof ProblemTypes)[keyof typeof ProblemTypes];
|
|
113
|
+
/**
|
|
114
|
+
* A single entry in the `errors` array of an `application/problem+json`
|
|
115
|
+
* response body.
|
|
116
|
+
*
|
|
117
|
+
* - `detail` -- a specific explanation of this occurrence.
|
|
118
|
+
* - `pointer` -- an RFC6901 JSON Pointer (in `#/field` form) identifying the
|
|
119
|
+
* offending part of the request body.
|
|
120
|
+
*/
|
|
121
|
+
export interface Problem {
|
|
122
|
+
detail: string;
|
|
123
|
+
pointer?: string;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* The `application/problem+json` response body a WAS server emits (RFC9457).
|
|
127
|
+
* `type` is one of {@link ProblemTypes}; `title` is a short human-readable
|
|
128
|
+
* summary; `errors` carries the per-occurrence {@link Problem} entries.
|
|
129
|
+
*
|
|
130
|
+
* Note: the wire field is `errors`. A server's internal error object may carry
|
|
131
|
+
* these under a different name (the reference server's `ProblemError` uses
|
|
132
|
+
* `problems`); the mapping to `errors` happens at serialization time.
|
|
133
|
+
*/
|
|
134
|
+
export interface ProblemDocument {
|
|
135
|
+
type: ProblemType | string;
|
|
136
|
+
title: string;
|
|
137
|
+
errors: Problem[];
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* The canonical HTTP status code for each problem kind. Both the server (when
|
|
141
|
+
* throwing) and the client (when interpreting a response) treat these as the
|
|
142
|
+
* default status associated with a `type`; a server MAY still override per
|
|
143
|
+
* occurrence, but the reference implementation does not.
|
|
144
|
+
*/
|
|
145
|
+
export declare const ProblemStatusCodes: Record<ProblemType, number>;
|
|
146
|
+
/**
|
|
147
|
+
* The storage limit for a backend (spec "Quotas"). When `isUnlimited` is
|
|
148
|
+
* `true`, `capacityBytes` MAY be omitted (the reference filesystem backend
|
|
149
|
+
* omits it unless a capacity was configured).
|
|
150
|
+
*/
|
|
151
|
+
export interface StorageLimit {
|
|
152
|
+
capacityBytes?: number;
|
|
153
|
+
isUnlimited: boolean;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* One member of a {@link LinkSet} (RFC9264): an `anchor` plus relation keys
|
|
157
|
+
* (e.g. `https://wallet.storage/spec#policy`) mapping to arrays of link
|
|
158
|
+
* targets.
|
|
159
|
+
*/
|
|
160
|
+
export interface LinkSetEntry {
|
|
161
|
+
anchor?: string;
|
|
162
|
+
[relation: string]: unknown;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* An RFC9264 `application/linkset+json` document, the return shape of the
|
|
166
|
+
* `linkset` reserved resource on a Space or Collection.
|
|
167
|
+
*/
|
|
168
|
+
export interface LinkSet {
|
|
169
|
+
linkset: LinkSetEntry[];
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Reserved Collection-id path segments (the spec's Reserved Path Segment
|
|
173
|
+
* Registry, plus the reference server's non-spec `import` endpoint). A
|
|
174
|
+
* client-chosen Collection id matching one of these would shadow the reserved
|
|
175
|
+
* route at that position (e.g. a Collection named `export` would shadow
|
|
176
|
+
* `/space/{id}/export`), so it MUST be rejected with 409 `reserved-id`.
|
|
177
|
+
*/
|
|
178
|
+
export declare const RESERVED_COLLECTION_IDS: Set<string>;
|
|
179
|
+
/**
|
|
180
|
+
* Reserved Resource-id path segments (the spec's Reserved Path Segment
|
|
181
|
+
* Registry). A client-chosen Resource id matching one of these would shadow the
|
|
182
|
+
* reserved route at that position, so it MUST be rejected with 409
|
|
183
|
+
* `reserved-id`. Space ids have no reserved siblings, so no set exists for the
|
|
184
|
+
* `space` kind.
|
|
185
|
+
*/
|
|
186
|
+
export declare const RESERVED_RESOURCE_IDS: Set<string>;
|
|
187
|
+
//# sourceMappingURL=common.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;GASG;AAEH;;;GAGG;AACH,MAAM,MAAM,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAA;AAEtD;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAA;AAIpD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,YAAY;IACvB;;;;OAIG;;IAGH,qEAAqE;;IAGrE;;;;OAIG;;IAGH;;;;OAIG;;IAGH;;;OAGG;;IAGH,8EAA8E;;IAG9E,mDAAmD;;IAGnD,8EAA8E;;IAG9E;;;OAGG;;IAGH;;;OAGG;;IAGH,2DAA2D;;IAG3D,kEAAkE;;IAGlE;;;OAGG;;IAGH;;;;;OAKG;;IAGH;;;OAGG;;IAGH,+EAA+E;;CAEvE,CAAA;AAEV,4DAA4D;AAC5D,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAA;AAE1E;;;;;;;GAOG;AACH,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,WAAW,GAAG,MAAM,CAAA;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,OAAO,EAAE,CAAA;CAClB;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAiB1D,CAAA;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,WAAW,EAAE,OAAO,CAAA;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;CAC5B;AAED;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,YAAY,EAAE,CAAA;CACxB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,aASlC,CAAA;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,aAMhC,CAAA"}
|
package/dist/common.js
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Cross-spec primitives shared by the WAS (and, later, EDV) data models: the
|
|
6
|
+
* capability-action vocabulary, the RFC9457 problem-type registry plus its
|
|
7
|
+
* `application/problem+json` body shape and canonical code -> HTTP-status map,
|
|
8
|
+
* the storage-limit shape, the RFC9264 linkset shapes, and the reserved
|
|
9
|
+
* path-segment registry.
|
|
10
|
+
*
|
|
11
|
+
* This module is pure types plus a handful of `const` values; it has no runtime
|
|
12
|
+
* dependencies and is fully isomorphic.
|
|
13
|
+
*/
|
|
14
|
+
const SPEC_URL = 'https://wallet.storage/spec';
|
|
15
|
+
/**
|
|
16
|
+
* Catalog of `type` URIs emitted in `application/problem+json` error responses.
|
|
17
|
+
*
|
|
18
|
+
* Per [[RFC9457]], a problem `type` identifies the *kind* of problem and is
|
|
19
|
+
* reused across operations; the per-occurrence specifics live in the `errors`
|
|
20
|
+
* array (`detail` / `pointer`) and the human summary in `title`. So these URIs
|
|
21
|
+
* are keyed by problem-kind, not by operation -- a single `type` such as
|
|
22
|
+
* `INVALID_ID` is emitted by Create / Update / Read across Spaces, Collections,
|
|
23
|
+
* and Resources alike.
|
|
24
|
+
*
|
|
25
|
+
* **Privacy-merged kinds.** Under the spec's maximum-privacy principle, an
|
|
26
|
+
* unauthorized caller MUST NOT be able to tell a missing resource from one they
|
|
27
|
+
* simply cannot access. `NOT_FOUND` therefore deliberately covers both the
|
|
28
|
+
* "resource absent" and "invalid authorization" conditions (Space / Collection
|
|
29
|
+
* / Resource not found, and failed capability invocation) -- callers cannot use
|
|
30
|
+
* `type` to probe existence.
|
|
31
|
+
*
|
|
32
|
+
* Each URI is a fragment anchor into the WAS specification's Error Type
|
|
33
|
+
* Registry appendix.
|
|
34
|
+
*/
|
|
35
|
+
export const ProblemTypes = {
|
|
36
|
+
/**
|
|
37
|
+
* Privacy-merged -- the resource does not exist, OR the caller is not
|
|
38
|
+
* authorized to access it. The two conditions are intentionally
|
|
39
|
+
* indistinguishable; do not split this kind (see file header).
|
|
40
|
+
*/
|
|
41
|
+
NOT_FOUND: `${SPEC_URL}#not-found`,
|
|
42
|
+
/** A Space / Collection / Resource id is missing or not URL-safe. */
|
|
43
|
+
INVALID_ID: `${SPEC_URL}#invalid-id`,
|
|
44
|
+
/**
|
|
45
|
+
* A client-supplied `id` in a `POST` create operation already exists.
|
|
46
|
+
* (Create-or-replace at a chosen id is the idempotent `PUT` path, which does
|
|
47
|
+
* not conflict.) Typical status 409.
|
|
48
|
+
*/
|
|
49
|
+
ID_CONFLICT: `${SPEC_URL}#id-conflict`,
|
|
50
|
+
/**
|
|
51
|
+
* A client-supplied `id` collides with a segment from the spec's Reserved
|
|
52
|
+
* Path Segment Registry (e.g. a Collection named `export` would shadow
|
|
53
|
+
* `/space/{id}/export`). Typical status 409.
|
|
54
|
+
*/
|
|
55
|
+
RESERVED_ID: `${SPEC_URL}#reserved-id`,
|
|
56
|
+
/**
|
|
57
|
+
* A Collection create/update names a `backend` id that is not in the Space's
|
|
58
|
+
* backends-available list. Typical status 409.
|
|
59
|
+
*/
|
|
60
|
+
UNSUPPORTED_BACKEND: `${SPEC_URL}#unsupported-backend`,
|
|
61
|
+
/** The request body is missing or invalid (missing required fields, etc.). */
|
|
62
|
+
INVALID_REQUEST_BODY: `${SPEC_URL}#invalid-request-body`,
|
|
63
|
+
/** A required `Content-Type` header is missing. */
|
|
64
|
+
MISSING_CONTENT_TYPE: `${SPEC_URL}#missing-content-type`,
|
|
65
|
+
/** Required `Authorization` / `Capability-Invocation` headers are missing. */
|
|
66
|
+
MISSING_AUTHORIZATION: `${SPEC_URL}#missing-authorization`,
|
|
67
|
+
/**
|
|
68
|
+
* The `Authorization`, `Capability-Invocation`, or `Digest` header is
|
|
69
|
+
* malformed, unparseable, or failed verification.
|
|
70
|
+
*/
|
|
71
|
+
INVALID_AUTHORIZATION_HEADER: `${SPEC_URL}#invalid-authorization-header`,
|
|
72
|
+
/**
|
|
73
|
+
* The DID that signed the capability invocation does not match the
|
|
74
|
+
* `controller` supplied in a Create Space request body.
|
|
75
|
+
*/
|
|
76
|
+
CONTROLLER_MISMATCH: `${SPEC_URL}#controller-mismatch`,
|
|
77
|
+
/** An uploaded archive is not a valid WAS space export. */
|
|
78
|
+
INVALID_IMPORT: `${SPEC_URL}#invalid-import`,
|
|
79
|
+
/** An underlying storage operation failed (server-side fault). */
|
|
80
|
+
STORAGE_ERROR: `${SPEC_URL}#storage-error`,
|
|
81
|
+
/**
|
|
82
|
+
* A write was rejected because the target backend's per-Space storage quota
|
|
83
|
+
* is exhausted (see the spec "Quotas" section). Typical status 507.
|
|
84
|
+
*/
|
|
85
|
+
QUOTA_EXCEEDED: `${SPEC_URL}#quota-exceeded`,
|
|
86
|
+
/**
|
|
87
|
+
* An upload exceeds the target backend's `maxUploadBytes` constraint (see
|
|
88
|
+
* the spec "Quotas" section). Unlike `quota-exceeded`, this rejection is
|
|
89
|
+
* per-request, not cumulative: smaller uploads may still succeed. Typical
|
|
90
|
+
* status 413.
|
|
91
|
+
*/
|
|
92
|
+
PAYLOAD_TOO_LARGE: `${SPEC_URL}#payload-too-large`,
|
|
93
|
+
/**
|
|
94
|
+
* The server does not implement this OPTIONAL operation (e.g. updating
|
|
95
|
+
* Resource Metadata). Typical status 501.
|
|
96
|
+
*/
|
|
97
|
+
UNSUPPORTED_OPERATION: `${SPEC_URL}#unsupported-operation`,
|
|
98
|
+
/** Fallback for an unexpected server-side fault with no more specific kind. */
|
|
99
|
+
INTERNAL_ERROR: `${SPEC_URL}#internal-error`
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* The canonical HTTP status code for each problem kind. Both the server (when
|
|
103
|
+
* throwing) and the client (when interpreting a response) treat these as the
|
|
104
|
+
* default status associated with a `type`; a server MAY still override per
|
|
105
|
+
* occurrence, but the reference implementation does not.
|
|
106
|
+
*/
|
|
107
|
+
export const ProblemStatusCodes = {
|
|
108
|
+
[ProblemTypes.NOT_FOUND]: 404,
|
|
109
|
+
[ProblemTypes.INVALID_ID]: 400,
|
|
110
|
+
[ProblemTypes.ID_CONFLICT]: 409,
|
|
111
|
+
[ProblemTypes.RESERVED_ID]: 409,
|
|
112
|
+
[ProblemTypes.UNSUPPORTED_BACKEND]: 409,
|
|
113
|
+
[ProblemTypes.INVALID_REQUEST_BODY]: 400,
|
|
114
|
+
[ProblemTypes.MISSING_CONTENT_TYPE]: 400,
|
|
115
|
+
[ProblemTypes.MISSING_AUTHORIZATION]: 401,
|
|
116
|
+
[ProblemTypes.INVALID_AUTHORIZATION_HEADER]: 400,
|
|
117
|
+
[ProblemTypes.CONTROLLER_MISMATCH]: 400,
|
|
118
|
+
[ProblemTypes.INVALID_IMPORT]: 400,
|
|
119
|
+
[ProblemTypes.STORAGE_ERROR]: 500,
|
|
120
|
+
[ProblemTypes.QUOTA_EXCEEDED]: 507,
|
|
121
|
+
[ProblemTypes.PAYLOAD_TOO_LARGE]: 413,
|
|
122
|
+
[ProblemTypes.UNSUPPORTED_OPERATION]: 501,
|
|
123
|
+
[ProblemTypes.INTERNAL_ERROR]: 500
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Reserved Collection-id path segments (the spec's Reserved Path Segment
|
|
127
|
+
* Registry, plus the reference server's non-spec `import` endpoint). A
|
|
128
|
+
* client-chosen Collection id matching one of these would shadow the reserved
|
|
129
|
+
* route at that position (e.g. a Collection named `export` would shadow
|
|
130
|
+
* `/space/{id}/export`), so it MUST be rejected with 409 `reserved-id`.
|
|
131
|
+
*/
|
|
132
|
+
export const RESERVED_COLLECTION_IDS = new Set([
|
|
133
|
+
'backends',
|
|
134
|
+
'collections',
|
|
135
|
+
'export',
|
|
136
|
+
'import',
|
|
137
|
+
'linkset',
|
|
138
|
+
'policy',
|
|
139
|
+
'query',
|
|
140
|
+
'quotas'
|
|
141
|
+
]);
|
|
142
|
+
/**
|
|
143
|
+
* Reserved Resource-id path segments (the spec's Reserved Path Segment
|
|
144
|
+
* Registry). A client-chosen Resource id matching one of these would shadow the
|
|
145
|
+
* reserved route at that position, so it MUST be rejected with 409
|
|
146
|
+
* `reserved-id`. Space ids have no reserved siblings, so no set exists for the
|
|
147
|
+
* `space` kind.
|
|
148
|
+
*/
|
|
149
|
+
export const RESERVED_RESOURCE_IDS = new Set([
|
|
150
|
+
'backend',
|
|
151
|
+
'linkset',
|
|
152
|
+
'policy',
|
|
153
|
+
'query',
|
|
154
|
+
'quota'
|
|
155
|
+
]);
|
|
156
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;GASG;AAeH,MAAM,QAAQ,GAAG,6BAA6B,CAAA;AAE9C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B;;;;OAIG;IACH,SAAS,EAAE,GAAG,QAAQ,YAAY;IAElC,qEAAqE;IACrE,UAAU,EAAE,GAAG,QAAQ,aAAa;IAEpC;;;;OAIG;IACH,WAAW,EAAE,GAAG,QAAQ,cAAc;IAEtC;;;;OAIG;IACH,WAAW,EAAE,GAAG,QAAQ,cAAc;IAEtC;;;OAGG;IACH,mBAAmB,EAAE,GAAG,QAAQ,sBAAsB;IAEtD,8EAA8E;IAC9E,oBAAoB,EAAE,GAAG,QAAQ,uBAAuB;IAExD,mDAAmD;IACnD,oBAAoB,EAAE,GAAG,QAAQ,uBAAuB;IAExD,8EAA8E;IAC9E,qBAAqB,EAAE,GAAG,QAAQ,wBAAwB;IAE1D;;;OAGG;IACH,4BAA4B,EAAE,GAAG,QAAQ,+BAA+B;IAExE;;;OAGG;IACH,mBAAmB,EAAE,GAAG,QAAQ,sBAAsB;IAEtD,2DAA2D;IAC3D,cAAc,EAAE,GAAG,QAAQ,iBAAiB;IAE5C,kEAAkE;IAClE,aAAa,EAAE,GAAG,QAAQ,gBAAgB;IAE1C;;;OAGG;IACH,cAAc,EAAE,GAAG,QAAQ,iBAAiB;IAE5C;;;;;OAKG;IACH,iBAAiB,EAAE,GAAG,QAAQ,oBAAoB;IAElD;;;OAGG;IACH,qBAAqB,EAAE,GAAG,QAAQ,wBAAwB;IAE1D,+EAA+E;IAC/E,cAAc,EAAE,GAAG,QAAQ,iBAAiB;CACpC,CAAA;AAiCV;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAgC;IAC7D,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,GAAG;IAC7B,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,GAAG;IAC9B,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,GAAG;IAC/B,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,GAAG;IAC/B,CAAC,YAAY,CAAC,mBAAmB,CAAC,EAAE,GAAG;IACvC,CAAC,YAAY,CAAC,oBAAoB,CAAC,EAAE,GAAG;IACxC,CAAC,YAAY,CAAC,oBAAoB,CAAC,EAAE,GAAG;IACxC,CAAC,YAAY,CAAC,qBAAqB,CAAC,EAAE,GAAG;IACzC,CAAC,YAAY,CAAC,4BAA4B,CAAC,EAAE,GAAG;IAChD,CAAC,YAAY,CAAC,mBAAmB,CAAC,EAAE,GAAG;IACvC,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,GAAG;IAClC,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE,GAAG;IACjC,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,GAAG;IAClC,CAAC,YAAY,CAAC,iBAAiB,CAAC,EAAE,GAAG;IACrC,CAAC,YAAY,CAAC,qBAAqB,CAAC,EAAE,GAAG;IACzC,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,GAAG;CACnC,CAAA;AA8BD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC;IAC7C,UAAU;IACV,aAAa;IACb,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,OAAO;IACP,QAAQ;CACT,CAAC,CAAA;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;IAC3C,SAAS;IACT,SAAS;IACT,QAAQ;IACR,OAAO;IACP,OAAO;CACR,CAAC,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Public entry point for `@interop/storage-core`: a flat re-export of the
|
|
6
|
+
* cross-spec primitives (`./common`) and the WAS data model (`./was`). The EDV
|
|
7
|
+
* data model will be added as `./edv` without changing this surface.
|
|
8
|
+
*/
|
|
9
|
+
export * from './common.js';
|
|
10
|
+
export * from './was.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;GAIG;AACH,cAAc,aAAa,CAAA;AAC3B,cAAc,UAAU,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Public entry point for `@interop/storage-core`: a flat re-export of the
|
|
6
|
+
* cross-spec primitives (`./common`) and the WAS data model (`./was`). The EDV
|
|
7
|
+
* data model will be added as `./edv` without changing this surface.
|
|
8
|
+
*/
|
|
9
|
+
export * from './common.js';
|
|
10
|
+
export * from './was.js';
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;GAIG;AACH,cAAc,aAAa,CAAA;AAC3B,cAAc,UAAU,CAAA"}
|
package/dist/was.d.ts
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* The Wallet Attached Storage (WAS) data model: the on-the-wire JSON shapes a
|
|
6
|
+
* WAS server emits and a client parses -- Space / Collection / Resource
|
|
7
|
+
* descriptions and summaries, listing shapes, resource metadata, the backend
|
|
8
|
+
* descriptor / usage shapes, the quota report, and the access-control policy
|
|
9
|
+
* document.
|
|
10
|
+
*
|
|
11
|
+
* These types are modeled to what the spec *guarantees* (e.g. on a
|
|
12
|
+
* {@link BackendDescriptor} only `id` is required). A producer that always
|
|
13
|
+
* populates the optional fields asserts that locally with `satisfies
|
|
14
|
+
* Required<T>` at the construction site rather than declaring a stricter type
|
|
15
|
+
* here.
|
|
16
|
+
*
|
|
17
|
+
* `controller` references `IDID` from `@interop/data-integrity-core` via a
|
|
18
|
+
* type-only import; that type is *used* in declarations but not re-exported --
|
|
19
|
+
* consumers that need `IDID` import it directly from `data-integrity-core`.
|
|
20
|
+
*/
|
|
21
|
+
import type { IDID } from '@interop/data-integrity-core';
|
|
22
|
+
import type { Action, StorageLimit } from './common.js';
|
|
23
|
+
/**
|
|
24
|
+
* A Space Description object -- the metadata stored for a Space.
|
|
25
|
+
*/
|
|
26
|
+
export interface SpaceDescription {
|
|
27
|
+
id: string;
|
|
28
|
+
/** e.g. `['Space']` */
|
|
29
|
+
type: string[];
|
|
30
|
+
/** optional human-readable name for the Space (see spec) */
|
|
31
|
+
name?: string;
|
|
32
|
+
/** the `did:key` that owns (controls) the Space */
|
|
33
|
+
controller: IDID;
|
|
34
|
+
/** absolute URL of the Space, when the server populates it */
|
|
35
|
+
url?: string;
|
|
36
|
+
/**
|
|
37
|
+
* URL of the Space's linkset resource (RFC9264), where auxiliary resources
|
|
38
|
+
* such as the access-control `policy` are discovered. Attached at response
|
|
39
|
+
* time, not persisted.
|
|
40
|
+
*/
|
|
41
|
+
linkset?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A reference to a storage backend, used when creating or configuring a
|
|
45
|
+
* Collection and when describing the backend a Collection is stored on.
|
|
46
|
+
*/
|
|
47
|
+
export interface BackendReference {
|
|
48
|
+
id: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* A Collection Description object -- the metadata stored for a Collection.
|
|
52
|
+
*/
|
|
53
|
+
export interface CollectionDescription {
|
|
54
|
+
id: string;
|
|
55
|
+
/** e.g. `['Collection']` */
|
|
56
|
+
type: string[];
|
|
57
|
+
name?: string;
|
|
58
|
+
/** absolute URL of the Collection, when the server populates it */
|
|
59
|
+
url?: string;
|
|
60
|
+
/**
|
|
61
|
+
* The storage backend selected for this Collection (spec "Collection Backend
|
|
62
|
+
* Selected"). Its `id` MUST be one of the Space's backends-available. Omitted
|
|
63
|
+
* by a client at create time, the server fills it with the default
|
|
64
|
+
* `{ id: 'default' }`; persisted thereafter.
|
|
65
|
+
*/
|
|
66
|
+
backend?: BackendReference;
|
|
67
|
+
/**
|
|
68
|
+
* URL of the Collection's linkset resource (RFC9264); see
|
|
69
|
+
* `SpaceDescription.linkset`. Attached at response time, not persisted.
|
|
70
|
+
*/
|
|
71
|
+
linkset?: string;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* An access-control policy document attached to a Space, Collection, or
|
|
75
|
+
* Resource (the `policy` reserved resource at each level). A `type`-discriminated
|
|
76
|
+
* open shape: v1 recognizes only `{ "type": "PublicCanRead" }`. Unrecognized
|
|
77
|
+
* `type` values grant nothing (fail-closed), so the request falls through to the
|
|
78
|
+
* normal zcap-only authorization decision. Policies are permissive-only: they
|
|
79
|
+
* can broaden access beyond what a capability grants, never restrict a valid
|
|
80
|
+
* capability holder.
|
|
81
|
+
*/
|
|
82
|
+
export interface PolicyDocument {
|
|
83
|
+
type: string;
|
|
84
|
+
[key: string]: unknown;
|
|
85
|
+
}
|
|
86
|
+
/** One entry in a {@link SpaceListing} (a Space within the repository). */
|
|
87
|
+
export interface SpaceSummary {
|
|
88
|
+
id: string;
|
|
89
|
+
name?: string;
|
|
90
|
+
/** relative URL of the Space */
|
|
91
|
+
url: string;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Return shape of the List Spaces operation (`GET /spaces/`): the Spaces within
|
|
95
|
+
* the repository the caller is authorized to see.
|
|
96
|
+
*/
|
|
97
|
+
export interface SpaceListing {
|
|
98
|
+
url: string;
|
|
99
|
+
totalItems: number;
|
|
100
|
+
items: SpaceSummary[];
|
|
101
|
+
}
|
|
102
|
+
/** One entry in a {@link CollectionsList} (a Collection within a Space). */
|
|
103
|
+
export interface CollectionSummary {
|
|
104
|
+
id: string;
|
|
105
|
+
/** relative URL, `/space/:spaceId/:collectionId` */
|
|
106
|
+
url: string;
|
|
107
|
+
name: string;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Return shape of the List Collections operation (the Collections within one
|
|
111
|
+
* Space). Renamed from the former `CollectionListing` to disambiguate it from
|
|
112
|
+
* {@link CollectionResourcesList}.
|
|
113
|
+
*/
|
|
114
|
+
export interface CollectionsList {
|
|
115
|
+
url: string;
|
|
116
|
+
totalItems: number;
|
|
117
|
+
items: CollectionSummary[];
|
|
118
|
+
}
|
|
119
|
+
/** One entry in a {@link CollectionResourcesList} (a Resource within a Collection). */
|
|
120
|
+
export interface ResourceSummary {
|
|
121
|
+
id: string;
|
|
122
|
+
/** relative URL of the Resource */
|
|
123
|
+
url: string;
|
|
124
|
+
contentType: string;
|
|
125
|
+
/** human-readable name from the Resource's `custom.name`, when set */
|
|
126
|
+
name?: string;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Return shape of the List Collection operation (the Resources within one
|
|
130
|
+
* Collection). Renamed from the former `CollectionListing` (server) /
|
|
131
|
+
* `ResourceListing` (client) to disambiguate it from {@link CollectionsList}.
|
|
132
|
+
*/
|
|
133
|
+
export interface CollectionResourcesList {
|
|
134
|
+
id: string;
|
|
135
|
+
url: string;
|
|
136
|
+
/**
|
|
137
|
+
* The listing-level name (the Collection's name). Mirrors the Collection
|
|
138
|
+
* Description's `name`.
|
|
139
|
+
*/
|
|
140
|
+
name?: string;
|
|
141
|
+
type: string[];
|
|
142
|
+
totalItems: number;
|
|
143
|
+
items: ResourceSummary[];
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* The user-writable portion of a Resource's Metadata object (spec "Resource
|
|
147
|
+
* Metadata Data Model"), nested under `custom`. Set via Update Resource Metadata
|
|
148
|
+
* (`PUT .../meta`); a full replacement, so any property omitted is cleared.
|
|
149
|
+
*/
|
|
150
|
+
export interface ResourceMetadataCustom {
|
|
151
|
+
/**
|
|
152
|
+
* Human-readable name for the Resource. The same `name` returned by List
|
|
153
|
+
* Collection -- updating it here updates the name shown in listings.
|
|
154
|
+
*/
|
|
155
|
+
name?: string;
|
|
156
|
+
/** Application-defined annotations; values SHOULD be strings (spec). */
|
|
157
|
+
tags?: Record<string, string>;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* A Resource Metadata object (spec "Resource Metadata Data Model"), addressable
|
|
161
|
+
* at the reserved `/meta` segment under a Resource. `contentType` and `size` are
|
|
162
|
+
* the REQUIRED server-managed fields; `createdAt` / `updatedAt` are the OPTIONAL
|
|
163
|
+
* server-managed timestamps, and `custom` holds the user-writable properties.
|
|
164
|
+
*/
|
|
165
|
+
export interface ResourceMetadata {
|
|
166
|
+
/** MIME type of the stored representation */
|
|
167
|
+
contentType: string;
|
|
168
|
+
/** length in bytes of the stored representation */
|
|
169
|
+
size: number;
|
|
170
|
+
/** RFC3339 date-time the Resource was created */
|
|
171
|
+
createdAt?: string;
|
|
172
|
+
/** RFC3339 date-time the Resource's content or custom metadata last changed */
|
|
173
|
+
updatedAt?: string;
|
|
174
|
+
/** user-writable properties (omitted when none are set) */
|
|
175
|
+
custom?: ResourceMetadataCustom;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* A Backend description object (spec "Backend Data Model"), as returned in the
|
|
179
|
+
* array at `GET /space/:spaceId/backends`. The spec only REQUIRES `id` and
|
|
180
|
+
* defines defaults for the rest; a server that always populates the optional
|
|
181
|
+
* fields asserts that at its construction site (`satisfies
|
|
182
|
+
* Required<BackendDescriptor>`).
|
|
183
|
+
*
|
|
184
|
+
* - `id` -- the registration id under the Space (`default` for the single
|
|
185
|
+
* server-configured backend the reference server ships with).
|
|
186
|
+
* - `name` -- a human-readable label.
|
|
187
|
+
* - `managedBy` -- who operates the backend: `server` (configured server-side)
|
|
188
|
+
* or `external` (a Bring Your Own Storage provider registered by the client).
|
|
189
|
+
* Spec default: `server`.
|
|
190
|
+
* - `storageMode` -- which representations the backend can store: `document`
|
|
191
|
+
* (structured JSON) and/or `blob` (opaque binary). Spec default: both.
|
|
192
|
+
* - `persistence` -- whether the storage engine keeps data on persistent media
|
|
193
|
+
* that survives a restart (`durable`) or only in memory (`volatile`). Spec
|
|
194
|
+
* default: `durable`.
|
|
195
|
+
*/
|
|
196
|
+
export interface BackendDescriptor {
|
|
197
|
+
id: string;
|
|
198
|
+
name?: string;
|
|
199
|
+
managedBy?: 'server' | 'external';
|
|
200
|
+
storageMode?: Array<'document' | 'blob'>;
|
|
201
|
+
persistence?: 'durable' | 'volatile';
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* A backend's current condition in a quota report (spec "Quotas"). `ok`,
|
|
205
|
+
* `near-limit`, and `over-quota` are derived from usage vs the configured limit;
|
|
206
|
+
* `unreachable` is reserved for `external` backends whose provider cannot be
|
|
207
|
+
* queried (the server-managed filesystem backend never reports it).
|
|
208
|
+
*/
|
|
209
|
+
export type BackendState = 'ok' | 'near-limit' | 'over-quota' | 'unreachable';
|
|
210
|
+
/** One Collection's consumption within a backend's `usageByCollection` array. */
|
|
211
|
+
export interface CollectionUsage {
|
|
212
|
+
id: string;
|
|
213
|
+
usageBytes: number;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* One backend's entry in a {@link SpaceQuotaReport} (spec "Quotas"). Combines
|
|
217
|
+
* the backend's identifying properties (`id` / `name` / `managedBy`, from its
|
|
218
|
+
* `describe()`) with the measured usage for the reporting Space.
|
|
219
|
+
*
|
|
220
|
+
* - `usageBytes` -- total bytes this Space consumes on this backend.
|
|
221
|
+
* - `restrictedActions` -- capability actions (uppercase HTTP verbs) currently
|
|
222
|
+
* unavailable on the backend; e.g. a full backend reports `["POST", "PUT"]`
|
|
223
|
+
* while still permitting reads and deletes.
|
|
224
|
+
* - `measuredAt` -- when the usage numbers were measured (distinct from the
|
|
225
|
+
* report's top-level `respondedAt`).
|
|
226
|
+
* - `usageByCollection` -- per-Collection breakdown. The spec makes this opt-in
|
|
227
|
+
* via `?include=collections`; the field stays optional so a backend may omit
|
|
228
|
+
* it.
|
|
229
|
+
*/
|
|
230
|
+
export interface BackendUsage {
|
|
231
|
+
id: string;
|
|
232
|
+
name?: string;
|
|
233
|
+
managedBy: 'server' | 'external';
|
|
234
|
+
state: BackendState;
|
|
235
|
+
usageBytes: number;
|
|
236
|
+
limit: StorageLimit;
|
|
237
|
+
/** operational constraints such as `maxUploadBytes` */
|
|
238
|
+
constraints?: {
|
|
239
|
+
maxUploadBytes?: number;
|
|
240
|
+
[key: string]: unknown;
|
|
241
|
+
};
|
|
242
|
+
restrictedActions: Action[];
|
|
243
|
+
measuredAt: string;
|
|
244
|
+
usageByCollection?: CollectionUsage[];
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* The Space Quota report (spec "Quotas"), returned by
|
|
248
|
+
* `GET /space/:spaceId/quotas`: a measurement timestamp plus one
|
|
249
|
+
* {@link BackendUsage} entry per backend registered for the Space.
|
|
250
|
+
*/
|
|
251
|
+
export interface SpaceQuotaReport {
|
|
252
|
+
respondedAt: string;
|
|
253
|
+
backends: BackendUsage[];
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Return shape of the Import Space operation: a per-merge tally.
|
|
257
|
+
*/
|
|
258
|
+
export interface ImportStats {
|
|
259
|
+
collectionsCreated: number;
|
|
260
|
+
collectionsSkipped: number;
|
|
261
|
+
resourcesCreated: number;
|
|
262
|
+
resourcesSkipped: number;
|
|
263
|
+
policiesCreated: number;
|
|
264
|
+
policiesSkipped: number;
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=was.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"was.d.ts","sourceRoot":"","sources":["../src/was.ts"],"names":[],"mappings":"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"}
|
package/dist/was.js
ADDED
package/dist/was.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"was.js","sourceRoot":"","sources":["../src/was.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@interop/storage-core",
|
|
3
|
+
"description": "Shared WAS/EDV wire-model types and error vocabulary for the Wallet Attached Storage server and client.",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "pnpm run clear && tsc",
|
|
8
|
+
"clear": "rimraf dist/*",
|
|
9
|
+
"fix": "eslint --fix src test && pnpm run format",
|
|
10
|
+
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"*.md\"",
|
|
11
|
+
"lint": "eslint src test",
|
|
12
|
+
"prepare": "pnpm run build",
|
|
13
|
+
"rebuild": "pnpm run clear && pnpm run build",
|
|
14
|
+
"test": "pnpm run fix && pnpm run lint && pnpm run test:node",
|
|
15
|
+
"test:node": "vitest run",
|
|
16
|
+
"test:coverage": "vitest run --coverage"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE.md"
|
|
22
|
+
],
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"react-native": "./dist/index.js",
|
|
27
|
+
"import": "./dist/index.js",
|
|
28
|
+
"default": "./dist/index.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"module": "dist/index.js",
|
|
32
|
+
"browser": "dist/index.js",
|
|
33
|
+
"types": "dist/index.d.ts",
|
|
34
|
+
"sideEffects": false,
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@interop/data-integrity-core": "^8.0.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@eslint/js": "^10.0.1",
|
|
40
|
+
"@types/node": "^25.9.1",
|
|
41
|
+
"@vitest/coverage-v8": "^4.1.7",
|
|
42
|
+
"eslint": "^10.4.0",
|
|
43
|
+
"eslint-config-prettier": "^10.1.8",
|
|
44
|
+
"globals": "^17.6.0",
|
|
45
|
+
"prettier": "^3.8.3",
|
|
46
|
+
"rimraf": "^6.1.3",
|
|
47
|
+
"typescript": "^5.9.3",
|
|
48
|
+
"typescript-eslint": "^8.59.4",
|
|
49
|
+
"vitest": "^4.1.7"
|
|
50
|
+
},
|
|
51
|
+
"publishConfig": {
|
|
52
|
+
"access": "public"
|
|
53
|
+
},
|
|
54
|
+
"keywords": [
|
|
55
|
+
"wallet-attached-storage",
|
|
56
|
+
"was",
|
|
57
|
+
"edv",
|
|
58
|
+
"storage",
|
|
59
|
+
"isomorphic"
|
|
60
|
+
],
|
|
61
|
+
"packageManager": "pnpm@11.5.0",
|
|
62
|
+
"engines": {
|
|
63
|
+
"node": ">=22.0"
|
|
64
|
+
},
|
|
65
|
+
"author": {
|
|
66
|
+
"name": "Interop Alliance",
|
|
67
|
+
"url": "https://github.com/interop-alliance/"
|
|
68
|
+
},
|
|
69
|
+
"license": "MIT",
|
|
70
|
+
"repository": {
|
|
71
|
+
"type": "git",
|
|
72
|
+
"url": "git+https://github.com/interop-alliance/storage-core.git"
|
|
73
|
+
},
|
|
74
|
+
"homepage": "https://github.com/interop-alliance/storage-core",
|
|
75
|
+
"bugs": "https://github.com/interop-alliance/storage-core/issues"
|
|
76
|
+
}
|