> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bijection.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Interface: BijectionStorageWriter

> Reference for the BijectionStorageWriter interface in bijection/server.

[server](/api/modules/server).BijectionStorageWriter

## Hierarchy

* [`StorageWriter`](/api/interfaces/server.StorageWriter)

* [`BijectionStorageReader`](/api/interfaces/server.BijectionStorageReader)

  ↳ **`BijectionStorageWriter`**

## Methods

### inspectProtectedFile

▸ **inspectProtectedFile**(`storageId`): `Promise`\<[`ProtectedFileBinding`](/api/interfaces/server.ProtectedFileBinding)>

Inspect a protected file's logical lifecycle in this transaction. The
native row and current source permissions are read dependencies, so an
erasure racing this transaction refuses its result or commit. Missing,
ordinary, erased, and unauthorized files do not disclose metadata.
This does not verify that physical blob bytes still exist.

#### Parameters

| Name | Type |
| :- | :- |
| `storageId` | [`GenericId`](/api/modules/values#genericid)\<`"_storage"`> |

#### Returns

`Promise`\<[`ProtectedFileBinding`](/api/interfaces/server.ProtectedFileBinding)>

#### Inherited from

[BijectionStorageReader](/api/interfaces/server.BijectionStorageReader).[inspectProtectedFile](/api/interfaces/server.BijectionStorageReader#inspectprotectedfile)

***

### prepareUpload

▸ **prepareUpload**\<`Completion`>(`options`): `Promise`\<`string`>

Prepare a client upload that already names what the file is for, and
return its single-use upload URL (valid for an hour).

The client POSTs the bytes to the URL, authenticated as the same user
(`BijectionHttpClient.uploadFile`). Size, content type and digest are
enforced while the bytes arrive. Then one transaction stores the file and
runs `complete` as that user with `{ file, ...args }`, so the completion
checks authorization when the file becomes real, and a file whose
completion throws is never published and its bytes are reclaimed. The
file is protected when the preparation or the completion read protected
data. A retry after a lost response returns the same file without
running the completion again.

**`Example`**

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
export const prepare = mutation({
  args: { report: v.id("reports") },
  handler: async (ctx, { report }) =>
    await ctx.storage.prepareUpload({
      complete: internal.reports.attach,
      args: { report },
      maxBytes: 10 * 1024 * 1024,
      contentType: "application/pdf",
    }),
});
export const attach = internalMutation({
  args: { file: v.id("_storage"), report: v.id("reports") },
  handler: async (ctx, { file, report }) => {
    await ctx.db.patch(report, { file });
  },
});
```

#### Type parameters

| Name | Type |
| :- | :- |
| `Completion` | extends [`UploadCompletionReference`](/api/modules/server#uploadcompletionreference) |

#### Parameters

| Name | Type |
| :- | :- |
| `options` | [`PrepareUploadOptions`](/api/interfaces/server.PrepareUploadOptions)\<`Completion`> |

#### Returns

`Promise`\<`string`>

***

### share

▸ **share**(`storageId`, `options`): `Promise`\<`string`>

Grant one recipient access to a protected file under current source policy.

#### Parameters

| Name | Type |
| :- | :- |
| `storageId` | [`GenericId`](/api/modules/values#genericid)\<`"_storage"`> |
| `options` | `Object` |
| `options.requestKey` | `string` |
| `options.recipient` | `string` |
| `options.expiresAt` | `number` |

#### Returns

`Promise`\<`string`>

***

### revokeShare

▸ **revokeShare**(`storageId`, `shareId`): `Promise`\<`void`>

Revoke one grant without changing other grants or the stored bytes.

#### Parameters

| Name | Type |
| :- | :- |
| `storageId` | [`GenericId`](/api/modules/values#genericid)\<`"_storage"`> |
| `shareId` | `string` |

#### Returns

`Promise`\<`void`>

***

### getUrl

▸ **getUrl**(`storageId`): `Promise`\<`null` | `string`>

Get the URL for a file in storage by its `Id<"_storage">`.

The GET response includes a standard HTTP Digest header with a sha256 checksum.

**`Example`**

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
const url = await ctx.storage.getUrl(storageId);
```

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `storageId` | [`GenericId`](/api/modules/values#genericid)\<`"_storage"`> | The `Id<"_storage">` of the file to fetch from Bijection storage. |

#### Returns

`Promise`\<`null` | `string`>

* A URL which fetches the file via an HTTP GET, or `null` if the file no longer exists.

#### Inherited from

[BijectionStorageReader](/api/interfaces/server.BijectionStorageReader).[getUrl](/api/interfaces/server.BijectionStorageReader#geturl)

▸ **getUrl**\<`T`>(`storageId`): `Promise`\<`null` | `string`>

**`Deprecated`**

Passing a string is deprecated, use `storage.getUrl(Id<"_storage">)` instead.

Get the URL for a file in storage by its [StorageId](/api/modules/server#storageid).

The GET response includes a standard HTTP Digest header with a sha256 checksum.

#### Type parameters

| Name | Type |
| :- | :- |
| `T` | extends `string` |

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `storageId` | `T` extends \{ `__tableName`: `any`  } ? `never` : `T` | The [StorageId](/api/modules/server#storageid) of the file to fetch from Bijection storage. |

#### Returns

`Promise`\<`null` | `string`>

* A url which fetches the file via an HTTP GET, or `null` if it no longer exists.

#### Inherited from

[BijectionStorageReader](/api/interfaces/server.BijectionStorageReader).[getUrl](/api/interfaces/server.BijectionStorageReader#geturl)

***

### getMetadata

▸ **getMetadata**(`storageId`): `Promise`\<`null` | [`FileMetadata`](/api/modules/server#filemetadata)>

**`Deprecated`**

Use `ctx.db.system.get("_storage", storageId)` instead, which returns
equivalent metadata from the `_storage` system table (with a slightly different shape):

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
const metadata = await ctx.db.system.get("_storage", storageId);
// { _id, _creationTime, sha256, size, contentType? }
```

Get metadata for a file.

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `storageId` | [`GenericId`](/api/modules/values#genericid)\<`"_storage"`> | The `Id<"_storage">` of the file. |

#### Returns

`Promise`\<`null` | [`FileMetadata`](/api/modules/server#filemetadata)>

* A [FileMetadata](/api/modules/server#filemetadata) object if found or `null` if not found.

#### Inherited from

[BijectionStorageReader](/api/interfaces/server.BijectionStorageReader).[getMetadata](/api/interfaces/server.BijectionStorageReader#getmetadata)

▸ **getMetadata**\<`T`>(`storageId`): `Promise`\<`null` | [`FileMetadata`](/api/modules/server#filemetadata)>

**`Deprecated`**

Use `ctx.db.system.get("_storage", storageId)` instead.

Get metadata for a file.

#### Type parameters

| Name | Type |
| :- | :- |
| `T` | extends `string` |

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `storageId` | `T` extends \{ `__tableName`: `any`  } ? `never` : `T` | The [StorageId](/api/modules/server#storageid) of the file. |

#### Returns

`Promise`\<`null` | [`FileMetadata`](/api/modules/server#filemetadata)>

* A [FileMetadata](/api/modules/server#filemetadata) object if found or `null` if not found.

#### Inherited from

[BijectionStorageReader](/api/interfaces/server.BijectionStorageReader).[getMetadata](/api/interfaces/server.BijectionStorageReader#getmetadata)

***

### generateUploadUrl

▸ **generateUploadUrl**(): `Promise`\<`string`>

Generate a short-lived URL for uploading a file into storage.

The client should make a POST request to this URL with the file as the
body. The response will be a JSON object containing a newly allocated
`Id<"_storage">` (`{ storageId: "..." }`).

**`Example`**

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
// In a mutation, generate the upload URL:
export const generateUploadUrl = mutation({
  args: {},
  returns: v.string(),
  handler: async (ctx) => {
    return await ctx.storage.generateUploadUrl();
  },
});

// On the client, upload the file:
// const uploadUrl = await generateUploadUrl();
// const result = await fetch(uploadUrl, { method: "POST", body: file });
// const { storageId } = await result.json();
```

#### Returns

`Promise`\<`string`>

* A short-lived URL for uploading a file via HTTP POST.

#### Inherited from

[StorageWriter](/api/interfaces/server.StorageWriter).[generateUploadUrl](/api/interfaces/server.StorageWriter#generateuploadurl)

***

### delete

▸ **delete**(`storageId`): `Promise`\<`void`>

Delete a file from Bijection storage.

Once a file is deleted, any URLs previously generated by [getUrl](/api/interfaces/server.BijectionStorageReader#geturl) will return 404s.

**`Example`**

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
await ctx.storage.delete(storageId);
```

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `storageId` | [`GenericId`](/api/modules/values#genericid)\<`"_storage"`> | The `Id<"_storage">` of the file to delete from Bijection storage. |

#### Returns

`Promise`\<`void`>

#### Inherited from

[StorageWriter](/api/interfaces/server.StorageWriter).[delete](/api/interfaces/server.StorageWriter#delete)

▸ **delete**\<`T`>(`storageId`): `Promise`\<`void`>

**`Deprecated`**

Passing a string is deprecated, use `storage.delete(Id<"_storage">)` instead.

Delete a file from Bijection storage.

Once a file is deleted, any URLs previously generated by [getUrl](/api/interfaces/server.BijectionStorageReader#geturl) will return 404s.

#### Type parameters

| Name | Type |
| :- | :- |
| `T` | extends `string` |

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `storageId` | `T` extends \{ `__tableName`: `any`  } ? `never` : `T` | The [StorageId](/api/modules/server#storageid) of the file to delete from Bijection storage. |

#### Returns

`Promise`\<`void`>

#### Inherited from

[StorageWriter](/api/interfaces/server.StorageWriter).[delete](/api/interfaces/server.StorageWriter#delete)
