2025-05-13 22:18:04 +02:00
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
// created_time is not an attribute defined on all models, but is present in all the resources
// coming from API
const SORT_DEFAULT_ATTRIBUTE = 'created_time' ;
const SORT_DIRECTION_ASCENDING = 'asc' ;
const SORT_DIRECTION_DESCENDING = 'desc' ;
const sortFunctions = {
string : ( a , b ) => String ( a ). localeCompare ( String ( b )),
date : ( a , b ) => new Date ( a ). getTime () - new Date ( b ). getTime (),
number : ( a , b ) => Number ( a ) - Number ( b ),
boolean : ( a , b ) => Number ( a ) - Number ( b ),
};
function getSortableValue ( schema , record , attribute ) {
if ( attribute === 'id' ) {
return record . id ;
}
// all models have a created_time attribute but not all models have it defined
if ( attribute === 'created_time' ) {
return record . attributes . created_time ;
}
if ( schema . attributes . has ( attribute )) {
return record . attributes [ attribute ];
}
const attributes = Array . from ( schema . attributes . keys ());
throw new Error (
`The attribute " ${ attribute } " does not map to the model definition of type " ${ record . type } ". Supported sortable attributes are 'id', 'created_time', or ${ attributes . map (( attr ) => `' ${ attr } '` ). join ( ', ' ) } ` ,
);
}
export const sortResults = ( results , { querySort , schema }) => {
querySort = querySort ?? {};
const sortAttribute = querySort . attribute || SORT_DEFAULT_ATTRIBUTE ;
// Default sort direction is ascending unless we are sorting by `created_time` (default sort attribute)
const defaultSortDirection =
2025-06-05 11:00:25 -07:00
sortAttribute === SORT_DEFAULT_ATTRIBUTE && ! querySort . sortFunction
2025-05-13 22:18:04 +02:00
? SORT_DIRECTION_DESCENDING
: SORT_DIRECTION_ASCENDING ;
const sortDirection = querySort . direction || defaultSortDirection ;
if (
! [ SORT_DIRECTION_ASCENDING , SORT_DIRECTION_DESCENDING ]. includes (
sortDirection ,
)
) {
throw new Error ( 'Invalid sort direction' );
}
2025-06-05 11:00:25 -07:00
// Execute custom sort function if one is provided.
if ( querySort . sortFunction ) {
return results . toSorted (( a , b ) => {
const sortResult = querySort . sortFunction ( a , b );
return sortDirection === SORT_DIRECTION_ASCENDING
? sortResult
: - 1 * sortResult ;
});
}
2025-05-13 22:18:04 +02:00
const sortAttributeDataType = schema . attributes . get ( sortAttribute ) ? . type ;
const sortFunction =
sortFunctions [ sortAttributeDataType ] ?? sortFunctions . string ;
return results . toSorted (( a , b ) => {
// Extract the values to sort and sort them.
const sortValueA = getSortableValue ( schema , a , sortAttribute );
const sortValueB = getSortableValue ( schema , b , sortAttribute );
const sortResult = sortFunction ( sortValueA , sortValueB );
return sortDirection === SORT_DIRECTION_ASCENDING
? sortResult
: - 1 * sortResult ;
});
};