@@ -92,6 +92,7 @@ const APPEND_FILE_FIELD = ['appendFile', 'appendFileName'] as const
9292const COMPRESS_FILE_FIELD = [ 'compressFile' , 'compressFileId' ] as const
9393const DECOMPRESS_FILE_FIELD = [ 'decompressFile' , 'decompressFileId' ] as const
9494const SHARE_FILE_FIELD = [ 'shareFile' , 'shareFileId' ] as const
95+ const MOVE_FILE_FIELD = [ 'moveFile' , 'moveFileId' ] as const
9596/* Text and file are mutually exclusive sources, so the clause names whichever
9697 one the card actually carries. */
9798const WRITE_CONTENT_FIELD = [ 'content' , 'writeFile' , 'writeFileId' ] as const
@@ -1129,6 +1130,7 @@ export const FileV5Block: BlockConfig<FileParserV3Output> = {
11291130 - Use Write to create a new workspace file and Append to add content to an existing one. Write adds a numeric suffix when the name is taken; turn on "Overwrite Existing File" to replace the contents of the file at that exact path (folder and name) instead — a same-named file in another folder is left alone.
11301131 - Use Compress to bundle one or more files into a single .zip archive stored in the workspace. The new archive is returned in the "files" output.
11311132 - Use Decompress to extract a .zip archive back into the workspace; the extracted files are returned in the "files" output, ready to chain into Get Content or downstream blocks.
1133+ - Move File takes one workspace file, picked or given as a canonical file ID such as an earlier block's file output, and the folder to move it into.
11321134 ` ,
11331135 canvasPresentation : {
11341136 defaultTitle : 'File' ,
@@ -1178,7 +1180,7 @@ export const FileV5Block: BlockConfig<FileParserV3Output> = {
11781180 file_delete_folder : [ { text : 'Delete folder' , field : FOLDER_PATH_FIELD , core : true } ] ,
11791181 file_restore_folder : [ { text : 'Restore folder' , field : 'restoreFolderId' , core : true } ] ,
11801182 file_move : [
1181- { text : 'Move' , field : 'moveFileId' , core : true } ,
1183+ { text : 'Move' , field : MOVE_FILE_FIELD , core : true } ,
11821184 { text : 'into' , field : MOVE_TARGET_FIELD } ,
11831185 ] ,
11841186 file_decompress : [ { text : 'Unzip' , field : DECOMPRESS_FILE_FIELD , core : true } ] ,
@@ -1873,11 +1875,24 @@ export const FileV5Block: BlockConfig<FileParserV3Output> = {
18731875 type : 'switch' as SubBlockType ,
18741876 condition : { field : 'operation' , value : 'file_delete_folder' } ,
18751877 } ,
1878+ {
1879+ id : 'moveFile' ,
1880+ title : 'File' ,
1881+ type : 'file-upload' as SubBlockType ,
1882+ canonicalParamId : 'moveFileInput' ,
1883+ acceptedTypes : '*' ,
1884+ placeholder : 'Select a workspace file' ,
1885+ mode : 'basic' ,
1886+ condition : { field : 'operation' , value : 'file_move' } ,
1887+ required : { field : 'operation' , value : 'file_move' } ,
1888+ } ,
18761889 {
18771890 id : 'moveFileId' ,
18781891 title : 'File ID' ,
18791892 type : 'short-input' as SubBlockType ,
1880- placeholder : 'Canonical workspace file ID' ,
1893+ canonicalParamId : 'moveFileInput' ,
1894+ placeholder : 'Workspace file ID' ,
1895+ mode : 'advanced' ,
18811896 condition : { field : 'operation' , value : 'file_move' } ,
18821897 required : { field : 'operation' , value : 'file_move' } ,
18831898 } ,
@@ -2045,8 +2060,35 @@ export const FileV5Block: BlockConfig<FileParserV3Output> = {
20452060 }
20462061
20472062 if ( operation === 'file_move' ) {
2063+ const moveInput = params . moveFileInput
2064+ if ( ! moveInput ) {
2065+ throw new Error ( 'File is required for move' )
2066+ }
2067+
2068+ /*
2069+ * The tool takes an id and nothing else, so a picked file resolves
2070+ * here by the id every picker selection and in-place upload carries.
2071+ * A file object without one is refused with the remedy rather than
2072+ * forwarded as a shape the contract rejects.
2073+ */
2074+ const fileIds = parseReadFileIds ( moveInput )
2075+ if ( Array . isArray ( fileIds ) ) {
2076+ throw new Error ( 'Move File accepts a single file at a time' )
2077+ }
2078+ const file = fileIds
2079+ ? null
2080+ : ( normalizeFileInput ( moveInput , {
2081+ single : true ,
2082+ errorMessage : 'Move File accepts a single file at a time' ,
2083+ } ) as Record < string , unknown > | undefined )
2084+ const pickedId = typeof file ?. id === 'string' ? file . id . trim ( ) : ''
2085+ const fileId = fileIds ?? pickedId
2086+ if ( ! fileId ) {
2087+ throw new Error ( 'Could not determine the file to move; pass its workspace file ID' )
2088+ }
2089+
20482090 return {
2049- fileId : optionalText ( params . moveFileId ) ,
2091+ fileId,
20502092 folderPath : optionalText ( params . moveTargetRef ) ,
20512093 workspaceId : params . _context ?. workspaceId ,
20522094 }
@@ -2293,9 +2335,9 @@ export const FileV5Block: BlockConfig<FileParserV3Output> = {
22932335 type : 'string' ,
22942336 description : 'Folder the file is moved into (move file)' ,
22952337 } ,
2296- moveFileId : {
2297- type : 'string ' ,
2298- description : 'Canonical ID of the file to move (move file)' ,
2338+ moveFileInput : {
2339+ type : 'json ' ,
2340+ description : 'Selected workspace file or canonical file ID to move (move file)' ,
22992341 } ,
23002342 restoreFolderId : {
23012343 type : 'string' ,
0 commit comments