Bucket

Buckets: files by key, private by default, with signed links and an S3-compatible escape hatch.

bucket = noclick.Bucket.from_name("uploads", create_if_missing=True)
bucket.put("invoices/0042.pdf", pdf_bytes, content_type="application/pdf")
link = bucket.signed_url("invoices/0042.pdf", expires_in=3600)

A key is a path-like name (invoices/0042.pdf); / separates folders only by convention, so listing with delimiter="/" shows them as folders.

class Bucket

A bucket of files by key. Private by default: files are reached through this client or a signedUrl; a public bucket also serves each file at url(key). Its region is a location hint object storage places it by when it has room there, fixed when it's created.

Attributes
idstring
namestring
publicboolean

Whether every file is readable at url(key) without a link.

sizeBytesnumber | null
objectCountnumber | null
publicBaseUrlstring | null

Where a public bucket serves its files (null while it's private).

usedByUsedBy[]

Who uses it: apps that bind it and agents with it in their tools.

notificationsBucketNotification[]

Where it tells about new files (notify; invite-only beta: empty).

regionRegionName | null

The region it keeps its data in, fixed when it was created.

userIdstring | null
createdAtDate | null
consoleUrlstring | null

This bucket in the developer console (null off the hosted API).

only

only(...operations: BucketTool[]): BucketOperations

A tool ref to some of its operations, for tools: "objects", "head", "put" (store a file from a url or from text, so the model never handles bytes), "signed_url" (a link that reads a file) and "remove". The bucket itself in tools gives all five, as {name}__objects and so on; policy names them bucket.objects, bucket.put, ... (bucket.*).

Parameters
operationsBucketTool[]required
Returns

A ref to just those operations, to list in tools=; bind(...) fixes arguments.

createstatic

static create(name: string, options?: BucketCreateOptions): Promise<Bucket>

Create a bucket, unique by name per user (a taken name throws Conflict with existingId).

Parameters
namestringrequired
options.publicboolean

Serve every file at a plain URL (url(key)); private by default.

(default false)
options.regionRegionName

Where it runs or keeps its data (regions()); omitted, your account's default region.

options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

Returns

The new, empty bucket.

fromNamestatic

static fromName(
  name: string,
  options?: BucketCreateOptions & { createIfMissing?: boolean },
): Bucket

A lazy reference to the bucket called name for the current (or given) user. With createIfMissing it's created on first use; one that exists is used as it is.

Parameters
namestringrequired
options.createIfMissingboolean
options.publicboolean

Serve every file at a plain URL (url(key)); private by default.

(default false)
options.regionRegionName

Where it runs or keeps its data (regions()); omitted, your account's default region.

options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

Returns

A bucket that loads (or is created) the first time it's used. Nothing is sent yet.

fromIdstatic

static fromId(bucketId: string, options?: CallOptions): Bucket

A lazy reference to a bucket by id.

Parameters
bucketIdstringrequired
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
Returns

A bucket that loads the first time you read a field. Nothing is sent yet.

getstatic

static get(bucketId: string, options?: CallOptions): Promise<Bucket>

Load a bucket by id now; an unknown id raises noclick.NotFound.

Parameters
bucketIdstringrequired
options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

Returns

The bucket, loaded: whether it's public, how many files it holds and their total size.

liststatic

static list(options?: ReadOptions & { limit?: number }): Promise<Bucket[]>

The current user's buckets (or those userFilter covers).

Parameters
options.limitnumber

Return at most this many.

options.userFilterUserFilter

Which users the read covers (user_id query), instead of acting as one (user).

options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

Returns

Every matching bucket, newest first, fetched page by page.

listPagestatic

static listPage(options?: ReadOptions & PageOptions): Promise<Page<Bucket>>

One page of buckets; pass nextCursor back as cursor.

Parameters
options.cursorstring | null

The next_cursor of the page before; omit it for the first page.

options.limitnumber

Return at most this many.

options.userFilterUserFilter

Which users the read covers (user_id query), instead of acting as one (user).

options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

Returns

A page whose data holds the buckets and whose next_cursor is None on the last page.

put

put(
  key: string,
  data: BucketData,
  options?: BucketPutOptions,
): Promise<BucketObject>

Store data at key, replacing what was there (up to 100 MB; larger files go through a PUT signed link).

Parameters
keystringrequired
dataBucketDatarequired
options.contentTypestring

Guessed from the key's extension when omitted.

options.metadataRecord<string, string>

Up to 2 KB of your own string pairs, returned with the file.

Returns

The file as stored, with its size and etag.

read

read(key: string): Promise<Uint8Array>

The file's bytes; a missing key throws NotFound.

Parameters
keystringrequired
Returns

The file's bytes, exactly as stored; decode text yourself.

head

head(key: string): Promise<BucketObject>

A file's size, type, etag and metadata, without downloading it.

Parameters
keystringrequired
Returns

The file's size, content type, etag, metadata and when it last changed.

objects

objects(
  options?: BucketObjectsOptions & { limit?: number },
): Promise<BucketObject[]>

The files under prefix, in key order (or the first limit), fetched page by page.

Parameters
options.delimiterstring

"/" rolls keys below the next / into one folder entry each.

options.limitnumber

Return at most this many.

options.prefixstring
Returns

Every matching file (or the first limit), fetched page by page.

objectsPage

objectsPage(
  options?: BucketObjectsOptions & PageOptions,
): Promise<Page<BucketObject>>

One page of objects; pass nextCursor back as cursor.

Parameters
options.delimiterstring

"/" rolls keys below the next / into one folder entry each.

options.cursorstring | null

The next_cursor of the page before; omit it for the first page.

options.limitnumber

Return at most this many.

options.prefixstring
Returns

A page whose data holds BucketObjects and whose next_cursor is None on the last page.

remove

remove(key: string): Promise<void>

Delete the file at key (a key that isn't there is fine).

Parameters
keystringrequired

versions

versions(key: string): Promise<ObjectVersion[]>

What key held before each write through NoClick of the last 30 days, newest first.

Parameters
keystringrequired
Returns

Each earlier version.

restoreVersion

restoreVersion(
  key: string,
  version: ObjectVersion | string,
): Promise<BucketObject>

Put key back as version held it; what it holds now is kept as a version in turn.

Parameters
keystringrequired
versionObjectVersion | stringrequired
Returns

The file, as it's stored again.

signedUrl

signedUrl(key: string, options?: BucketSignedUrlOptions): Promise<string>

A link that reads (GET) or uploads (PUT) the file without a NoClick key, until it expires.

Parameters
keystringrequired
options.method"GET" | "PUT"

GET reads the file, PUT uploads it (up to 5 GB).

(default "GET")
options.expiresInnumber

Seconds the link works: 60 to 604,800 (a week); 3600 by default.

(default 3600)
options.contentTypestring

A PUT link's upload must send this type.

Returns

The link. Anyone who has it can use it until it expires, so hand it only to whoever needs it.

url

url(key: string): Promise<string>

The plain URL a public bucket serves key at; a private bucket throws NotAvailable.

Parameters
keystringrequired
Returns

public_base_url followed by the key; it works for as long as the bucket stays public.

update

update(options: { public?: boolean }): Promise<this>

Change the bucket's settings; making it private stops every public URL at once.

Parameters
options.publicboolean
Returns

This bucket, with the server's current fields.

notifyinvite-only beta

notify(
  queue: string | { _ensure(): Promise<JsonObject> },
  options?: { prefix?: string; enabled?: boolean },
): Promise<this>

Invite-only beta.

Put a message on queue (a Queue or its name, in the bucket's own user) for every file stored under prefix (the whole bucket when omitted), however it arrived: put, a PUT signed link or S3 credentials. The message is { event: "put", bucket, key, size, content_type, etag, at }. Asking again for the same queue and prefix changes nothing; enabled: false stops it.

await recordings.notify("new-recordings", { prefix: "calls/" });
Parameters
queuestring | { _ensure(): Promise<JsonObject> }required
options.prefixstring
options.enabledboolean
Returns

This bucket, whose notifications list where it tells.

s3Credentialsinvite-only beta

s3Credentials(
  options?: { readOnly?: boolean; ttlS?: number },
): Promise<S3Credentials>

Invite-only beta. Keys for the S3-compatible endpoint, valid ttlS seconds (900 to 43,200; 3600 by default).

Parameters
options.readOnlyboolean
options.ttlSnumberdefault 3600
Returns

The endpoint, bucket name, keys and expires_at. The secret is shown once; mint new ones when they expire.

export

export(): Promise<Operation<ExportBundle>>

Export every file, to take anywhere: a zip holding each one at its key (under buckets/<name>/files/), with index.jsonl listing each key's content type and metadata. A key that can't be a path in a zip (an empty, . or .. part) is kept under renamed/, and the index says which. wait() resolves to an ExportBundle: the zip at url, valid 7 days.

Returns

An operation whose wait() gives an ExportBundle: the zip at url, valid 7 days.

delete

delete(options?: { force?: boolean }): Promise<TrashItem>

Delete the bucket: it goes to the trash, restorable for 30 days (its files stored, and billed, until it's purged). It must be empty unless force (which takes its files too), and in no agent's tools. Returns its TrashItem.

Parameters
options.forceboolean
Returns

Its TrashItem: restore() puts it back, files and all.

BucketObject

interface BucketObject

A file in a bucket. In a listing with a delimiter, an entry with isFolder stands for every key under that prefix, and only its key is set.

Attributes
keystring
sizenumber | null
contentTypestring | null
etagstring | null

Changes whenever the content does.

metadataRecord<string, string>
updatedAtDate | null
isFolderboolean
rawJsonObject

The response JSON exactly as the API sent it.

ObjectVersion

interface ObjectVersion

What a file held before a write through NoClick replaced it (op changed) or removed it (deleted), kept 30 days. An upload through a signed link or S3 credentials keeps none.

Attributes
idstring
keystring
op"changed" | "deleted"
sizenumber | null
replacedAtDate | null
rawJsonObject

The response JSON exactly as the API sent it.

BucketOperations

class BucketOperations

Some of a bucket's operations as an agent's tools (bucket.only(...)), with the arguments bind(...) fixed.

Attributes
bucketBucket
operationsBucketTool[]
bindingsJsonObject

The arguments NoClick fills on every call, out of the model's reach.

bind

bind(args: JsonObject): BucketOperations

Fix arguments of these operations, as ConnectionOperations.bind does. prefix is the one to bind here: every key the tools take and return is then under it, so one bucket holds a folder per user.

uploads.only("objects", "put", "signed_url").bind({ prefix: "users/{{user.id}}/" })
Parameters
argsJsonObjectrequired
Returns

A new ref with these arguments bound on top of any bound before.

S3Credentialsinvite-only beta

interface S3Credentials

Invite-only beta.

Short-lived keys for the bucket's S3-compatible endpoint (rclone, the AWS CLI, an S3 library). bucket is its name on that endpoint, not its NoClick name.

Attributes
endpointstring
bucketstring
accessKeyIdstring
secretAccessKeystring
sessionTokenstring | null
regionstring
readOnlyboolean
expiresAtDate | null
rawJsonObject

The response JSON exactly as the API sent it.