From 3b00cd2d1414bcc38e8bfd4c605d0a7e9766ea4d Mon Sep 17 00:00:00 2001 From: Juan Fernando Castro Date: Tue, 29 Sep 2026 12:47:23 -0400 Subject: [PATCH] docs: easy fs sharing recipe (PUT-1958) (#3973) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: add the easy fs sharing recipe share(), listShared(), getShares() and unshare() — the fs ground the existing recipes do not already cover. * docs: add a playground example per operation in the fs sharing recipe One runnable example for each section of the recipe: share, mode, listShared, getShares and unshare. * docs: open the sharing recipe with what it lets an app build * docs: ground the sharing examples in a document-editor flow Each example now sits in the UI that would call it — a Share button, a role picker, a shared-with-me inbox, an access list, ending a review. * remove redundant examples and refine recipe --------- Co-authored-by: Reynaldi Chernando --- src/docs/src/examples.js | 6 + .../examples/fs-share-a-file-mode.html | 32 +++++ src/docs/src/recipes/share-a-file.md | 116 ++++++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 src/docs/src/playground/examples/fs-share-a-file-mode.html create mode 100644 src/docs/src/recipes/share-a-file.md diff --git a/src/docs/src/examples.js b/src/docs/src/examples.js index 4bd20a590..4a9776700 100644 --- a/src/docs/src/examples.js +++ b/src/docs/src/examples.js @@ -450,6 +450,12 @@ const examples = [ slug: 'fs-getShareLink', source: '/playground/examples/fs-getShareLink.html', }, + { + title: 'Choose how much access to give', + description: 'Grant read, write or manage access when sharing a file with Puter.js filesystem API. Run and modify this example instantly in your browser.', + slug: 'fs-share-a-file-mode', + source: '/playground/examples/fs-share-a-file-mode.html', + }, ], }, { diff --git a/src/docs/src/playground/examples/fs-share-a-file-mode.html b/src/docs/src/playground/examples/fs-share-a-file-mode.html new file mode 100644 index 000000000..b7ded1279 --- /dev/null +++ b/src/docs/src/playground/examples/fs-share-a-file-mode.html @@ -0,0 +1,32 @@ + + + +

Brand assets

+ + + + + + diff --git a/src/docs/src/recipes/share-a-file.md b/src/docs/src/recipes/share-a-file.md new file mode 100644 index 000000000..6439dcd9a --- /dev/null +++ b/src/docs/src/recipes/share-a-file.md @@ -0,0 +1,116 @@ +--- +title: Share a File +description: "Learn how to add file sharing to your app with Puter.js, so users can share files in their Puter account with other people." +tags: [fs, auth] +order: 45 +--- + +Every file in Puter lives inside one user's Puter account, and only that user +can open it. When another Puter user needs the same file, share it with them +using the [filesystem API](/FS/). They can then open it from their own account, +without anyone copying the file or sending a link. + +This lets you build sharing right inside your app, so people can work together +on a file. + +## Share with someone + +Pass the path and who to share it with: + +```js +await puter.fs.share('report.txt', 'alice'); +``` + +A string with an `@` in it is read as an email address, anything else as a +username. You can also be explicit, which is worth doing when the value comes +from user input: + +```js +await puter.fs.share('report.txt', { username: 'alice' }); +await puter.fs.share('report.txt', { email: 'alice@example.com' }); +``` + +Sharing with an email address that has no Puter account yet sends an +invitation instead, which grants access once that address is confirmed. + +## Choose how much access + +The third argument is the mode, and it defaults to `'read'`: + +```js +await puter.fs.share('budget.xlsx', 'alice', 'write'); +``` + +- `'read'`: open it. +- `'write'`: open and change it. Does **not** allow sharing it onward. +- `'manage'`: everything `'write'` allows, plus re-sharing it. +- `'list'`, `'see'`: weaker than `read`, for making something discoverable + without exposing what is in it. + +Sharing the same item with the same person again **replaces** their access +instead of adding a second share, so changing someone from read to write is one +more call: + +```js +const [share] = await puter.fs.share('budget.xlsx', 'alice', 'write'); + +share.mode; // 'write' +share.isNew; // false, she already had access, at a different mode +``` + +The `isNew` field is `true` when the person did not have access before, and +`false` when they already had access. Use it to decide whether to show a +confirmation. + +## See what has been shared with you + +```js +const { items } = await puter.fs.listShared(); + +for (const item of items) { + console.log(item.name, item.mode, item.owner); +} +``` + +This resolves to an object with an `items` array, not to an +array. Your own files are never in it. + +Shared items appear at a **masked path** of the form `///`. +It works with any `puter.fs` method, so you can read one directly from the +listing: + +```js +const [first] = items; +const blob = await puter.fs.read(first.path); +console.log(await blob.text()); +``` + +The masked path hides *where* the item is stored in the owner's account, and +what other files are next to it. Label the item with `name`, since the masked +path has no meaningful folder to show. + +## See who you shared something with + +```js +const shares = await puter.fs.getShares('report.txt'); + +for (const share of shares) { + console.log(share.holder, share.mode); +} +``` + +This lists shares made by **anyone** holding `manage` on the item, not only +yours, so an owner can see who else it was shared with by the people they gave +`manage` to. + +## Take access back + +```js +const { revoked } = await puter.fs.unshare('report.txt', 'alice'); +``` + +`revoked` counts the grants actually removed. `0` means there was nothing to +remove, which is not an error, so unsharing twice is safe. + +To remove your own access to a file someone else shared with you, pass +**yourself** as the recipient.