@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.
- package/README.md +4 -4
- package/dist/index.js +4 -4
- package/dist/types/auth/device.d.ts +1 -1
- package/dist/types/auth/index.d.ts +2 -2
- package/dist/types/auth/tokens.d.ts +15 -15
- package/dist/types/client.d.ts +10 -10
- package/dist/types/errors.d.ts +12 -15
- package/dist/types/http.d.ts +74 -118
- package/dist/types/index.d.ts +1 -2
- package/dist/types/local/qr.d.ts +1 -1
- package/dist/types/local/wordlist.d.ts +2 -3
- package/dist/types/resources/account.d.ts +14 -17
- package/dist/types/resources/auth/index.d.ts +1 -1
- package/dist/types/resources/auth/passkeys.d.ts +127 -163
- package/dist/types/resources/auth/sessions.d.ts +110 -152
- package/dist/types/resources/chests.d.ts +27 -31
- package/dist/types/resources/dynamicQrs.d.ts +29 -45
- package/dist/types/resources/forms.d.ts +37 -58
- package/dist/types/resources/jobs.d.ts +28 -40
- package/dist/types/resources/media.d.ts +48 -61
- package/dist/types/resources/music/artists.d.ts +179 -245
- package/dist/types/resources/music/imports.d.ts +181 -210
- package/dist/types/resources/music/index.d.ts +8 -7
- package/dist/types/resources/music/playlists.d.ts +77 -110
- package/dist/types/resources/music/social.d.ts +153 -228
- package/dist/types/resources/music/songs.d.ts +160 -206
- package/dist/types/resources/realtime.d.ts +75 -88
- package/dist/types/resources/shortLinks.d.ts +33 -45
- package/dist/types/resources/storage/upload.d.ts +42 -56
- package/dist/types/resources/storage.d.ts +71 -104
- package/dist/types/resources/tools/backgroundRemoval.d.ts +11 -13
- package/dist/types/resources/tools/captions.d.ts +107 -135
- package/dist/types/resources/tools/upscale.d.ts +12 -16
- package/dist/types/types.d.ts +29 -38
- package/package.json +1 -1
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The direct-upload driver.
|
|
3
3
|
*
|
|
4
|
-
* Bytes never pass through
|
|
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
|
|
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
|
-
*
|
|
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.
|
|
34
|
-
*
|
|
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
|
-
*
|
|
40
|
-
*
|
|
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
|
-
*
|
|
44
|
-
*
|
|
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
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* -
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
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
|
|
104
|
-
* that never mentions checksums. That is the whole reason this
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
115
|
+
/** Parallel presigned PUTs in flight by default. Keep it modest. */
|
|
130
116
|
export declare const DEFAULT_UPLOAD_CONCURRENCY = 4;
|
|
131
117
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
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
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
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
|
|
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
|
|
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
|
|
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
|
|
406
|
-
*
|
|
407
|
-
*
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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
|
|
12
|
-
* client instance so a
|
|
13
|
-
*
|
|
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;
|
|
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
|
-
*
|
|
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
|
-
* -
|
|
22
|
+
* - 300 requests a minute for the whole upload control plane. Paced by
|
|
24
23
|
* {@link UploadManager}.
|
|
25
|
-
* -
|
|
26
|
-
*
|
|
27
|
-
* - the general 600
|
|
28
|
-
*
|
|
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
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
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
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
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
|
|
56
|
-
*
|
|
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
|
|
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
|
|
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
|
|
105
|
-
*
|
|
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
|
|
161
|
-
*
|
|
162
|
-
*
|
|
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
|
|
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
|
|
236
|
-
*
|
|
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
|
|
243
|
-
* `id`, `created_at` and `updated_at
|
|
244
|
-
*
|
|
245
|
-
*
|
|
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
|
|
281
|
-
*
|
|
282
|
-
*
|
|
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]`
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
* the
|
|
326
|
-
*
|
|
327
|
-
*
|
|
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
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
*
|
|
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
|
-
*
|
|
353
|
-
*
|
|
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
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
*
|
|
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
|
|
399
|
-
*
|
|
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
|
-
*
|
|
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
|
|
493
|
-
*
|
|
494
|
-
*
|
|
495
|
-
*
|
|
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
|
|
505
|
-
* silently drops any field
|
|
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
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
|
5
|
-
*
|
|
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
|
-
*
|
|
9
|
-
*
|
|
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
|
|
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` -
|
|
22
|
-
*
|
|
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
|
|
26
|
-
* {@link
|
|
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.
|
|
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
|
|
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.
|