diff --git a/.gitignore b/.gitignore index 955ed25..bffcf95 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.DS_Store yarn-error.log dist/ output/*.ts diff --git a/src/convert.test.ts b/src/convert.test.ts index fcb65d9..535f371 100644 --- a/src/convert.test.ts +++ b/src/convert.test.ts @@ -1,131 +1,78 @@ -// import { arbitraryQuery } from "../output/output"; import * as Codegen from "./convert"; import * as Types from "./types"; -describe("includesOneOf", () => { - it("Makes any sense whatsoever", () => { - expect(Codegen.includesOneOf("dog", ["dog"])).toBeTruthy(); - }); - it("Works with multiple", () => { - expect(Codegen.includesOneOf("dog", ["log", "dog"])).toBeTruthy(); - }); - it("Works with multiple even with nonsense everywhere", () => { - expect(Codegen.includesOneOf("_____dog___", ["log", "dog"])).toBeTruthy(); - }); - it("Doesn't find something that's not there", () => { - expect(Codegen.includesOneOf("dog", ["log"])).toBeFalsy(); - }); -}); +const stable: Types.Output = { + kind: "Object", + name: "Stable" as Types.TypeName, + output: "fc.record({horse: arbitraryHorse })" as Types.Generated, + deps: ["Horse" as Types.TypeName] +}; +const horse: Types.Output = { + kind: "Object", + name: "Horse" as Types.TypeName, + output: "fc.record({saddle: arbitrarySaddle})" as Types.Generated, + deps: ["Saddle" as Types.TypeName] +}; +const saddle: Types.Output = { + kind: "Object", + name: "Saddle" as Types.TypeName, + output: "fc.record({chair: arbitraryChair})" as Types.Generated, + deps: [] +}; +const things: Types.Output = { + kind: "Union", + name: "Things" as Types.TypeName, + output: "fc.oneof(arbitraryStable, arbitrarySaddle)" as Types.Generated, + deps: ["Stable" as Types.TypeName, "Saddle" as Types.TypeName] +}; describe("sortASTs", () => { it("Puts mentions later", () => { - const stable: Types.Output = { - kind: "Object", - name: "Stable" as Types.TypeName, - output: "fc.record({horse: arbitraryHorse })" as Types.Generated, - deps: [], - }; - const horse: Types.Output = { - kind: "Object", - name: "Horse" as Types.TypeName, - output: "fc.record({saddle: arbitrarySaddle})" as Types.Generated, - deps: [], - }; - const saddle: Types.Output = { - kind: "Object", - name: "Saddle" as Types.TypeName, - output: "fc.record({chair: arbitraryChair})" as Types.Generated, - deps: [], - }; - const things: Types.Output = { - kind: "Union", - name: "Things" as Types.TypeName, - output: "fc.oneof(arbitraryStable, arbitrarySaddle)" as Types.Generated, - deps: [], - }; - const expectedOrder = [saddle, horse, stable, things]; - expect(Codegen.sortASTs([things, stable, horse, saddle])).toStrictEqual( - expectedOrder - ); - expect(Codegen.sortASTs([stable, horse, saddle, things])).toStrictEqual( - expectedOrder - ); - }); - - it("Does the twitter ones", () => { - const Query: Types.Output = { - kind: "Object", - name: "Query" as Types.TypeName, - output: `fc.record({Tweet: arbitraryTweet,Tweets: fc.array(arbitraryTweet),TweetsMeta: arbitraryMeta,User: arbitraryUser,Notifications: fc.array(arbitraryNotification),NotificationsMeta: arbitraryMeta})` as Types.Generated, - deps: [], - }; - const Tweet: Types.Output = { - kind: "Object", - name: "Tweet" as Types.TypeName, - output: `fc.record({id: arbitraryID,body: arbitraryString,date: arbitraryDate,Author: arbitraryUser,Stats: arbitraryStat})` as Types.Generated, - deps: [], - }; - const User: Types.Output = { - kind: "Object", - name: "User" as Types.TypeName, - output: `fc.record({id: arbitraryID,username: arbitraryString,first_name: arbitraryString,last_name: arbitraryString,full_name: arbitraryString,name: arbitraryString,avatar_url: arbitraryUrl})` as Types.Generated, - deps: [], - }; - const Stat: Types.Output = { - kind: "Object", - name: "Stat" as Types.TypeName, - output: `fc.record({views: arbitraryInt,likes: arbitraryInt,retweets: arbitraryInt,responses: arbitraryInt})` as Types.Generated, - deps: [], - }; - const Meta: Types.Output = { - kind: "Object", - name: "Meta" as Types.TypeName, - output: `fc.record({count: arbitraryInt})` as Types.Generated, - deps: [], - }; - - const Notification: Types.Output = { - kind: "Object", - name: "Notification" as Types.TypeName, - output: `fc.record({id: arbitraryID,date: arbitraryDate,type: arbitraryString})` as Types.Generated, - deps: [], - }; - - const Mutation: Types.Output = { - kind: "Object", - name: "Mutation" as Types.TypeName, - output: `fc.record({createTweet: arbitraryTweet,deleteTweet: arbitraryTweet,markTweetRead: arbitraryBoolean})` as Types.Generated, - deps: [], - }; - - const StatOrNotification: Types.Output = { - kind: "Union", - name: "StatOrNotification" as Types.TypeName, - output: `fc.oneof(arbitraryStat, arbitraryNotification)` as Types.Generated, - deps: [], - }; - - const expectedTweetOrder = [ - User, - Stat, - Tweet, - Meta, - Notification, - Query, - Mutation, - StatOrNotification, + const expectedOrder = [ + "Saddle" as Types.TypeName, + "Horse" as Types.TypeName, + "Stable" as Types.TypeName, + "Things" as Types.TypeName ]; expect( - Codegen.sortASTs([ - Query, - Tweet, - User, - Stat, - Meta, - Notification, - Mutation, - StatOrNotification, - ]) - ).toStrictEqual(expectedTweetOrder); + Codegen.sortASTs([things, stable, horse, saddle]).map(a => a.name) + ).toStrictEqual(expectedOrder); + expect( + Codegen.sortASTs([stable, horse, saddle, things]).map(a => a.name) + ).toStrictEqual(expectedOrder); + }); +}); + +describe("moveASTs", () => { + it("Moves everything with zero deps", () => { + const used: Types.Output[] = []; + const remaining = [stable, horse, saddle, things]; + const result = Codegen.moveASTs(used, remaining); + if (result._tag === "Right") { + expect(result.payload.used.length).toEqual(1); + expect(result.payload.remaining.length).toEqual(3); + } else { + throw "moveASTs failed"; + } + }); + it("Moves everything with deps that have already been moved across", () => { + const used = [saddle]; + const remaining = [horse, stable, things]; + const result = Codegen.moveASTs(used, remaining); + if (result._tag === "Right") { + expect(result.payload.used.length).toEqual(2); + expect(result.payload.remaining.length).toEqual(2); + } else { + throw "moveASTs failed"; + } + }); + it("Bruce forces it to a satifying conclusion", () => { + const remaining = [stable, horse, saddle, things]; + const result = Codegen.magicSort(remaining, 100); + if (result._tag === "Right") { + expect(result && result.payload.length).toEqual(4); + } else { + throw "fail!"; + } }); }); diff --git a/src/convert.ts b/src/convert.ts index de26fd3..2acd708 100644 --- a/src/convert.ts +++ b/src/convert.ts @@ -5,10 +5,20 @@ import { GraphQLNamedType, FieldDefinitionNode, TypeNode, - EnumValueDefinitionNode, + EnumValueDefinitionNode } from "graphql"; import * as fc from "fast-check"; -import { TypeName, Maybe, Output, Kind, Generated } from "./types"; +import { + TypeName, + Maybe, + Output, + Kind, + Generated, + Either, + left, + right, + caseEither +} from "./types"; const nodeName = (node: TypeDefinitionNode): TypeName => node ? (node.name.value as TypeName) : ("no node" as TypeName); @@ -30,7 +40,7 @@ const withFieldType = (typeNode: TypeNode): FieldReturn => { const internalType = withFieldType(typeNode.type); return { output: `fc.array(${internalType.output})` as Generated, - deps: internalType.deps, + deps: internalType.deps }; } else { // therefore typeNode.kind === 'NonNullType' @@ -44,13 +54,13 @@ const withField = (field: FieldDefinitionNode): FieldReturn => { const fieldType = withFieldType(field.type); return { output: `${fieldName}: ${fieldType.output}` as Generated, - deps: fieldType.deps, + deps: fieldType.deps }; }; const withEnum = (values: readonly EnumValueDefinitionNode[]): Generated => { const v = values - .map((value) => { + .map(value => { const val = value.name.value; return `fc.constant("${val}")`; }) @@ -60,15 +70,15 @@ const withEnum = (values: readonly EnumValueDefinitionNode[]): Generated => { const withUnion = (types: readonly NamedTypeNode[]): FieldReturn => { const fieldReturns = types.map(withNamedFieldType); - const output = fieldReturns.map((i) => i.output).join(", "); + const output = fieldReturns.map(i => i.output).join(", "); return { output: `fc.oneof(${output})` as Generated, - deps: flattenDeps(fieldReturns), + deps: flattenDeps(fieldReturns) }; }; const flattenDeps = (fieldReturns: FieldReturn[]): TypeName[] => - fieldReturns.map((i) => i.deps).reduce((as, a) => as.concat(a), []); + fieldReturns.map(i => i.deps).reduce((as, a) => as.concat(a), []); const withAstNode = (name: TypeName, node: TypeDefinitionNode): Output => { switch (node.kind) { @@ -77,35 +87,40 @@ const withAstNode = (name: TypeName, node: TypeDefinitionNode): Output => { kind: "Scalar", name, output: `fc.anything()` as Generated, - deps: [], + deps: [] }; case "EnumTypeDefinition": return { kind: "Enum", name, output: withEnum(node.values || []), - deps: [], + deps: [] }; case "InputObjectTypeDefinition": - // not yet supported - return { kind: "InputObject", name, output: "" as Generated, deps: [] }; + // this is awful + return { + kind: "InputObject", + name, + output: "fc.anything()" as Generated, + deps: [] + }; case "InterfaceTypeDefinition": const iFieldReturns = (node.fields || []).map(withField); - const iFieldOutput = iFieldReturns.map((i) => i.output).join(","); + const iFieldOutput = iFieldReturns.map(i => i.output).join(","); return { kind: "Interface", name, output: `fc.record({${iFieldOutput}})` as Generated, - deps: flattenDeps(iFieldReturns), + deps: flattenDeps(iFieldReturns) }; case "ObjectTypeDefinition": const oFieldReturns = (node.fields || []).map(withField); - const oFieldOutput = oFieldReturns.map((i) => i.output).join(","); + const oFieldOutput = oFieldReturns.map(i => i.output).join(","); return { kind: "Object", name, output: `fc.record({${oFieldOutput}})` as Generated, - deps: flattenDeps(oFieldReturns), + deps: flattenDeps(oFieldReturns) }; case "UnionTypeDefinition": const uFieldReturns = withUnion(node.types || []); @@ -114,7 +129,7 @@ const withAstNode = (name: TypeName, node: TypeDefinitionNode): Output => { kind: "Union", name, output: uFieldReturns.output, - deps: uFieldReturns.deps, + deps: uFieldReturns.deps }; } }; @@ -143,7 +158,7 @@ const getArbitraryName = (typeName: TypeName): Generated => const getNamedTypes = (schema: GraphQLSchema): GraphQLNamedType[] => { const typesMap = schema.getTypeMap(); const namedTypes: Maybe[] = Object.keys(typesMap).map( - (key) => { + key => { const item = schema.getType(key); return item || null; } @@ -163,7 +178,7 @@ const withNamedType = (item: GraphQLNamedType): Output | null => { kind: "Primitive", name: item.name as TypeName, output: prim, - deps: [], + deps: [] }; } else { return null; @@ -173,100 +188,107 @@ const withNamedType = (item: GraphQLNamedType): Output | null => { const notNull = (a: A | null): a is A => a !== null; -const byKind = (k: Kind) => (a: Output) => a.kind === k; +const removeKind = (k: Kind) => (a: Output) => a.kind !== k; const render = (val: Output) => { const { name, output } = val; return `export const ${getArbitraryName(name)} = ${output}`; }; -const logThen = (a: A): A => { - console.log(a); - return a; -}; - -export const getSchemaDeclarations = (schema: GraphQLSchema): string => { - const namedTypes = getNamedTypes(schema); - - const primitives = namedTypes - .map(withNamedType) - //.map(logThen) - .filter(notNull) - .filter(byKind("Primitive")) +export const getSchemaDeclarations = (schema: GraphQLSchema): string => + sortASTs(getNamedTypes(schema).map(withNamedType).filter(notNull)) .map(render) - .join("\n"); + .join("\n\n"); - const scalars = namedTypes - .map(withNamedType) - //.map(logThen) - .filter(notNull) - .filter(byKind("Scalar")) - .map(render) - .join("\n"); - - const enums = namedTypes - .map(withNamedType) - //.map(logThen) - .filter(notNull) - .filter(byKind("Enum")) - .map(render) - .join("\n"); - - const unions = namedTypes - .map(withNamedType) - //.map(logThen) - .filter(notNull) - .filter(byKind("Union")); +const filterSplit = ( + as: A[], + f: (a: A) => boolean +): { yes: A[]; no: A[] } => ({ + yes: as.filter(f), + no: as.filter(a => !f(a)) +}); - const interfaces = namedTypes - .map(withNamedType) - //.map(logThen) - .filter(notNull) - .filter(byKind("Interface")); - - const objects = namedTypes - .map(withNamedType) - //.map(logThen) - .filter(notNull) - .filter(byKind("Object")); +export const sortASTs = (as: Output[]): Output[] => { + const limit = 10000; + return caseEither(magicSort(as, limit), { + onRight: payload => payload, + onLeft: err => { + throw err; + return []; + } + }); +}; - const mixed = sortASTs([...unions, ...objects, ...interfaces]) - .map(render) - .join("\n"); +const showProgress = (used: Output[], remaining: Output[]): void => { + const unresolved = [ + ...new Set(remaining.map(a => a.deps).reduce((as, a) => as.concat(a), [])) + ]; + const resolved = used.map(a => a.name); + console.log("RESOLVED", resolved); + console.log("UNRESOLVED", unresolved); +}; - return `${primitives}\n${enums}\n${scalars}\n${mixed}`; +export const magicSort = ( + as: Output[], + startingLimit: number +): Either => { + let limit = startingLimit; + let newRemaining = as; + let newUsed: Output[] = []; + let error = `Could not resolve ordering within ${startingLimit} tries`; + while (newRemaining.length > 0 && limit > 0) { + const succeeded = caseEither(moveASTs(newUsed, newRemaining), { + onRight: payload => { + newUsed = payload.used; + newRemaining = payload.remaining; + limit = limit - 1; + return true; + }, + onLeft: err => { + error = err; + return false; + } + }); + // showProgress(newUsed, newRemaining); + if (!succeeded) { + break; + } + } + if (newRemaining.length > 0) { + return left(error); + } + return right(newUsed); }; -const findableKeys = (key: TypeName) => [ - `${getArbitraryName(key)},`, - `${getArbitraryName(key)})`, - `${getArbitraryName(key)}}`, - `${getArbitraryName(key)} `, -]; +type ASTReturn = Either< + string, + { + used: Output[]; + remaining: Output[]; + } +>; -export const includesOneOf = (val: string, opts: string[]): boolean => - opts - .map((opt) => val.includes(opt)) - .reduce((total, value) => total || value, false); +export const moveASTs = (used: Output[], remaining: Output[]): ASTReturn => { + // remove everything in used from deps list + const usedDeps = used.map(a => a.name); -// if one object mentions another definition, put it after that definition -export const sortASTs = (as: Output[]): Output[] => - [...as].sort( - ({ name: key, output: val }, { name: newKey, output: newVal }) => { - // console.log(`${_a}: ${key}: ${val}`); - // console.log(`${_b}: ${newKey}: ${newVal}`); - const leftMentionsRight = includesOneOf(newVal, findableKeys(key)); - const rightMentionsLeft = includesOneOf(val, findableKeys(newKey)); - if (leftMentionsRight) { - // console.log(`moving ${key} left to avoid ${newKey}:${newVal}`); - return -1; // move left before right - } else if (rightMentionsLeft) { - // console.log(`${newKey} moves left to go before ${key}:${val}`); - return 1; // move right before left - } - /*console.log( - `Not moving ${key} because it's not found in ${newKey}:${newVal}` - );*/ - return 0; - } + const remainingFiltered = remaining.map(a => ({ + ...a, + deps: a.deps.filter(dep => !usedDeps.includes(dep)) + })); + + // move everything with empty deps list left + const { yes: moved, no: keep } = filterSplit( + remainingFiltered, + a => a.deps.length === 0 ); + + // done + const newUsed = [...used, ...moved]; + if (newUsed.length === used.length) { + return left( + `No changes made, unresolvable. ${newUsed.length} moved, ${keep.length} remaining to move.` + ); + } + return right({ used: newUsed, remaining: keep }); +}; diff --git a/src/index.ts b/src/index.ts index 381d40f..756b829 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,7 +6,6 @@ module.exports = { plugin: (schema: GraphQLSchema, documents: any, config: any) => { const declarations = getSchemaDeclarations(schema); const output = `import * as fc from 'fast-check'\n${declarations}`; - return output; return format(output, { parser: "typescript" }); diff --git a/src/types.ts b/src/types.ts index ddb9580..cf0190d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,6 +2,30 @@ export type Maybe = null | undefined | T; /// +export type Either = + | { _tag: "Left"; error: E } + | { _tag: "Right"; payload: A }; + +export const left = (error: E): Either => ({ + _tag: "Left", + error +}); + +export const right = (payload: A): Either => ({ + _tag: "Right", + payload +}); + +export const caseEither = ( + either: Either, + cases: { onLeft: (e: E) => B; onRight: (a: A) => B } +): B => + either._tag === "Left" + ? cases.onLeft(either.error) + : cases.onRight(either.payload); + +/// + type Nominal = { readonly symbol: A; }; diff --git a/test/github-schema.graphql b/test/github-schema.graphql index e27ac85..17ae3ad 100644 --- a/test/github-schema.graphql +++ b/test/github-schema.graphql @@ -451,6 +451,11 @@ input AddPullRequestReviewInput { The Node ID of the pull request to modify. """ pullRequestId: ID! + + """ + The review line comment threads. + """ + threads: [DraftPullRequestReviewThread] } """ @@ -473,6 +478,66 @@ type AddPullRequestReviewPayload { reviewEdge: PullRequestReviewEdge } +""" +Autogenerated input type of AddPullRequestReviewThread +""" +input AddPullRequestReviewThreadInput { + """ + Body of the thread's first comment. + """ + body: String! + + """ + A unique identifier for the client performing the mutation. + """ + clientMutationId: String + + """ + The line of the blob to which the thread refers. The end of the line range for multi-line comments. + """ + line: Int! + + """ + Path to the file being commented on. + """ + path: String! + + """ + The Node ID of the review to modify. + """ + pullRequestReviewId: ID! + + """ + The side of the diff on which the line resides. For multi-line comments, this is the side for the end of the line range. + """ + side: DiffSide = RIGHT + + """ + The first line of the range to which the comment refers. + """ + startLine: Int + + """ + The side of the diff on which the start line resides. + """ + startSide: DiffSide = RIGHT +} + +""" +Autogenerated return type of AddPullRequestReviewThread +""" +type AddPullRequestReviewThreadPayload { + """ + A unique identifier for the client performing the mutation. + """ + clientMutationId: String + + """ + The newly created thread. + """ + thread: PullRequestReviewThread +} + """ Autogenerated input type of AddReaction """ @@ -2124,6 +2189,11 @@ type Commit implements GitObject & Node & Subscribable & UniformResourceLocatabl """ oid: GitObjectID! + """ + The organization this commit was made on behalf of. + """ + onBehalfOf: Organization + """ The parents of a commit. """ @@ -2266,7 +2336,7 @@ input CommitAuthor { """ Represents a comment on a given Commit. """ -type CommitComment implements Comment & Deletable & Node & Reactable & RepositoryNode & Updatable & UpdatableComment { +type CommitComment implements Comment & Deletable & Minimizable & Node & Reactable & RepositoryNode & Updatable & UpdatableComment { """ The actor who authored the comment. """ @@ -5381,6 +5451,21 @@ enum DeploymentStatusState { SUCCESS } +""" +The possible sides of a diff. +""" +enum DiffSide { + """ + The left side of the diff. + """ + LEFT + + """ + The right side of the diff. + """ + RIGHT +} + """ Represents a 'disconnected' event on a given issue or pull request. """ @@ -5467,6 +5552,41 @@ input DraftPullRequestReviewComment { position: Int! } +""" +Specifies a review comment thread to be left with a Pull Request Review. +""" +input DraftPullRequestReviewThread { + """ + Body of the comment to leave. + """ + body: String! + + """ + The line of the blob to which the thread refers. The end of the line range for multi-line comments. + """ + line: Int! + + """ + Path to the file being commented on. + """ + path: String! + + """ + The side of the diff on which the line resides. For multi-line comments, this is the side for the end of the line range. + """ + side: DiffSide = RIGHT + + """ + The first line of the range to which the comment refers. + """ + startLine: Int + + """ + The side of the diff on which the start line resides. + """ + startSide: DiffSide = RIGHT +} + """ An account to manage multiple organizations with consolidated policy and billing. """ @@ -8498,7 +8618,7 @@ type Gist implements Node & Starrable & UniformResourceLocatable { """ Represents a comment on an Gist. """ -type GistComment implements Comment & Deletable & Node & Updatable & UpdatableComment { +type GistComment implements Comment & Deletable & Minimizable & Node & Updatable & UpdatableComment { """ The actor who authored the comment. """ @@ -9862,7 +9982,7 @@ type Issue implements Assignable & Closable & Comment & Labelable & Lockable & N """ Represents a comment on an Issue. """ -type IssueComment implements Comment & Deletable & Node & Reactable & RepositoryNode & Updatable & UpdatableComment { +type IssueComment implements Comment & Deletable & Minimizable & Node & Reactable & RepositoryNode & Updatable & UpdatableComment { """ The actor who authored the comment. """ @@ -12502,6 +12622,61 @@ type MilestonedEvent implements Node { subject: MilestoneItem! } +""" +Entities that can be minimized. +""" +interface Minimizable { + """ + Returns whether or not a comment has been minimized. + """ + isMinimized: Boolean! + + """ + Returns why the comment was minimized. + """ + minimizedReason: String + + """ + Check if the current viewer can minimize this object. + """ + viewerCanMinimize: Boolean! +} + +""" +Autogenerated input type of MinimizeComment +""" +input MinimizeCommentInput { + """ + The classification of comment + """ + classifier: ReportedContentClassifiers! + + """ + A unique identifier for the client performing the mutation. + """ + clientMutationId: String + + """ + The Node ID of the subject to modify. + """ + subjectId: ID! +} + +""" +Autogenerated return type of MinimizeComment +""" +type MinimizeCommentPayload { + """ + A unique identifier for the client performing the mutation. + """ + clientMutationId: String + + """ + The comment that was minimized. + """ + minimizedComment: Minimizable +} + """ Autogenerated input type of MoveProjectCard """ @@ -12647,6 +12822,11 @@ type Mutation { """ addPullRequestReviewComment(input: AddPullRequestReviewCommentInput!): AddPullRequestReviewCommentPayload + """ + Adds a new thread to a pending Pull Request Review. + """ + addPullRequestReviewThread(input: AddPullRequestReviewThreadInput!): AddPullRequestReviewThreadPayload + """ Adds a reaction to a subject. """ @@ -12862,6 +13042,11 @@ type Mutation { """ mergePullRequest(input: MergePullRequestInput!): MergePullRequestPayload + """ + Minimizes a comment on an Issue, Commit, Pull Request, or Gist + """ + minimizeComment(input: MinimizeCommentInput!): MinimizeCommentPayload + """ Moves a project card to another place. """ @@ -12977,6 +13162,11 @@ type Mutation { """ unmarkIssueAsDuplicate(input: UnmarkIssueAsDuplicateInput!): UnmarkIssueAsDuplicatePayload + """ + Unminimizes a comment on an Issue, Commit, Pull Request, or Gist + """ + unminimizeComment(input: UnminimizeCommentInput!): UnminimizeCommentPayload + """ Marks a review thread as unresolved. """ @@ -20109,7 +20299,7 @@ type PullRequestReview implements Comment & Deletable & Node & Reactable & Repos """ A review comment associated with a given repository pull request. """ -type PullRequestReviewComment implements Comment & Deletable & Node & Reactable & RepositoryNode & Updatable & UpdatableComment { +type PullRequestReviewComment implements Comment & Deletable & Minimizable & Node & Reactable & RepositoryNode & Updatable & UpdatableComment { """ The actor who authored the comment. """ @@ -20600,6 +20790,11 @@ type PullRequestReviewThread implements Node { """ skip: Int ): PullRequestReviewCommentConnection! + + """ + The side of the diff on which this thread was placed. + """ + diffSide: DiffSide! id: ID! """ @@ -20607,6 +20802,21 @@ type PullRequestReviewThread implements Node { """ isResolved: Boolean! + """ + The line in the file to which this thread refers + """ + line: Int + + """ + The original line in the file to which this thread refers. + """ + originalLine: Int + + """ + The original start line in the file to which this thread refers (multi-line only). + """ + originalStartLine: Int + """ Identifies the pull request associated with this thread. """ @@ -20622,6 +20832,16 @@ type PullRequestReviewThread implements Node { """ resolvedBy: User + """ + The side of the diff that the first line of the thread starts on (multi-line only) + """ + startDiffSide: DiffSide + + """ + The start line in the file to which this thread refers (multi-line only) + """ + startLine: Int + """ Whether or not the viewer can resolve this thread """ @@ -26126,6 +26346,41 @@ type RepoRemoveTopicAuditEntry implements AuditEntry & Node & OrganizationAuditE userUrl: URI } +""" +The reasons a piece of content can be reported or minimized. +""" +enum ReportedContentClassifiers { + """ + An abusive or harassing piece of content + """ + ABUSE + + """ + A duplicated piece of content + """ + DUPLICATE + + """ + An irrelevant piece of content + """ + OFF_TOPIC + + """ + An outdated piece of content + """ + OUTDATED + + """ + The content has been resolved + """ + RESOLVED + + """ + A spammy piece of content + """ + SPAM +} + """ A repository contains the content for a project. """ @@ -33086,6 +33341,36 @@ type UnmarkedAsDuplicateEvent implements Node { id: ID! } +""" +Autogenerated input type of UnminimizeComment +""" +input UnminimizeCommentInput { + """ + A unique identifier for the client performing the mutation. + """ + clientMutationId: String + + """ + The Node ID of the subject to modify. + """ + subjectId: ID! +} + +""" +Autogenerated return type of UnminimizeComment +""" +type UnminimizeCommentPayload { + """ + A unique identifier for the client performing the mutation. + """ + clientMutationId: String + + """ + The comment that was unminimized. + """ + unminimizedComment: Minimizable +} + """ Represents an 'unpinned' event on a given issue or pull request. """ diff --git a/test/test-schema.graphql b/test/test-schema.graphql index 934d887..b60f110 100644 --- a/test/test-schema.graphql +++ b/test/test-schema.graphql @@ -88,7 +88,12 @@ interface Deletable { type Query { Tweet(id: ID!): Tweet - Tweets(limit: Int, skip: Int, sort_field: String, sort_order: String): [Tweet] + Tweets( + limit: Int + skip: Int + sort_field: String + sort_order: String + ): [Tweet] TweetsMeta: Meta User(id: ID!): User Notifications(limit: Int): [Notification] @@ -101,4 +106,4 @@ type Mutation { markTweetRead(id: ID!): Boolean } -# union StatOrNotification = Stat | Notification +union StatOrNotification = Stat | Notification diff --git a/tsconfig.json b/tsconfig.json index 9b3b870..04fec14 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,7 +21,7 @@ // "removeComments": true, /* Do not emit comments to output. */ // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + "downlevelIteration": true /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */, // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */