github-project

JavaScript SDK for GitHub's new Projects

Usage no npm install needed!

<script type="module">
  import githubProject from 'https://cdn.skypack.dev/github-project';
</script>

README

github-project

JavaScript SDK for GitHub's new Projects

Test

Features

  • Use the new Projects as a database of issues and pull requests with custom fields.
  • Simple interaction with item fields and content (issue/pull request) properties.
  • Look up items by issue/pull request node IDs.
  • 100% test coverage and type definitions.

Usage

Browsers Load github-project directly from cdn.skypack.dev
<script type="module">
import GitHubProject from "https://cdn.skypack.dev/github-project";
</script>
Node

Install with npm install github-project

import GitHubProject from "github-project";

A project always belongs to an organization and has a number. For authentication you can pass a personal access token with the write:org scope. For read-only access the read:org scope is sufficient.

fields is map of internal field names to the project's column labels.

const project = new GitHubProject({
  org: "my-org",
  number: 1,
  token: "ghp_s3cR3t",
  fields: {
    priority: "Priority",
    dueAt: "Due",
  },
});

// log out all items
const items = await project.items.list();
for (const item of items) {
  // every item has a `.fields` property for the custome fields
  // and an `.content` property which is set unless the item is a draft
  console.log(
    "%s is due on %s (Priority: %d, Assignees: %j)",
    item.fields.title,
    item.fields.dueAt,
    item.fields.priority,
    item.isDraft
      ? "_draft_"
      : item.content.assignees.map(({ login }) => login).join(",")
  );
}

// add a new item using an existing issue
// You would usually retriev the issue node ID from an event payload, such as `event.issue.node_id`
const newItem = await project.items.add(issue.node_id, { priority: 1 });

// retrieve a single item using the issue node ID (passing item node ID as string works, too)
const item = await project.items.get({ contentId: issue.node_id });

// item is undefined when not found
if (item) {
  // update an item
  const updatedItem = await project.items.update(item.id, { priority: 2 });

  // remove item
  await project.items.remove(item.id);
}

API

Constructor

const project = new GitHubProject(options);
name type description
options.org string

Required. The account name of the GitHub organization.

options.number Number

Required. Project number as you see it in the URL of the project.

options.token String

Required unless options.octokit is set. When set to a personal access token or an OAuth token, the read:org scope is required for read-only access, and the write:org scope is required for read-write access. When set to an installation access token, the organization_projects:read permission is required for read-only access, and the organization_projects:write permission is required for read-write access.

options.octokit Octokit

Required unless options.token is set. You can pass an @octokit/core instance, or an instance of any Octokit class that is built upon it, such as octokit.

options.fields Object

A map of internal names for fields to the column names. By default, the colum names for all custom fields are used for both keys and values. The title key will always be set to "Title" and status to "Status" to account for the built-in fields. The other built-in columns Assignees, Labels, Milestone, and Repository cannot be set through the project and are not considered fields. You have to set them on the issue or pull request, and you can access them by item.content.assignees, item.content.labels etc (for both issues and pull requests).

project.items.list()

const items = await project.items.list();

Returns the first 100 items of the project.

project.items.add()

const newItem = await project.items.add(contentId /*, fields*/);

Adds a new item to the project, sets the fields if any were passed, and returns the new item. If the item already exists then it's a no-op, the existing item is still updated with the passed fields if any were passed.

Note: GitHub has currently no API to add a draft issue to a project.

name type description
contentId string

Required. The graphql node ID of the issue or pull request you want to add.

fields object

Map of internal field names to their values.

project.items.get()

const item = await project.items.get(itemNodeId);

Retrieve a single item based on its issue or pull request node ID. Resolves with undefined if item cannot be found.

name type description
itemNodeId string

Required. The graphql node ID of the project item

project.items.getByContentId()

const item = await project.items.getByContentId(contentId);

Retrieve a single item based on its issue or pull request node ID. Resolves with undefined if item cannot be found.

name type description
contentId string

Required. The graphql node ID of the issue/pull request the item is linked to.

project.items.getByContentRepositoryAndNumber()

const item = await project.items.getByContentRepositoryAndNumber(
  repositoryName,
  issueOrPullRequestNumber
);

Retrieve a single item based on its issue or pull request node ID. Resolves with undefined if item cannot be found.

name type description
repositoryName string

Required. The repository name, without the owner/.

issueOrPullRequestNumber number

Required. The number of the issue or pull request.

project.items.update()

const updatedItem = await project.items.update(itemNodeId, fields);

Update an exist item. To unset a field, set it to null. Returns undefined if item cannot be found.

name type description
itemNodeId string

Required. The graphql node ID of the project item

fields object

Map of internal field names to their values.

project.items.updateByContentId()

const updatedItem = await project.items.updateByContentId(contentId, fields);

Update an exist item based on the node ID of its linked issue or pull request. To unset a field, set it to null. Returns undefined if item cannot be found.

name type description
contentId string

Required. The graphql node ID of the issue/pull request the item is linked to.

fields object

Map of internal field names to their values.

project.items.updateByContentRepositoryAndNumber()

const updatedItem = await project.items.updateByContentRepositoryAndNumber(
  repositoryName,
  issueOrPullRequestNumber
  fields
);

Update an exist item based on the node ID of its linked issue or pull request. To unset a field, set it to null. Returns undefined if item cannot be found.

name type description
repositoryName string

Required. The repository name, without the owner/.

issueOrPullRequestNumber number

Required. The number of the issue or pull request.

fields object

Map of internal field names to their values.

project.items.remove()

await project.items.remove(itemNodeId);

Removes a single item. Resolves with undefined, no matter if item was found or not.

name type description
itemNodeId string

Required. The graphql node ID of the project item

project.items.removeByContentId()

await project.items.removeByContentId(contentId);

Removes a single item based on the Node ID of its linked issue or pull request. Resolves with undefined, no matter if item was found or not.

name type description
contentId string

Required. The graphql node ID of the issue/pull request the item is linked to.

project.items.removeByContentRepositoryAndNumber()

await project.items.removeByContentRepositoryAndNumber(
  repositoryName,
  issueOrPullRequestNumber
);

Removes a single item based on the Node ID of its linked issue or pull request. Resolves with undefined, no matter if item was found or not.

name type description
repositoryName string

Required. The repository name, without the owner/.

issueOrPullRequestNumber number

Required. The number of the issue or pull request.

License

ISC