get github issues by their ids through graphql endpoints - github

I am trying to get the list of issues by their ids from Github using graphql, but looks like I am missing something or its not possible.
query ($ids:['517','510']!) {
repository(owner:"owner", name:"repo") {
issues(last:20, states:CLOSED) {
edges {
node {
title
url
body
author{
login
}
labels(first:5) {
edges {
node {
name
}
}
}
}
}
}
}
}
The above query is giving me response as below,
{
"errors": [
{
"message": "Parse error on \"'\" (error) at [1, 14]",
"locations": [
{
"line": 1,
"column": 14
}
]
}
]
}
Kindly help me identify if its possible or that I am doing something wrong here.

You can use aliases in order to build a single request requesting multiple issue object :
{
repository(name: "material-ui", owner: "mui-org") {
issue1: issue(number: 2) {
title
createdAt
}
issue2: issue(number: 3) {
title
createdAt
}
issue3: issue(number: 10) {
title
createdAt
}
}
}
Try it in the explorer
which gives :
{
"data": {
"repository": {
"issue1": {
"title": "Support for ref's on Input component",
"createdAt": "2014-10-15T15:49:13Z"
},
"issue2": {
"title": "Unable to pass onChange event to Input component",
"createdAt": "2014-10-15T16:23:28Z"
},
"issue3": {
"title": "Is it possible for me to make this work if I'm using React version 0.12.0?",
"createdAt": "2014-10-30T14:11:59Z"
}
}
}
}
This request can also be simplified using fragments to prevent repetition:
{
repository(name: "material-ui", owner: "mui-org") {
issue1: issue(number: 2) {
...IssueFragment
}
issue2: issue(number: 3) {
...IssueFragment
}
issue3: issue(number: 10) {
...IssueFragment
}
}
}
fragment IssueFragment on Issue {
title
createdAt
}
The request can be built programmatically, such as in this example python script :
import requests
token = "YOUR_TOKEN"
issueIds = [2,3,10]
repoName = "material-ui"
repoOwner = "mui-org"
query = """
query($name: String!, $owner: String!) {
repository(name: $name, owner: $owner) {
%s
}
}
fragment IssueFragment on Issue {
title
createdAt
}
"""
issueFragments = "".join([
"""
issue%d: issue(number: %d) {
...IssueFragment
}""" % (t,t) for t in issueIds
])
r = requests.post("https://api.github.com/graphql",
headers = {
"Authorization": f"Bearer {token}"
},
json = {
"query": query % issueFragments,
"variables": {
"name": repoName,
"owner": repoOwner
}
}
)
print(r.json()["data"]["repository"])

I don't think you can fetch for issues and pass in an array of integers for their ids.
But you can search for a single issue by id like so (this works for me)
query ($n: Int!) {
repository(owner:"owner", name:"repo-name") {
issue (number: $n) {
state
title
author {
url
}
}
}
}
where $n is {"n": <your_number>} defined.
If you have an array of ids, then you can just make multiple queries to GitHub.
Sadly, with this approach, you cannot specify what the state of the issue to be. But I think the logic is that once you know the issue Id, you shouldn't care what state it is, since you have that exact id.

Related

How to get dependencyGraphManifests of a particular branch only using github graphql

I'm trying to get dependencyGraphManifests of a particular branch only, such as the default branch, I'm not really sure if this is even possible.
Here is my full query:
query orgRepos {
organization(login: "octokit") {
id
repositories(
first: 2
orderBy: {field: CREATED_AT, direction: ASC}
) {
edges {
node {
defaultBranchRef {
name
repository {
url
name
dependencyGraphManifests(withDependencies: true) {
totalCount
edges {
node {
blobPath
dependencies {
nodes {
packageName
requirements
}
}
}
}
}
}
}
}
}
}
}
}
But the response returns every manifest file.
Here is a simplified response:
"node": {
"defaultBranchRef": {
"name": "main",
"repository": {
"url": "https://github.com/octokit/octokit.js",
"name": "octokit.js",
"dependencyGraphManifests": {
"totalCount": 7,
"edges": [
{
"node": {
"blobPath": "/octokit/octokit.js/blob/main/package-lock.json"
}
},
{
"node": {
"blobPath": "/octokit/octokit.js/blob/main/package.json"
}
},
{
"node": {
"blobPath": "/octokit/octokit.js/blob/main/docs/package.json"
}
},
{
"node": {
"blobPath": "/octokit/octokit.js/blob/main/.github/workflows/release.yml"
}
},
{
"node": {
"blobPath": "/octokit/octokit.js/blob/main/.github/workflows/test.yml"
}
},
{
"node": {
"blobPath": "/octokit/octokit.js/blob/main/.github/workflows/update-prettier.yml"
}
}
]
}
}
}
}
It also worth noting that some of the blobpaths return invalid paths, such as /octokit/octokit.js/blob/main/docs/package.json, which doesn't actually exists on the default branch(its on a different branch). Is this a bug?

Hasura permissions to fetch data depending on users block status

I've got these tables:
Table blocked_users
id (pk) | initiator_id (fk) | target_id (fk)
1 | a | b
Table post
id (pk) | author_profile (fk)
1 | a
2 | b
3 | c
4 | d
I'm trying to get my head around the proper select permissions, I've tried many combinations and I cannot get the desired result -> Get the posts and exclude the users that either I have blocked or they have blocked me.
This is one of the many permissions I've tried:
blocked_by_me is blocked_users.initiator_id → author_profile.id
been_blocked_by is blocked_users.target_id → author_profile.id
{
"_and": [
{ "deleted_at": { "_is_null": true } },
{ "author_profile": { "deleted_at": { "_is_null": true } } },
{
"_and": [
{
"author_profile": {
"been_blocked_by": {
"initiator_id": {
"_eq": "X-Hasura-User-Id"
}
}
}
},
{
"author_profile": {
"blocked_by_me": {
"initiator_id": {
"_eq": "X-Hasura-User-Id"
}
}
}
}
]
}
]
}
And one of the many queries I tried: (with no permissions on post)
query GetPosts(
$created_at: order_by = desc
$limit: Int! = 12
$offset: Int! = 0
) {
post(
limit: $limit
offset: $offset
order_by: { created_at: $created_at }
where: {
_not: {
author_profile: {
_or: [
{
been_blocked_by: { initiator_id: { _eq: "a" } }
blocked_by_me: { target_id: { _neq: "b" } }
}
]
}
}
_and: {
deleted_at: { _is_null: true }
author_profile: { deleted_at: { _is_null: true } }
}
}
) {
author_profile {
id
first_name
}
}
}
With the query above, if a user has made a post and that user's id does not exist on blocked_users then the post of that user won't be returned by the query, in other words, the query returns only the posts of the users that have at least one record on blocked_users (not blocked by me or that user have not blocked me).
Get the posts and exclude the users that either I have blocked or they have blocked me.
You want your select permission exclude the posts from users who either blocked you or are blocked by you. Using the same array relationships that you have, we can write a permission for post like:
{
"_not": {
"_or": [
{
"author_profile": {
"been_blocked_by": { "initiator_id": { "_eq": "X-Hasura-User-Id" } }
}
},
{
"author_profile": {
"blocked_by_me": { "target_id": { "_eq": "X-Hasura-User-Id" } }
}
}
]
}
}
We are basically telling Hasura to only show the posts that are _not by authors who have been_blocked_by us _or by authors who blocked us.

How to return the a formatted response from a mongo query/projection?

I'm trying to create an API to validate a promocode. I have minimal experience with mongo and the backend in general so I'm a bit confused in what is the best approach to do what I'm trying to accomplish.
I have this PromoCode form in the client. When a user types a promocode I would like for my backend to
verify if the code exists in one of the docs.
if it exists then return that code, the value for that code and the couponId
if the code doesn't exist then return an error.
My db is structured like this. The user will type one of those codes inside the codes: []
{
"_id": {
"$oid": "603f7a3b52e0233dd23bef79"
},
"couponId": "rate50",
"value": 50,
"codes": ["K3D01XJ50", "2PACYFN50", "COKRHEQ50"]
},
{
"_id": {
"$oid": "603f799d52e0233dd23bef78"
},
"couponId": "rate100",
"value": 100,
"codes": ["rdJ2ZMF100", "GKAAYLP100", "B9QZILN100"]
}
My route is structure like this:
router.post('/promoCode', (req, res, next) => {
const { promoCode } = req.body;
console.log('this is the req.body.promoCode on /promoCode', promoCode)
if (!promoCode) {
throw new Error('A promoCode needs to be passed')
}
promoCodesModel
.validatePromoCode(req.body.promoCode)
.then((response) => {
console.log('response inside /promoCode', response)
res.status(200).json({ data: response })
})
.catch((error) => {
res.status(400).json({ result: 'nok', error: error })
})
})
The validatePromoCode function is the following:
const validatePromoCode = async (code) => {
try {
let promoCode = await PromoCodesModel.find(
{"codes": code},
{_id: 0, codes: { $elemMatch: { $eq: code }} })
console.log('This is the promocode', promoCode)
return promoCode
} catch (err) {
throw new Error (err.stack)
}
}
All this seems to sort of work since I get the following response when the code is typed correctly
{
"data": [
{
"codes": [
"COKRHEQ50"
]
}
]
}
when typed incorrectly I get
{
"data": []
}
What I would like to get back is. (How can I accomplish this ?). Thanks
// when typed correctly
{
"data": { value: 50, couponId: "rate50", code: "COKRHEQ50" }
}
// when typed incorrectly
{
"error": "this is not valid code"
}
TL;DR: I would like to return a formatted query with specific values from a mongo query or an error object if that value does not exist on the document object.
Ok just figured it out
To be able to get the this responsed (what I wanted):
{
"data": [
{
"codes": [
"K3D01XJ50"
],
"couponId": "rate50",
"value": 50
}
]
}
I ended up having to do this on validatePromoCode
onst validatePromoCode = async (code) => {
try {
let promoCode = await PromoCodesModel.find(
{ codes: code },
{ _id: 0, codes: { $elemMatch: { $eq: code } }, couponId: 1, value: 1 },
)
return promoCode
} catch (err) {
throw new Error(err.stack)
}
}
But is there a better way on doing this ? Thanks

Github API - How to know if an issue was closed by a fork pull request?

How can I know given an closed issue, if it was closed through a pull request, specifically through a fork pull request, and how can I get the Id of the fork?
I've been reading in the issues/pull request/events API docs but haven't found anything.
It's possible using GraphQL API v4 using timelineItems and filtering on event with state CLOSED_EVENT
{
repository(name: "material-ui", owner: "mui-org") {
issue(number: 19641) {
timelineItems(itemTypes: CLOSED_EVENT, last: 1) {
nodes {
... on ClosedEvent {
createdAt
closer {
...on PullRequest {
baseRefName
baseRepository {
nameWithOwner
}
headRefName
headRepository {
nameWithOwner
}
}
}
}
}
}
}
}
}
Try it in the explorer
The closer field contains the source of the closing :
via pull request: PullRequest
via commit messages: Commit
or via the closed button: null
The following requests are example for the 3 types of closing
Closing via pull request
This pull request closed this issue
{
repository(name: "material-ui", owner: "mui-org") {
issue(number: 19641) {
timelineItems(itemTypes: CLOSED_EVENT, last: 1) {
nodes {
... on ClosedEvent {
createdAt
closer {
__typename
}
}
}
}
}
}
}
Output
{
"data": {
"repository": {
"issue": {
"timelineItems": {
"nodes": [
{
"createdAt": "2020-05-20T09:06:11Z",
"closer": {
"__typename": "PullRequest"
}
}
]
}
}
}
}
}
Closing via commit message
This commit closed this issue
{
repository(name: "rubinius", owner: "rubinius") {
issue(number: 1536) {
timelineItems(itemTypes: CLOSED_EVENT, last: 1) {
nodes {
... on ClosedEvent {
createdAt
closer {
__typename
}
}
}
}
}
}
}
Output
{
"data": {
"repository": {
"issue": {
"timelineItems": {
"nodes": [
{
"createdAt": "2012-01-30T22:33:11Z",
"closer": {
"__typename": "Commit"
}
}
]
}
}
}
}
}
Closing via button
This issue was closed via the close button :
{
repository(name: "rubinius", owner: "rubinius") {
issue(number: 3830) {
timelineItems(itemTypes: CLOSED_EVENT, last: 1) {
nodes {
... on ClosedEvent {
createdAt
closer {
__typename
}
}
}
}
}
}
}
Output
{
"data": {
"repository": {
"issue": {
"timelineItems": {
"nodes": [
{
"createdAt": "2020-02-02T22:31:05Z",
"closer": null
}
]
}
}
}
}
}

GitHub Graphql : Getting sponsor tier information for the sponsors of a user

I am using the GitHub graphql for getting the sponsor information of a user. While I am able to get the sponsors for a particular user, I am unable to get the sponsorship-tier information for the sponsors. The graphql query that I have written is as follows:
{
user(login: <<loginID>>) {
name
sponsorshipsAsMaintainer(first: 1) {
totalCount
nodes {
createdAt
privacyLevel
tier {
createdAt
name
description
}
sponsor {
login
}
}
}
}
}
The results i get for a user are as follows. Ideally, in the query I was hoping to get the tier information but the result returns a null for the tier field.
{
"data": {
"user": {
"name": "XXX",
"sponsorshipsAsMaintainer": {
"totalCount": 11,
"nodes": [
{
"createdAt": "2020-02-16T10:39:14Z",
"privacyLevel": "PUBLIC",
"tier": null,
"sponsor": {
"login": "XXX"
}
}
]
}
}
}
}
Any help or information to get the tier information for a sponsor would be appreciated. Thank you very much.
To date tier is still null and I haven't figured out what's the issue with that.
However I managed to fetch the tiers information using the following query:
query getTiers($login: String!) {
user(login: $login) {
sponsorshipsAsSponsor(first: 1) {
nodes {
sponsorable {
sponsorsListing {
tiers(first: 5) {
nodes {
id
}
}
}
}
}
}
}
}
I'm using the following query to look up sponsors, and I only get tier information for my own tiers. I assume the viewer's databaseId must match the sponsorable databaseId to see this information
query {
user(login: "${login}") {
sponsorshipsAsSponsor(first: 100) {
nodes {
privacyLevel
tier {
monthlyPriceInDollars
}
sponsorable {
... on User {
databaseId
}
... on Organization {
databaseId
}
}
}
}
}
}
Here is a user that is sponsoring three other projects besides mine (I replaced the other project's databaseIds)
{
"data": {
"user": {
"sponsorshipsAsSponsor": {
"nodes": [
{
"privacyLevel": "PUBLIC",
"tier": {
"monthlyPriceInDollars": 3
},
"sponsorable": {
"databaseId": 220908 <--- Me
}
},
{
"privacyLevel": "PUBLIC",
"tier": null,
"sponsorable": {
"databaseId": 1
}
},
{
"privacyLevel": "PUBLIC",
"tier": null,
"sponsorable": {
"databaseId": 1
}
},
{
"privacyLevel": "PUBLIC",
"tier": null,
"sponsorable": {
"databaseId": 1
}
}
]
}
}
}
}