Merge remote-tracking branch 'origin/develop'

This commit is contained in:
Timothy Warren 2021-10-07 21:56:35 -04:00
commit 0518e3898b
4 changed files with 496 additions and 26 deletions

10
Jenkinsfile vendored
View File

@ -36,16 +36,6 @@ pipeline {
sh 'php ./vendor/bin/phpunit --colors=never'
}
}
stage('Code Cleanliness') {
agent any
steps {
sh "php ./vendor/bin/phpstan analyse -c phpstan.neon -n --no-progress --no-ansi --error-format=checkstyle | awk '{\$1=\$1;print}' > build/logs/phpstan.log"
recordIssues(
failOnError: false,
tools: [phpStan(reportEncoding: 'UTF-8', pattern: 'build/logs/phpstan.log')]
)
}
}
stage('Coverage') {
agent any
steps {

View File

@ -1,6 +1,9 @@
query ($slug: String!) {
findProfileBySlug(slug: $slug) {
libraryEvents(first: 100, kind: [PROGRESSED, UPDATED]) {
libraryEvents(first: 100, kind: [PROGRESSED, UPDATED], sort: [{
direction: DESCENDING,
on: UPDATED_AT,
}]) {
nodes {
id
changedData

View File

@ -88,6 +88,13 @@ final class AnimeTransformer extends AbstractTransformer {
$role = $staffing['role'];
$name = $person['names']['localized'][$person['names']['canonical']];
// If this person object is so broken as to not have a proper image object,
// just skip it. No point in showing a role with nothing in it.
if ($person === null || $person['id'] === null || $person['image'] === null || $person['image']['original'] === null)
{
continue;
}
if ( ! array_key_exists($role, $staff))
{
$staff[$role] = [];

View File

@ -115,6 +115,18 @@ interface Media {
"Returns the last _n_ elements from the list."
last: Int
): MappingConnection!
"A list of your wiki submissions for this media"
myWikiSubmissions(
"Returns the elements in the list that come after the specified cursor."
after: String,
"Returns the elements in the list that come before the specified cursor."
before: String,
"Returns the first _n_ elements from the list."
first: Int,
"Returns the last _n_ elements from the list."
last: Int,
sort: [WikiSubmissionSortOption]
): WikiSubmissionConnection!
"The time of the next release of this media"
nextRelease: ISO8601DateTime
"The country in which the media was primarily produced"
@ -219,6 +231,9 @@ union FavoriteItemUnion = Anime | Character | Manga | Person
"Objects which are Mappable"
union MappingItemUnion = Anime | Category | Character | Episode | Manga | Person | Producer
"Objects which are Reportable"
union ReportItemUnion = Comment | MediaReaction | Post | Review
"A user account on Kitsu"
type Account implements WithTimestamps {
"The country this user resides in"
@ -252,6 +267,19 @@ type Account implements WithTimestamps {
updatedAt: ISO8601DateTime!
}
type AccountMutations {
"Send a password reset email"
resetPassword(
"The email address to reset the password for"
email: String!
): AccountResetPasswordPayload
}
"Autogenerated return type of AccountResetPassword"
type AccountResetPasswordPayload {
email: String!
}
type Anime implements Episodic & Media & WithTimestamps {
"The recommended minimum age group for this media"
ageRating: AgeRatingEnum
@ -318,6 +346,18 @@ type Anime implements Episodic & Media & WithTimestamps {
"Returns the last _n_ elements from the list."
last: Int
): MappingConnection!
"A list of your wiki submissions for this media"
myWikiSubmissions(
"Returns the elements in the list that come after the specified cursor."
after: String,
"Returns the elements in the list that come before the specified cursor."
before: String,
"Returns the first _n_ elements from the list."
first: Int,
"Returns the last _n_ elements from the list."
last: Int,
sort: [WikiSubmissionSortOption]
): WikiSubmissionConnection!
"The time of the next release of this media"
nextRelease: ISO8601DateTime
"The country in which the media was primarily produced"
@ -647,9 +687,9 @@ type Comment implements WithTimestamps {
"The user who created this comment for the parent post."
author: Profile!
"Unmodified content."
content: String!
content: String
"Html formatted content."
contentFormatted: String!
contentFormatted: String
createdAt: ISO8601DateTime!
id: ID!
"Users who liked this comment"
@ -811,6 +851,47 @@ type FavoriteEdge {
node: Favorite
}
"Related media grouped together"
type Franchise implements WithTimestamps {
createdAt: ISO8601DateTime!
id: ID!
"All media related to a franchise"
installments(
"Returns the elements in the list that come after the specified cursor."
after: String,
"Returns the elements in the list that come before the specified cursor."
before: String,
"Returns the first _n_ elements from the list."
first: Int,
"Returns the last _n_ elements from the list."
last: Int,
sort: [InstallmentSortOption]
): InstallmentConnection
"The name of this franchise in various languages"
titles: TitlesList!
updatedAt: ISO8601DateTime!
}
"The connection type for Franchise."
type FranchiseConnection {
"A list of edges."
edges: [FranchiseEdge]
"A list of nodes."
nodes: [Franchise]
"Information to aid in pagination."
pageInfo: PageInfo!
"The total amount of nodes."
totalCount: Int!
}
"An edge in a connection."
type FranchiseEdge {
"A cursor for use in pagination."
cursor: String!
"The item at the end of the edge."
node: Franchise
}
type Generic implements Error {
"The error code."
code: String
@ -833,19 +914,54 @@ type Image {
views(names: [String!]): [ImageView!]!
}
type ImageView implements WithTimestamps {
createdAt: ISO8601DateTime!
type ImageView {
"The height of the image"
height: Int
"The name of this view of the image"
name: String!
updatedAt: ISO8601DateTime!
"The URL of this view of the image"
url: String!
"The width of the image"
width: Int
}
"Individual media that belongs to a franchise"
type Installment implements WithTimestamps {
"Order based chronologically"
alternativeOrder: Int
createdAt: ISO8601DateTime!
"The franchise related to this installment"
franchise: Franchise!
id: ID!
"The media related to this installment"
media: Media!
"Order based by date released"
releaseOrder: Int
"Further explains the media relationship corresponding to a franchise"
tag: InstallmentTagEnum
updatedAt: ISO8601DateTime!
}
"The connection type for Installment."
type InstallmentConnection {
"A list of edges."
edges: [InstallmentEdge]
"A list of nodes."
nodes: [Installment]
"Information to aid in pagination."
pageInfo: PageInfo!
"The total amount of nodes."
totalCount: Int!
}
"An edge in a connection."
type InstallmentEdge {
"A cursor for use in pagination."
cursor: String!
"The item at the end of the edge."
node: Installment
}
"The user library filterable by media_type and status"
type Library {
"All Library Entries for a specific Media"
@ -1201,6 +1317,18 @@ type Manga implements Media & WithTimestamps {
"Returns the last _n_ elements from the list."
last: Int
): MappingConnection!
"A list of your wiki submissions for this media"
myWikiSubmissions(
"Returns the elements in the list that come after the specified cursor."
after: String,
"Returns the elements in the list that come before the specified cursor."
before: String,
"Returns the first _n_ elements from the list."
first: Int,
"Returns the last _n_ elements from the list."
last: Int,
sort: [WikiSubmissionSortOption]
): WikiSubmissionConnection!
"The time of the next release of this media"
nextRelease: ISO8601DateTime
"The country in which the media was primarily produced"
@ -1567,12 +1695,14 @@ type MediaStaffEdge {
}
type Mutation {
account: AccountMutations!
anime: AnimeMutations!
episode: EpisodeMutations!
libraryEntry: LibraryEntryMutations!
mapping: MappingMutations!
post: PostMutations!
pro: ProMutations!
wikiSubmission: WikiSubmissionMutations!
}
"Information about pagination in a connection."
@ -1645,9 +1775,9 @@ type Post implements WithTimestamps {
sort: [CommentSortOption]
): CommentConnection!
"Unmodified content."
content: String!
content: String
"Html formatted content."
contentFormatted: String!
contentFormatted: String
createdAt: ISO8601DateTime!
"Users that are watching this post"
follows(
@ -1718,12 +1848,12 @@ type PostMutations {
"Lock a Post."
lock(
"Lock a Post."
input: LockInput!
input: PostLockInput!
): PostLockPayload
"Unlock a Post."
unlock(
"Unlock a Post."
input: UnlockInput!
input: PostUnlockInput!
): PostUnlockPayload
}
@ -1854,9 +1984,11 @@ type Profile implements WithTimestamps {
before: String,
"Returns the first _n_ elements from the list."
first: Int,
kind: [LibraryEventKindEnum!],
"Will return all if not supplied"
kind: [LibraryEventKindEnum!] = [PROGRESSED, UPDATED, REACTED, RATED, ANNOTATED],
"Returns the last _n_ elements from the list."
last: Int
last: Int,
sort: [LibraryEventSortOption]
): LibraryEventConnection!
"The user's general location"
location: String
@ -1891,6 +2023,18 @@ type Profile implements WithTimestamps {
proMessage: String
"The PRO level the user currently has"
proTier: ProTierEnum
"Reviews created by this user"
reviews(
"Returns the elements in the list that come after the specified cursor."
after: String,
"Returns the elements in the list that come before the specified cursor."
before: String,
"Returns the first _n_ elements from the list."
first: Int,
"Returns the last _n_ elements from the list."
last: Int,
sort: [WikiSubmissionSortOption]
): ReviewConnection
"Links to the user on other (social media) sites."
siteLinks(
"Returns the elements in the list that come after the specified cursor."
@ -1913,6 +2057,20 @@ type Profile implements WithTimestamps {
waifu: Character
"The properly-gendered term for the user's waifu. This should normally only be 'Waifu' or 'Husbando' but some people are jerks, including the person who wrote this..."
waifuOrHusbando: String
"Wiki submissions created by this user"
wikiSubmissions(
"Returns the elements in the list that come after the specified cursor."
after: String,
"Returns the elements in the list that come before the specified cursor."
before: String,
"Returns the first _n_ elements from the list."
first: Int,
"Returns the last _n_ elements from the list."
last: Int,
sort: [WikiSubmissionSortOption],
"Will return all if not supplied"
statuses: [WikiSubmissionStatusEnum!] = [DRAFT, PENDING, APPROVED, REJECTED]
): WikiSubmissionConnection!
}
"The connection type for Profile."
@ -2014,6 +2172,21 @@ type Query {
findProfileById(id: ID!): Profile
"Find a single User by Slug"
findProfileBySlug(slug: String!): Profile
"Find a single Report by ID"
findReportById(id: ID!): Report
"Find a single Wiki Submission by ID"
findWikiSubmissionById(id: ID!): WikiSubmission
"All Franchise in the Kitsu database"
franchises(
"Returns the elements in the list that come after the specified cursor."
after: String,
"Returns the elements in the list that come before the specified cursor."
before: String,
"Returns the first _n_ elements from the list."
first: Int,
"Returns the last _n_ elements from the list."
last: Int
): FranchiseConnection
"List trending media on Kitsu"
globalTrending(
"Returns the elements in the list that come after the specified cursor."
@ -2101,6 +2274,30 @@ type Query {
): ProfileConnection!
"Random anime or manga"
randomMedia(ageRatings: [AgeRatingEnum!]!, mediaType: MediaTypeEnum!): Media!
"All Reports in the Kitsu database"
reports(
"Returns the elements in the list that come after the specified cursor."
after: String,
"Returns the elements in the list that come before the specified cursor."
before: String,
"Returns the first _n_ elements from the list."
first: Int,
"Returns the last _n_ elements from the list."
last: Int
): ReportConnection
"Select all Reports that match with a supplied status."
reportsByStatus(
"Returns the elements in the list that come after the specified cursor."
after: String,
"Returns the elements in the list that come before the specified cursor."
before: String,
"Returns the first _n_ elements from the list."
first: Int,
"Returns the last _n_ elements from the list."
last: Int,
"Will return all if not supplied"
statuses: [ReportStatusEnum!] = [REPORTED, RESOLVED, DECLINED]
): ReportConnection
"Search for Anime by title using Algolia. The most relevant results will be at the top."
searchAnimeByTitle(
"Returns the elements in the list that come after the specified cursor."
@ -2153,6 +2350,20 @@ type Query {
): ProfileConnection
"Get your current session info"
session: Session!
"Select all Wiki Submissions that match with a supplied status."
wikiSubmissionsByStatuses(
"Returns the elements in the list that come after the specified cursor."
after: String,
"Returns the elements in the list that come before the specified cursor."
before: String,
"Returns the first _n_ elements from the list."
first: Int,
"Returns the last _n_ elements from the list."
last: Int,
sort: [WikiSubmissionSortOption],
"Will return all if not supplied"
statuses: [WikiSubmissionStatusEnum!] = [DRAFT, PENDING, APPROVED, REJECTED]
): WikiSubmissionConnection
}
"A quote from a media"
@ -2228,6 +2439,101 @@ type QuoteLineEdge {
node: QuoteLine
}
"A report made by a user"
type Report implements WithTimestamps {
createdAt: ISO8601DateTime!
"Additional information related to why the report was made"
explanation: String
id: ID!
"The moderator who responded to this report"
moderator: Profile
"The entity that the report is related to"
naughty: ReportItemUnion!
"The reason for why the report was made"
reason: ReportReasonEnum!
"The user who made this report"
reporter: Profile!
"The resolution status for this report"
status: ReportStatusEnum!
updatedAt: ISO8601DateTime!
}
"The connection type for Report."
type ReportConnection {
"A list of edges."
edges: [ReportEdge]
"A list of nodes."
nodes: [Report]
"Information to aid in pagination."
pageInfo: PageInfo!
"The total amount of nodes."
totalCount: Int!
}
"An edge in a connection."
type ReportEdge {
"A cursor for use in pagination."
cursor: String!
"The item at the end of the edge."
node: Report
}
"A media review made by a user"
type Review implements WithTimestamps {
"The author who wrote this review."
author: Profile!
"The review data"
content: String!
createdAt: ISO8601DateTime!
"The review data formatted"
formattedContent: String!
id: ID!
"Does this review contain spoilers from the media"
isSpoiler: Boolean!
"The library entry related to this review."
libraryEntry: LibraryEntry!
"Users who liked this review"
likes(
"Returns the elements in the list that come after the specified cursor."
after: String,
"Returns the elements in the list that come before the specified cursor."
before: String,
"Returns the first _n_ elements from the list."
first: Int,
"Returns the last _n_ elements from the list."
last: Int
): ProfileConnection!
"The media related to this review."
media: Media!
"When this review was written based on media progress."
progress: Int!
"The user rating for this media"
rating: Int!
"Potentially migrated over from hummingbird."
source: String!
updatedAt: ISO8601DateTime!
}
"The connection type for Review."
type ReviewConnection {
"A list of edges."
edges: [ReviewEdge]
"A list of nodes."
nodes: [Review]
"Information to aid in pagination."
pageInfo: PageInfo!
"The total amount of nodes."
totalCount: Int!
}
"An edge in a connection."
type ReviewEdge {
"A cursor for use in pagination."
cursor: String!
"The item at the end of the edge."
node: Review
}
"Information about a user session"
type Session {
"The account associated with this session"
@ -2417,6 +2723,79 @@ type Volume implements WithTimestamps {
updatedAt: ISO8601DateTime!
}
"A Wiki Submission is used to either create or edit existing data in our database. This will allow a simple and convient way for users to submit issues/corrections without all the work being left to the mods."
type WikiSubmission implements WithTimestamps {
"The user who created this draft"
author: Profile!
createdAt: ISO8601DateTime!
"The full object that holds all the details for any modifications/additions/deletions made to the entity you are editing. This will be validated using JSON Schema."
data: JSON
id: ID!
"Any additional information that may need to be provided related to the Wiki Submission"
notes: String
"The status of the Wiki Submission"
status: WikiSubmissionStatusEnum!
"The title given to the Wiki Submission. This will default to the title of what is being edited."
title: String
updatedAt: ISO8601DateTime!
}
"The connection type for WikiSubmission."
type WikiSubmissionConnection {
"A list of edges."
edges: [WikiSubmissionEdge]
"A list of nodes."
nodes: [WikiSubmission]
"Information to aid in pagination."
pageInfo: PageInfo!
"The total amount of nodes."
totalCount: Int!
}
"Autogenerated return type of WikiSubmissionCreateDraft"
type WikiSubmissionCreateDraftPayload {
errors: [Error!]
wikiSubmission: WikiSubmission
}
"An edge in a connection."
type WikiSubmissionEdge {
"A cursor for use in pagination."
cursor: String!
"The item at the end of the edge."
node: WikiSubmission
}
type WikiSubmissionMutations {
"Create a wiki submission draft"
createDraft(
"Create a wiki submission draft."
input: WikiSubmissionCreateDraftInput!
): WikiSubmissionCreateDraftPayload
"Submit a wiki submission draft"
submitDraft(
"Submit a wiki submission draft. This will change the status to pending."
input: WikiSubmissionSubmitDraftInput!
): WikiSubmissionSubmitDraftPayload
"Update a wiki submission draft"
updateDraft(
"Update a wiki submission draft."
input: WikiSubmissionUpdateDraftInput!
): WikiSubmissionUpdateDraftPayload
}
"Autogenerated return type of WikiSubmissionSubmitDraft"
type WikiSubmissionSubmitDraftPayload {
errors: [Error!]
wikiSubmission: WikiSubmission
}
"Autogenerated return type of WikiSubmissionUpdateDraft"
type WikiSubmissionUpdateDraftPayload {
errors: [Error!]
wikiSubmission: WikiSubmission
}
enum AgeRatingEnum {
"Acceptable for all ages"
G
@ -2468,6 +2847,26 @@ enum FollowSortEnum {
FOLLOWING_FOLLOWER
}
enum InstallmentSortEnum {
ALTERNATIVE_ORDER
RELEASE_ORDER
}
enum InstallmentTagEnum {
"Same universe/world/reality/timeline, completely different characters."
ALTERNATE_SETTING
"Same setting, same characters, story is told differently."
ALTERNATE_VERSION
"Characters from different media meet in the same story."
CROSSOVER
"The main story."
MAIN_STORY
"Takes place sometime during the main storyline."
SIDE_STORY
"Uses characters of a different series, but is not an alternate setting or story."
SPINOFF
}
enum LibraryEntryStatusEnum {
"The user completed this media."
COMPLETED
@ -2494,6 +2893,11 @@ enum LibraryEventKindEnum {
UPDATED
}
enum LibraryEventSortEnum {
CREATED_AT
UPDATED_AT
}
enum LockedReasonEnum {
CLOSED
SPAM
@ -2622,6 +3026,23 @@ enum ReleaseStatusEnum {
UPCOMING
}
enum ReportReasonEnum {
"No bulli!"
BULLYING
"Not Safe For Work"
NSFW
OFFENSIVE
OTHER
SPAM
SPOILER
}
enum ReportStatusEnum {
DECLINED
REPORTED
RESOLVED
}
enum SitePermissionEnum {
"Administrator/staff member of Kitsu"
ADMIN
@ -2645,6 +3066,18 @@ enum TitleLanguagePreferenceEnum {
ROMANIZED
}
enum WikiSubmissionSortEnum {
CREATED_AT
UPDATED_AT
}
enum WikiSubmissionStatusEnum {
APPROVED
DRAFT
PENDING
REJECTED
}
input AnimeCreateInput {
ageRating: AgeRatingEnum
ageRatingGuide: String
@ -2716,6 +3149,11 @@ input GenericDeleteInput {
id: ID!
}
input InstallmentSortOption {
direction: SortDirection!
on: InstallmentSortEnum!
}
input LibraryEntryCreateInput {
finishedAt: ISO8601DateTime
mediaId: ID!
@ -2781,9 +3219,9 @@ input LibraryEntryUpdateStatusByMediaInput {
status: LibraryEntryStatusEnum!
}
input LockInput {
id: ID!
lockedReason: LockedReasonEnum!
input LibraryEventSortOption {
direction: SortDirection!
on: LibraryEventSortEnum!
}
input MappingCreateInput {
@ -2806,11 +3244,20 @@ input PostLikeSortOption {
on: PostLikeSortEnum!
}
input PostLockInput {
id: ID!
lockedReason: LockedReasonEnum!
}
input PostSortOption {
direction: SortDirection!
on: PostSortEnum!
}
input PostUnlockInput {
id: ID!
}
input TitlesListInput {
alternatives: [String!]
canonical: String
@ -2818,8 +3265,28 @@ input TitlesListInput {
localized: Map
}
input UnlockInput {
input WikiSubmissionCreateDraftInput {
data: JSON!
notes: String
title: String
}
input WikiSubmissionSortOption {
direction: SortDirection!
on: WikiSubmissionSortEnum!
}
input WikiSubmissionSubmitDraftInput {
data: JSON!
id: ID!
notes: String
title: String
}
input WikiSubmissionUpdateDraftInput {
data: JSON!
id: ID!
notes: String
}
@ -2832,6 +3299,9 @@ scalar ISO8601Date
"An ISO 8601-encoded datetime"
scalar ISO8601DateTime
"Represents untyped JSON"
scalar JSON
"A loose key-value map in GraphQL"
scalar Map