@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 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
+ [![Node.js CI](https://github.com/interop-alliance/storage-core/workflows/CI/badge.svg)](https://github.com/interop-alliance/storage-core/actions?query=workflow%3A%22CI%22)
4
+ [![NPM Version](https://img.shields.io/npm/v/@interop/storage-core.svg)](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.
@@ -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"}
@@ -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
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=was.js.map
@@ -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
+ }