feat(files): export markdown as zip with embedded images (#4413)

* feat(files): export markdown as zip with embedded images in assets/ folder

* fix(files): sanitize zip filenames, fix storage context cast, cap embedded image count

* fix(files): fix race condition in asset filename deduplication

* chore(files): remove extraneous comments from export route

* fix(files): sanitize markdown zip entry name, full uuid fallback for filename dedup

* fix(files): extract userId const to satisfy TypeScript narrowing in async callback

* fix(files): use replacer function to prevent $ special-char corruption in markdown URL rewrite

* fix(files): wrap zip buffer in Uint8Array for NextResponse BodyInit compatibility

* lock behavior

* fix(workflow): track resolved isAdmin in prevIsAdminRef to prevent stale lock notification

When workspacePermissions loads asynchronously, prevCanAdminRef (which only
tracked effectivePermissions.canAdmin) would not detect the change, causing
the early-return guard to skip rebuilding the notification with the correct
unlock-button visibility. Track the same resolved value (workspacePermissions
?.viewer?.isAdmin ?? effectivePermissions.canAdmin) that is actually used to
build the notification.

* refactor(uploads): rename server fn to fetchWorkspaceFileBuffer, move client download to uploads/client/download.ts as triggerFileDownload

* more lock updates

* fix(tests): update mocks for fetchWorkspaceFileBuffer rename
This commit is contained in:
Waleed
2026-05-02 20:07:48 -07:00
committed by GitHub
parent 79214497c5
commit a479e88718
26 changed files with 268 additions and 79 deletions
+2 -2
View File
@@ -9,8 +9,8 @@ const QUERY_HOOKS_DIR = path.join(ROOT, 'apps/sim/hooks/queries')
const SELECTOR_HOOKS_DIR = path.join(ROOT, 'apps/sim/hooks/selectors')
const BASELINE = {
totalRoutes: 724,
zodRoutes: 724,
totalRoutes: 725,
zodRoutes: 725,
nonZodRoutes: 0,
} as const