Skip to content

Commit 8c5da02

Browse files
feat(file): include public share status in File read output (#5191)
* feat(file): include public share status in File read output The read operation now attaches each workspace file's public share status as a "share" field (the share record, or null when not shared), batch-fetched via getSharesForResources to avoid N+1. Picker/upload input files have no canonical id and carry share: null. * refactor(file): read share status uses visibility vocabulary, no row internals Read's per-file "share" is now { visibility, url, allowedEmails } using the same visibility vocabulary as Manage Sharing: 'private' when not shared (url null, no config) instead of null, otherwise public/password/email/sso with the link. Drops row internals (id, token, resourceType, resourceId, isActive, hasPassword). * fix(file): mark picker files private without a share lookup Input (picker/upload) files only have a synthetic id (storage key/URL), so looking them up in the shares map could collide with a canonical file id and attach the wrong share. Give them an explicit private share instead. * docs(file): terser share-status output descriptions * chore(file): drop verbose comment in read share enrichment
1 parent 4554df9 commit 8c5da02

2 files changed

Lines changed: 21 additions & 2 deletions

File tree

apps/sim/app/api/tools/file/manage/route.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
1717
import { isSupportedFileType, parseBuffer } from '@/lib/file-parsers'
1818
import {
1919
getShareForResource,
20+
getSharesForResources,
2021
ShareValidationError,
2122
upsertFileShare,
2223
} from '@/lib/public-shares/share-manager'
@@ -417,12 +418,30 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
417418
)
418419
}
419420

421+
const shares = await getSharesForResources('file', selectedFileIds)
422+
const privateReadShare = () => ({
423+
visibility: 'private' as const,
424+
url: null,
425+
allowedEmails: [] as string[],
426+
})
427+
const toReadShare = (fileId: string) => {
428+
const share = shares.get(fileId)
429+
if (!share || !share.isActive) return privateReadShare()
430+
return {
431+
visibility: share.authType,
432+
url: share.url,
433+
allowedEmails: share.allowedEmails,
434+
}
435+
}
420436
const userFiles = files
421437
.map((file) => workspaceFileToUserFile(file))
422438
.filter((file): file is NonNullable<ReturnType<typeof workspaceFileToUserFile>> =>
423439
Boolean(file)
424440
)
425-
.concat(selectedInputFiles)
441+
.map((file) => ({ ...file, share: toReadShare(file.id) }))
442+
// Picker/upload entries have only a synthetic id (storage key/URL), so they
443+
// never carry a canonical share — mark them private without a lookup.
444+
.concat(selectedInputFiles.map((file) => ({ ...file, share: privateReadShare() })))
426445

427446
logger.info('Files retrieved', {
428447
count: userFiles.length,

apps/sim/blocks/blocks/file.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1361,7 +1361,7 @@ export const FileV5Block: BlockConfig<FileParserV3Output> = {
13611361
files: {
13621362
type: 'file[]',
13631363
description:
1364-
'Workspace file objects (read), fetched file objects (fetch), the compressed archive (compress), or extracted files (decompress)',
1364+
'Workspace file objects with share status (read), fetched file objects (fetch), the compressed archive (compress), or extracted files (decompress)',
13651365
},
13661366
contents: {
13671367
type: 'array',

0 commit comments

Comments
 (0)