@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
@@ -8,11 +8,10 @@
8
8
  *
9
9
  * ## Three runtimes, and where they stop agreeing
10
10
  *
11
- * The same transport runs in a browser (the Next.js frontend), in React Native
12
- * (the Expo app) and in Bun (the CLI and the MCP server). They agree on
13
- * `fetch`, `AbortController`, `Headers`, `FormData` and `setTimeout`. They do
14
- * NOT agree on three things, each of which has a named capability check here
15
- * rather than a `try` and a shrug:
11
+ * The same transport runs in a browser, in React Native and in Bun or a Worker
12
+ * isolate. They agree on `fetch`, `AbortController`, `Headers`, `FormData` and
13
+ * `setTimeout`. They do NOT agree on three things, each of which has a named
14
+ * capability check here rather than a `try` and a shrug:
16
15
  *
17
16
  * | capability | browser | React Native | Worker / Bun |
18
17
  * | --------------------------------- | ------- | ------------ | ------------ |
@@ -32,7 +31,7 @@ export declare const DEFAULT_BASE_URL = "https://backend.omelhorsite.pt";
32
31
  *
33
32
  * Answered by probing the globals, never by sniffing a platform name, and
34
33
  * recomputed on every call so a polyfill installed after import is seen. See
35
- * the table in the module note for how the three clients score.
34
+ * the table in the module note for how the three runtimes score.
36
35
  */
37
36
  export interface TransportCapabilities {
38
37
  /** `fetch` hands back a readable body that can be consumed as it arrives. */
@@ -51,9 +50,7 @@ export declare function transportCapabilities(): TransportCapabilities;
51
50
  * UI, and it has a hard "no" on React Native. RN's `fetch` is its
52
51
  * `XMLHttpRequest` with a whatwg-fetch shim over it: the whole body is
53
52
  * accumulated by the native layer and handed over at the end, `response.body`
54
- * is `undefined`, and there is no `ReadableStream` in the runtime at all -
55
- * confirmed by grep over `oms-music/src`, which mentions neither
56
- * `ReadableStream` nor `getReader` anywhere.
53
+ * is `undefined`, and there is no `ReadableStream` in the runtime at all.
57
54
  *
58
55
  * That is not a gap to polyfill. Nothing that runs in JS can make the native
59
56
  * networking layer emit partial bodies, and the shims that claim to (RN's
@@ -79,10 +76,9 @@ export declare function transportCapabilities(): TransportCapabilities;
79
76
  * is to call it and use this only to decide what the UI PROMISES: a typing
80
77
  * indicator that never types is worse than a spinner that admits it is waiting.
81
78
  *
82
- * The consumer this was designed against is the frontend's `BookChatService`,
83
- * which reads an SSE-shaped body (`data: {"delta": "..."}` lines) off
84
- * `POST /books/:id/chat`. Framing the lines is the domain's job; this and
85
- * `streamText` only promise decoded text in order.
79
+ * The typical consumer reads an SSE-shaped body (`data: {"delta": "..."}`
80
+ * lines) off `POST /books/:id/chat`. Framing the lines is the caller's job;
81
+ * this and `streamText` only promise decoded text in order.
86
82
  *
87
83
  * The three probes are all needed. `ReadableStream` existing does not mean
88
84
  * `fetch` produces one (a polyfilled global over RN's fetch is exactly that
@@ -93,7 +89,7 @@ export declare function transportCapabilities(): TransportCapabilities;
93
89
  export declare function supportsResponseStreaming(): boolean;
94
90
  /**
95
91
  * Whether `XMLHttpRequest` is available, which is the only route to byte-level
96
- * UPLOAD progress in any of the three clients.
92
+ * UPLOAD progress on any runtime.
97
93
  *
98
94
  * True in a browser and in React Native (RN's networking is XHR underneath and
99
95
  * `xhr.upload.onprogress` fires there); false in a Worker-class isolate and in
@@ -209,7 +205,7 @@ export type JsonBody = unknown;
209
205
  export type FormFieldValue = string | number | boolean | FileInput | NativeFile | null | undefined;
210
206
  /**
211
207
  * Fields of a multipart form. An array value is appended once per entry with a
212
- * `[]` suffix, which is how Rails reads a list (`clips[]`).
208
+ * `[]` suffix (`clips[]`), which is how the API reads a list.
213
209
  */
214
210
  export type FormFields = Record<string, FormFieldValue | FormFieldValue[]>;
215
211
  /** Options for a request that carries a query string. */
@@ -238,12 +234,11 @@ export interface GetOptions extends RequestOptions {
238
234
  * it never saw, so replaying it is how one `create` call becomes two records.
239
235
  * Safe methods carry no such risk, which is the whole reason the split exists.
240
236
  *
241
- * `429` is the exception, and it is safe on every method because of how this
242
- * particular backend produces one. It comes either from `Rack::Attack`, which
243
- * answers from middleware before the router is reached, or from a
244
- * `too_many_requests!` guard that every controller places BEFORE the write it
245
- * protects. A 429 is therefore proof the request was refused rather than
246
- * performed, and waiting out `Retry-After` and trying again is exactly right.
237
+ * `429` is the exception, and it is safe on every method because this API only
238
+ * ever answers one BEFORE performing the request: a rate-limited request is
239
+ * refused, never carried out. A 429 is therefore proof the request was refused
240
+ * rather than performed, and waiting out `Retry-After` and trying again is
241
+ * exactly right.
247
242
  *
248
243
  * ## Opting a mutator back in
249
244
  *
@@ -262,45 +257,18 @@ export interface GetOptions extends RequestOptions {
262
257
  * notepad) under a fresh random identifier on each attempt.
263
258
  *
264
259
  * This is narrower than the SDK's 0.2.0 behaviour, which retried 5xx on every
265
- * verb. Nothing in `resources/` relied on that: every call site that mentions
266
- * retry is turning it OFF.
267
- *
268
- * ## Why this and not the mobile app's rule
269
- *
270
- * `oms-music/src/api/retryPolicy.ts` states the rule the app arrived at after
271
- * the empty-Home bug: **retry for TIME, never for a RESPONSE**. A transport
272
- * failure (a `fetch` that throws, DNS, the iOS radio still waking) is time and
273
- * is worth asking again; a `4xx` is an answer and asking again does not change
274
- * it; a `5xx` gets one extra go for a deploy or a blinking proxy; `429` gets
275
- * none. Two attempts, `error.status >= 500` as the whole predicate.
276
- *
277
- * That rule is right for what it governs and wrong to copy here, for one
278
- * reason: it sits under react-query, where every retried operation is a QUERY.
279
- * "Repeat any transport error" is safe when the thing being repeated is a read.
280
- * This SDK carries the writes too, and the app's own mutations do NOT go
281
- * through that policy. Applying it verbatim would replay a `POST /songs` whose
282
- * answer was lost on a lift ride and mint the record twice, which is precisely
283
- * the failure the method split above exists to prevent. So the SDK keeps the
284
- * axis the app does not have to think about (the METHOD) and agrees with it on
285
- * the axis it does: a `4xx` is never retried anywhere.
286
- *
287
- * On `429` the two genuinely disagree, and the disagreement is deliberate on
288
- * both sides. The app declines because its ceiling-aware screens would rather
289
- * show "slow down" at once than sit on a hidden `Retry-After` sleep, and
290
- * because react-query re-throws a parked error before the network is even
291
- * consulted. The SDK retries because it also serves the CLI and the MCP server,
292
- * where the right move on a rate limit is to wait the header out and continue,
293
- * and because this backend's `429` provably precedes the write (Rack::Attack in
294
- * middleware, `too_many_requests!` ahead of every guarded action). A mobile
295
- * host that wants the app's behaviour asks for it per call - `retry: false` -
296
- * or, at the client, gets the closest match with `new Oms({ retry: { maxAttempts: 2 } })`:
297
- * one extra attempt, safe methods only, exactly the app's shape.
298
- *
299
- * One consequence to design around rather than discover: a retried `429` obeys
300
- * `Retry-After`, this API sets it from a one-minute window, and `timeoutMs`
301
- * bounds ONE attempt rather than the call. A rate-limited call can therefore
302
- * take minutes of wall clock. Anything with a user watching it should pass a
303
- * `signal` it can abort, or turn retrying off.
260
+ * verb.
261
+ *
262
+ * ## Rate limits and wall clock
263
+ *
264
+ * A retried `429` obeys `Retry-After`, this API sets it from a one-minute
265
+ * window, and `timeoutMs` bounds ONE attempt rather than the call. A
266
+ * rate-limited call can therefore take minutes of wall clock. A UI with a
267
+ * person watching it may rather show "slow down" at once than sit on a hidden
268
+ * sleep: pass a `signal` it can abort, turn retrying off per call with
269
+ * `retry: false`, or cap it at the client with
270
+ * `new Oms({ retry: { maxAttempts: 2 } })` - one extra attempt, safe methods
271
+ * only.
304
272
  */
305
273
  export declare class ApiClient {
306
274
  /** API root with no trailing slash. */
@@ -328,7 +296,7 @@ export declare class ApiClient {
328
296
  delete<T>(path: string, options?: GetOptions): Promise<T>;
329
297
  /**
330
298
  * `POST` a `multipart/form-data` body, parsed as JSON. Use this for every
331
- * endpoint that takes an upload through Rails (the tools). Storage uploads
299
+ * endpoint that takes a multipart upload (the tools). Storage uploads
332
300
  * do NOT go through here - they are presigned and go straight to the object
333
301
  * store; see `resources/storage/upload.ts`.
334
302
  *
@@ -345,7 +313,7 @@ export declare class ApiClient {
345
313
  *
346
314
  * `response.body` is NOT a promise this method can make: React Native has no
347
315
  * `ReadableStream` and leaves it undefined, so any code reaching for
348
- * `.body.getReader()` here works in the browser and the CLI and throws on a
316
+ * `.body.getReader()` here works in a browser and in Bun and throws on a
349
317
  * phone. Test with {@link supportsResponseStreaming} first, or use
350
318
  * {@link ApiClient.streamText}, which contains that fork already.
351
319
  */
@@ -359,7 +327,7 @@ export declare class ApiClient {
359
327
  * This is the primitive a streaming endpoint is built on. It promises exactly
360
328
  * two things - decoded text, in order, with nothing lost - and deliberately
361
329
  * promises nothing about chunk boundaries, because they are not the same on
362
- * the three clients:
330
+ * the three runtimes:
363
331
  *
364
332
  * - browser and Bun: one yield per network chunk, as it lands;
365
333
  * - React Native: ONE yield, containing everything, after the server has
@@ -370,20 +338,18 @@ export declare class ApiClient {
370
338
  * So a caller must not assume a chunk is a frame, a line, or a whole
371
339
  * anything: a `data:` line can arrive split across two chunks, and on RN a
372
340
  * hundred of them arrive as one string. Buffer, then split on your own
373
- * delimiter. `BookChatService` in the frontend is the reference reader (SSE
374
- * `data:` lines carrying `{ delta, done, error }`) and shows the shape of it;
375
- * framing belongs to the domain module, not here.
341
+ * delimiter. The book chat endpoint, for instance, answers SSE `data:` lines
342
+ * carrying `{ delta, done, error }`; framing them belongs to the caller, not
343
+ * here.
376
344
  *
377
- * ## The silence limit exists because of an outage
345
+ * ## The silence limit
378
346
  *
379
- * A stalled sidecar answered `200` and then said nothing for two minutes at a
380
- * time, and `await reader.read()` has no deadline of its own, so the chat
381
- * panel span for as long as the tab stayed open. `timeoutMs` does not help:
382
- * it is disposed once the headers arrive (it has to be, or no stream could
383
- * outlive it). `silenceTimeoutMs` bounds the gap BETWEEN chunks instead and
384
- * raises {@link OmsTimeoutError} when nothing arrives for that long. It has
385
- * to sit well clear of a cold model's first token; 45s is the number the
386
- * frontend settled on and the default here.
347
+ * A server can answer `200` and then say nothing for minutes, and
348
+ * `await reader.read()` has no deadline of its own. `timeoutMs` does not
349
+ * help: it is disposed once the headers arrive (it has to be, or no stream
350
+ * could outlive it). `silenceTimeoutMs` bounds the gap BETWEEN chunks instead
351
+ * and raises {@link OmsTimeoutError} when nothing arrives for that long. It
352
+ * has to sit well clear of a cold model's first token; 45s is the default.
387
353
  *
388
354
  * Pass `0` to disable it, and mean it: an unbounded read is a spinner with no
389
355
  * way out. It does not apply on the buffered path, where the single `text()`
@@ -437,29 +403,25 @@ export declare abstract class Resource {
437
403
  constructor(http: ApiClient);
438
404
  }
439
405
  /**
440
- * The backend's null sentinel: a single backspace character, `U+0008`.
406
+ * The API's null sentinel: a single backspace character, `U+0008`.
441
407
  *
442
408
  * A query string has no way to say `null`. `?parent_id=` is the empty string,
443
409
  * `?parent_id=null` is the four-letter word "null", and omitting the key
444
410
  * entirely says something else again. So the API picked a character no real
445
- * value ever contains and decodes it back to `nil` on arrival:
446
- * `CrudActions#define_option_param_getter` runs
447
- * `value.transform_values! { |v| v == "\b" ? nil : v }` over every filter
448
- * bucket, and `GroupChatsController`, `GroupChatMessagesController` and
449
- * `BookServices::Creator` each repeat the same test on the fields they read by
450
- * hand.
451
- *
452
- * Where that `nil` lands is what makes it worth having. `Searchable.exact_search`
453
- * is `where(params)`, so `exact_search[parent_id]` set to the sentinel becomes
454
- * `WHERE parent_id IS NULL` - the only way to ask for the storage root nodes,
455
- * for a comment with no parent, for anything unassigned.
411
+ * value ever contains and decodes it back to null on arrival, inside every
412
+ * filter bucket and in the handful of body fields that accept it.
413
+ *
414
+ * Where that null lands is what makes it worth having: `exact_search[parent_id]`
415
+ * set to the sentinel becomes `WHERE parent_id IS NULL` - the only way to ask
416
+ * for the storage root nodes, for a comment with no parent, for anything
417
+ * unassigned.
456
418
  *
457
419
  * Exported because it is part of the wire format, not because you should need
458
420
  * it: {@link encodeQuery} writes it for you whenever a query value is `null`.
459
421
  */
460
422
  export declare const NULL_SENTINEL = "\b";
461
423
  /**
462
- * Encodes query parameters the way Rails parses them.
424
+ * Encodes query parameters the way the API parses them.
463
425
  *
464
426
  * - `{ page: 2 }` -> `page=2`
465
427
  * - `{ ids: ["a", "b"] }` -> `ids%5B%5D=a&ids%5B%5D=b`
@@ -476,16 +438,14 @@ export declare const NULL_SENTINEL = "\b";
476
438
  * - `undefined` means "I am not filtering on this column". Dropping the key is
477
439
  * the correct encoding.
478
440
  * - `null` means "filter where this column IS NULL". There is no literal for
479
- * that in a URL, so it goes out as {@link NULL_SENTINEL} and the backend
480
- * turns it back into `nil`.
441
+ * that in a URL, so it goes out as {@link NULL_SENTINEL} and the server
442
+ * turns it back into null.
481
443
  *
482
- * Encoding `null` as "drop the key" - which this function used to do - is the
483
- * dangerous direction. The filter simply vanishes and `Searchable.exact_search`
484
- * returns early (`return self unless params.present?`), so the endpoint answers
485
- * with the UNFILTERED set: a request for the root of somebody's drive comes
486
- * back as their entire tree. That failure has bitten this API before, from the
487
- * other end, and is why `CrudActions#reject_unknown_filter_keys!` now 400s on a
488
- * key it does not recognise rather than quietly widening the query.
444
+ * Encoding `null` as "drop the key" is the dangerous direction. The filter
445
+ * simply vanishes and the endpoint answers with the UNFILTERED set: a request
446
+ * for the root of somebody's drive comes back as their entire tree. For the
447
+ * same reason the API answers `400` to a filter key it does not recognise
448
+ * rather than quietly widening the query.
489
449
  *
490
450
  * The sentinel is written at every depth, even though the server only decodes
491
451
  * it one level inside a filter bucket (`search`, `exact_search`, `modifiers`,
@@ -495,20 +455,17 @@ export declare const NULL_SENTINEL = "\b";
495
455
  *
496
456
  * ## Dates
497
457
  *
498
- * A `Date` reaches `typeof value === "object"` like anything else, and
499
- * `Object.entries(new Date())` is `[]`, so before this branch existed a date
500
- * filter did not merely arrive malformed - the key disappeared and the listing
501
- * came back unfiltered. ISO-8601 is what the server reads:
502
- * `QuerySearcher#date_search` runs `String#to_date_safe` (`Date.parse`) over
503
- * the value and turns an unparseable one into `nil`, which silently drops that
504
- * side of the range. Bodies need no equivalent branch, because `JSON.stringify`
505
- * already calls `Date.prototype.toJSON` and emits the same string.
458
+ * A `Date` is sent as its ISO-8601 string, which is what the server's date
459
+ * filters parse. An unparseable value is silently treated as absent, which
460
+ * drops that side of the range. Bodies need no equivalent branch, because
461
+ * `JSON.stringify` already calls `Date.prototype.toJSON` and emits the same
462
+ * string.
506
463
  *
507
464
  * ## The brackets are percent-encoded, and that is load-bearing
508
465
  *
509
466
  * `search[title]` goes out as `search%5Btitle%5D`, never as raw `[` and `]`.
510
- * Both parse identically in Rails, so this looks like the kind of noise someone
511
- * tidies away on a quiet afternoon. It is not, and the reason is iOS.
467
+ * Both parse identically on the server, so this looks like the kind of noise
468
+ * someone tidies away on a quiet afternoon. It is not, and the reason is iOS.
512
469
  *
513
470
  * `[` and `]` are not legal in a URI query (RFC 3986 reserves them for the host
514
471
  * component). Every browser tolerates them; Apple's URL stack does not. Give
@@ -534,16 +491,16 @@ export declare function encodeQuery(params: QueryParams): string;
534
491
  * asked for again.
535
492
  *
536
493
  * `PUT` and `DELETE` are idempotent by RFC 9110 and are still absent, because
537
- * idempotent is not the same as harmless to replay HERE. Rails' `destroy` is
538
- * behind a `find_by` that answers `404` the second time, so a `DELETE` retried
539
- * after a torn connection reports "not found" for a row it deleted perfectly
540
- * well - a success turned into an error the caller then acts on.
494
+ * idempotent is not the same as harmless to replay HERE. A `DELETE` answers
495
+ * `404` the second time, so one retried after a torn connection reports "not
496
+ * found" for a row it deleted perfectly well - a success turned into an error
497
+ * the caller then acts on.
541
498
  */
542
499
  export declare const SAFE_METHODS: ReadonlySet<string>;
543
500
  /** True when {@link SAFE_METHODS} contains `method`, case-insensitively. */
544
501
  export declare function isSafeMethod(method: string): boolean;
545
502
  /**
546
- * Builds the `modifiers[page]` string the backend expects (`"2:100"`).
503
+ * Builds the `modifiers[page]` string the API expects (`"2:100"`).
547
504
  *
548
505
  * Both halves go through `resolvePageSize` / `resolvePageNumber`, which is the
549
506
  * same pair `createPage` uses. That is the point: the size on the wire and the
@@ -552,9 +509,8 @@ export declare function isSafeMethod(method: string): boolean;
552
509
  * told `hasMore: false` while 700 rows sit behind it.
553
510
  *
554
511
  * @throws {TypeError} for a page size that is not a finite number of at least
555
- * 1. `"1:NaN"` on the wire reads as size `0` in
556
- * `QueryModifier#apply_pagination`, which skips `limit`/`offset` altogether
557
- * and returns the entire table.
512
+ * 1. `"1:NaN"` on the wire reads as size `0` on the server, which then skips
513
+ * pagination altogether and returns the entire table.
558
514
  */
559
515
  export declare function pageModifier(page?: number, pageSize?: number): string;
560
516
  /**
@@ -563,8 +519,8 @@ export declare function pageModifier(page?: number, pageSize?: number): string;
563
519
  * `null` and `undefined` fields are OMITTED, which is the opposite of what
564
520
  * {@link encodeQuery} does with `null` and is right for the same reason it is
565
521
  * right there: what the receiver reads from an absent field. A multipart body
566
- * only ever feeds a create here, and an absent field means `params[:x]` is
567
- * `nil` - already the value a sentinel would decode to, so writing one would
522
+ * only ever feeds a create here, and an absent field is read as null on the
523
+ * server - already the value a sentinel would decode to, so writing one would
568
524
  * add a step that changes nothing. In a query the absent key means "no filter",
569
525
  * which is a different answer entirely.
570
526
  *
@@ -609,7 +565,7 @@ export declare function backoffDelay(attempt: number, retry: ResolvedRetry): num
609
565
  export declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
610
566
  /**
611
567
  * How long {@link ApiClient.streamText} will wait for the NEXT chunk before it
612
- * gives up: 45 seconds, the number the frontend's `BookChatService` arrived at.
568
+ * gives up: 45 seconds.
613
569
  *
614
570
  * It is a silence limit, not a total: a stream that keeps producing runs as
615
571
  * long as it likes. The value has to clear a cold model's first token (the
@@ -8,8 +8,7 @@
8
8
  * const link = await oms.shortLinks.create({ url: "https://example.com" });
9
9
  * ```
10
10
  *
11
- * This package is the product; the CLI and the MCP server are two clients of
12
- * it. Three rules make that work, and they are not negotiable:
11
+ * Three rules shape the package, and they are not negotiable:
13
12
  *
14
13
  * 1. It runs in a Cloudflare-Worker-class isolate. No `node:*`, no `process`,
15
14
  * no filesystem, no stdout. `fetch` is injectable through the constructor.
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * This module encodes a payload into a module matrix and renders it as SVG.
5
5
  * That is the whole isolate-safe surface: SVG is text, so it works in a Worker,
6
- * in the CLI and in a browser alike.
6
+ * in Bun and in a browser alike.
7
7
  *
8
8
  * Raster output (PNG, JPEG) is deliberately NOT here. It needs a canvas or an
9
9
  * image encoder, neither of which every target runtime has, and the host
@@ -19,8 +19,7 @@
19
19
  * few dozen lines of actual logic in `password.ts`. Nothing here is
20
20
  * platform-specific, so it is isolate-safe like the rest of `local/`.
21
21
  *
22
- * This file is DATA, copied verbatim from `frontend/lib/crypto/wordlist.ts` -
23
- * the same list the web app's vault draws from. Keep the two in step rather
24
- * than editing either by hand.
22
+ * This file is DATA. Regenerate it from the source rather than editing it by
23
+ * hand.
25
24
  */
26
25
  export declare const EFF_LONG_WORDLIST: readonly string[];
@@ -12,7 +12,7 @@ import type { BaseRecord, FileInput, Id, Paginated, RequestOptions, Timestamp }
12
12
  /**
13
13
  * A user as the API renders them.
14
14
  *
15
- * Most fields are conditional: the blueprint hides `email` and `gender` unless
15
+ * Most fields are conditional: the API hides `email` and `gender` unless
16
16
  * they are public or you are the owner or an administrator, and hides
17
17
  * `group`, `last_seen_at`, `sessions_count` and `deactivated_at` from everyone
18
18
  * but an administrator. An absent key therefore means "not visible to you",
@@ -218,7 +218,7 @@ export declare class AccountSessionsNamespace extends Resource {
218
218
  * `DELETE /sessions/:id` - ends the session THIS credential is using.
219
219
  *
220
220
  * There is no argument on purpose. The endpoint never reads the `:id` in the
221
- * path: it destroys `Current.session`, whatever id you send. Revoking
221
+ * path: it destroys the calling session, whatever id you send. Revoking
222
222
  * another device's session is not possible through the API today, and a
223
223
  * method that appeared to do it would silently log the caller out instead.
224
224
  *
@@ -259,8 +259,8 @@ export declare class AccountNamespace extends Resource {
259
259
  */
260
260
  updatePicture(picture: FileInput, options?: RequestOptions): Promise<User>;
261
261
  /**
262
- * `GET /account/usage` - consumption per area, for the bars the CLI prints
263
- * before starting an expensive job.
262
+ * `GET /account/usage` - consumption per area, for a usage screen or a
263
+ * check before starting an expensive job.
264
264
  */
265
265
  usage(options?: RequestOptions): Promise<AccountUsage>;
266
266
  /** `GET /users/:id` - another user, by stable id. Requires a credential. */
@@ -289,21 +289,20 @@ export declare class AccountNamespace extends Resource {
289
289
  * SENT WITH NO CREDENTIAL AT ALL, and that is the point of this method rather
290
290
  * than an oversight.
291
291
  *
292
- * The endpoint is anonymous by design: `UsersController` lists `picture` in
293
- * `allow_unauthenticated_access`, and `User.viewable_by` is `->(user) { all }`,
294
- * so a signed-in caller and a stranger resolve the same row and get the same
295
- * bytes. Sending a credential buys nothing, and it is what breaks the call.
292
+ * The endpoint is anonymous by design: a signed-in caller and a stranger get
293
+ * the same bytes. Sending a credential buys nothing, and it is what breaks
294
+ * the call.
296
295
  *
297
- * Why it breaks. The action answers `302` to `minio.omelhorsite.pt` with a
296
+ * Why it breaks. The endpoint answers `302` to the object store with a
298
297
  * presigned URL, and `fetch` follows that hop. Per the Fetch standard, when a
299
298
  * CORS request is redirected cross-origin and the request's origin already
300
299
  * differs from the current URL's origin, the origin is replaced by an opaque
301
- * one - so the second hop reaches the store with `Origin: null`. MinIO
300
+ * one - so the second hop reaches the store with `Origin: null`. The store
302
301
  * answers a null origin with `Access-Control-Allow-Origin: *`. A wildcard is
303
302
  * illegal for a credentialed request no matter what
304
303
  * `Access-Control-Allow-Credentials` says, so a client built with
305
- * `sessionCookie: true` - the production web app - would have the browser
306
- * reject the response before any JavaScript saw it. Every avatar on the page
304
+ * `sessionCookie: true` would have the browser reject the response before
305
+ * any JavaScript saw it. Every avatar on the page
307
306
  * would fail, and fail as an opaque "Failed to fetch".
308
307
  *
309
308
  * Dropping the credential removes the wildcard problem entirely: an
@@ -330,9 +329,8 @@ export declare class AccountNamespace extends Resource {
330
329
  * while rendering a friends list, a member picker or a message thread; an
331
330
  * async URL would turn every avatar into a state update and a second paint.
332
331
  *
333
- * It can be synchronous because the route carries no credential: `picture` is
334
- * in `allow_unauthenticated_access` and `User.viewable_by` is `all`, so there
335
- * is nothing to resolve and nothing to leak. The URL is safe to put in
332
+ * It can be synchronous because the route needs no credential, so there is
333
+ * nothing to resolve and nothing to leak. The URL is safe to put in
336
334
  * markup, to log, and to hand to someone else.
337
335
  *
338
336
  * ```tsx
@@ -341,8 +339,7 @@ export declare class AccountNamespace extends Resource {
341
339
  *
342
340
  * Do NOT add a `crossorigin` attribute. Without one the element makes a
343
341
  * no-cors request and the `302` to the object store is followed with no CORS
344
- * check at all, which is why this path has always worked in the web app.
345
- * `crossorigin="use-credentials"` re-creates exactly the failure
342
+ * check at all. `crossorigin="use-credentials"` re-creates exactly the failure
346
343
  * {@link picture} documents, and `crossorigin="anonymous"` only buys the
347
344
  * ability to read the pixels back out of a canvas.
348
345
  *
@@ -9,7 +9,7 @@
9
9
  * | credential | OAuth access token (JWT) | opaque `Session` token or cookie |
10
10
  * | who issues it | `/oauth/token`, the device grant | `POST /sessions` |
11
11
  * | authority | only the granted scopes | the whole account |
12
- * | who uses it | third-party apps, the CLI, MCP | the web app, oms-music |
12
+ * | who uses it | third-party apps and automation | first-party apps |
13
13
  * | reaches | endpoints declaring an `oauth_scope` | everything |
14
14
  *
15
15
  * `enforce_oauth_scope!` denies by omission, so an OAuth token cannot reach