@gemmein/sdk 0.4.3 → 0.4.4
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/dist/index.cjs +7 -1
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -1
- package/llms.txt +19 -6
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -671,6 +671,12 @@ class CollectionClient {
|
|
|
671
671
|
* Pass `{ name }` so the download carries a real filename, and
|
|
672
672
|
* `{ contentType }` when the Blob has no type of its own.
|
|
673
673
|
*
|
|
674
|
+
* W7.4 — `{ for: userId }` names ONE other person who may read this file
|
|
675
|
+
* (addressed and direct collections only — the rules where recipients
|
|
676
|
+
* exist). The attachment on a direct message: upload with
|
|
677
|
+
* `{ for: recipientId }`, store the ref in the record you send them, and
|
|
678
|
+
* their `g.files.link(ref)` works. Without `for`, only you can link it.
|
|
679
|
+
*
|
|
674
680
|
* There is deliberately no `url` here. A URL that outlives a refund is the
|
|
675
681
|
* bug this replaced.
|
|
676
682
|
*/
|
|
@@ -682,7 +688,7 @@ class CollectionClient {
|
|
|
682
688
|
// Step 1: Get presigned upload URL
|
|
683
689
|
const presign = await this.request("/upload", {
|
|
684
690
|
method: "POST",
|
|
685
|
-
body: JSON.stringify({ name, size: file.size, contentType }),
|
|
691
|
+
body: JSON.stringify({ name, size: file.size, contentType, ...(options?.for ? { for: options.for } : {}) }),
|
|
686
692
|
});
|
|
687
693
|
// Step 2: Upload directly to S3 via presigned POST
|
|
688
694
|
const form = new FormData();
|
package/dist/index.d.cts
CHANGED
|
@@ -500,12 +500,19 @@ export declare class CollectionClient<T extends Record<string, unknown> = Record
|
|
|
500
500
|
* Pass `{ name }` so the download carries a real filename, and
|
|
501
501
|
* `{ contentType }` when the Blob has no type of its own.
|
|
502
502
|
*
|
|
503
|
+
* W7.4 — `{ for: userId }` names ONE other person who may read this file
|
|
504
|
+
* (addressed and direct collections only — the rules where recipients
|
|
505
|
+
* exist). The attachment on a direct message: upload with
|
|
506
|
+
* `{ for: recipientId }`, store the ref in the record you send them, and
|
|
507
|
+
* their `g.files.link(ref)` works. Without `for`, only you can link it.
|
|
508
|
+
*
|
|
503
509
|
* There is deliberately no `url` here. A URL that outlives a refund is the
|
|
504
510
|
* bug this replaced.
|
|
505
511
|
*/
|
|
506
512
|
upload(file: Blob | File, options?: {
|
|
507
513
|
name?: string;
|
|
508
514
|
contentType?: string;
|
|
515
|
+
for?: string;
|
|
509
516
|
}): Promise<{
|
|
510
517
|
id: string;
|
|
511
518
|
ref: FileRef;
|
package/dist/index.d.ts
CHANGED
|
@@ -500,12 +500,19 @@ export declare class CollectionClient<T extends Record<string, unknown> = Record
|
|
|
500
500
|
* Pass `{ name }` so the download carries a real filename, and
|
|
501
501
|
* `{ contentType }` when the Blob has no type of its own.
|
|
502
502
|
*
|
|
503
|
+
* W7.4 — `{ for: userId }` names ONE other person who may read this file
|
|
504
|
+
* (addressed and direct collections only — the rules where recipients
|
|
505
|
+
* exist). The attachment on a direct message: upload with
|
|
506
|
+
* `{ for: recipientId }`, store the ref in the record you send them, and
|
|
507
|
+
* their `g.files.link(ref)` works. Without `for`, only you can link it.
|
|
508
|
+
*
|
|
503
509
|
* There is deliberately no `url` here. A URL that outlives a refund is the
|
|
504
510
|
* bug this replaced.
|
|
505
511
|
*/
|
|
506
512
|
upload(file: Blob | File, options?: {
|
|
507
513
|
name?: string;
|
|
508
514
|
contentType?: string;
|
|
515
|
+
for?: string;
|
|
509
516
|
}): Promise<{
|
|
510
517
|
id: string;
|
|
511
518
|
ref: FileRef;
|
package/dist/index.js
CHANGED
|
@@ -655,6 +655,12 @@ export class CollectionClient {
|
|
|
655
655
|
* Pass `{ name }` so the download carries a real filename, and
|
|
656
656
|
* `{ contentType }` when the Blob has no type of its own.
|
|
657
657
|
*
|
|
658
|
+
* W7.4 — `{ for: userId }` names ONE other person who may read this file
|
|
659
|
+
* (addressed and direct collections only — the rules where recipients
|
|
660
|
+
* exist). The attachment on a direct message: upload with
|
|
661
|
+
* `{ for: recipientId }`, store the ref in the record you send them, and
|
|
662
|
+
* their `g.files.link(ref)` works. Without `for`, only you can link it.
|
|
663
|
+
*
|
|
658
664
|
* There is deliberately no `url` here. A URL that outlives a refund is the
|
|
659
665
|
* bug this replaced.
|
|
660
666
|
*/
|
|
@@ -666,7 +672,7 @@ export class CollectionClient {
|
|
|
666
672
|
// Step 1: Get presigned upload URL
|
|
667
673
|
const presign = await this.request("/upload", {
|
|
668
674
|
method: "POST",
|
|
669
|
-
body: JSON.stringify({ name, size: file.size, contentType }),
|
|
675
|
+
body: JSON.stringify({ name, size: file.size, contentType, ...(options?.for ? { for: options.for } : {}) }),
|
|
670
676
|
});
|
|
671
677
|
// Step 2: Upload directly to S3 via presigned POST
|
|
672
678
|
const form = new FormData();
|
package/llms.txt
CHANGED
|
@@ -291,7 +291,7 @@ go-live. Everything else is yours.
|
|
|
291
291
|
- Images & files: NEVER base64 into record data and NEVER wire up your own
|
|
292
292
|
storage bucket — uploads are built in:
|
|
293
293
|
`const file = await g.collection("posts").upload(blob, { name })`
|
|
294
|
-
→ `{ id, ref, contentType, sizeBytes }`. Store `file.ref` (`"file:
|
|
294
|
+
→ `{ id, ref, contentType, sizeBytes }`. Store `file.ref` (`"file:9f2c…"` — a UUID form)
|
|
295
295
|
in a record field like any text — that's how a record "has" an image or
|
|
296
296
|
a document.
|
|
297
297
|
Store the REFERENCE, never a URL: a reference never expires and grants
|
|
@@ -318,14 +318,27 @@ go-live. Everything else is yours.
|
|
|
318
318
|
the console shows by name).
|
|
319
319
|
Honest bound: revoking access stops NEW links immediately; a link already
|
|
320
320
|
issued works until it expires. Gemmein controls delivery, it can't take
|
|
321
|
-
back a file someone already downloaded.
|
|
321
|
+
back a file someone already downloaded. A file can name ONE other reader:
|
|
322
|
+
`upload(blob, { for: userId })` (addressed/direct collections only) — the
|
|
323
|
+
direct message's attachment; the recipient's `files.link` works, everyone
|
|
324
|
+
else's still refuses. Without `for`, only the uploader can link it —
|
|
325
|
+
including in a client portal, where the OWNER hands a client a document
|
|
326
|
+
from the dashboard (attach it on the client's record there).
|
|
322
327
|
- Shapes: collections your users write (community, shared, direct) have a
|
|
323
328
|
SHAPE — the set of fields allowed. While your human builds, the server
|
|
324
329
|
learns it from your writes automatically (nothing to do); when they go
|
|
325
|
-
live it locks.
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
330
|
+
live it locks. Field kinds the shape learns: text, number, yes/no, list,
|
|
331
|
+
link (a stored record id), json, and FILE — a field that held an
|
|
332
|
+
upload()'s ref learns as a file field — and WHICH class (an image field
|
|
333
|
+
vs a document field, from what you actually uploaded). Once locked, the
|
|
334
|
+
field accepts only a reference to a real, confirmed file of this app
|
|
335
|
+
that the writer may read, of the right class — a ZIP into a profile
|
|
336
|
+
photo field is refused with the teach, as is a made-up or foreign ref
|
|
337
|
+
("file not found"). A 400 invalid_shape means the field isn't in the locked
|
|
338
|
+
shape or the value doesn't fit its kind. A live shape is sealed and
|
|
339
|
+
cannot take new fields — stop, tell your human which field you needed,
|
|
340
|
+
and send only the fields the shape already has. Never rename fields to
|
|
341
|
+
dodge it.
|
|
329
342
|
- Contention (bookings, slugs, stock, shared edits): when two users can race
|
|
330
343
|
for the same thing, a permission model can't save you — preconditions do,
|
|
331
344
|
and they're just arguments on calls you already make. A 409 `conflict` from
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gemmein/sdk",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "Gemmein SDK \u2014 passwordless auth, safe storage, and Stripe-driven record flips for AI-built apps. Small enough that one prompt teaches the whole API.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|