Closed notrab closed 2 years ago
Hello @notrab ! Thanks, again for the MR.
However I can't merge right now cause it failed to pass one test (I will create a CI / CD for this in the future).
It crashes on the anilist GraphQL API: https://graphql.anilist.co/ .
The previous version don't:
Also, I've seen that you changed some linting, what formater did you use? I would like to keep this consistent at some point. I was using the deno linting / formatting but I can agree that it's not really great.
The issue seems to be related to the graphql parser.
Hey @nohehf
Thanks for checking this over. I'll take a look at the above, and get back to you.
As for formatting, I guess this was done by my Prettier extension. I've never used Deno before, so I wasn't aware of any built-in fmt-like utility. I'll sort that too.
It would appear before my changes it also generated an invalid schema. It just so happens there was no check on this.
Oh okay alright, the issue is that object fields are commented by default, so if you have a query field with only object fields the generated query will be empty so incorrect. This choice was made to prevent infinite nested query fields. Every generated request is not valid by default but human-readable and easily editable. I don't really know how to patch this without changing this choice, which I think is important. I don't think the goal of GraphMan should be to generate valid queries all the time, tho this prevents doing clean graphql parsing. Let me know your thoughts abt this, I'll be happy to discuss it.
@nohehf perhaps we could include __typename
by default in all queries so it's at least valid?
@nohehf I added __typename
and ran deno fmt
.
lmkwyt
I still have some concerns with using the graphql parser: I had done some custom parsing so that arguments are line by line if there are too many for example. Indeed I do feel that even not standard this is much more redable:
query(
$mediaId: Int,
$date: Int,
$trending: Int,
$averageScore: Int,
$popularity: Int,
$episode: Int,
$releasing: Boolean,
$mediaId_not: Int,
$mediaId_in: [Int],
$mediaId_not_in: [Int],
$date_greater: Int,
$date_lesser: Int,
$trending_greater: Int,
$trending_lesser: Int,
$trending_not: Int,
$averageScore_greater: Int,
$averageScore_lesser: Int,
$averageScore_not: Int,
$popularity_greater: Int,
$popularity_lesser: Int,
$popularity_not: Int,
$episode_greater: Int,
$episode_lesser: Int,
$episode_not: Int,
$sort: [MediaTrendSort]
){
MediaTrend(
mediaId: $mediaId,
date: $date,
trending: $trending,
averageScore: $averageScore,
popularity: $popularity,
episode: $episode,
releasing: $releasing,
mediaId_not: $mediaId_not,
mediaId_in: $mediaId_in,
mediaId_not_in: $mediaId_not_in,
date_greater: $date_greater,
date_lesser: $date_lesser,
trending_greater: $trending_greater,
trending_lesser: $trending_lesser,
trending_not: $trending_not,
averageScore_greater: $averageScore_greater,
averageScore_lesser: $averageScore_lesser,
averageScore_not: $averageScore_not,
popularity_greater: $popularity_greater,
popularity_lesser: $popularity_lesser,
popularity_not: $popularity_not,
episode_greater: $episode_greater,
episode_lesser: $episode_lesser,
episode_not: $episode_not,
sort: $sort
){
mediaId # The id of the tag
date # The day the data was recorded (timestamp)
trending # The amount of media activity on the day
averageScore # A weighted average score of all the user's scores of the media
popularity # The number of users with the media on their list
inProgress # The number of users with watching/reading the media
releasing # If the media was being released at this time
episode # The episode number of the anime released on this day
# media # The related media
}
}
than
query MediaTrend($mediaId: Int, $date: Int, $trending: Int, $averageScore: Int, $popularity: Int, $episode: Int, $releasing: Boolean, $mediaId_not: Int, $mediaId_in: [Int], $mediaId_not_in: [Int], $date_greater: Int, $date_lesser: Int, $trending_greater: Int, $trending_lesser: Int, $trending_not: Int, $averageScore_greater: Int, $averageScore_lesser: Int, $averageScore_not: Int, $popularity_greater: Int, $popularity_lesser: Int, $popularity_not: Int, $episode_greater: Int, $episode_lesser: Int, $episode_not: Int, $sort: [MediaTrendSort]) {
MediaTrend(
mediaId: $mediaId
date: $date
trending: $trending
averageScore: $averageScore
popularity: $popularity
episode: $episode
releasing: $releasing
mediaId_not: $mediaId_not
mediaId_in: $mediaId_in
mediaId_not_in: $mediaId_not_in
date_greater: $date_greater
date_lesser: $date_lesser
trending_greater: $trending_greater
trending_lesser: $trending_lesser
trending_not: $trending_not
averageScore_greater: $averageScore_greater
averageScore_lesser: $averageScore_lesser
averageScore_not: $averageScore_not
popularity_greater: $popularity_greater
popularity_lesser: $popularity_lesser
popularity_not: $popularity_not
episode_greater: $episode_greater
episode_lesser: $episode_lesser
episode_not: $episode_not
sort: $sort
) {
__typename
mediaId
date
trending
averageScore
popularity
inProgress
releasing
episode
}
}
But lmkwyt about this, not sure of my opinion after writing it.
I also noticed an issue with the Page query with your changes. while there is the _typename field, you removed the other fields that should be commented:
query Page($page: Int, $perPage: Int) {
Page(page: $page, perPage: $perPage) {
__typename
}
}
should be (in terms of content, not formatting):
query( $page: Int, $perPage: Int){
Page( page: $page, perPage: $perPage){
__typename
# pageInfo # The pagination information
# users
# media
# characters
# staff
# studios
# mediaList
# airingSchedules
# mediaTrends
# notifications # Type: LIST
# followers
# following
# activities # Type: LIST
# activityReplies
# threads
# threadComments
# reviews
# recommendations
# likes
}
}
Okay so I investigated a bit, and it seems like graphql.parse()
removes comments, and there is no parameter to prevent that, so the only solution I see would be to add them after the parsing tho it might be a huge mess. Let me know if you have any thoughts on this
Okay, so I've found a workaround. I generate a random hash for every field before the parsing, so the query gets parsed and formatted correctly, (see tempField). I then replace all of those hashes with the correct field (with comments). The caveat is that some parts of the query are not properly parsed, but it's the best solution I think. So now we have:
query Media($id: Int, $idMal: Int, $startDate: FuzzyDateInt, $endDate: FuzzyDateInt, $season: MediaSeason, $seasonYear: Int, $type: MediaType, $format: MediaFormat, $status: MediaStatus, $episodes: Int, $duration: Int, $chapters: Int, $volumes: Int, $isAdult: Boolean, $genre: String, $tag: String, $minimumTagRank: Int, $tagCategory: String, $onList: Boolean, $licensedBy: String, $licensedById: Int, $averageScore: Int, $popularity: Int, $source: MediaSource, $countryOfOrigin: CountryCode, $isLicensed: Boolean, $search: String, $id_not: Int, $id_in: [Int], $id_not_in: [Int], $idMal_not: Int, $idMal_in: [Int], $idMal_not_in: [Int], $startDate_greater: FuzzyDateInt, $startDate_lesser: FuzzyDateInt, $startDate_like: String, $endDate_greater: FuzzyDateInt, $endDate_lesser: FuzzyDateInt, $endDate_like: String, $format_in: [MediaFormat], $format_not: MediaFormat, $format_not_in: [MediaFormat], $status_in: [MediaStatus], $status_not: MediaStatus, $status_not_in: [MediaStatus], $episodes_greater: Int, $episodes_lesser: Int, $duration_greater: Int, $duration_lesser: Int, $chapters_greater: Int, $chapters_lesser: Int, $volumes_greater: Int, $volumes_lesser: Int, $genre_in: [String], $genre_not_in: [String], $tag_in: [String], $tag_not_in: [String], $tagCategory_in: [String], $tagCategory_not_in: [String], $licensedBy_in: [String], $licensedById_in: [Int], $averageScore_not: Int, $averageScore_greater: Int, $averageScore_lesser: Int, $popularity_not: Int, $popularity_greater: Int, $popularity_lesser: Int, $source_in: [MediaSource], $sort: [MediaSort]) {
Media(
id: $id
idMal: $idMal
startDate: $startDate
endDate: $endDate
season: $season
seasonYear: $seasonYear
type: $type
format: $format
status: $status
episodes: $episodes
duration: $duration
chapters: $chapters
volumes: $volumes
isAdult: $isAdult
genre: $genre
tag: $tag
minimumTagRank: $minimumTagRank
tagCategory: $tagCategory
onList: $onList
licensedBy: $licensedBy
licensedById: $licensedById
averageScore: $averageScore
popularity: $popularity
source: $source
countryOfOrigin: $countryOfOrigin
isLicensed: $isLicensed
search: $search
id_not: $id_not
id_in: $id_in
id_not_in: $id_not_in
idMal_not: $idMal_not
idMal_in: $idMal_in
idMal_not_in: $idMal_not_in
startDate_greater: $startDate_greater
startDate_lesser: $startDate_lesser
startDate_like: $startDate_like
endDate_greater: $endDate_greater
endDate_lesser: $endDate_lesser
endDate_like: $endDate_like
format_in: $format_in
format_not: $format_not
format_not_in: $format_not_in
status_in: $status_in
status_not: $status_not
status_not_in: $status_not_in
episodes_greater: $episodes_greater
episodes_lesser: $episodes_lesser
duration_greater: $duration_greater
duration_lesser: $duration_lesser
chapters_greater: $chapters_greater
chapters_lesser: $chapters_lesser
volumes_greater: $volumes_greater
volumes_lesser: $volumes_lesser
genre_in: $genre_in
genre_not_in: $genre_not_in
tag_in: $tag_in
tag_not_in: $tag_not_in
tagCategory_in: $tagCategory_in
tagCategory_not_in: $tagCategory_not_in
licensedBy_in: $licensedBy_in
licensedById_in: $licensedById_in
averageScore_not: $averageScore_not
averageScore_greater: $averageScore_greater
averageScore_lesser: $averageScore_lesser
popularity_not: $popularity_not
popularity_greater: $popularity_greater
popularity_lesser: $popularity_lesser
source_in: $source_in
sort: $sort
) {
__typename
id # The id of the media
idMal # The mal id of the media
# title # The official titles of the media in various languages
type # The type of the media; anime or manga
format # The format the media was released in
status # The current releasing status of the media
description # Short description of the media's story and characters
# startDate # The first official release date of the media
# endDate # The last official release date of the media
season # The season the media was initially released in
seasonYear # The season year the media was initially released in
seasonInt # The year & season the media was initially released in
episodes # The amount of episodes the anime has when complete
duration # The general length of each anime episode in minutes
chapters # The amount of chapters the manga has when complete
volumes # The amount of volumes the manga has when complete
countryOfOrigin # Where the media was created. (ISO 3166-1 alpha-2)
isLicensed # If the media is officially licensed or a self-published doujin release
source # Source type the media was adapted from.
hashtag # Official Twitter hashtags for the media
# trailer # Media trailer or advertisement
updatedAt # When the media's data was last updated
# coverImage # The cover images of the media
bannerImage # The banner image of the media
genres # The genres of the media
synonyms # Alternative titles of the media
averageScore # A weighted average score of all the user's scores of the media
meanScore # Mean score of all the user's scores of the media
popularity # The number of users with the media on their list
isLocked # Locked media may not be added to lists our favorited. This may be due to the entry pending for deletion or other reasons.
trending # The amount of related activity in the past hour
favourites # The amount of user's who have favourited the media
# tags # List of tags that describes elements and themes of the media
# relations # Other media in the same or connecting franchise
# characters
# staff
# studios
isFavourite # If the media is marked as favourite by the current authenticated user
isFavouriteBlocked # If the media is blocked from being added to favourites
isAdult # If the media is intended only for 18+ adult audiences
# nextAiringEpisode # The media's next episode airing schedule
# airingSchedule # The media's entire airing schedule
# trends # The media's daily trend stats
# externalLinks # External links to another site related to the media
# streamingEpisodes # Data and links to legal streaming episodes on external sites
# rankings # The ranking of the media in a particular time span and format compared to other media
# mediaListEntry # The authenticated user's media list entry for the media
# reviews
# recommendations
# stats
siteUrl # The url for the media page on the AniList website
autoCreateForumThread # If the media should have forum thread automatically created for it on airing episode release
isRecommendationBlocked # If the media is blocked from being recommended to/from
isReviewBlocked # If the media is blocked from being reviewed
modNotes # Notes for site moderators
}
}
I'll clean this, remove unused manual formatting and merge. Ty @notrab
@nohehf wow! Nice. Sorry, I was away from my computer for a few hours today so only just catching up on notifications now. Thanks for the fixes! 😍
I ran the final output through the
print
/parse
functions ofgraphql
to remove any unwanted spaces. This should mean we can simplify some of the formatting functions, and rely on this, as well asJSON.stringify
later (for variables, etc.)lmkwyt