import type { ClientContext } from './internal/request.js'; import { Collection } from './Collection.js'; import type { BackendDescriptor, BackendReference, BackendRegistration, CollectionEncryption, CollectionsList, GrantOptions, HandleOptions, IDID, IDelegatedZcap, IZcap, ImportStats, LinkSet, PolicyDocument, SpaceDescription, SpaceQuotaReport } from './types.js'; export declare class Space { #private; readonly id: string; /** * @param options {object} * @param options.context {ClientContext} * @param options.spaceId {string} * @param [options.capability] {IZcap} capability attached to every request */ constructor({ context, spaceId, capability }: { context: ClientContext; spaceId: string; capability?: IZcap; }); /** * Reads the Space Description. Returns `null` if the space is missing or not * visible to you (WAS returns 404 for both not-found and unauthorized). * * @returns {Promise} */ describe(): Promise; /** * Creates or updates the space by id (upsert). Merges the given fields over * the current description; `controller` defaults to the wrapped signer's DID. * * Fails closed when the current description is unreadable and the caller did * not supply a full description (both `name` and `controller`), mirroring * {@link Collection.configure}: WAS returns 404 for both not-found and * unauthorized, so a write-capable but not read-capable caller invoking * `configure({ name })` would otherwise merge forward from a `null` current -- * silently defaulting `controller` to the wrapped signer's DID (a stealth * ownership change) and dropping the existing `name`. Pass `force: true` to * proceed anyway (a deliberate create through a handle), or supply both * `name` and `controller` explicitly so nothing is merged from the unreadable * current. * * @param desc {object} * @param [desc.name] {string} * @param [desc.controller] {string} * @param [desc.type] {string[]} the Space Description's `type` array (e.g. * a typed auxiliary Space). The server accepts it at creation only and * treats it as immutable afterwards, so pass it on the create; on an * update the current description's `type` is re-sent unchanged * @param [desc.force] {boolean} proceed even when the current description is * unreadable and a full description is not supplied (see above) * @returns {Promise} */ configure(desc: { name?: string; controller?: string; type?: string[]; force?: boolean; }): Promise; /** * Deletes the space. Idempotent. * * @returns {Promise} */ delete(): Promise; /** * Returns a lazy handle to a collection by id. No I/O. * * @param collectionId {string} * @param options {object} * @param [options.capability] {IZcap} * @returns {Collection} */ collection(collectionId: string, options?: HandleOptions): Collection; /** * Creates a collection within the space (server-generated id unless `id` is * given). Throws `NotFoundError` if the space does not exist. * * @param desc {object} * @param [desc.id] {string} * @param [desc.name] {string} * @param [desc.backend] {BackendReference} * @param [desc.encryption] {CollectionEncryption} declare the collection * client-side encrypted. When the descriptor can route -- for the `'edv'` * scheme that means it carries its epoch roster -- the returned handle is * pre-seeded with it as an encryption override, so the immediate next * write encrypts without a descriptor-discovery round-trip. A bare * `{ scheme: 'edv' }` declares the collection encrypted but is not * pre-seeded (the handle uses descriptor discovery instead); reads and * writes are refused fail-closed until `ensureFirstEpoch` installs the * epoch roster. * @param [desc.generator] {IDID} DID of the application the collection is * being provisioned for. Controller-asserted attribution: the server * persists it without verifying it, and it stays writable afterwards * (`configure`/`replaceDescription`), so an existing collection can be * backfilled. * @param [desc.generatorOrigin] {string} the Web origin the `generator` * DID was bound to at provisioning time, on the same footing. * @returns {Promise} */ createCollection(desc?: { id?: string; name?: string; backend?: BackendReference; encryption?: CollectionEncryption; generator?: IDID; generatorOrigin?: string; }): Promise; /** * Lists the collections in the space. Transparently follows the server's * `next` pagination links, buffering every page into a single list (the * returned envelope omits `next`). Convenient, but holds the whole listing in * memory -- for a large space prefer `collectionsPages()`, which streams one * page at a time and allows stopping early. Returns `null` if the space is * missing or not visible to you (404 conflation caveat). * * @returns {Promise} */ collections(): Promise; /** * Lazily yields the collections listing one page at a time, following the * server's `next` links on demand (each page fetched with the same * authorization). Use this to stream a large space in constant memory or to * stop early. Yields nothing if the space is missing or not visible to you * (404 conflation caveat) -- unlike `collections()`, the iterator does not * distinguish that from an empty space. * * @returns {AsyncGenerator} */ collectionsPages(): AsyncGenerator; /** * Lists the storage backends available within this space. Returns `null` if * the space is missing or not visible to you (404 conflation caveat). A * server without backend support surfaces its 501 as `NotImplementedError`. * * Each descriptor's optional `features` array advertises optional server * affordances (e.g. `conditional-writes`). See {@link Collection.backend} for * the full note. * * @returns {Promise} */ backends(): Promise; /** * Registers a new `external` ("Bring Your Own Storage") backend against this * space (`POST /space/:id/backends`). The registration body carries the * secret-bearing `connection` (e.g. an OAuth authorization code); the server * persists it and returns the **sanitized** descriptor (no secrets). Requires * the Space controller's authority (the same key that owns the space). * * Throws `ConflictError` if a backend with this `id` already exists * (`id-conflict`) or the server does not permit the `provider` * (`unsupported-backend`), and `ValidationError` (400) for a malformed body * (e.g. the reserved `default` id). To replace an existing backend's * connection (the re-consent path), use {@link updateBackend}. * * @param registration {BackendRegistration} the backend to register * (`{ id, provider, connection: { kind, ... }, name?, storageMode?, * features? }`) * @returns {Promise} the sanitized descriptor of the * newly registered backend */ registerBackend(registration: BackendRegistration): Promise; /** * Creates or replaces a registered `external` backend by id * (`PUT /space/:id/backends/:id`) -- the re-consent / refresh path, used to * swap in fresh `connection` material after a backend's status went `expired` * or `revoked`. The target id is taken from `registration.id`. Requires the * Space controller's authority. * * Returns the sanitized descriptor when the PUT **created** a new record (the * server replies 201 with a body); returns `null` when it **replaced** an * existing record in place (the server replies 204, no body) -- read it back * with {@link backends} if you need the refreshed descriptor. * * @param registration {BackendRegistration} the backend to upsert; its `id` * selects the target record * @returns {Promise} the descriptor on create, or * `null` on in-place replace */ updateBackend(registration: BackendRegistration): Promise; /** * Deregisters (forgets) a registered `external` backend by id * (`DELETE /space/:id/backends/:id`). Idempotent -- deregistering an absent * backend still resolves. Requires the Space controller's authority. * * This removes the server's record and its stored connection; whether the * upstream provider grant (e.g. an OAuth refresh token) is also revoked is a * server/provider concern, not guaranteed by this call. * * @param backendId {string} the registered backend's id * @returns {Promise} */ deregisterBackend(backendId: string): Promise; /** * Reads the space's storage quota report, grouped by backend. Returns `null` * if the space is missing or not visible to you (404 conflation caveat). A * server without quota support surfaces its 501 as `NotImplementedError`. * * @param [options] {object} * @param [options.includeCollections] {boolean} request the per-Collection * `usageByCollection` breakdown on each backend entry (the spec's * `?include=collections` opt-in); omitted by default to keep the report lean * @returns {Promise} */ quotas({ includeCollections }?: { includeCollections?: boolean; }): Promise; /** * Delegates access to this space. Prefills the grant `target` with this * space's URL (and the bound `capability`, if any, for re-delegation). * * @param options {GrantOptions} * @returns {Promise} */ grant(options: GrantOptions): Promise; /** * Revokes a capability rooted in this space -- the inverse of {@link grant}. * From then on the capability is rejected wherever a Space-rooted chain is * verified: writes, privileged routes, and the capability leg of reads. * * Two callers are authorized: this space's controller, and any controller in * the capability's own delegation chain (so a delegee can revoke the * capability it holds, without a separate grant). Anyone else gets a * `NotFoundError`, as does a capability rooted in a different space. * * Revocation withdraws only what the *capability* granted. Access an * access-control policy grants independently survives it, so a `PublicCanRead` * target stays publicly readable afterwards. It is also prospective: a revoked * reader of an encrypted collection still holds the keys for ciphertext it * already fetched. * * **Not idempotent.** Revoking an already-revoked capability throws * `ValidationError` (the server's 400), because its chain now contains a * revoked link. The server reports that with the same problem type it uses for * a tampered, expired, or foreign-rooted capability, so this method cannot * distinguish them and does not swallow any of them. Catch `ValidationError` * if you want revoking twice to be a no-op. * * @param zcap {IDelegatedZcap} the delegated capability to revoke * @returns {Promise} */ revoke(zcap: IDelegatedZcap): Promise; /** * Exports the whole space as a tar (`application/x-tar`) archive. * * The entire archive is buffered into memory (a `Uint8Array` cannot be * produced incrementally), so exporting a very large space costs its full * size in RAM. For a constant-memory path use {@link exportStream}; for the * `import()` companion container use {@link exportBlob}. * * @returns {Promise} */ export(): Promise; /** * Exports the whole space as a tar (`application/x-tar`) archive, as a Blob * typed `application/x-tar`. Pairs directly with `import(tar)`, so copying a * space is `spaceB.import(await spaceA.exportBlob())`. * * Note: in Node a Blob is memory-backed, so this does not reduce peak memory * versus {@link export} -- it is a typed-container convenience (browsers may * spill large Blobs to disk). For the true constant-memory path use * {@link exportStream}. * * @returns {Promise} */ exportBlob(): Promise; /** * Exports the whole space as a tar (`application/x-tar`) archive, as a lazily * consumed byte stream -- constant memory, for piping to a file, a * `CompressionStream`, or another request. * * The stream must be consumed or cancelled; an abandoned stream holds its * connection open. * * @returns {Promise>} */ exportStream(): Promise>; /** * Imports (merges) a tar archive into the space. * * @param tar {Uint8Array | Blob} * @returns {Promise} */ import(tar: Uint8Array | Blob): Promise; /** * Reads the space's access-control policy. Returns `null` when no policy is * set (or it is not visible to you). A space-level policy is inherited by all * collections and resources unless overridden by a more specific one. Managing * a policy is a controller-level operation. * * @returns {Promise} */ getPolicy(): Promise; /** * Sets (creates or replaces) the space's access-control policy. * * @param policy {PolicyDocument} * @returns {Promise} */ setPolicy(policy: PolicyDocument): Promise; /** * Returns `true` when this space's policy is `PublicCanRead`. * * @returns {Promise} */ isPublic(): Promise; /** * Makes the whole space world-readable: every collection and resource under * it becomes readable without authorization (unless overridden by a more * specific policy). Sugar for `setPolicy({ type: 'PublicCanRead' })`. * * @returns {Promise} */ setPublic(): Promise; /** * Removes the space's access-control policy, reverting it to capability-only * access. Idempotent. * * @returns {Promise} */ clearPolicy(): Promise; /** * Reads the space's linkset (RFC9264 policy discovery). Returns `null` if the * space is missing or not visible to you. * * @returns {Promise} */ linkset(): Promise; } //# sourceMappingURL=Space.d.ts.map