feat(search): add sortable fields & typesense error handler (#1204)

This commit is contained in:
Kyrch
2026-05-10 15:37:39 -03:00
committed by GitHub
parent 519fc09ef4
commit fa27b2dd80
25 changed files with 109 additions and 73 deletions
+3 -5
View File
@@ -159,17 +159,15 @@ $user->assignRole('Admin');
### Search ### Search
You can skip this if you are using Docker.
If we want to enable scout, we need to configure a search engine.
Change the `SCOUT_DRIVER` variable in `.env` to "typesense". Add additional configuration like host and port. Change the `SCOUT_DRIVER` variable in `.env` to "typesense". Add additional configuration like host and port.
Import models into our indices using: Import models into our indices using:
```sh ```sh
# Import Models with a seeder # Import Models using a custom artisan command
php artisan scout:import-all php artisan scout:import-all
# or through Docker
sail artisan scout:import-all
``` ```
### Local Storage ### Local Storage
@@ -28,8 +28,8 @@ enum PermissionSort implements EnumSort
return match ($this) { return match ($this) {
self::ID => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_ID), self::ID => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_ID, SortDirection::DESC), self::ID_DESC => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_NAME, isStringField: true), self::NAME => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_NAME),
self::NAME_DESC => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true), self::NAME_DESC => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_NAME, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_CREATED_AT), self::CREATED_AT => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_CREATED_AT, SortDirection::DESC), self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_UPDATED_AT), self::UPDATED_AT => new FieldSortCriteria($this->name, Permission::ATTRIBUTE_UPDATED_AT),
+2 -2
View File
@@ -30,8 +30,8 @@ enum RoleSort implements EnumSort
return match ($this) { return match ($this) {
self::ID => new FieldSortCriteria($this->name, Role::ATTRIBUTE_ID), self::ID => new FieldSortCriteria($this->name, Role::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Role::ATTRIBUTE_ID, SortDirection::DESC), self::ID_DESC => new FieldSortCriteria($this->name, Role::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Role::ATTRIBUTE_NAME, isStringField: true), self::NAME => new FieldSortCriteria($this->name, Role::ATTRIBUTE_NAME),
self::NAME_DESC => new FieldSortCriteria($this->name, Role::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true), self::NAME_DESC => new FieldSortCriteria($this->name, Role::ATTRIBUTE_NAME, SortDirection::DESC),
self::PRIORITY => new FieldSortCriteria($this->name, Role::ATTRIBUTE_PRIORITY), self::PRIORITY => new FieldSortCriteria($this->name, Role::ATTRIBUTE_PRIORITY),
self::PRIORITY_DESC => new FieldSortCriteria($this->name, Role::ATTRIBUTE_PRIORITY, SortDirection::DESC), self::PRIORITY_DESC => new FieldSortCriteria($this->name, Role::ATTRIBUTE_PRIORITY, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Role::ATTRIBUTE_CREATED_AT), self::CREATED_AT => new FieldSortCriteria($this->name, Role::ATTRIBUTE_CREATED_AT),
+4 -4
View File
@@ -30,10 +30,10 @@ enum PageSort implements EnumSort
return match ($this) { return match ($this) {
self::ID => new FieldSortCriteria($this->name, Page::ATTRIBUTE_ID), self::ID => new FieldSortCriteria($this->name, Page::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Page::ATTRIBUTE_ID, SortDirection::DESC), self::ID_DESC => new FieldSortCriteria($this->name, Page::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Page::ATTRIBUTE_NAME, isStringField: true), self::NAME => new FieldSortCriteria($this->name, Page::ATTRIBUTE_NAME),
self::NAME_DESC => new FieldSortCriteria($this->name, Page::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true), self::NAME_DESC => new FieldSortCriteria($this->name, Page::ATTRIBUTE_NAME, SortDirection::DESC),
self::SLUG => new FieldSortCriteria($this->name, Page::ATTRIBUTE_SLUG, isStringField: true), self::SLUG => new FieldSortCriteria($this->name, Page::ATTRIBUTE_SLUG),
self::SLUG_DESC => new FieldSortCriteria($this->name, Page::ATTRIBUTE_SLUG, SortDirection::DESC, isStringField: true), self::SLUG_DESC => new FieldSortCriteria($this->name, Page::ATTRIBUTE_SLUG, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Page::ATTRIBUTE_CREATED_AT), self::CREATED_AT => new FieldSortCriteria($this->name, Page::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Page::ATTRIBUTE_CREATED_AT, SortDirection::DESC), self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Page::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Page::ATTRIBUTE_UPDATED_AT), self::UPDATED_AT => new FieldSortCriteria($this->name, Page::ATTRIBUTE_UPDATED_AT),
+4 -4
View File
@@ -34,12 +34,12 @@ enum PlaylistSort implements EnumSort
return match ($this) { return match ($this) {
self::ID => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_ID), self::ID => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_ID, SortDirection::DESC), self::ID_DESC => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_NAME, isStringField: true), self::NAME => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_NAME),
self::NAME_DESC => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true), self::NAME_DESC => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_NAME, SortDirection::DESC),
self::LIKES_COUNT => new FieldSortCriteria($this->name, 'like_aggregate_sum_value', qualifyColumn: QualifyColumn::NO), self::LIKES_COUNT => new FieldSortCriteria($this->name, 'like_aggregate_sum_value', qualifyColumn: QualifyColumn::NO),
self::LIKES_COUNT_DESC => new FieldSortCriteria($this->name, 'like_aggregate_sum_value', SortDirection::DESC, qualifyColumn: QualifyColumn::NO), self::LIKES_COUNT_DESC => new FieldSortCriteria($this->name, 'like_aggregate_sum_value', SortDirection::DESC, QualifyColumn::NO),
self::TRACKS_COUNT => new FieldSortCriteria($this->name, 'tracks_count', qualifyColumn: QualifyColumn::NO)->setAggregateRelation(Playlist::RELATION_TRACKS, AggregateFunction::COUNT), self::TRACKS_COUNT => new FieldSortCriteria($this->name, 'tracks_count', qualifyColumn: QualifyColumn::NO)->setAggregateRelation(Playlist::RELATION_TRACKS, AggregateFunction::COUNT),
self::TRACKS_COUNT_DESC => new FieldSortCriteria($this->name, 'tracks_count', SortDirection::DESC, qualifyColumn: QualifyColumn::NO)->setAggregateRelation(Playlist::RELATION_TRACKS, AggregateFunction::COUNT), self::TRACKS_COUNT_DESC => new FieldSortCriteria($this->name, 'tracks_count', SortDirection::DESC, QualifyColumn::NO)->setAggregateRelation(Playlist::RELATION_TRACKS, AggregateFunction::COUNT),
self::CREATED_AT => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_CREATED_AT), self::CREATED_AT => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_CREATED_AT, SortDirection::DESC), self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_UPDATED_AT), self::UPDATED_AT => new FieldSortCriteria($this->name, Playlist::ATTRIBUTE_UPDATED_AT),
@@ -36,12 +36,12 @@ enum ArtistMemberSort implements EnumSort
return match ($this) { return match ($this) {
self::ID => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_ID), self::ID => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_ID, SortDirection::DESC), self::ID_DESC => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_NAME, isStringField: true), self::NAME => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_NAME),
self::NAME_DESC => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true), self::NAME_DESC => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_NAME, SortDirection::DESC),
self::MEMBER_ALIAS => new PivotSortCriteria($this->name, ArtistMember::ATTRIBUTE_ALIAS, isStringField: true), self::MEMBER_ALIAS => new PivotSortCriteria($this->name, ArtistMember::ATTRIBUTE_ALIAS),
self::MEMBER_ALIAS_DESC => new PivotSortCriteria($this->name, ArtistMember::ATTRIBUTE_ALIAS, SortDirection::DESC, isStringField: true), self::MEMBER_ALIAS_DESC => new PivotSortCriteria($this->name, ArtistMember::ATTRIBUTE_ALIAS, SortDirection::DESC),
self::MEMBER_AS => new PivotSortCriteria($this->name, ArtistMember::ATTRIBUTE_AS, isStringField: true), self::MEMBER_AS => new PivotSortCriteria($this->name, ArtistMember::ATTRIBUTE_AS),
self::MEMBER_AS_DESC => new PivotSortCriteria($this->name, ArtistMember::ATTRIBUTE_AS, SortDirection::DESC, isStringField: true), self::MEMBER_AS_DESC => new PivotSortCriteria($this->name, ArtistMember::ATTRIBUTE_AS, SortDirection::DESC),
self::MEMBER_RELEVANCE => new PivotSortCriteria($this->name, ArtistMember::ATTRIBUTE_RELEVANCE), self::MEMBER_RELEVANCE => new PivotSortCriteria($this->name, ArtistMember::ATTRIBUTE_RELEVANCE),
self::MEMBER_RELEVANCE_DESC => new PivotSortCriteria($this->name, ArtistMember::ATTRIBUTE_RELEVANCE, SortDirection::DESC), self::MEMBER_RELEVANCE_DESC => new PivotSortCriteria($this->name, ArtistMember::ATTRIBUTE_RELEVANCE, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_CREATED_AT), self::CREATED_AT => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_CREATED_AT),
@@ -41,9 +41,9 @@ enum AnimeThemeEntrySort implements EnumSort
self::VERSION => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_VERSION), self::VERSION => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_VERSION),
self::VERSION_DESC => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_VERSION, SortDirection::DESC), self::VERSION_DESC => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_VERSION, SortDirection::DESC),
self::LIKES_COUNT => new FieldSortCriteria($this->name, 'like_aggregate_sum_value', qualifyColumn: QualifyColumn::NO), self::LIKES_COUNT => new FieldSortCriteria($this->name, 'like_aggregate_sum_value', qualifyColumn: QualifyColumn::NO),
self::LIKES_COUNT_DESC => new FieldSortCriteria($this->name, 'like_aggregate_sum_value', SortDirection::DESC, qualifyColumn: QualifyColumn::NO), self::LIKES_COUNT_DESC => new FieldSortCriteria($this->name, 'like_aggregate_sum_value', SortDirection::DESC, QualifyColumn::NO),
self::TRACKS_COUNT => new FieldSortCriteria($this->name, 'tracks_count', qualifyColumn: QualifyColumn::NO)->setAggregateRelation(AnimeThemeEntry::RELATION_TRACKS, AggregateFunction::COUNT), self::TRACKS_COUNT => new FieldSortCriteria($this->name, 'tracks_count', qualifyColumn: QualifyColumn::NO)->setAggregateRelation(AnimeThemeEntry::RELATION_TRACKS, AggregateFunction::COUNT),
self::TRACKS_COUNT_DESC => new FieldSortCriteria($this->name, 'tracks_count', SortDirection::DESC, qualifyColumn: QualifyColumn::NO)->setAggregateRelation(AnimeThemeEntry::RELATION_TRACKS, AggregateFunction::COUNT), self::TRACKS_COUNT_DESC => new FieldSortCriteria($this->name, 'tracks_count', SortDirection::DESC, QualifyColumn::NO)->setAggregateRelation(AnimeThemeEntry::RELATION_TRACKS, AggregateFunction::COUNT),
self::CREATED_AT => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_CREATED_AT), self::CREATED_AT => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_CREATED_AT, SortDirection::DESC), self::CREATED_AT_DESC => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_UPDATED_AT), self::UPDATED_AT => new FieldSortCriteria($this->name, AnimeThemeEntry::ATTRIBUTE_UPDATED_AT),
@@ -40,10 +40,10 @@ enum AnimeThemeSort implements EnumSort
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, AnimeTheme::ATTRIBUTE_CREATED_AT, SortDirection::DESC), self::CREATED_AT_DESC => new FieldSortCriteria($this->name, AnimeTheme::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, AnimeTheme::ATTRIBUTE_UPDATED_AT), self::UPDATED_AT => new FieldSortCriteria($this->name, AnimeTheme::ATTRIBUTE_UPDATED_AT),
self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, AnimeTheme::ATTRIBUTE_UPDATED_AT, SortDirection::DESC), self::UPDATED_AT_DESC => new FieldSortCriteria($this->name, AnimeTheme::ATTRIBUTE_UPDATED_AT, SortDirection::DESC),
self::SONG_TITLE => new RelationSortCriteria($this->name, Song::ATTRIBUTE_TITLE, AnimeTheme::RELATION_SONG, isStringField: true), self::SONG_TITLE => new RelationSortCriteria($this->name, Song::ATTRIBUTE_TITLE, AnimeTheme::RELATION_SONG),
self::SONG_TITLE_DESC => new RelationSortCriteria($this->name, Song::ATTRIBUTE_TITLE, AnimeTheme::RELATION_SONG, SortDirection::DESC, isStringField: true), self::SONG_TITLE_DESC => new RelationSortCriteria($this->name, Song::ATTRIBUTE_TITLE, AnimeTheme::RELATION_SONG, SortDirection::DESC),
self::SONG_TITLE_NATIVE => new RelationSortCriteria($this->name, Song::ATTRIBUTE_TITLE_NATIVE, AnimeTheme::RELATION_SONG, isStringField: true), self::SONG_TITLE_NATIVE => new RelationSortCriteria($this->name, Song::ATTRIBUTE_TITLE_NATIVE, AnimeTheme::RELATION_SONG),
self::SONG_TITLE_NATIVE_DESC => new RelationSortCriteria($this->name, Song::ATTRIBUTE_TITLE_NATIVE, AnimeTheme::RELATION_SONG, SortDirection::DESC, isStringField: true), self::SONG_TITLE_NATIVE_DESC => new RelationSortCriteria($this->name, Song::ATTRIBUTE_TITLE_NATIVE, AnimeTheme::RELATION_SONG, SortDirection::DESC),
self::RANDOM => new RandomSortCriteria($this->name, ''), self::RANDOM => new RandomSortCriteria($this->name, ''),
}; };
} }
+2 -2
View File
@@ -30,8 +30,8 @@ enum AnimeSort implements EnumSort
return match ($this) { return match ($this) {
self::ID => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_ID), self::ID => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_ID, SortDirection::DESC), self::ID_DESC => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_NAME, isStringField: true), self::NAME => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_NAME),
self::NAME_DESC => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true), self::NAME_DESC => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_NAME, SortDirection::DESC),
self::YEAR => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_YEAR), self::YEAR => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_YEAR),
self::YEAR_DESC => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_YEAR, SortDirection::DESC), self::YEAR_DESC => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_YEAR, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_CREATED_AT), self::CREATED_AT => new FieldSortCriteria($this->name, Anime::ATTRIBUTE_CREATED_AT),
+2 -2
View File
@@ -28,8 +28,8 @@ enum ArtistSort implements EnumSort
return match ($this) { return match ($this) {
self::ID => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_ID), self::ID => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_ID, SortDirection::DESC), self::ID_DESC => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_NAME, isStringField: true), self::NAME => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_NAME),
self::NAME_DESC => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true), self::NAME_DESC => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_NAME, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_CREATED_AT), self::CREATED_AT => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_CREATED_AT, SortDirection::DESC), self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_UPDATED_AT), self::UPDATED_AT => new FieldSortCriteria($this->name, Artist::ATTRIBUTE_UPDATED_AT),
+4 -4
View File
@@ -32,10 +32,10 @@ enum AudioSort implements EnumSort
return match ($this) { return match ($this) {
self::ID => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_ID), self::ID => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_ID, SortDirection::DESC), self::ID_DESC => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_ID, SortDirection::DESC),
self::BASENAME => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_BASENAME, isStringField: true), self::BASENAME => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_BASENAME),
self::BASENAME_DESC => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_BASENAME, SortDirection::DESC, isStringField: true), self::BASENAME_DESC => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_BASENAME, SortDirection::DESC),
self::FILENAME => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_FILENAME, isStringField: true), self::FILENAME => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_FILENAME),
self::FILENAME_DESC => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_FILENAME, SortDirection::DESC, isStringField: true), self::FILENAME_DESC => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_FILENAME, SortDirection::DESC),
self::SIZE => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_SIZE), self::SIZE => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_SIZE),
self::SIZE_DESC => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_SIZE, SortDirection::DESC), self::SIZE_DESC => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_SIZE, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_CREATED_AT), self::CREATED_AT => new FieldSortCriteria($this->name, Audio::ATTRIBUTE_CREATED_AT),
@@ -36,8 +36,8 @@ enum ExternalResourceSort implements EnumSort
self::SITE_DESC => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_SITE, SortDirection::DESC), self::SITE_DESC => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_SITE, SortDirection::DESC),
self::EXTERNAL_ID => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_EXTERNAL_ID), self::EXTERNAL_ID => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_EXTERNAL_ID),
self::EXTERNAL_ID_DESC => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_EXTERNAL_ID, SortDirection::DESC), self::EXTERNAL_ID_DESC => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_EXTERNAL_ID, SortDirection::DESC),
self::LINK => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_LINK, isStringField: true), self::LINK => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_LINK),
self::LINK_DESC => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_LINK, SortDirection::DESC, isStringField: true), self::LINK_DESC => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_LINK, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_CREATED_AT), self::CREATED_AT => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_CREATED_AT, SortDirection::DESC), self::CREATED_AT_DESC => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_UPDATED_AT), self::UPDATED_AT => new FieldSortCriteria($this->name, ExternalResource::ATTRIBUTE_UPDATED_AT),
+2 -2
View File
@@ -28,8 +28,8 @@ enum SeriesSort implements EnumSort
return match ($this) { return match ($this) {
self::ID => new FieldSortCriteria($this->name, Series::ATTRIBUTE_ID), self::ID => new FieldSortCriteria($this->name, Series::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Series::ATTRIBUTE_ID, SortDirection::DESC), self::ID_DESC => new FieldSortCriteria($this->name, Series::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Series::ATTRIBUTE_NAME, isStringField: true), self::NAME => new FieldSortCriteria($this->name, Series::ATTRIBUTE_NAME),
self::NAME_DESC => new FieldSortCriteria($this->name, Series::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true), self::NAME_DESC => new FieldSortCriteria($this->name, Series::ATTRIBUTE_NAME, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Series::ATTRIBUTE_CREATED_AT), self::CREATED_AT => new FieldSortCriteria($this->name, Series::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Series::ATTRIBUTE_CREATED_AT, SortDirection::DESC), self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Series::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Series::ATTRIBUTE_UPDATED_AT), self::UPDATED_AT => new FieldSortCriteria($this->name, Series::ATTRIBUTE_UPDATED_AT),
@@ -36,14 +36,14 @@ enum PerformanceSort implements EnumSort
return match ($this) { return match ($this) {
self::ID => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_ID), self::ID => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_ID, SortDirection::DESC), self::ID_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_ID, SortDirection::DESC),
self::ALIAS => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_ALIAS, isStringField: true), self::ALIAS => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_ALIAS),
self::ALIAS_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_ALIAS, SortDirection::DESC, isStringField: true), self::ALIAS_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_ALIAS, SortDirection::DESC),
self::AS => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_AS, isStringField: true), self::AS => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_AS),
self::AS_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_AS, SortDirection::DESC, isStringField: true), self::AS_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_AS, SortDirection::DESC),
self::MEMBER_ALIAS => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_MEMBER_ALIAS, isStringField: true), self::MEMBER_ALIAS => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_MEMBER_ALIAS),
self::MEMBER_ALIAS_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_MEMBER_ALIAS, SortDirection::DESC, isStringField: true), self::MEMBER_ALIAS_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_MEMBER_ALIAS, SortDirection::DESC),
self::MEMBER_AS => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_MEMBER_AS, isStringField: true), self::MEMBER_AS => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_MEMBER_AS),
self::MEMBER_AS_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_MEMBER_AS, SortDirection::DESC, isStringField: true), self::MEMBER_AS_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_MEMBER_AS, SortDirection::DESC),
self::RELEVANCE => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_RELEVANCE), self::RELEVANCE => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_RELEVANCE),
self::RELEVANCE_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_RELEVANCE, SortDirection::DESC), self::RELEVANCE_DESC => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_RELEVANCE, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_CREATED_AT), self::CREATED_AT => new FieldSortCriteria($this->name, Performance::ATTRIBUTE_CREATED_AT),
+4 -4
View File
@@ -30,10 +30,10 @@ enum SongSort implements EnumSort
return match ($this) { return match ($this) {
self::ID => new FieldSortCriteria($this->name, Song::ATTRIBUTE_ID, SortDirection::ASC), self::ID => new FieldSortCriteria($this->name, Song::ATTRIBUTE_ID, SortDirection::ASC),
self::ID_DESC => new FieldSortCriteria($this->name, Song::ATTRIBUTE_ID, SortDirection::DESC), self::ID_DESC => new FieldSortCriteria($this->name, Song::ATTRIBUTE_ID, SortDirection::DESC),
self::TITLE => new FieldSortCriteria($this->name, Song::ATTRIBUTE_TITLE, isStringField: true), self::TITLE => new FieldSortCriteria($this->name, Song::ATTRIBUTE_TITLE),
self::TITLE_DESC => new FieldSortCriteria($this->name, Song::ATTRIBUTE_TITLE, SortDirection::DESC, isStringField: true), self::TITLE_DESC => new FieldSortCriteria($this->name, Song::ATTRIBUTE_TITLE, SortDirection::DESC),
self::TITLE_NATIVE => new FieldSortCriteria($this->name, Song::ATTRIBUTE_TITLE_NATIVE, isStringField: true), self::TITLE_NATIVE => new FieldSortCriteria($this->name, Song::ATTRIBUTE_TITLE_NATIVE),
self::TITLE_NATIVE_DESC => new FieldSortCriteria($this->name, Song::ATTRIBUTE_TITLE_NATIVE, SortDirection::DESC, isStringField: true), self::TITLE_NATIVE_DESC => new FieldSortCriteria($this->name, Song::ATTRIBUTE_TITLE_NATIVE, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Song::ATTRIBUTE_CREATED_AT), self::CREATED_AT => new FieldSortCriteria($this->name, Song::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Song::ATTRIBUTE_CREATED_AT, SortDirection::DESC), self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Song::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Song::ATTRIBUTE_UPDATED_AT), self::UPDATED_AT => new FieldSortCriteria($this->name, Song::ATTRIBUTE_UPDATED_AT),
+2 -2
View File
@@ -28,8 +28,8 @@ enum StudioSort implements EnumSort
return match ($this) { return match ($this) {
self::ID => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_ID), self::ID => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_ID, SortDirection::DESC), self::ID_DESC => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_NAME, isStringField: true), self::NAME => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_NAME),
self::NAME_DESC => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true), self::NAME_DESC => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_NAME, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_CREATED_AT), self::CREATED_AT => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_CREATED_AT, SortDirection::DESC), self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_UPDATED_AT), self::UPDATED_AT => new FieldSortCriteria($this->name, Studio::ATTRIBUTE_UPDATED_AT),
+2 -2
View File
@@ -28,8 +28,8 @@ enum SynonymSort implements EnumSort
return match ($this) { return match ($this) {
self::ID => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_ID), self::ID => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_ID, SortDirection::DESC), self::ID_DESC => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_ID, SortDirection::DESC),
self::TEXT => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_TEXT, isStringField: true), self::TEXT => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_TEXT),
self::TEXT_DESC => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_TEXT, SortDirection::DESC, isStringField: true), self::TEXT_DESC => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_TEXT, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_CREATED_AT), self::CREATED_AT => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_CREATED_AT, SortDirection::DESC), self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_UPDATED_AT), self::UPDATED_AT => new FieldSortCriteria($this->name, Synonym::ATTRIBUTE_UPDATED_AT),
@@ -30,10 +30,10 @@ enum ThemeGroupSort implements EnumSort
return match ($this) { return match ($this) {
self::ID => new FieldSortCriteria($this->name, Group::ATTRIBUTE_ID), self::ID => new FieldSortCriteria($this->name, Group::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Group::ATTRIBUTE_ID, SortDirection::DESC), self::ID_DESC => new FieldSortCriteria($this->name, Group::ATTRIBUTE_ID, SortDirection::DESC),
self::NAME => new FieldSortCriteria($this->name, Group::ATTRIBUTE_NAME, isStringField: true), self::NAME => new FieldSortCriteria($this->name, Group::ATTRIBUTE_NAME),
self::NAME_DESC => new FieldSortCriteria($this->name, Group::ATTRIBUTE_NAME, SortDirection::DESC, isStringField: true), self::NAME_DESC => new FieldSortCriteria($this->name, Group::ATTRIBUTE_NAME, SortDirection::DESC),
self::SLUG => new FieldSortCriteria($this->name, Group::ATTRIBUTE_SLUG, isStringField: true), self::SLUG => new FieldSortCriteria($this->name, Group::ATTRIBUTE_SLUG),
self::SLUG_DESC => new FieldSortCriteria($this->name, Group::ATTRIBUTE_SLUG, SortDirection::DESC, isStringField: true), self::SLUG_DESC => new FieldSortCriteria($this->name, Group::ATTRIBUTE_SLUG, SortDirection::DESC),
self::CREATED_AT => new FieldSortCriteria($this->name, Group::ATTRIBUTE_CREATED_AT), self::CREATED_AT => new FieldSortCriteria($this->name, Group::ATTRIBUTE_CREATED_AT),
self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Group::ATTRIBUTE_CREATED_AT, SortDirection::DESC), self::CREATED_AT_DESC => new FieldSortCriteria($this->name, Group::ATTRIBUTE_CREATED_AT, SortDirection::DESC),
self::UPDATED_AT => new FieldSortCriteria($this->name, Group::ATTRIBUTE_UPDATED_AT), self::UPDATED_AT => new FieldSortCriteria($this->name, Group::ATTRIBUTE_UPDATED_AT),
+4 -4
View File
@@ -34,10 +34,10 @@ enum VideoSort implements EnumSort
return match ($this) { return match ($this) {
self::ID => new FieldSortCriteria($this->name, Video::ATTRIBUTE_ID), self::ID => new FieldSortCriteria($this->name, Video::ATTRIBUTE_ID),
self::ID_DESC => new FieldSortCriteria($this->name, Video::ATTRIBUTE_ID, SortDirection::DESC), self::ID_DESC => new FieldSortCriteria($this->name, Video::ATTRIBUTE_ID, SortDirection::DESC),
self::BASENAME => new FieldSortCriteria($this->name, Video::ATTRIBUTE_BASENAME, isStringField: true), self::BASENAME => new FieldSortCriteria($this->name, Video::ATTRIBUTE_BASENAME),
self::BASENAME_DESC => new FieldSortCriteria($this->name, Video::ATTRIBUTE_BASENAME, SortDirection::DESC, isStringField: true), self::BASENAME_DESC => new FieldSortCriteria($this->name, Video::ATTRIBUTE_BASENAME, SortDirection::DESC),
self::FILENAME => new FieldSortCriteria($this->name, Video::ATTRIBUTE_FILENAME, isStringField: true), self::FILENAME => new FieldSortCriteria($this->name, Video::ATTRIBUTE_FILENAME),
self::FILENAME_DESC => new FieldSortCriteria($this->name, Video::ATTRIBUTE_FILENAME, SortDirection::DESC, isStringField: true), self::FILENAME_DESC => new FieldSortCriteria($this->name, Video::ATTRIBUTE_FILENAME, SortDirection::DESC),
self::RESOLUTION => new FieldSortCriteria($this->name, Video::ATTRIBUTE_RESOLUTION), self::RESOLUTION => new FieldSortCriteria($this->name, Video::ATTRIBUTE_RESOLUTION),
self::RESOLUTION_DESC => new FieldSortCriteria($this->name, Video::ATTRIBUTE_RESOLUTION, SortDirection::DESC), self::RESOLUTION_DESC => new FieldSortCriteria($this->name, Video::ATTRIBUTE_RESOLUTION, SortDirection::DESC),
self::SIZE => new FieldSortCriteria($this->name, Video::ATTRIBUTE_SIZE), self::SIZE => new FieldSortCriteria($this->name, Video::ATTRIBUTE_SIZE),
+5
View File
@@ -7,10 +7,12 @@ namespace App\GraphQL\Directives;
use App\Contracts\GraphQL\EnumSort; use App\Contracts\GraphQL\EnumSort;
use App\Enums\Http\Api\Field\AggregateFunction; use App\Enums\Http\Api\Field\AggregateFunction;
use App\GraphQL\Sort\FieldSortCriteria; use App\GraphQL\Sort\FieldSortCriteria;
use App\GraphQL\Sort\RelationSortCriteria;
use GraphQL\Error\Error; use GraphQL\Error\Error;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Database\Query\Builder as QueryBuilder; use Illuminate\Database\Query\Builder as QueryBuilder;
use Illuminate\Support\Str;
use Laravel\Scout\Builder as ScoutBuilder; use Laravel\Scout\Builder as ScoutBuilder;
use Nuwave\Lighthouse\Schema\Directives\BaseDirective; use Nuwave\Lighthouse\Schema\Directives\BaseDirective;
use Nuwave\Lighthouse\Scout\ScoutBuilderDirective; use Nuwave\Lighthouse\Scout\ScoutBuilderDirective;
@@ -63,8 +65,11 @@ GRAPHQL;
foreach ($value as $sort) { foreach ($value as $sort) {
$criteria = $sort->getSortCriteria(); $criteria = $sort->getSortCriteria();
throw_if(Str::startsWith($criteria->__toString(), 'ID'), Error::class, 'Sorting by this value is not supported when using the \'search\' parameter.');
match (true) { match (true) {
$criteria instanceof FieldSortCriteria => $builder->orderBy($criteria->getColumn(), $criteria->getDirection()->value), $criteria instanceof FieldSortCriteria => $builder->orderBy($criteria->getColumn(), $criteria->getDirection()->value),
$criteria instanceof RelationSortCriteria => $builder->orderBy($criteria->getRelation().'.'.$criteria->getColumn(), $criteria->getDirection()->value),
default => throw new Error('Sorting by this value is not supported when using the \'search\' parameter.'), default => throw new Error('Sorting by this value is not supported when using the \'search\' parameter.'),
}; };
} }
@@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\ErrorHandler;
use Closure;
use GraphQL\Error\Error;
use Nuwave\Lighthouse\Execution\ErrorHandler;
use Typesense\Exceptions\TypesenseClientError;
class TypesenseErrorHandler implements ErrorHandler
{
public function __invoke(?Error $error, Closure $next): ?array
{
$underlyingException = $error?->getPrevious();
if ($underlyingException instanceof TypesenseClientError) {
return $next(new Error(
'Sorting by this value is not supported when using the \'search\' parameter.',
$error->getNodes(),
$error->getSource(),
$error->getPositions(),
$error->getPath(),
));
}
return $next($error);
}
}
-6
View File
@@ -19,7 +19,6 @@ abstract class SortCriteria implements Stringable
protected string $enumName, protected string $enumName,
protected string $column, protected string $column,
protected SortDirection $direction = SortDirection::ASC, protected SortDirection $direction = SortDirection::ASC,
protected bool $isStringField = false,
protected QualifyColumn $qualifyColumn = QualifyColumn::YES, protected QualifyColumn $qualifyColumn = QualifyColumn::YES,
) {} ) {}
@@ -33,11 +32,6 @@ abstract class SortCriteria implements Stringable
return $this->direction; return $this->direction;
} }
public function isStringField(): bool
{
return $this->isStringField;
}
public function setAggregateRelation(string $relation, AggregateFunction $function): static public function setAggregateRelation(string $relation, AggregateFunction $function): static
{ {
$this->aggregateRelation = $relation; $this->aggregateRelation = $relation;
@@ -18,7 +18,7 @@ class EnabledOnlyOnLocalhost
public function handle(Request $request, Closure $next): mixed public function handle(Request $request, Closure $next): mixed
{ {
if (Feature::for(null)->active(FeatureConstants::ENABLED_ONLY_ON_LOCALHOST)) { if (Feature::for(null)->active(FeatureConstants::ENABLED_ONLY_ON_LOCALHOST)) {
abort_if(!in_array($request->ip(), Config::array('app.local_ips'), true), 403, 'Route only available for localhost'); abort_if(! in_array($request->ip(), Config::array('app.local_ips'), true), 403, 'Route only available for localhost');
} }
return $next($request); return $next($request);
+1
View File
@@ -330,6 +330,7 @@ return [
Nuwave\Lighthouse\Execution\AuthorizationErrorHandler::class, Nuwave\Lighthouse\Execution\AuthorizationErrorHandler::class,
Nuwave\Lighthouse\Execution\ValidationErrorHandler::class, Nuwave\Lighthouse\Execution\ValidationErrorHandler::class,
Nuwave\Lighthouse\Execution\ReportingErrorHandler::class, Nuwave\Lighthouse\Execution\ReportingErrorHandler::class,
App\GraphQL\ErrorHandler\TypesenseErrorHandler::class,
], ],
/* /*
+10 -1
View File
@@ -246,6 +246,7 @@ return [
[ [
'name' => 'name', 'name' => 'name',
'type' => 'string', 'type' => 'string',
'sort' => true,
], ],
[ [
'name' => 'season', 'name' => 'season',
@@ -311,6 +312,12 @@ return [
'type' => 'object', 'type' => 'object',
'optional' => true, 'optional' => true,
], ],
[
'name' => 'song.title',
'type' => 'string',
'optional' => true,
'sort' => true,
],
], ],
], ],
'search-parameters' => [ 'search-parameters' => [
@@ -368,6 +375,7 @@ return [
[ [
'name' => 'name', 'name' => 'name',
'type' => 'string', 'type' => 'string',
'sort' => true,
], ],
[ [
'name' => 'synonyms', 'name' => 'synonyms',
@@ -476,6 +484,7 @@ return [
[ [
'name' => 'name', 'name' => 'name',
'type' => 'string', 'type' => 'string',
'sort' => true,
], ],
[ [
'name' => 'created_at', 'name' => 'created_at',
@@ -503,7 +512,6 @@ return [
[ [
'name' => 'text', 'name' => 'text',
'type' => 'string', 'type' => 'string',
'sort' => true,
], ],
], ],
], ],
@@ -548,6 +556,7 @@ return [
[ [
'name' => 'filename', 'name' => 'filename',
'type' => 'string', 'type' => 'string',
'sort' => true,
], ],
[ [
'name' => 'tags', 'name' => 'tags',