1 import { literal, OrderItem, Sequelize } from 'sequelize'
3 // Translate for example "-name" to [ [ 'name', 'DESC' ], [ 'id', 'ASC' ] ]
4 function getSort (value: string, lastSort: OrderItem = [ 'id', 'ASC' ]): OrderItem[] {
5 const { direction, field } = buildSortDirectionAndField(value)
7 let finalField: string | ReturnType<typeof Sequelize.col>
9 if (field.toLowerCase() === 'match') { // Search
10 finalField = Sequelize.col('similarity')
15 return [ [ finalField, direction ], lastSort ]
18 function getAdminUsersSort (value: string): OrderItem[] {
19 const { direction, field } = buildSortDirectionAndField(value)
21 let finalField: string | ReturnType<typeof Sequelize.col>
23 if (field === 'videoQuotaUsed') { // Users list
24 finalField = Sequelize.col('videoQuotaUsed')
29 const nullPolicy = direction === 'ASC'
34 return [ [ finalField as any, direction, nullPolicy ], [ 'id', 'ASC' ] ]
37 function getPlaylistSort (value: string, lastSort: OrderItem = [ 'id', 'ASC' ]): OrderItem[] {
38 const { direction, field } = buildSortDirectionAndField(value)
40 if (field.toLowerCase() === 'name') {
41 return [ [ 'displayName', direction ], lastSort ]
44 return getSort(value, lastSort)
47 function getVideoSort (value: string, lastSort: OrderItem = [ 'id', 'ASC' ]): OrderItem[] {
48 const { direction, field } = buildSortDirectionAndField(value)
50 if (field.toLowerCase() === 'trending') { // Sort by aggregation
52 [ Sequelize.fn('COALESCE', Sequelize.fn('SUM', Sequelize.col('VideoViews.views')), '0'), direction ],
54 [ Sequelize.col('VideoModel.views'), direction ],
58 } else if (field === 'publishedAt') {
60 [ 'ScheduleVideoUpdate', 'updateAt', direction + ' NULLS LAST' ],
62 [ Sequelize.col('VideoModel.publishedAt'), direction ],
68 let finalField: string | ReturnType<typeof Sequelize.col>
71 if (field.toLowerCase() === 'match') { // Search
72 finalField = Sequelize.col('similarity')
77 const firstSort: OrderItem = typeof finalField === 'string'
78 ? finalField.split('.').concat([ direction ]) as OrderItem
79 : [ finalField, direction ]
81 return [ firstSort, lastSort ]
84 function getBlacklistSort (value: string, lastSort: OrderItem = [ 'id', 'ASC' ]): OrderItem[] {
85 const { direction, field } = buildSortDirectionAndField(value)
87 const videoFields = new Set([ 'name', 'duration', 'views', 'likes', 'dislikes', 'uuid' ])
89 if (videoFields.has(field)) {
91 [ literal(`"Video.${field}" ${direction}`) ],
96 return getSort(value, lastSort)
99 function getInstanceFollowsSort (value: string, lastSort: OrderItem = [ 'id', 'ASC' ]): OrderItem[] {
100 const { direction, field } = buildSortDirectionAndField(value)
102 if (field === 'redundancyAllowed') {
104 [ 'ActorFollowing.Server.redundancyAllowed', direction ],
109 return getSort(value, lastSort)
112 function getChannelSyncSort (value: string): OrderItem[] {
113 const { direction, field } = buildSortDirectionAndField(value)
114 if (field.toLowerCase() === 'videochannel') {
116 [ literal('"VideoChannel.name"'), direction ]
119 return [ [ field, direction ] ]
122 function buildSortDirectionAndField (value: string) {
124 let direction: 'ASC' | 'DESC'
126 if (value.substring(0, 1) === '-') {
128 field = value.substring(1)
134 return { direction, field }
138 buildSortDirectionAndField,
145 getInstanceFollowsSort