Repository: DefinitelyTyped/dt-mergebot
Pull request #437 (2022-03-31 23:37:04)

Allow other owners to merge when infrastructure is edited
The bot offers it to them, but doesn’t respect the request.


Patch:
diff --git a/src/pr-info.ts b/src/pr-info.ts
index 9b6ef8e..c24158f 100644
--- a/src/pr-info.ts
+++ b/src/pr-info.ts
@@ -225,7 +225,7 @@ export async function deriveStateForPR(
     const comments = noNullish(prInfo.comments.nodes);
     const mergeOfferDate = getMergeOfferDate(comments, prInfo.headRefOid);
     const mergeRequest = getMergeRequest(comments,
-                                         pkgInfo.length === 1 ? [author, ...pkgInfo[0]!.owners] : [author],
+                                         pkgInfo.filter(p => p.name).length === 1 ? [author, ...pkgInfo.find(p => p.name)!.owners] : [author],
                                          max([createdDate, reopenedDate, lastPushDate]));
     const lastActivityDate = max([createdDate, lastPushDate, lastCommentDate, blessing?.date, reopenedDate, latestReview]);
     const mainBotCommentID = getMainCommentID(comments);


Test patch:
diff --git a/src/_tests/fixtures/59628/_downloads.json b/src/_tests/fixtures/59628/_downloads.json
new file mode 100644
index 0000000..25a2871
--- /dev/null
+++ b/src/_tests/fixtures/59628/_downloads.json
@@ -0,0 +1,3 @@
+{
+  "twemoji": 242870
+}
diff --git a/src/_tests/fixtures/59628/_files.json b/src/_tests/fixtures/59628/_files.json
new file mode 100644
index 0000000..a598a5d
--- /dev/null
+++ b/src/_tests/fixtures/59628/_files.json
@@ -0,0 +1,3 @@
+{
+  "e11ae5d76bb7c11e606ed5aa0e47c1f1e81fd88d:types/twemoji/index.d.ts": "// Type definitions for twemoji 12.1\n// Project: https://github.com/twitter/twemoji\n// Definitions by: Markus Tacker <https://github.com/coderbyheart>\n//                 Piotr Błażejewicz <https://github.com/peterblazejewicz>\n//                 David Wheatley <https://github.com/davwheat>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// TypeScript Version: 2.2\n\n/**\n * A simple library that provides standard Unicode emoji support across all platforms.\n * Twemoji v12.0 adheres to the Unicode 12.0 spec and supports the Emoji 12.0 spec\n * The Twemoji library offers support for 3,075 emojis.\n */\nexport as namespace twemoji;\n\n/**\n * default assets url, by default will be Twitter Inc. CDN\n */\nexport const base: string;\n\n/**\n * default assets file extensions, by default '.png'\n */\nexport const ext: string;\n\n/**\n * default assets/folder size, by default \"72x72\"\n * available via Twitter CDN: 72\n */\nexport const size: string;\n\n/**\n * default class name, by default 'emoji'\n */\nexport const className: string;\n\n/**\n * basic utilities / helpers to convert code points\n * to JavaScript surrogates and vice versa\n */\nexport const convert: {\n    /**\n     * Given an HEX codepoint, returns UTF16 surrogate pairs.\n     *\n     * @param   codepoint string  generic codepoint, i.e. '1F4A9'\n     * @return  string  codepoint transformed into utf16 surrogates pair,\n     *          i.e. \\uD83D\\uDCA9\n     *\n     * @example\n     *  twemoji.convert.fromCodePoint('1f1e8');\n     *  // \"\\ud83c\\udde8\"\n     *\n     *  '1f1e8-1f1f3'.split('-').map(twemoji.convert.fromCodePoint).join('')\n     *  // \"\\ud83c\\udde8\\ud83c\\uddf3\"\n     */\n    fromCodePoint: (codepoint: string) => string;\n\n    /**\n     * Given UTF16 surrogate pairs, returns the equivalent HEX codepoint.\n     *\n     * @param   unicodeSurrogates   string  generic utf16 surrogates pair, i.e. \\uD83D\\uDCA9\n     * @param   sep                 string  optional separator for double code points, default='-'\n     * @return  string  utf16 transformed into codepoint, i.e. '1F4A9'\n     *\n     * @example\n     *  twemoji.convert.toCodePoint('\\ud83c\\udde8\\ud83c\\uddf3');\n     *  // \"1f1e8-1f1f3\"\n     *\n     *  twemoji.convert.toCodePoint('\\ud83c\\udde8\\ud83c\\uddf3', '~');\n     *  // \"1f1e8~1f1f3\"\n     */\n    toCodePoint: (unicodeSurrogates: string, sep?: string) => string;\n};\n\n/**\n * User first: used to remove missing images\n * preserving the original text intent when\n * a fallback for network problems is desired.\n * Automatically added to Image nodes via DOM\n * It could be recycled for string operations via:\n *  $('img.emoji').on('error', twemoji.onerror)\n */\nexport function onerror(): void;\n\n/**\n * Given a string, invokes the callback argument\n * per each emoji found in such string.\n * This is the most raw version used by\n * the .parse(string) method itself.\n *\n * @param   text      string    generic string to parse\n * @param   callback  Function  a generic callback that will be\n *                              invoked to replace the content.\n *                              This calback wil receive standard\n *                              String.prototype.replace(str, callback)\n *                              arguments such:\n *  callback(\n *    rawText,  // the emoji match\n *  );\n *\n *                    and others commonly received via replace.\n */\nexport function replace(text: string, callback: () => void): string;\n\n/**\n * Simplify string tests against emoji.\n *\n * @param   text string  some text that might contain emoji\n * @return  boolean true if any emoji was found, false otherwise.\n *\n * @example\n *\n *  if (twemoji.test(someContent)) {\n *    console.log(\"emoji All The Things!\");\n *  }\n */\nexport function test(text: string): boolean;\n\n/**\n * If given to parse, this callback will be invoked per each found emoji.\n *\n * If this callback returns a falsy value instead of a valid `src` to use for the image, nothing will actually change for that specific emoji.\n *\n * @param icon the lower case HEX code point i.e. \"1f4a9\"\n * @param options all info for this parsing operation\n * @param variant the optional \\uFE0F (\"as image\") variant, in case this info is anyhow meaningful. By default this is ignored.\n */\nexport type ParseCallback = (icon: string, options: object, variant: string) => string | false;\n\n/**\n * If given to parse, this object with all properties will be used per each found emoji.\n *\n *            callback   Function  the callback to invoke per each found emoji.\n *            base       string    the base url, by default twemoji.base\n *            ext        string    the image extension, by default twemoji.ext\n *            size       string    the assets size, by default twemoji.size\n */\nexport interface ParseObject {\n    /**\n     * the callback to invoke per each found emoji.\n     *\n     * default: the common replacer\n     */\n    callback: ParseCallback;\n    /**\n     * The function to invoke in order to generate additional, custom attributes for the image tag.\n     *\n     * @param the lower case HEX code point i.e. \"1f4a9\"\n     * @param variant the optional \\uFE0F (\"as image\") variant, in case this info is anyhow meaningful. By default this is ignored.\n     */\n    attributes: (icon: string, variant: string) => object;\n    /**\n     * default: MaxCDN\n     */\n    base: string;\n    /**\n     * default: \".png\"\n     */\n    ext: string;\n    /**\n     * default: \"emoji\"\n     */\n    className: string;\n    /**\n     * default: \"72x72\"\n     */\n    size: string | number;\n    /**\n     * in case it's specified it replaces .size info, if any\n     */\n    folder: string;\n}\n\n/**\n * Main method/logic to generate either <img> tags or HTMLImage nodes.\n *  \"emojify\" a generic text or DOM Element.\n *\n * @overloads\n *\n * String replacement for `innerHTML` or server side operations\n *  twemoji.parse(string);\n *  twemoji.parse(string, Function);\n *  twemoji.parse(string, Object);\n *\n * HTMLElement tree parsing for safer operations over existing DOM\n *  twemoji.parse(HTMLElement);\n *  twemoji.parse(HTMLElement, Function);\n *  twemoji.parse(HTMLElement, Object);\n *\n * @param   what string|HTMLElement  the source to parse and enrich with emoji.\n *\n *          string              replace emoji matches with <img> tags.\n *                              Mainly used to inject emoji via `innerHTML`\n *                              It does **not** parse the string or validate it,\n *                              it simply replaces found emoji with a tag.\n *                              NOTE: be sure this won't affect security.\n *\n *          HTMLElement         walk through the DOM tree and find emoji\n *                              that are inside **text node only** (nodeType === 3)\n *                              Mainly used to put emoji in already generated DOM\n *                              without compromising surrounding nodes and\n *                              **avoiding** the usage of `innerHTML`.\n *                              NOTE: Using DOM elements instead of strings should\n *                              improve security without compromising too much\n *                              performance compared with a less safe `innerHTML`.\n *\n * @param   how object|Function\n *\n * @example\n *\n *  twemoji.parse(\"I \\u2764\\uFE0F emoji!\");\n *  // I <img class=\"emoji\" draggable=\"false\" alt=\"❤️\" src=\"/assets/2764.gif\"/> emoji!\n *\n *\n *  twemoji.parse(\"I \\u2764\\uFE0F emoji!\", function(iconId, options) {\n *    return '/assets/' + iconId + '.gif';\n *  });\n *  // I <img class=\"emoji\" draggable=\"false\" alt=\"❤️\" src=\"/assets/2764.gif\"/> emoji!\n *\n *\n * twemoji.parse(\"I \\u2764\\uFE0F emoji!\", {\n *   size: 72,\n *   callback: function(iconId, options) {\n *     return '/assets/' + options.size + '/' + iconId + options.ext;\n *   }\n * });\n *  // I <img class=\"emoji\" draggable=\"false\" alt=\"❤️\" src=\"/assets/72x72/2764.png\"/> emoji!\n */\nexport function parse<T extends string | HTMLElement>(what: T, how?: Partial<ParseObject> | ParseCallback): T;\n"
+}
diff --git a/src/_tests/fixtures/59628/_response.json b/src/_tests/fixtures/59628/_response.json
new file mode 100644
index 0000000..8afc7fa
--- /dev/null
+++ b/src/_tests/fixtures/59628/_response.json
@@ -0,0 +1,357 @@
+{
+  "data": {
+    "repository": {
+      "id": "MDEwOlJlcG9zaXRvcnk2MDkzMzE2",
+      "pullRequest": {
+        "id": "PR_kwDOAFz6BM41bNTc",
+        "title": ":tada: 'twemoji' no longer required",
+        "createdAt": "2022-03-31T19:26:36Z",
+        "author": {
+          "login": "peterblazejewicz",
+          "__typename": "User"
+        },
+        "authorAssociation": "MEMBER",
+        "baseRef": {
+          "name": "master",
+          "__typename": "Ref"
+        },
+        "labels": {
+          "nodes": [
+            {
+              "name": "Popular package",
+              "__typename": "Label"
+            },
+            {
+              "name": "Self Merge",
+              "__typename": "Label"
+            },
+            {
+              "name": "Owner Approved",
+              "__typename": "Label"
+            },
+            {
+              "name": "Edits Infrastructure",
+              "__typename": "Label"
+            },
+            {
+              "name": "Maintainer Approved",
+              "__typename": "Label"
+            }
+          ],
+          "__typename": "LabelConnection"
+        },
+        "isDraft": false,
+        "mergeable": "MERGEABLE",
+        "number": 59628,
+        "state": "OPEN",
+        "headRefOid": "15c10d80e670b01133ffe2d37c4ffe3d3c3f3941",
+        "changedFiles": 6,
+        "additions": 4,
+        "deletions": 313,
+        "commitIds": {
+          "nodes": [
+            {
+              "commit": {
+                "oid": "15c10d80e670b01133ffe2d37c4ffe3d3c3f3941",
+                "parents": {
+                  "nodes": [
+                    {
+                      "oid": "e11ae5d76bb7c11e606ed5aa0e47c1f1e81fd88d",
+                      "__typename": "Commit"
+                    }
+                  ],
+                  "__typename": "CommitConnection"
+                },
+                "__typename": "Commit"
+              },
+              "__typename": "PullRequestCommit"
+            }
+          ],
+          "__typename": "PullRequestCommitConnection"
+        },
+        "timelineItems": {
+          "nodes": [
+            {
+              "actor": {
+                "login": "typescript-bot",
+                "__typename": "User"
+              },
+              "createdAt": "2022-03-31T19:32:10Z",
+              "projectColumnName": "Needs Maintainer Action",
+              "__typename": "MovedColumnsInProjectEvent"
+            },
+            {
+              "actor": {
+                "login": "typescript-bot",
+                "__typename": "User"
+              },
+              "createdAt": "2022-03-31T22:12:55Z",
+              "projectColumnName": "Waiting for Author to Merge",
+              "__typename": "MovedColumnsInProjectEvent"
+            }
+          ],
+          "__typename": "PullRequestTimelineItemsConnection"
+        },
+        "reviews": {
+          "nodes": [
+            {
+              "author": {
+                "login": "davwheat",
+                "__typename": "User"
+              },
+              "commit": {
+                "oid": "15c10d80e670b01133ffe2d37c4ffe3d3c3f3941",
+                "__typename": "Commit"
+              },
+              "comments": {
+                "nodes": [],
+                "__typename": "PullRequestReviewCommentConnection"
+              },
+              "authorAssociation": "CONTRIBUTOR",
+              "state": "APPROVED",
+              "submittedAt": "2022-03-31T19:33:37Z",
+              "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59628#pullrequestreview-928083763",
+              "__typename": "PullRequestReview"
+            },
+            {
+              "author": {
+                "login": "andrewbranch",
+                "__typename": "User"
+              },
+              "commit": {
+                "oid": "15c10d80e670b01133ffe2d37c4ffe3d3c3f3941",
+                "__typename": "Commit"
+              },
+              "comments": {
+                "nodes": [],
+                "__typename": "PullRequestReviewCommentConnection"
+              },
+              "authorAssociation": "MEMBER",
+              "state": "APPROVED",
+              "submittedAt": "2022-03-31T22:12:17Z",
+              "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59628#pullrequestreview-928237599",
+              "__typename": "PullRequestReview"
+            }
+          ],
+          "__typename": "PullRequestReviewConnection"
+        },
+        "commits": {
+          "totalCount": 1,
+          "nodes": [
+            {
+              "commit": {
+                "checkSuites": {
+                  "nodes": [
+                    {
+                      "databaseId": 5883803312,
+                      "app": {
+                        "name": "GitHub Actions",
+                        "__typename": "App"
+                      },
+                      "conclusion": "SUCCESS",
+                      "resourcePath": "/DefinitelyTyped/DefinitelyTyped/commit/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941/checks?check_suite_id=5883803312",
+                      "status": "COMPLETED",
+                      "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/commit/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941/checks?check_suite_id=5883803312",
+                      "checkRuns": {
+                        "nodes": [
+                          {
+                            "title": null,
+                            "__typename": "CheckRun"
+                          }
+                        ],
+                        "__typename": "CheckRunConnection"
+                      },
+                      "__typename": "CheckSuite"
+                    },
+                    {
+                      "databaseId": 5883805587,
+                      "app": {
+                        "name": "Azure Pipelines",
+                        "__typename": "App"
+                      },
+                      "conclusion": "SUCCESS",
+                      "resourcePath": "/DefinitelyTyped/DefinitelyTyped/commit/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941/checks?check_suite_id=5883805587",
+                      "status": "COMPLETED",
+                      "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/commit/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941/checks?check_suite_id=5883805587",
+                      "checkRuns": {
+                        "nodes": [
+                          {
+                            "title": "Build #20220331.39 succeeded",
+                            "__typename": "CheckRun"
+                          }
+                        ],
+                        "__typename": "CheckRunConnection"
+                      },
+                      "__typename": "CheckSuite"
+                    }
+                  ],
+                  "__typename": "CheckSuiteConnection"
+                },
+                "status": null,
+                "authoredDate": "2022-03-31T19:23:51Z",
+                "committedDate": "2022-03-31T19:23:51Z",
+                "pushedDate": "2022-03-31T19:26:15Z",
+                "oid": "15c10d80e670b01133ffe2d37c4ffe3d3c3f3941",
+                "__typename": "Commit"
+              },
+              "__typename": "PullRequestCommit"
+            }
+          ],
+          "__typename": "PullRequestCommitConnection"
+        },
+        "comments": {
+          "totalCount": 5,
+          "nodes": [
+            {
+              "id": "IC_kwDOAFz6BM5ArAD6",
+              "author": {
+                "login": "typescript-bot",
+                "__typename": "User"
+              },
+              "databaseId": 1085014266,
+              "body": "@peterblazejewicz Thank you for submitting this PR!\n\n***This is a live comment which I will keep updated.***\n\nThis PR touches some part of DefinitelyTyped infrastructure, so a DT maintainer will need to review it. This is rare — did you mean to do this?\n\n## 1 package in this PR (and infra files)\n\n* `twemoji` (*probably deleted!*) — [on npm](https://www.npmjs.com/package/twemoji), [on unpkg](https://unpkg.com/browse/twemoji@latest/) (author is owner)\n  - owner-approval: @davwheat\n* Infra files\n  - [`notNeededPackages.json`](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59628/files/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941#diff-a275c2eae7b8f788a52327e76809026ee1bc5ea614393806c8f3cbab07202621)\n\n## Code Reviews\n\nThis PR can be merged once it's reviewed by a DT maintainer.\n\nYou can test the changes of this PR [in the Playground](https://www.typescriptlang.org/play/?dtPR=59628&install-plugin=playground-dt-review).\n\n## Status\n\n * ✅ No merge conflicts\n * ✅ Continuous integration tests have passed\n * ✅ A DT maintainer needs to approve changes which affect DT infrastructure ([`notNeededPackages.json`](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59628/files/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941#diff-a275c2eae7b8f788a52327e76809026ee1bc5ea614393806c8f3cbab07202621))\n\nAll of the items on the list are green. **To merge, you need to post a comment including the string \"Ready to merge\"** to bring in your changes.\n\n----------------------\n... diagnostics scrubbed ...\n<!--typescript_bot_welcome-->",
+              "createdAt": "2022-03-31T19:27:13Z",
+              "reactions": {
+                "nodes": [],
+                "__typename": "ReactionConnection"
+              },
+              "__typename": "IssueComment"
+            },
+            {
+              "id": "IC_kwDOAFz6BM5ArAEU",
+              "author": {
+                "login": "typescript-bot",
+                "__typename": "User"
+              },
+              "databaseId": 1085014292,
+              "body": "🔔 @coderbyheart @davwheat — please [review this PR](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59628/files) in the next few days. Be sure to explicitly select **`Approve`** or **`Request Changes`** in the GitHub UI so I know what's going on.\n<!--typescript_bot_pinging-reviewers-->",
+              "createdAt": "2022-03-31T19:27:16Z",
+              "reactions": {
+                "nodes": [],
+                "__typename": "ReactionConnection"
+              },
+              "__typename": "IssueComment"
+            },
+            {
+              "id": "IC_kwDOAFz6BM5AroSK",
+              "author": {
+                "login": "typescript-bot",
+                "__typename": "User"
+              },
+              "databaseId": 1085179018,
+              "body": "@peterblazejewicz: Everything looks good here. I am ready to merge this PR (at 15c10d8) on your behalf whenever you think it's ready.\n\nIf you'd like that to happen, please post a comment saying:\n\n> Ready to merge\n\nand I'll merge this PR almost instantly. Thanks for helping out! :heart:\n\n(@coderbyheart, @davwheat: you can do this too.)\n<!--typescript_bot_merge-offer-->",
+              "createdAt": "2022-03-31T22:12:56Z",
+              "reactions": {
+                "nodes": [],
+                "__typename": "ReactionConnection"
+              },
+              "__typename": "IssueComment"
+            },
+            {
+              "id": "IC_kwDOAFz6BM5ArpCN",
+              "author": {
+                "login": "davwheat",
+                "__typename": "User"
+              },
+              "databaseId": 1085182093,
+              "body": "Ready to merge",
+              "createdAt": "2022-03-31T22:17:03Z",
+              "reactions": {
+                "nodes": [],
+                "__typename": "ReactionConnection"
+              },
+              "__typename": "IssueComment"
+            },
+            {
+              "id": "IC_kwDOAFz6BM5ArxKw",
+              "author": {
+                "login": "andrewbranch",
+                "__typename": "User"
+              },
+              "databaseId": 1085215408,
+              "body": "@typescript-bot 🤨",
+              "createdAt": "2022-03-31T23:05:00Z",
+              "reactions": {
+                "nodes": [],
+                "__typename": "ReactionConnection"
+              },
+              "__typename": "IssueComment"
+            }
+          ],
+          "__typename": "IssueCommentConnection"
+        },
+        "files": {
+          "totalCount": 6,
+          "nodes": [
+            {
+              "path": "notNeededPackages.json",
+              "additions": 4,
+              "deletions": 0,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/twemoji/index.d.ts",
+              "additions": 0,
+              "deletions": 229,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/twemoji/test/twemoji-tests.common-js.ts",
+              "additions": 0,
+              "deletions": 30,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/twemoji/test/twemoji-tests.global.ts",
+              "additions": 0,
+              "deletions": 28,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/twemoji/tsconfig.json",
+              "additions": 0,
+              "deletions": 25,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/twemoji/tslint.json",
+              "additions": 0,
+              "deletions": 1,
+              "__typename": "PullRequestChangedFile"
+            }
+          ],
+          "pageInfo": {
+            "hasNextPage": false,
+            "endCursor": "Ng",
+            "__typename": "PageInfo"
+          },
+          "__typename": "PullRequestChangedFileConnection"
+        },
+        "projectCards": {
+          "nodes": [
+            {
+              "id": "PRC_lALOAFz6BM4AORWwzgTEe7s",
+              "project": {
+                "id": "MDc6UHJvamVjdDM3NDExMDQ=",
+                "number": 5,
+                "name": "New Pull Request Status Board",
+                "__typename": "Project"
+              },
+              "column": {
+                "id": "MDEzOlByb2plY3RDb2x1bW43NTUyOTIz",
+                "name": "Waiting for Author to Merge",
+                "__typename": "ProjectColumn"
+              },
+              "__typename": "ProjectCard"
+            }
+          ],
+          "__typename": "ProjectCardConnection"
+        },
+        "__typename": "PullRequest"
+      },
+      "__typename": "Repository"
+    }
+  },
+  "loading": false,
+  "networkStatus": 7
+}
diff --git a/src/_tests/fixtures/59628/derived.json b/src/_tests/fixtures/59628/derived.json
new file mode 100644
index 0000000..ecca257
--- /dev/null
+++ b/src/_tests/fixtures/59628/derived.json
@@ -0,0 +1,84 @@
+{
+  "type": "info",
+  "now": "2022-03-31T23:12:03.301Z",
+  "pr_number": 59628,
+  "author": "peterblazejewicz",
+  "headCommitOid": "15c10d80e670b01133ffe2d37c4ffe3d3c3f3941",
+  "mergeBaseOid": "e11ae5d76bb7c11e606ed5aa0e47c1f1e81fd88d",
+  "lastPushDate": "2022-03-31T19:26:15.000Z",
+  "lastActivityDate": "2022-03-31T23:05:00.000Z",
+  "mergeOfferDate": "2022-03-31T22:12:56.000Z",
+  "mergeRequestDate": "2022-03-31T22:17:03.000Z",
+  "mergeRequestUser": "davwheat",
+  "hasMergeConflict": false,
+  "isFirstContribution": false,
+  "tooManyFiles": false,
+  "hugeChange": false,
+  "popularityLevel": "Popular",
+  "pkgInfo": [
+    {
+      "name": null,
+      "kind": "edit",
+      "files": [
+        {
+          "path": "notNeededPackages.json",
+          "kind": "infrastructure"
+        }
+      ],
+      "owners": [],
+      "addedOwners": [],
+      "deletedOwners": [],
+      "popularityLevel": "Critical"
+    },
+    {
+      "name": "twemoji",
+      "kind": "delete",
+      "files": [
+        {
+          "path": "types/twemoji/index.d.ts",
+          "kind": "definition"
+        },
+        {
+          "path": "types/twemoji/test/twemoji-tests.common-js.ts",
+          "kind": "test"
+        },
+        {
+          "path": "types/twemoji/test/twemoji-tests.global.ts",
+          "kind": "test"
+        },
+        {
+          "path": "types/twemoji/tsconfig.json",
+          "kind": "package-meta-ok"
+        },
+        {
+          "path": "types/twemoji/tslint.json",
+          "kind": "package-meta-ok"
+        }
+      ],
+      "owners": [
+        "coderbyheart",
+        "peterblazejewicz",
+        "davwheat"
+      ],
+      "addedOwners": [],
+      "deletedOwners": [],
+      "popularityLevel": "Popular"
+    }
+  ],
+  "reviews": [
+    {
+      "type": "approved",
+      "reviewer": "andrewbranch",
+      "date": "2022-03-31T22:12:17.000Z",
+      "isMaintainer": true
+    },
+    {
+      "type": "approved",
+      "reviewer": "davwheat",
+      "date": "2022-03-31T19:33:37.000Z",
+      "isMaintainer": false
+    }
+  ],
+  "mainBotCommentID": 1085014266,
+  "ciResult": "pass"
+}
diff --git a/src/_tests/fixtures/59628/mutations.json b/src/_tests/fixtures/59628/mutations.json
new file mode 100644
index 0000000..7ac50c9
--- /dev/null
+++ b/src/_tests/fixtures/59628/mutations.json
@@ -0,0 +1,31 @@
+[
+  {
+    "mutation": "mutation ($input: UpdateIssueCommentInput!) {\n  updateIssueComment(input: $input) {\n    __typename\n  }\n}\n",
+    "variables": {
+      "input": {
+        "id": "IC_kwDOAFz6BM5ArAD6",
+        "body": "@peterblazejewicz Thank you for submitting this PR!\n\n***This is a live comment which I will keep updated.***\n\nThis PR touches some part of DefinitelyTyped infrastructure, so a DT maintainer will need to review it. This is rare — did you mean to do this?\n\n## 1 package in this PR (and infra files)\n\n* `twemoji` (*probably deleted!*) — [on npm](https://www.npmjs.com/package/twemoji), [on unpkg](https://unpkg.com/browse/twemoji@latest/) (author is owner)\n  - owner-approval: @davwheat\n* Infra files\n  - [`notNeededPackages.json`](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59628/files/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941#diff-a275c2eae7b8f788a52327e76809026ee1bc5ea614393806c8f3cbab07202621)\n\n## Code Reviews\n\nThis PR can be merged once it's reviewed by a DT maintainer.\n\nYou can test the changes of this PR [in the Playground](https://www.typescriptlang.org/play/?dtPR=59628&install-plugin=playground-dt-review).\n\n## Status\n\n * ✅ No merge conflicts\n * ✅ Continuous integration tests have passed\n * ✅ A DT maintainer needs to approve changes which affect DT infrastructure ([`notNeededPackages.json`](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59628/files/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941#diff-a275c2eae7b8f788a52327e76809026ee1bc5ea614393806c8f3cbab07202621))\n\nAll of the items on the list are green. **To merge, you need to post a comment including the string \"Ready to merge\"** to bring in your changes.\n\n----------------------\n... diagnostics scrubbed ...\n<!--typescript_bot_welcome-->"
+      }
+    }
+  },
+  {
+    "mutation": "mutation ($input: MoveProjectCardInput!) {\n  moveProjectCard(input: $input) {\n    __typename\n  }\n}\n",
+    "variables": {
+      "input": {
+        "cardId": "PRC_lALOAFz6BM4AORWwzgTEe7s",
+        "columnId": "MDEzOlByb2plY3RDb2x1bW43NTUyOTI1"
+      }
+    }
+  },
+  {
+    "mutation": "mutation ($input: MergePullRequestInput!) {\n  mergePullRequest(input: $input) {\n    __typename\n  }\n}\n",
+    "variables": {
+      "input": {
+        "commitHeadline": "🤖 Merge PR #59628 :tada: 'twemoji' no longer required by @peterblazejewicz",
+        "expectedHeadOid": "15c10d80e670b01133ffe2d37c4ffe3d3c3f3941",
+        "mergeMethod": "SQUASH",
+        "pullRequestId": "PR_kwDOAFz6BM41bNTc"
+      }
+    }
+  }
+]
diff --git a/src/_tests/fixtures/59628/result.json b/src/_tests/fixtures/59628/result.json
new file mode 100644
index 0000000..0afd218
--- /dev/null
+++ b/src/_tests/fixtures/59628/result.json
@@ -0,0 +1,23 @@
+{
+  "projectColumn": "Recently Merged",
+  "labels": [
+    "Popular package",
+    "Owner Approved",
+    "Maintainer Approved",
+    "Edits Infrastructure",
+    "Self Merge"
+  ],
+  "responseComments": [
+    {
+      "tag": "welcome",
+      "status": "@peterblazejewicz Thank you for submitting this PR!\n\n***This is a live comment which I will keep updated.***\n\nThis PR touches some part of DefinitelyTyped infrastructure, so a DT maintainer will need to review it. This is rare — did you mean to do this?\n\n## 1 package in this PR (and infra files)\n\n* `twemoji` (*probably deleted!*) — [on npm](https://www.npmjs.com/package/twemoji), [on unpkg](https://unpkg.com/browse/twemoji@latest/) (author is owner)\n  - owner-approval: @davwheat\n* Infra files\n  - [`notNeededPackages.json`](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59628/files/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941#diff-a275c2eae7b8f788a52327e76809026ee1bc5ea614393806c8f3cbab07202621)\n\n## Code Reviews\n\nThis PR can be merged once it's reviewed by a DT maintainer.\n\nYou can test the changes of this PR [in the Playground](https://www.typescriptlang.org/play/?dtPR=59628&install-plugin=playground-dt-review).\n\n## Status\n\n * ✅ No merge conflicts\n * ✅ Continuous integration tests have passed\n * ✅ A DT maintainer needs to approve changes which affect DT infrastructure ([`notNeededPackages.json`](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59628/files/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941#diff-a275c2eae7b8f788a52327e76809026ee1bc5ea614393806c8f3cbab07202621))\n\nAll of the items on the list are green. **To merge, you need to post a comment including the string \"Ready to merge\"** to bring in your changes.\n\n----------------------\n... diagnostics scrubbed ..."
+    },
+    {
+      "tag": "merge-offer",
+      "status": "@peterblazejewicz: Everything looks good here. I am ready to merge this PR (at 15c10d8) on your behalf whenever you think it's ready.\n\nIf you'd like that to happen, please post a comment saying:\n\n> Ready to merge\n\nand I'll merge this PR almost instantly. Thanks for helping out! :heart:\n\n(@coderbyheart, @davwheat: you can do this too.)"
+    }
+  ],
+  "shouldClose": false,
+  "shouldMerge": true,
+  "shouldUpdateLabels": true
+}