@omelhorsite/sdk 0.4.0 → 0.4.1

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.
Files changed (35) hide show
  1. package/README.md +4 -4
  2. package/dist/index.js +4 -4
  3. package/dist/types/auth/device.d.ts +1 -1
  4. package/dist/types/auth/index.d.ts +2 -2
  5. package/dist/types/auth/tokens.d.ts +15 -15
  6. package/dist/types/client.d.ts +10 -10
  7. package/dist/types/errors.d.ts +12 -15
  8. package/dist/types/http.d.ts +74 -118
  9. package/dist/types/index.d.ts +1 -2
  10. package/dist/types/local/qr.d.ts +1 -1
  11. package/dist/types/local/wordlist.d.ts +2 -3
  12. package/dist/types/resources/account.d.ts +14 -17
  13. package/dist/types/resources/auth/index.d.ts +1 -1
  14. package/dist/types/resources/auth/passkeys.d.ts +127 -163
  15. package/dist/types/resources/auth/sessions.d.ts +110 -152
  16. package/dist/types/resources/chests.d.ts +27 -31
  17. package/dist/types/resources/dynamicQrs.d.ts +29 -45
  18. package/dist/types/resources/forms.d.ts +37 -58
  19. package/dist/types/resources/jobs.d.ts +28 -40
  20. package/dist/types/resources/media.d.ts +48 -61
  21. package/dist/types/resources/music/artists.d.ts +179 -245
  22. package/dist/types/resources/music/imports.d.ts +181 -210
  23. package/dist/types/resources/music/index.d.ts +8 -7
  24. package/dist/types/resources/music/playlists.d.ts +77 -110
  25. package/dist/types/resources/music/social.d.ts +153 -228
  26. package/dist/types/resources/music/songs.d.ts +160 -206
  27. package/dist/types/resources/realtime.d.ts +75 -88
  28. package/dist/types/resources/shortLinks.d.ts +33 -45
  29. package/dist/types/resources/storage/upload.d.ts +42 -56
  30. package/dist/types/resources/storage.d.ts +71 -104
  31. package/dist/types/resources/tools/backgroundRemoval.d.ts +11 -13
  32. package/dist/types/resources/tools/captions.d.ts +107 -135
  33. package/dist/types/resources/tools/upscale.d.ts +12 -16
  34. package/dist/types/types.d.ts +29 -38
  35. package/package.json +1 -1
@@ -1,13 +1,12 @@
1
1
  /**
2
2
  * The direct-upload driver.
3
3
  *
4
- * Bytes never pass through Rails. The flow the backend implements, and the one
5
- * this module follows exactly:
4
+ * Bytes never pass through the API. The flow:
6
5
  *
7
6
  * 1. `POST /fs_nodes/batch_upload_urls` with a manifest of up to 100 files
8
7
  * (`client_id`, `name`, `size`, and optionally `relative_path`,
9
8
  * `content_type`, `checksum`). ONE request does directory resolution, one
10
- * quota reservation under a single lock, node creation and plan minting.
9
+ * quota reservation, node creation and plan minting.
11
10
  * 2. Per file the server answers a {@link UploadPlan}:
12
11
  * - `strategy: "direct"` below 32 MiB: PUT the whole body to a presigned URL
13
12
  * with the exact headers returned, then remember `blob_signed_id`;
@@ -25,27 +24,21 @@
25
24
  * self-contained implementation - see the note there.
26
25
  * - The presigned PUTs go to the object store, NOT to the API. They must be
27
26
  * sent with the injected fetch but WITHOUT the `Authorization` header, or
28
- * MinIO rejects the request for having two authentication schemes.
27
+ * the store rejects the request for having two authentication schemes.
29
28
  *
30
29
  * A node whose bytes never landed is adopted on the next attempt rather than
31
30
  * failing, so a torn batch is simply retried with the same manifest.
32
31
  *
33
- * Multipart is not an optimisation. The object store sits behind Cloudflare on
34
- * a plan that caps a request body at roughly 100 MB, so anything larger has no
35
- * other way in.
32
+ * Multipart is not an optimisation. A single request to the object store is
33
+ * capped at roughly 100 MB, so anything larger has no other way in.
36
34
  *
37
35
  * ## Progress, and why it ticks per transfer rather than per byte
38
36
  *
39
- * The bytes go to a presigned MinIO URL. Rails is never in the data path, and
40
- * neither is rack-attack - so a progress bar here is a pure client-side
41
- * problem, and the SDK solves it as far as `fetch` allows and no further.
37
+ * `fetch` has no upload-progress event, and the two ways around it were both
38
+ * rejected for the core:
42
39
  *
43
- * `fetch` has no upload-progress event. The two ways out were weighed and both
44
- * were rejected for the core:
45
- *
46
- * - **XHR**, which is what the web frontend's axios uses today, is the only API
47
- * that reports request bytes as they leave. It does not exist in a
48
- * Cloudflare-Worker-class isolate, and this package must load there.
40
+ * - **XHR** is the only API that reports request bytes as they leave. It does
41
+ * not exist in a Worker-class isolate, and this package must load there.
49
42
  * - **A counting `ReadableStream` request body** would run in an isolate, and
50
43
  * still does not work HERE. A stream body forces chunked transfer encoding,
51
44
  * while a presigned PUT is signed over a fixed `Content-Length` (and, on the
@@ -82,35 +75,28 @@ import type { FsNode } from "../storage";
82
75
  * import { MULTIPART_THRESHOLD } from "@omelhorsite/sdk";
83
76
  * ```
84
77
  *
85
- * The number was verified in all three places it is currently written down, and
86
- * as of this writing they agree:
87
- *
88
- * - `FsServices::NodeBatchCreator::MULTIPART_THRESHOLD = 32.megabytes`, which
89
- * is the only one that decides anything. The server compares
90
- * `entry[:size] >= MULTIPART_THRESHOLD` and puts `strategy` in the plan.
91
- * - the web frontend's `lib/upload_core.ts`, which keeps its own literal.
92
- * - here.
93
- *
94
- * The client-side copies exist because the CHECKSUM has to be in the manifest
95
- * before the server has decided anything: below the threshold the digest is
96
- * mandatory (it is Content-MD5-bound into the presigned signature), at or above
97
- * it is pointless (multipart verifies per-part ETags). So the comparison is
98
- * made twice, and {@link manifestEntryFor} uses `<` against exactly the
99
- * server's `>=`.
78
+ * The server decides the strategy per file with `size >= 32 MiB` and puts it
79
+ * in the plan. The client-side copy exists because the CHECKSUM has to be in
80
+ * the manifest before the server has decided anything: below the threshold
81
+ * the digest is mandatory (it is Content-MD5-bound into the presigned
82
+ * signature), at or above it is pointless (multipart verifies per-part ETags).
83
+ * So the comparison is made twice, and {@link manifestEntryFor} uses `<`
84
+ * against exactly the server's `>=`.
100
85
  *
101
86
  * Drift is expensive and silent in one direction: a client that thinks the
102
87
  * threshold is HIGHER than the server's omits the checksum on a file the server
103
- * still plans as direct, and the upload dies at MinIO with a signature error
104
- * that never mentions checksums. That is the whole reason this is exported.
88
+ * still plans as direct, and the upload dies at the object store with a
89
+ * signature error that never mentions checksums. That is the whole reason this
90
+ * is exported.
105
91
  */
106
92
  export declare const MULTIPART_THRESHOLD: number;
107
93
  /**
108
- * Part size for the multipart path. Mirrors the backend, but it is only a
94
+ * Part size for the multipart path. The server's default, but only a
109
95
  * fallback: the real part size is whatever `multipart/start` answered, and that
110
96
  * is the number the driver slices with.
111
97
  */
112
98
  export declare const MULTIPART_PART_SIZE: number;
113
- /** Maximum files in one `batch_upload_urls` call. Mirrors the backend. */
99
+ /** Maximum files in one `batch_upload_urls` call. Server limit. */
114
100
  export declare const MAX_BATCH = 100;
115
101
  /**
116
102
  * Files sent in one `batch_upload_urls` call by default.
@@ -120,25 +106,25 @@ export declare const MAX_BATCH = 100;
120
106
  * run leaves reserved-but-unused bytes behind.
121
107
  */
122
108
  export declare const DEFAULT_BATCH_SIZE = 50;
123
- /** Maximum part URLs requested in one call. Mirrors the backend. */
109
+ /** Maximum part URLs requested in one call. Server limit. */
124
110
  export declare const MAX_PART_URLS = 100;
125
- /** Parts one multipart upload may have. Mirrors the backend's `MAX_PARTS`. */
111
+ /** Parts one multipart upload may have. Server limit. */
126
112
  export declare const MAX_PARTS = 10000;
127
113
  /** Part URLs asked for in one round trip. Below {@link MAX_PART_URLS} on purpose. */
128
114
  export declare const PART_URL_WINDOW = 32;
129
- /** Parallel presigned PUTs in flight by default. The store is a Pi behind Cloudflare. */
115
+ /** Parallel presigned PUTs in flight by default. Keep it modest. */
130
116
  export declare const DEFAULT_UPLOAD_CONCURRENCY = 4;
131
117
  /**
132
- * The `fs_upload/authed` throttle: `batch_upload_urls`, `batch_attach_blobs`
133
- * and every `multipart/*` call share 300 requests a minute, keyed by session.
134
- * {@link UploadManager} paces itself against this so a large run degrades into
135
- * waiting rather than into a wall of 429s.
118
+ * `batch_upload_urls`, `batch_attach_blobs` and every `multipart/*` call
119
+ * share 300 requests a minute, keyed by session. {@link UploadManager} paces
120
+ * itself against this so a large run degrades into waiting rather than into a
121
+ * wall of 429s.
136
122
  */
137
123
  export declare const FS_UPLOAD_RATE_LIMIT = 300;
138
124
  /**
139
- * The `fs_bulk_job/authed` throttle: `copy`, `create_directories`,
140
- * `empty_trash` and `move_to_trash` share TWELVE requests a minute. It is the
141
- * tightest limit in the API and the easiest one to trip by looping.
125
+ * `copy`, `create_directories`, `empty_trash` and `move_to_trash` share
126
+ * TWELVE requests a minute. It is the tightest limit in the API and the
127
+ * easiest one to trip by looping.
142
128
  */
143
129
  export declare const FS_BULK_JOB_RATE_LIMIT = 12;
144
130
  /** One entry of the manifest sent to `batch_upload_urls`. */
@@ -247,7 +233,7 @@ export interface UploadInput {
247
233
  * folder upload costs no extra round trips. A `..` segment is a 400.
248
234
  */
249
235
  readonly relativePaths?: string[];
250
- /** Parallel PUTs in flight. Keep it modest: the store is a Pi behind Cloudflare. */
236
+ /** Parallel PUTs in flight. Keep it modest. */
251
237
  readonly concurrency?: number;
252
238
  /** Files per `batch_upload_urls` call. Clamped to {@link MAX_BATCH}. */
253
239
  readonly batchSize?: number;
@@ -338,7 +324,7 @@ export interface UploadManagerOptions {
338
324
  *
339
325
  * Two things the wrapper MUST get right, both of which the SDK's own
340
326
  * transport already does. It must not add an `Authorization` header or a
341
- * cookie: the presigned signature is the credential and MinIO rejects a
327
+ * cookie: the presigned signature is the credential and the store rejects a
342
328
  * request carrying two authentication schemes. And it must expose `ETag` on
343
329
  * the `Response` it builds, or the multipart tier has nothing to complete
344
330
  * with - in a browser that additionally needs `ETag` in the bucket's
@@ -356,7 +342,7 @@ export interface UploadManagerOptions {
356
342
  * steps, for instance to resume a torn multipart.
357
343
  */
358
344
  export declare class UploadManager extends Resource {
359
- /** Paces every control-plane call against the `fs_upload` throttle. */
345
+ /** Paces every control-plane call against the 300-a-minute upload limit. */
360
346
  readonly gate: StorageRateGate;
361
347
  private readonly transport;
362
348
  private readonly md5;
@@ -402,9 +388,9 @@ export declare class UploadManager extends Resource {
402
388
  * progress accounting drives `createBatch` -> {@link putDirect} /
403
389
  * {@link uploadMultipart} -> {@link attachBlobs} itself, and this is where it
404
390
  * learns the per-file strategy and the byte counts it will be reporting
405
- * against. Whatever it does, it must pace itself against `fs_upload` (300
406
- * requests a minute, shared by every call in this class) - {@link gate} is
407
- * exposed for exactly that.
391
+ * against. Whatever it does, it must pace itself against the 300 requests a
392
+ * minute shared by every call in this class - {@link gate} is exposed for
393
+ * exactly that.
408
394
  *
409
395
  * @throws {OmsApiError} 400 on a structural problem, 404 when the parent is
410
396
  * not a directory the caller may write to.
@@ -417,8 +403,8 @@ export declare class UploadManager extends Resource {
417
403
  * PUTs one whole body to a presigned URL.
418
404
  *
419
405
  * Sends the plan's headers verbatim and NO `Authorization`: this request goes
420
- * to the object store, not to the API. MinIO refuses a request that carries
421
- * both a presigned signature and a bearer header.
406
+ * to the object store, not to the API, and the store refuses a request that
407
+ * carries both a presigned signature and a bearer header.
422
408
  *
423
409
  * Retries a network fault or a 5xx from the store. A 4xx is never retried: an
424
410
  * expired signature or a checksum mismatch is deterministic and a retry only
@@ -450,7 +436,7 @@ export declare class UploadManager extends Resource {
450
436
  * with per-item results even when every item failed: read `attached` on each
451
437
  * one, and never infer success from the status. A caller driving the flow by
452
438
  * hand must not skip this - a node with no blob is invisible in listings and
453
- * is eventually swept by `FsNodeUploadReaperJob`.
439
+ * is eventually swept by the server.
454
440
  */
455
441
  attachBlobs(attachments: Array<{
456
442
  fs_node_id: Id;
@@ -504,7 +490,7 @@ export declare class UploadManager extends Resource {
504
490
  * parts, PUT them in parallel, complete.
505
491
  *
506
492
  * Parts are sliced with the size the SERVER reported, never with
507
- * {@link MULTIPART_PART_SIZE}, so a change on the backend does not silently
493
+ * {@link MULTIPART_PART_SIZE}, so a server-side change does not silently
508
494
  * corrupt an upload here.
509
495
  *
510
496
  * Phases 2 and 3 at once for a file at or above {@link MULTIPART_THRESHOLD}:
@@ -562,7 +548,7 @@ export declare class UploadManager extends Resource {
562
548
  /**
563
549
  * Base64 MD5 of a blob, in the exact form `Content-MD5` wants.
564
550
  *
565
- * The algorithm is not negotiable: the backend binds this digest into the
551
+ * The algorithm is not negotiable: the server binds this digest into the
566
552
  * presigned PUT signature as `Content-MD5`, so anything else makes the object
567
553
  * store reject the upload with a signature error that never mentions checksums.
568
554
  *
@@ -1,45 +1,43 @@
1
1
  /**
2
2
  * The `storage` namespace: the virtual filesystem.
3
3
  *
4
- * A node is a file or a directory, identified by an opaque id. Since the ltree
5
- * migration the id IS the address: there is no `path` column any more, and
6
- * navigation goes parent id -> children, with `ancestors()` for a breadcrumb.
7
- * Never build or parse a path string.
4
+ * A node is a file or a directory, identified by an opaque id. The id IS the
5
+ * address: a node carries no path, and navigation goes parent id -> children,
6
+ * with `ancestors()` for a breadcrumb. Never build or parse a path string.
8
7
  *
9
8
  * {@link StorageNamespace.resolvePath} exists for humans typing `docs/a.pdf`,
10
9
  * and it is exactly what it looks like: one request per segment, walking
11
- * `name` + `parent_id` down the filtered index. It memoises what it learns per
12
- * client instance so a CLI session does not re-walk the same prefix, but the
13
- * cheap call is always the one that already has an id.
10
+ * `name` + `parent_id` down a filtered listing. It memoises what it learns per
11
+ * client instance so a second walk down the same prefix is free, but the cheap
12
+ * call is always the one that already has an id.
14
13
  *
15
14
  * Uploads do NOT stream through this namespace. Bytes go straight to object
16
- * storage with a presigned URL; Rails only mints the plan and, at the end,
15
+ * storage with a presigned URL; the API only mints the plan and, at the end,
17
16
  * binds the blob. That whole dance lives in `storage/upload.ts` and is reached
18
17
  * through {@link StorageNamespace.upload}.
19
18
  *
20
- * Four throttles bound what this namespace can do, and they are far tighter
19
+ * Three rate limits bound what this namespace can do, and two are far tighter
21
20
  * than the API's general ceiling:
22
21
  *
23
- * - `fs_upload` - 300/min for the whole upload control plane. Paced by
22
+ * - 300 requests a minute for the whole upload control plane. Paced by
24
23
  * {@link UploadManager}.
25
- * - `fs_bulk_job` - TWELVE a minute for `copy`, `createDirectories`,
26
- * `emptyTrash` and `trash` together. Paced by {@link StorageNamespace.bulkGate}.
27
- * - the general 600/min for everything else.
28
- * - the direct PUTs at the object store, which rack-attack never sees at all.
24
+ * - TWELVE a minute for `copy`, `createDirectories`, `emptyTrash` and `trash`
25
+ * together. Paced by {@link StorageNamespace.bulkGate}.
26
+ * - the general 600 a minute for everything else.
27
+ *
28
+ * The direct PUTs at the object store are not rate limited by the API.
29
29
  */
30
30
  /**
31
31
  * The server's null sentinel: U+0008, a literal backspace.
32
32
  *
33
- * `CrudActions` rewrites any filter value equal to it before the query layer
34
- * ever sees it - `transform_values! { |v| v == "\b" ? nil : v }`, applied to
35
- * every option bag, not just to `exact_search`. Through `exact_search` that is
36
- * exactly what is wanted: `where(parent_id: nil)`, the root nodes.
33
+ * The server reads any filter value equal to it as `null`, in every option
34
+ * bag. Through `exact_search[parent_id]` that is exactly what is wanted: the
35
+ * nodes with no parent, i.e. the roots.
37
36
  *
38
- * Through `extra_options` the same rewrite is a trap, because
39
- * `QueryExtraOptions::FsNodes` opens with
40
- * `return unless params[:parent_id].present?` and `nil` is not present, so the
41
- * filter is dropped without a word. {@link StorageNamespace.list} is built
42
- * around that difference; do not collapse the two filters back together.
37
+ * Through `extra_options[parent_id]` the same value is a trap: a `null` there
38
+ * counts as no filter at all, and the filter is dropped without a word.
39
+ * {@link StorageNamespace.list} is built around that difference; do not
40
+ * collapse the two filters back together.
43
41
  */
44
42
  import { type ApiClient, Resource } from "../http";
45
43
  import type { ListParams } from "../listing";
@@ -52,27 +50,14 @@ export type FsNodeKind = "file" | "directory";
52
50
  /**
53
51
  * A node in the virtual filesystem.
54
52
  *
55
- * This is the WHOLE record, and it was checked against the blueprint CHAIN
56
- * rather than against the table, because those two disagree.
57
- * `FsNodeBlueprint` declares `name`, `parent_id`, `kind`, `size`,
58
- * `max_size`; it extends `ApplicationBlueprint`, which contributes `id`,
59
- * `created_at` and `updated_at`; and its `:extended` view has an EMPTY body,
60
- * which in Blueprinter inherits the base fields rather than emitting nothing.
61
- * So `list`, `get`, `create` and `update` all answer the same eight fields.
62
- * Reading a view name and assuming it adds something has already produced bugs
63
- * in this repo - follow the `<` before deciding a field does or does not exist.
64
- *
65
- * The `fs_nodes` TABLE is wider than that, and the difference is never sent:
66
- * `creator_id`, `updater_id`, `destroyer_id`, `signed_url_generated`,
67
- * `is_vault_root` and the `id_path` ltree are all real columns that appear in
68
- * no view. Declaring them client-side is worse than leaving them out, because
69
- * every later reader then believes they arrive.
53
+ * This is the WHOLE record: `list`, `get`, `create` and `update` all answer
54
+ * the same eight fields.
70
55
  *
71
- * There is no `data` and no `url` field either: bytes are reached through
56
+ * There is no `data` and no `url` field: bytes are reached through
72
57
  * {@link StorageNamespace.download}, {@link StorageNamespace.downloadStream} or
73
58
  * {@link StorageNamespace.downloadUrl}, never off the record. And no
74
59
  * `content_type` and no `path` - the type is decided from the name at download
75
- * time, and the `path` column was dropped in the ltree migration.
60
+ * time, and a node is addressed by id.
76
61
  */
77
62
  export interface FsNode extends BaseRecord {
78
63
  readonly name: string;
@@ -101,10 +86,8 @@ export interface FsRoots {
101
86
  * A bulk operation the server runs in the background.
102
87
  *
103
88
  * `copy`, `createDirectories`, `trash` and `emptyTrash` all answer with nothing
104
- * but a job id: the work happens in a worker and the response says only that it
105
- * was enqueued. Poll it with `oms.jobs.wait(jobId)`; this namespace has no
106
- * access to the jobs namespace and deliberately does not grow a second polling
107
- * loop.
89
+ * but a job id: the response says only that the work was enqueued. Poll it
90
+ * with `oms.jobs.wait(jobId)`.
108
91
  */
109
92
  export interface FsBulkJob {
110
93
  /** Feed this to `oms.jobs.get` / `oms.jobs.wait`. */
@@ -125,7 +108,6 @@ export interface FsStream {
125
108
  /** Byte length when the server sent one. Always `undefined` for a zip. */
126
109
  readonly size: number | undefined;
127
110
  }
128
- /** Filters for {@link StorageNamespace.list}. */
129
111
  /** Filter columns of `GET /fs_nodes`. */
130
112
  export declare const FS_NODE_FILTER_COLUMNS: readonly ["id", "created_at", "updated_at", "name", "parent_id"];
131
113
  /** `extra_options` keys of `GET /fs_nodes`. */
@@ -157,10 +139,9 @@ export interface ListFsNodesParams extends ListParams<(typeof FS_NODE_FILTER_COL
157
139
  * Also return the parent itself, so one call gets both the folder's metadata
158
140
  * and its children. It occupies a slot on the page like any other row.
159
141
  *
160
- * IGNORED when `parentId` is `null`, and that is a correction rather than a
161
- * convenience: the server-side filter behind this flag cannot express "no
162
- * parent" at all, and asking it to used to answer with the caller's whole
163
- * tree. The roots have no folder to fold in anyway. The detail is on
142
+ * IGNORED when `parentId` is `null`: the server-side filter behind this flag
143
+ * cannot express "no parent", and asking it to answers with the caller's
144
+ * whole tree. The roots have no folder to fold in anyway. The detail is on
164
145
  * {@link StorageNamespace.list}.
165
146
  */
166
147
  readonly includeSelf?: boolean;
@@ -197,7 +178,7 @@ export interface FsGrant extends BaseRecord {
197
178
  readonly grantee_id: Id | null;
198
179
  /** Write access. Always `false` on a public grant - the server validates it. */
199
180
  readonly editable: boolean;
200
- /** Only on the `:extended` view, i.e. from `get`, `create` and `update`. */
181
+ /** Only from `get`, `create` and `update`; absent in listings. */
201
182
  readonly fs_node?: FsNode;
202
183
  readonly grantor?: User;
203
184
  readonly grantee?: User | null;
@@ -232,17 +213,17 @@ export interface SharedFsNodeView {
232
213
  *
233
214
  * Creating one with a `granteeId` notifies that user. Creating one WITHOUT a
234
215
  * grantee mints a public link: the server also creates a short link in the `ss`
235
- * namespace whose endpoint is the grant's own id, pointing at the frontend's
236
- * `/storage/shared?id=<node>` page. Deleting the grant deletes that link.
216
+ * namespace whose endpoint is the grant's own id. Deleting the grant deletes
217
+ * that link.
237
218
  */
238
219
  export declare class FsGrantsNamespace extends Resource {
239
220
  /**
240
221
  * `GET /fs_grants` - the grants you hold: issued by you, or issued to you.
241
222
  *
242
- * There is no server-side filter for the node. The controller allows only
243
- * `id`, `created_at` and `updated_at` as search keys, and an unknown key is a
244
- * 400, not a wider result - so narrowing to one node is a client-side filter
245
- * over this listing. {@link StorageNamespace.shared} is the cheap way to ask
223
+ * There is no server-side filter for the node. The only search keys accepted
224
+ * are `id`, `created_at` and `updated_at`, and an unknown key is a 400, not a
225
+ * wider result - so narrowing to one node is a client-side filter over this
226
+ * listing. {@link StorageNamespace.shared} is the cheap way to ask
246
227
  * "how is THIS node shared".
247
228
  *
248
229
  * @throws {OmsAuthError} 401 when anonymous.
@@ -277,9 +258,9 @@ export declare class StorageNamespace extends Resource {
277
258
  /** Sharing grants. */
278
259
  readonly grants: FsGrantsNamespace;
279
260
  /**
280
- * Paces the four bulk-job endpoints against the `fs_bulk_job` throttle, which
281
- * is twelve requests a minute for all of them together. A loop that trashes
282
- * files one at a time waits here rather than collecting 429s.
261
+ * Paces the four bulk-job endpoints against their shared limit of twelve
262
+ * requests a minute. A loop that trashes files one at a time waits here
263
+ * rather than collecting 429s.
283
264
  */
284
265
  readonly bulkGate: StorageRateGate;
285
266
  /**
@@ -318,40 +299,29 @@ export declare class StorageNamespace extends Resource {
318
299
  * TWO server-side filters address a directory and they are NOT
319
300
  * interchangeable. That asymmetry is the whole subtlety of this method:
320
301
  *
321
- * - `exact_search[parent_id]` reaches `Searchable.exact_search`, which is a
322
- * bare `where(params)`. The controller has already rewritten a `\b` value
323
- * to `nil` by then, so the sentinel lands as `WHERE parent_id IS NULL` -
324
- * and since `FsNode.root_nodes` is exactly `where(parent_id: nil)`, this is
325
- * the only filter in the API that can say "the roots". The ltree
326
- * `id_path` is the source of truth for ANCESTRY, but rootness is still a
327
- * null `parent_id`.
328
- * - `extra_options[parent_id]` reaches `QueryExtraOptions::FsNodes`, which
329
- * runs `where(parent_id: x).or(where(id: x))` and so folds the folder
330
- * itself back into its own listing. Convenient - and guarded by
331
- * `return unless params[:parent_id].present?`, with that same `\b` -> `nil`
332
- * rewrite happening first. Hand it the sentinel and the guard drops the
333
- * filter IN SILENCE. The request still answers 200; it just answers with
334
- * the caller's ENTIRE listable tree, page after page, instead of three
335
- * rows. It is the same failure shape as the `inside_path` incident that
336
- * `reject_unknown_filter_keys!` was written for, except this key IS known,
337
- * so nothing rejects it.
302
+ * - `exact_search[parent_id]` selects the children only. A `\b` value is
303
+ * read as `null` and selects the nodes with no parent, so this is the only
304
+ * filter in the API that can say "the roots".
305
+ * - `extra_options[parent_id]` selects the children AND the folder itself.
306
+ * Hand it the sentinel and the filter is dropped IN SILENCE. The request
307
+ * still answers 200; it just answers with the caller's ENTIRE listable
308
+ * tree, page after page, instead of three rows.
338
309
  *
339
310
  * Hence `includeSelf` is honoured under a real directory and ignored at the
340
311
  * top of the tree. Not client-side taste: it is the only combination the
341
312
  * server can actually express.
342
313
  *
343
- * The endpoint is conditional-GET aware and answers 304 to a matching
344
- * `If-None-Match`. The SDK never sends one, and asks the runtime not to
345
- * revalidate on its own, because a 304 has no body and would surface here as
346
- * an error rather than as an empty page.
314
+ * The endpoint answers 304 to a matching `If-None-Match`. The SDK never
315
+ * sends one, and asks the runtime not to revalidate on its own, because a
316
+ * 304 has no body and would surface here as an error rather than as an
317
+ * empty page.
347
318
  */
348
319
  list(params?: ListFsNodesParams, options?: RequestOptions): Promise<Paginated<FsNode>>;
349
320
  /**
350
321
  * `GET /fs_nodes/:id` - one node.
351
322
  *
352
- * Resolves against the broader `viewable_by` scope, so a node reached through
353
- * a public share link answers here even though it never appears in
354
- * {@link list}.
323
+ * Visibility is wider than {@link list}'s: a node reached through a public
324
+ * share link answers here even though it never appears in a listing.
355
325
  *
356
326
  * @throws {OmsApiError} 404 when the node does not exist or is not visible.
357
327
  */
@@ -370,11 +340,10 @@ export declare class StorageNamespace extends Resource {
370
340
  * Resolves a slash-separated path under a starting node, walking children one
371
341
  * level at a time.
372
342
  *
373
- * A convenience for humans and CLIs, NOT how the API works. The `path` column
374
- * was dropped in the ltree migration and nothing on the server accepts a path
375
- * string, so each segment costs one filtered listing. Results are memoised
376
- * per client instance, which makes a second walk down the same prefix free,
377
- * but the cheap call is always the one that already has an id.
343
+ * A convenience for humans, NOT how the API works. Nothing on the server
344
+ * accepts a path string, so each segment costs one filtered listing. Results
345
+ * are memoised per client instance, which makes a second walk down the same
346
+ * prefix free, but the cheap call is always the one that already has an id.
378
347
  *
379
348
  * `.` is skipped and `..` climbs to the parent. A leading `/` means "from the
380
349
  * home root" and ignores `from`.
@@ -394,9 +363,9 @@ export declare class StorageNamespace extends Resource {
394
363
  * blobs and reads the finished nodes back.
395
364
  *
396
365
  * Files at or above `MULTIPART_THRESHOLD` (32 MiB, exported from this
397
- * package) take the multipart path automatically, and that is not tuning:
398
- * the object store sits behind Cloudflare with a request-body cap around
399
- * 100 MB, so it is the only way a large file gets in at all.
366
+ * package) take the multipart path automatically, and that is not tuning: a
367
+ * single request to the object store is capped at roughly 100 MB, so it is
368
+ * the only way a large file gets in at all.
400
369
  *
401
370
  * A per-file rejection - a quota that ran out, a name that collides with a
402
371
  * directory - does not throw. It comes back in
@@ -422,7 +391,7 @@ export declare class StorageNamespace extends Resource {
422
391
  * job's result is the list of directories that were created. Existing levels
423
392
  * are reused, so re-running the same paths is a no-op that creates nothing.
424
393
  *
425
- * Costs one of the twelve `fs_bulk_job` requests a minute. Pass every path in
394
+ * Counts against the twelve bulk-job requests a minute. Pass every path in
426
395
  * one call rather than looping.
427
396
  *
428
397
  * @throws {OmsApiError} 400 when `paths` is empty or the parent is not a
@@ -489,10 +458,10 @@ export declare class StorageNamespace extends Resource {
489
458
  * `GET /fs_nodes/:id/zip` - a directory and every file under it that the
490
459
  * caller can see, as a zip archive.
491
460
  *
492
- * Streamed, and streamed for real: the server generates it with
493
- * `ActionController::Live`, so there is no `Content-Length` and no way to
494
- * know the size in advance. Never retried automatically either - a retry
495
- * restarts the whole archive from zero.
461
+ * Streamed, and streamed for real: the server generates the archive as it
462
+ * sends it, so there is no `Content-Length` and no way to know the size in
463
+ * advance. Never retried automatically either - a retry restarts the whole
464
+ * archive from zero.
496
465
  *
497
466
  * @throws {OmsApiError} 400 when the node is not a directory, 404 when it is
498
467
  * not visible.
@@ -501,8 +470,8 @@ export declare class StorageNamespace extends Resource {
501
470
  /**
502
471
  * `PATCH /fs_nodes/:id` with a new name.
503
472
  *
504
- * The returned node is checked against what was asked for. The controller
505
- * silently drops any field outside its update allowlist, so a 200 alone
473
+ * The returned node is checked against what was asked for. The server
474
+ * silently drops any field it does not accept on update, so a 200 alone
506
475
  * proves nothing about the write having happened.
507
476
  *
508
477
  * @throws {OmsApiError} 400 when the name collides with a sibling or contains
@@ -512,9 +481,7 @@ export declare class StorageNamespace extends Resource {
512
481
  /**
513
482
  * `PATCH /fs_nodes/:id` with a new parent.
514
483
  *
515
- * The server refuses a move that would make a node its own ancestor; that
516
- * cycle check is the fix for the 2026-07-27 copy outage and must not be
517
- * second-guessed client-side.
484
+ * The server refuses a move that would make a node its own ancestor.
518
485
  *
519
486
  * Like {@link rename}, the answer is verified rather than assumed.
520
487
  *
@@ -533,7 +500,7 @@ export declare class StorageNamespace extends Resource {
533
500
  * filters the index does, so a copy with NO selection would resolve to the
534
501
  * caller's entire listable tree and duplicate it.
535
502
  *
536
- * Costs one of the twelve `fs_bulk_job` requests a minute.
503
+ * Counts against the twelve bulk-job requests a minute.
537
504
  */
538
505
  copy(input: CopyFsNodesInput, options?: RequestOptions): Promise<FsBulkJob>;
539
506
  /**
@@ -546,7 +513,7 @@ export declare class StorageNamespace extends Resource {
546
513
  * Refuses an empty id list for the same reason {@link copy} does: with no
547
514
  * selection the endpoint resolves to the caller's whole listable tree.
548
515
  *
549
- * Costs one of the twelve `fs_bulk_job` requests a minute, so trash the whole
516
+ * Counts against the twelve bulk-job requests a minute, so trash the whole
550
517
  * selection in one call.
551
518
  */
552
519
  trash(ids: Id[], options?: RequestOptions): Promise<FsBulkJob>;
@@ -605,7 +572,7 @@ export declare class StorageNamespace extends Resource {
605
572
  /**
606
573
  * Fetches an object-storage URL on the injected transport with no credential
607
574
  * of ours attached. The presigned signature in the URL IS the credential, and
608
- * a bearer header alongside it is what makes MinIO reject the request.
575
+ * the store rejects a request that carries a bearer header alongside it.
609
576
  */
610
577
  private fetchObject;
611
578
  }
@@ -1,15 +1,14 @@
1
1
  /**
2
2
  * Background removal: cuts the subject out of an image.
3
3
  *
4
- * `POST /background_removals` enqueues a proxy job and answers immediately with
5
- * a row plus a `job_id` and, for an anonymous caller, a `watch_token`. Poll
4
+ * `POST /background_removals` enqueues a job and answers immediately with a
5
+ * row plus a `job_id` and, for an anonymous caller, a `watch_token`. Poll
6
6
  * through `oms.jobs` with that handle, or use {@link BackgroundRemovalNamespace.run}.
7
7
  *
8
- * Backend limits: 15 MiB, and an image bomb (absurd pixel count for its byte
9
- * size) is rejected with a 400 before any work starts.
8
+ * Limits: 15 MiB, and an image bomb (absurd pixel count for its byte size) is
9
+ * rejected with a 400 before any work starts.
10
10
  *
11
- * This tool has no daily quota - it is one of the two that the `Quotas`
12
- * catalogue does not meter - so there is no `quota()` here to call first.
11
+ * This tool has no daily quota, so there is no `quota()` here to call first.
13
12
  */
14
13
  import { Resource } from "../../http";
15
14
  import type { FileInput, Id, RequestOptions } from "../../types";
@@ -18,12 +17,12 @@ import { type ToolCaptcha, type ToolJobHandle, type ToolRecord, type ToolRunOpti
18
17
  * A background removal run.
19
18
  *
20
19
  * Both routes that answer with one - `POST /background_removals` and
21
- * `GET /background_removals/:id` - render the `:extended` view, so `result_url`
22
- * is always PRESENT and simply `null` until the run completes.
20
+ * `GET /background_removals/:id` - answer the same shape, so `result_url` is
21
+ * always PRESENT and simply `null` until the run completes.
23
22
  *
24
23
  * `progress_percent`, inherited from {@link ToolRecord}, is never sent for this
25
- * tool: `BackgroundRemovalBlueprint` has no such field. Progress lives on the
26
- * {@link Job} row that {@link BackgroundRemovalCreated.job_id} names.
24
+ * tool. Progress lives on the {@link Job} row that
25
+ * {@link BackgroundRemovalCreated.job_id} names.
27
26
  */
28
27
  export interface BackgroundRemoval extends ToolRecord {
29
28
  /**
@@ -38,7 +37,7 @@ export interface BackgroundRemoval extends ToolRecord {
38
37
  export type BackgroundRemovalCreated = BackgroundRemoval & ToolJobHandle;
39
38
  /** Arguments for starting a run. */
40
39
  export interface CreateBackgroundRemovalInput extends ToolCaptcha {
41
- /** The image. Backend cap: 15 MiB. */
40
+ /** The image. Cap: 15 MiB. */
42
41
  readonly file: FileInput;
43
42
  }
44
43
  /** The `backgroundRemoval` tool, reachable as `oms.tools.backgroundRemoval`. */
@@ -56,8 +55,7 @@ export declare class BackgroundRemovalNamespace extends Resource {
56
55
  *
57
56
  * NOT retried by default, unlike most of the SDK. The transport's policy
58
57
  * replays a `POST` that died with a 502, and here that would re-upload the
59
- * image and start a second run on a sidecar that serialises them. Pass
60
- * `retry: {}` to opt back in.
58
+ * image and start a second run. Pass `retry: {}` to opt back in.
61
59
  *
62
60
  * @throws {OmsApiError} 400 when the image is too large or looks like a bomb.
63
61
  * @throws {OmsAuthError} 401 when anonymous and the captcha is missing or bad.