@@ -106,7 +106,7 @@ function _get_version_id_by_stat({ino, mtimeNsBigint}) {
106
106
return 'mtime-' + mtimeNsBigint . toString ( 36 ) + '-ino-' + ino . toString ( 36 ) ;
107
107
}
108
108
109
- function _is_version_object_including_null_version ( filename ) {
109
+ function _is_version_or_null_in_file_name ( filename ) {
110
110
const is_version_object = _is_version_object ( filename ) ;
111
111
if ( ! is_version_object ) {
112
112
return _is_version_null_version ( filename ) ;
@@ -637,6 +637,7 @@ class NamespaceFS {
637
637
* key: string,
638
638
* common_prefix: boolean,
639
639
* stat?: nb.NativeFSStats,
640
+ * is_latest: boolean,
640
641
* }} Result
641
642
*/
642
643
@@ -725,15 +726,17 @@ class NamespaceFS {
725
726
const isDir = await is_directory_or_symlink_to_directory ( ent , fs_context , path . join ( dir_path , ent . name ) ) ;
726
727
727
728
let r ;
728
- if ( list_versions && _is_version_object_including_null_version ( ent . name ) ) {
729
+ if ( list_versions && _is_version_or_null_in_file_name ( ent . name ) ) {
729
730
r = {
730
731
key : this . _get_version_entry_key ( dir_key , ent ) ,
731
732
common_prefix : isDir ,
733
+ is_latest : false
732
734
} ;
733
735
} else {
734
736
r = {
735
737
key : this . _get_entry_key ( dir_key , ent , isDir ) ,
736
738
common_prefix : isDir ,
739
+ is_latest : true
737
740
} ;
738
741
}
739
742
await insert_entry_to_results_arr ( r ) ;
@@ -848,6 +851,20 @@ class NamespaceFS {
848
851
}
849
852
} ;
850
853
854
+ let previous_key ;
855
+ /**
856
+ * delete markers are always in the .versions folder, so we need to have special case to determine
857
+ * if they are delete markers. since the result list is ordered by latest entries first, the first
858
+ * entry of every key is the latest
859
+ * TODO need different way to check for isLatest in case of unordered list object versions
860
+ * @param {Object } obj_info
861
+ */
862
+ const set_latest_delete_marker = obj_info => {
863
+ if ( obj_info . delete_marker && previous_key !== obj_info . key ) {
864
+ obj_info . is_latest = true ;
865
+ }
866
+ } ;
867
+
851
868
const prefix_dir_key = prefix . slice ( 0 , prefix . lastIndexOf ( '/' ) + 1 ) ;
852
869
await process_dir ( prefix_dir_key ) ;
853
870
await Promise . all ( results . map ( async r => {
@@ -869,15 +886,17 @@ class NamespaceFS {
869
886
if ( r . common_prefix ) {
870
887
res . common_prefixes . push ( r . key ) ;
871
888
} else {
872
- obj_info = this . _get_object_info ( bucket , r . key , r . stat , 'null' , false , true ) ;
889
+ obj_info = this . _get_object_info ( bucket , r . key , r . stat , false , r . is_latest ) ;
873
890
if ( ! list_versions && obj_info . delete_marker ) {
874
891
continue ;
875
892
}
876
893
if ( this . _is_hidden_version_path ( obj_info . key ) ) {
877
894
obj_info . key = path . normalize ( obj_info . key . replace ( HIDDEN_VERSIONS_PATH + '/' , '' ) ) ;
878
895
obj_info . key = _get_filename ( obj_info . key ) ;
896
+ set_latest_delete_marker ( obj_info ) ;
879
897
}
880
898
res . objects . push ( obj_info ) ;
899
+ previous_key = obj_info . key ;
881
900
}
882
901
if ( res . is_truncated ) {
883
902
if ( list_versions && _is_version_object ( r . key ) ) {
@@ -921,7 +940,7 @@ class NamespaceFS {
921
940
}
922
941
}
923
942
this . _throw_if_delete_marker ( stat ) ;
924
- return this . _get_object_info ( params . bucket , params . key , stat , params . version_id || 'null' , isDir ) ;
943
+ return this . _get_object_info ( params . bucket , params . key , stat , isDir ) ;
925
944
} catch ( err ) {
926
945
if ( this . _should_update_issues_report ( params , file_path , err ) ) {
927
946
this . run_update_issues_report ( object_sdk , err ) ;
@@ -2293,16 +2312,18 @@ class NamespaceFS {
2293
2312
}
2294
2313
2295
2314
/**
2296
- * @param {string } bucket
2297
- * @param {string } key
2298
- * @param {nb.NativeFSStats } stat
2315
+ * @param {string } bucket
2316
+ * @param {string } key
2317
+ * @param {nb.NativeFSStats } stat
2318
+ * @param {Boolean } isDir
2319
+ * @param {boolean } [is_latest=true]
2299
2320
* @returns {nb.ObjectInfo }
2300
2321
*/
2301
- _get_object_info ( bucket , key , stat , return_version_id , isDir , is_latest = true ) {
2322
+ _get_object_info ( bucket , key , stat , isDir , is_latest = true ) {
2302
2323
const etag = this . _get_etag ( stat ) ;
2303
2324
const create_time = stat . mtime . getTime ( ) ;
2304
2325
const encryption = this . _get_encryption_info ( stat ) ;
2305
- const version_id = return_version_id && this . _is_versioning_enabled ( ) && this . _get_version_id_by_xattr ( stat ) ;
2326
+ const version_id = ( this . _is_versioning_enabled ( ) || this . _is_versioning_suspended ( ) ) && this . _get_version_id_by_xattr ( stat ) ;
2306
2327
const delete_marker = stat . xattr ?. [ XATTR_DELETE_MARKER ] === 'true' ;
2307
2328
const dir_content_type = stat . xattr ?. [ XATTR_DIR_CONTENT ] && ( ( Number ( stat . xattr ?. [ XATTR_DIR_CONTENT ] ) > 0 && 'application/octet-stream' ) || 'application/x-directory' ) ;
2308
2329
const content_type = stat . xattr ?. [ XATTR_CONTENT_TYPE ] ||
0 commit comments