feature(github) add from bower

This commit is contained in:
coderaiser 2015-06-04 06:46:02 -04:00
parent 1bcd27db77
commit 9902e13c11
12 changed files with 1089 additions and 1787 deletions

View file

@ -26,6 +26,7 @@
"menu": "~0.7.8",
"promise-polyfill": "~2.0.0",
"format-io": "~0.9.6",
"rendy": "~1.1.0"
"rendy": "~1.1.0",
"github": "~0.10.6"
}
}

View file

@ -25,10 +25,9 @@ var CloudCmd, Util, join, DOM, CloudFunc, Github, cb;
}
function load(callback) {
var dir = CloudCmd.LIBDIRCLIENT + 'storage/github/',
var dir = '/modules/github/',
url = CloudCmd.join([
dir + 'lib/underscore.js',
dir + 'lib/base64.js',
dir + 'lib/underscore-min.js',
dir + 'github.js'
]);

View file

@ -1,499 +0,0 @@
// Github.js 0.7.0
// (c) 2012 Michael Aufreiter, Development Seed
// Github.js is freely distributable under the MIT license.
// For all details and documentation:
// http://substance.io/michael/github
(function() {
var Github;
var API_URL = 'https://api.github.com';
Github = window.Github = function(options) {
// HTTP Request Abstraction
// =======
//
// I'm not proud of this and neither should you be if you were responsible for the XMLHttpRequest spec.
function _request(method, path, data, cb, raw) {
function getURL() {
var url = API_URL + path;
return url + ((/\?/).test(url) ? "&" : "?") + (new Date()).getTime();
}
var xhr = new XMLHttpRequest();
if (!raw) {xhr.dataType = "json";}
xhr.open(method, getURL());
xhr.onreadystatechange = function () {
if (this.readyState == 4) {
if (this.status >= 200 && this.status < 300 || this.status === 304) {
cb(null, raw ? this.responseText : this.responseText ? JSON.parse(this.responseText) : true);
} else {
cb({request: this, error: this.status});
}
}
};
xhr.setRequestHeader('Accept','application/vnd.github.raw');
xhr.setRequestHeader('Content-Type','application/json');
if (
(options.auth == 'oauth' && options.token) ||
(options.auth == 'basic' && options.username && options.password)
) {
xhr.setRequestHeader('Authorization',options.auth == 'oauth'
? 'token '+ options.token
: 'Basic ' + Base64.encode(options.username + ':' + options.password)
);
}
data ? xhr.send(JSON.stringify(data)) : xhr.send();
}
// User API
// =======
Github.User = function() {
this.repos = function(cb) {
_request("GET", "/user/repos?type=all&per_page=1000&sort=updated", null, function(err, res) {
cb(err, res);
});
};
// List user organizations
// -------
this.orgs = function(cb) {
_request("GET", "/user/orgs", null, function(err, res) {
cb(err, res);
});
};
// List authenticated user's gists
// -------
this.gists = function(cb) {
_request("GET", "/gists", null, function(err, res) {
cb(err,res);
});
};
// Show user information
// -------
this.show = function(username, cb) {
var command = username ? "/users/"+username : "/user";
_request("GET", command, null, function(err, res) {
cb(err, res);
});
};
// List user repositories
// -------
this.userRepos = function(username, cb) {
_request("GET", "/users/"+username+"/repos?type=all&per_page=1000&sort=updated", null, function(err, res) {
cb(err, res);
});
};
// List a user's gists
// -------
this.userGists = function(username, cb) {
_request("GET", "/users/"+username+"/gists", null, function(err, res) {
cb(err,res);
});
};
// List organization repositories
// -------
this.orgRepos = function(orgname, cb) {
_request("GET", "/orgs/"+orgname+"/repos?type=all&per_page=1000&sort=updated&direction=desc", null, function(err, res) {
cb(err, res);
});
};
// Follow user
// -------
this.follow = function(username, cb) {
_request("PUT", "/user/following/"+username, null, function(err, res) {
cb(err, res);
});
};
// Unfollow user
// -------
this.unfollow = function(username, cb) {
_request("DELETE", "/user/following/"+username, null, function(err, res) {
cb(err, res);
});
};
};
// Repository API
// =======
Github.Repository = function(options) {
var repo = options.name;
var user = options.user;
var that = this;
var repoPath = "/repos/" + user + "/" + repo;
var currentTree = {
"branch": null,
"sha": null
};
// Uses the cache if branch has not been changed
// -------
function updateTree(branch, cb) {
if (branch === currentTree.branch && currentTree.sha) return cb(null, currentTree.sha);
that.getRef("heads/"+branch, function(err, sha) {
currentTree.branch = branch;
currentTree.sha = sha;
cb(err, sha);
});
}
// Get a particular reference
// -------
this.getRef = function(ref, cb) {
_request("GET", repoPath + "/git/refs/" + ref, null, function(err, res) {
if (err) return cb(err);
cb(null, res.object.sha);
});
};
// Create a new reference
// --------
//
// {
// "ref": "refs/heads/my-new-branch-name",
// "sha": "827efc6d56897b048c772eb4087f854f46256132"
// }
this.createRef = function(options, cb) {
_request("POST", repoPath + "/git/refs", options, cb);
};
// Delete a reference
// --------
//
// repo.deleteRef('heads/gh-pages')
// repo.deleteRef('tags/v1.0')
this.deleteRef = function(ref, cb) {
_request("DELETE", repoPath + "/git/refs/"+ref, options, cb);
};
// List all branches of a repository
// -------
this.listBranches = function(cb) {
_request("GET", repoPath + "/git/refs/heads", null, function(err, heads) {
if (err) return cb(err);
cb(null, _.map(heads, function(head) { return _.last(head.ref.split('/')); }));
});
};
// Retrieve the contents of a blob
// -------
this.getBlob = function(sha, cb) {
_request("GET", repoPath + "/git/blobs/" + sha, null, cb, 'raw');
};
// For a given file path, get the corresponding sha (blob for files, tree for dirs)
// -------
this.getSha = function(branch, path, cb) {
// Just use head if path is empty
if (path === "") return that.getRef("heads/"+branch, cb);
that.getTree(branch+"?recursive=true", function(err, tree) {
var file = _.select(tree, function(file) {
return file.path === path;
})[0];
cb(null, file ? file.sha : null);
});
};
// Retrieve the tree a commit points to
// -------
this.getTree = function(tree, cb) {
_request("GET", repoPath + "/git/trees/"+tree, null, function(err, res) {
if (err) return cb(err);
cb(null, res.tree);
});
};
// Post a new blob object, getting a blob SHA back
// -------
this.postBlob = function(content, cb) {
if (typeof(content) === "string") {
content = {
"content": content,
"encoding": "utf-8"
};
}
_request("POST", repoPath + "/git/blobs", content, function(err, res) {
if (err) return cb(err);
cb(null, res.sha);
});
};
// Update an existing tree adding a new blob object getting a tree SHA back
// -------
this.updateTree = function(baseTree, path, blob, cb) {
var data = {
"base_tree": baseTree,
"tree": [
{
"path": path,
"mode": "100644",
"type": "blob",
"sha": blob
}
]
};
_request("POST", repoPath + "/git/trees", data, function(err, res) {
if (err) return cb(err);
cb(null, res.sha);
});
};
// Post a new tree object having a file path pointer replaced
// with a new blob SHA getting a tree SHA back
// -------
this.postTree = function(tree, cb) {
_request("POST", repoPath + "/git/trees", { "tree": tree }, function(err, res) {
if (err) return cb(err);
cb(null, res.sha);
});
};
// Create a new commit object with the current commit SHA as the parent
// and the new tree SHA, getting a commit SHA back
// -------
this.commit = function(parent, tree, message, cb) {
var data = {
"message": message,
"author": {
"name": options.username
},
"parents": [
parent
],
"tree": tree
};
_request("POST", repoPath + "/git/commits", data, function(err, res) {
currentTree.sha = res.sha; // update latest commit
if (err) return cb(err);
cb(null, res.sha);
});
};
// Update the reference of your head to point to the new commit SHA
// -------
this.updateHead = function(head, commit, cb) {
_request("PATCH", repoPath + "/git/refs/heads/" + head, { "sha": commit }, function(err, res) {
cb(err);
});
};
// Show repository information
// -------
this.show = function(cb) {
_request("GET", repoPath, null, cb);
};
// Get contents
// --------
this.contents = function(path, cb) {
_request("GET", repoPath + "/contents", { path: path }, cb);
};
// Fork repository
// -------
this.fork = function(cb) {
_request("POST", repoPath + "/forks", null, cb);
};
// Create pull request
// --------
this.createPullRequest = function(options, cb) {
_request("POST", repoPath + "/pulls", options, cb);
};
// Read file at given path
// -------
this.read = function(branch, path, cb) {
that.getSha(branch, path, function(err, sha) {
if (!sha) return cb("not found", null);
that.getBlob(sha, function(err, content) {
cb(err, content, sha);
});
});
};
// Remove a file from the tree
// -------
this.remove = function(branch, path, cb) {
updateTree(branch, function(err, latestCommit) {
that.getTree(latestCommit+"?recursive=true", function(err, tree) {
// Update Tree
var newTree = _.reject(tree, function(ref) { return ref.path === path; });
_.each(newTree, function(ref) {
if (ref.type === "tree") delete ref.sha;
});
that.postTree(newTree, function(err, rootTree) {
that.commit(latestCommit, rootTree, 'Deleted '+path , function(err, commit) {
that.updateHead(branch, commit, function(err) {
cb(err);
});
});
});
});
});
};
// Move a file to a new location
// -------
this.move = function(branch, path, newPath, cb) {
updateTree(branch, function(err, latestCommit) {
that.getTree(latestCommit+"?recursive=true", function(err, tree) {
// Update Tree
_.each(tree, function(ref) {
if (ref.path === path) ref.path = newPath;
if (ref.type === "tree") delete ref.sha;
});
that.postTree(tree, function(err, rootTree) {
that.commit(latestCommit, rootTree, 'Deleted '+path , function(err, commit) {
that.updateHead(branch, commit, function(err) {
cb(err);
});
});
});
});
});
};
// Write file contents to a given branch and path
// -------
this.write = function(branch, path, content, message, cb) {
updateTree(branch, function(err, latestCommit) {
if (err) return cb(err);
that.postBlob(content, function(err, blob) {
if (err) return cb(err);
that.updateTree(latestCommit, path, blob, function(err, tree) {
if (err) return cb(err);
that.commit(latestCommit, tree, message, function(err, commit) {
if (err) return cb(err);
that.updateHead(branch, commit, cb);
});
});
});
});
};
};
// Gists API
// =======
Github.Gist = function(options) {
var id = options.id;
var gistPath = "/gists/"+id;
// Read the gist
// --------
this.read = function(cb) {
_request("GET", gistPath, null, function(err, gist) {
cb(err, gist);
});
};
// Create the gist
// --------
// {
// "description": "the description for this gist",
// "public": true,
// "files": {
// "file1.txt": {
// "content": "String file contents"
// }
// }
// }
this.create = function(options, cb){
_request("POST", "/gists", options, cb);
};
// Delete the gist
// --------
this.delete = function(cb) {
_request("DELETE", gistPath, null, function(err,res) {
cb(err,res);
});
};
// Fork a gist
// --------
this.fork = function(cb) {
_request("POST", gistPath+"/fork", null, function(err,res) {
cb(err,res);
});
};
// Update a gist with the new stuff
// --------
this.update = function(options, cb) {
_request("PATCH", gistPath, options, function(err,res) {
cb(err,res);
});
};
};
// Top Level API
// -------
this.getRepo = function(user, repo) {
return new Github.Repository({user: user, name: repo});
};
this.getUser = function() {
return new Github.User();
};
this.getGist = function(id) {
return new Github.Gist({id: id});
};
};
}).call(this);

View file

@ -1,80 +0,0 @@
// This code was written by Tyler Akins and has been placed in the
// public domain. It would be nice if you left this header intact.
// Base64 code from Tyler Akins -- http://rumkin.com
var Base64 = (function () {
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var obj = {
/**
* Encodes a string in base64
* @param {String} input The string to encode in base64.
*/
encode: function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
do {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) +
keyStr.charAt(enc3) + keyStr.charAt(enc4);
} while (i < input.length);
return output;
},
/**
* Decodes a base64 string.
* @param {String} input The string to decode.
*/
decode: function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
do {
enc1 = keyStr.indexOf(input.charAt(i++));
enc2 = keyStr.indexOf(input.charAt(i++));
enc3 = keyStr.indexOf(input.charAt(i++));
enc4 = keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
} while (i < input.length);
return output;
}
};
return obj;
})();

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,35 @@
{
"name": "github-api",
"main": "github.js",
"version": "0.10.6",
"homepage": "https://github.com/michael/github",
"authors": [
"Sergey Klimov <sergey.v.klimov@gmail.com> (http://darvin.github.com/)"
],
"description": "Github.js provides a minimal higher-level wrapper around git's plumbing commands, exposing an API for manipulating GitHub repositories on the file level. It is being developed in the context of Prose, a content editor for GitHub.",
"moduleType": [
"globals"
],
"keywords": [
"github",
"oauth"
],
"license": "BSD",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"_release": "0.10.6",
"_resolution": {
"type": "version",
"tag": "v0.10.6",
"commit": "c2696ec3971c6a3cc2ec9194f84d870818aea305"
},
"_source": "git://github.com/michael/github.git",
"_target": "~0.10.6",
"_originalSource": "github",
"_direct": true
}

View file

@ -1,7 +1,19 @@
# Github.js
[![Stories in Ready](https://badge.waffle.io/michael/github.png?label=ready&title=Ready)](https://waffle.io/michael/github)[![Build Status](https://travis-ci.org/darvin/github.svg?branch=master)](https://travis-ci.org/darvin/github)[![Coverage Status](https://img.shields.io/coveralls/michael/github.svg)](https://coveralls.io/r/michael/github)
Github.js provides a minimal higher-level wrapper around git's [plumbing commands](http://git-scm.com/book/en/Git-Internals-Plumbing-and-Porcelain), exposing an API for manipulating GitHub repositories on the file level. It is being developed in the context of [Prose](http://prose.io), a content editor for GitHub.
This repo is now officially maintained by [DevelopmentSeed](https://github.com/developmentseed), the people behind [Prose.io](http://prose.io).
## Installation
Either grab `github.js` from this repo or install via NPM:
```
npm install github-api
```
## Usage
Create a Github instance.
@ -18,11 +30,30 @@ Or if you prefer OAuth, it looks like this:
```js
var github = new Github({
token: "OAUTH_TOKEN"
token: "OAUTH_TOKEN",
auth: "oauth"
});
```
You can use either:
* Authorised App Tokens (via client/secret pairs), used for bigger applications, created in web-flows/on the fly
* Personal Access Tokens (simpler to set up), used on command lines, scripts etc, created in GitHub web UI
See these pages for more info:
[Creating an access token for command-line use](https://help.github.com/articles/creating-an-access-token-for-command-line-use)
[Github API OAuth Overview] (http://developer.github.com/v3/oauth)
Enterprise Github instances may be specified using the `apiUrl` option:
```js
var github = new Github({
apiUrl: "https://serverName/api/v3",
...
});
```
## Repository API
@ -36,10 +67,16 @@ Show repository information
repo.show(function(err, repo) {});
```
Get contents at a particular path.
Delete a repository
```js
repo.contents("path/to/dir", function(err, contents) {});
repo.deleteRepo(function(err, res) {});
```
Get contents at a particular path in a particular branch.
```js
repo.contents(branch, "path/to/dir", function(err, contents) {});
```
Fork repository. This operation runs asynchronously. You may want to poll for `repo.contents` until the forked repo is ready.
@ -48,6 +85,12 @@ Fork repository. This operation runs asynchronously. You may want to poll for `r
repo.fork(function(err) {});
```
Create new branch for repo. You can omit oldBranchName to default to "master".
```js
repo.branch(oldBranchName, newBranchName, function(err) {});
```
Create Pull Request.
```js
@ -55,7 +98,7 @@ var pull = {
title: message,
body: "This pull request has been automatically generated by Prose.io.",
base: "gh-pages",
head: "michael" + ":" + "prose-patch",
head: "michael" + ":" + "prose-patch"
};
repo.createPullRequest(pull, function(err, pullRequest) {});
```
@ -93,6 +136,12 @@ repo.remove('master', 'path/to/file', function(err) {});
Exploring files of a repository is easy too by accessing the top level tree object.
```js
repo.getCommit('master', sha, function(err, commit) {});
```
Get information about a particular commit.
```js
repo.getTree('master', function(err, tree) {});
```
@ -131,6 +180,11 @@ Delete a reference.
repo.deleteRef('heads/gh-pages', function(err) {});
```
Get contributors list with additions, deletions, and commit counts.
```js
repo.contributors(function(err, data) {});
```
## User API
@ -139,10 +193,10 @@ repo.deleteRef('heads/gh-pages', function(err) {});
var user = github.getUser();
```
List all repositories of the authenticated user.
List all repositories of the authenticated user, including private repositories and repositories in which the user is a collaborator and not an owner.
```js
user.repos(username, function(err, repos) {});
user.repos(function(err, repos) {});
```
List organizations the autenticated user belongs to.
@ -154,7 +208,13 @@ user.orgs(function(err, orgs) {});
List authenticated user's gists.
```js
user.gists(username, function(err, gists) {});
user.gists(function(err, gists) {});
```
List unread notifications for the authenticated user.
```js
user.notifications(function(err, notifications) {});
```
Show user information for a particular username. Also works for organizations.
@ -169,6 +229,15 @@ List public repositories for a particular user.
user.userRepos(username, function(err, repos) {});
```
Create a new repo for the authenticated user
```js
user.createRepo({"name": "test"}, function(err, res) {});
```
Repo description, homepage, private/public can also be set.
For a full list of options see the docs [here](https://developer.github.com/v3/repos/#create)
List repositories for a particular organization. Includes private repositories if you are authorized.
```js
@ -195,7 +264,7 @@ gist.read(function(err, gist) {
});
```
Updating the contents of a Git. Please consult the documentation on [GitHub](http://developer.github.com/v3/gists/).
Updating the contents of a Gist. Please consult the documentation on [GitHub](http://developer.github.com/v3/gists/).
```js
var delta = {
@ -216,32 +285,58 @@ var delta = {
};
gist.update(delta, function(err, gist) {
});
```
## Issues API
```js
var issues = github.getIssues(username, reponame);
```
## Tests
To read all the issues of a given repository
Github.js is automatically™ tested by the users of [Prose](http://prose.io). Because of that, we decided to save some time by not maintaining a test suite. Yes, you heard right. :) However, you can still consider it stable since it is used in production.
```js
issues.list(options, function(err, issues) {});
```
##Setup
Github.js has the following dependencies:
- Underscore
- Base64 (for basic auth). You can leave this if you are not using basic auth.
- btoa (included in modern browsers, an npm module is included in package.json for node)
Include these before github.js :
```
<script src="lib/underscore-min.js">
<script src="lib/base64.js">
<script src="github.js">
```
## Compatibility
[![browser support](https://ci.testling.com/darvin/github.png)](https://ci.testling.com/darvin/github)
## Change Log
### 0.10.X
Create and delete repositories
Repos - getCommit
### 0.9.X
Paging (introduced at tail end of 0.8.X, note: different callbacks for success & errors now)
### 0.8.X
Fixes and tweaks, simpler auth, CI tests, node.js support, Raw+JSON, UTF8, plus:
Users - follow, unfollow, get info, notifications
Gists - create
Issues - get
Repos - createRepo, deleteRepo, createBranch, star, unstar, isStarred, getCommits, listTags, listPulls, getPull, compare
Hooks - listHooks, getHook, createHook, editHook, deleteHook
### 0.7.X
@ -253,7 +348,7 @@ Adds support for organizations and fixes an encoding issue.
### 0.5.X
Smart caching of latest commit sha.
Smart caching of latest commit sha.
### 0.4.X
@ -269,4 +364,4 @@ Consider commit messages.
### 0.1.X
Initial version.
Initial version.

25
modules/github/bower.json Normal file
View file

@ -0,0 +1,25 @@
{
"name": "github-api",
"main": "github.js",
"version": "0.10.6",
"homepage": "https://github.com/michael/github",
"authors": [
"Sergey Klimov <sergey.v.klimov@gmail.com> (http://darvin.github.com/)"
],
"description": "Github.js provides a minimal higher-level wrapper around git's plumbing commands, exposing an API for manipulating GitHub repositories on the file level. It is being developed in the context of Prose, a content editor for GitHub.",
"moduleType": [
"globals"
],
"keywords": [
"github",
"oauth"
],
"license": "BSD",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}

851
modules/github/github.js Normal file
View file

@ -0,0 +1,851 @@
/*!
* @overview Github.js
*
* @copyright (c) 2013 Michael Aufreiter, Development Seed
* Github.js is freely distributable.
*
* @license Licensed under MIT license
*
* For all details and documentation:
* http://substance.io/michael/github
*/
(function() {
'use strict';
// Initial Setup
// -------------
var XMLHttpRequest, _;
/* istanbul ignore else */
if (typeof exports !== 'undefined') {
XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
_ = require('underscore');
if (typeof btoa === 'undefined') {
var btoa = require('btoa'); //jshint ignore:line
}
} else {
_ = window._;
}
//prefer native XMLHttpRequest always
/* istanbul ignore if */
if (typeof window !== 'undefined' && typeof window.XMLHttpRequest !== 'undefined'){
XMLHttpRequest = window.XMLHttpRequest;
}
var Github = function(options) {
var API_URL = options.apiUrl || 'https://api.github.com';
// HTTP Request Abstraction
// =======
//
// I'm not proud of this and neither should you be if you were responsible for the XMLHttpRequest spec.
function _request(method, path, data, cb, raw, sync) {
function getURL() {
var url = path.indexOf('//') >= 0 ? path : API_URL + path;
return url + ((/\?/).test(url) ? '&' : '?') + (new Date()).getTime();
}
var xhr = new XMLHttpRequest();
xhr.open(method, getURL(), !sync);
if (!sync) {
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
if (this.status >= 200 && this.status < 300 || this.status === 304) {
cb(null, raw ? this.responseText : this.responseText ? JSON.parse(this.responseText) : true, this);
} else {
cb({path: path, request: this, error: this.status});
}
}
};
}
if (!raw) {
xhr.dataType = 'json';
xhr.setRequestHeader('Accept','application/vnd.github.v3+json');
} else {
xhr.setRequestHeader('Accept','application/vnd.github.v3.raw+json');
}
xhr.setRequestHeader('Content-Type','application/json;charset=UTF-8');
if ((options.token) || (options.username && options.password)) {
var authorization = options.token ? 'token ' + options.token : 'Basic ' + btoa(options.username + ':' + options.password);
xhr.setRequestHeader('Authorization', authorization);
}
if (data) {
xhr.send(JSON.stringify(data));
} else {
xhr.send();
}
if (sync) {
return xhr.response;
}
}
function _requestAllPages(path, cb) {
var results = [];
(function iterate() {
_request('GET', path, null, function(err, res, xhr) {
if (err) {
return cb(err);
}
results.push.apply(results, res);
var links = (xhr.getResponseHeader('link') || '').split(/\s*,\s*/g),
next = _.find(links, function(link) { return /rel="next"/.test(link); });
if (next) {
next = (/<(.*)>/.exec(next) || [])[1];
}
if (!next) {
cb(err, results);
} else {
path = next;
iterate();
}
});
})();
}
// User API
// =======
Github.User = function() {
this.repos = function(cb) {
// Github does not always honor the 1000 limit so we want to iterate over the data set.
_requestAllPages('/user/repos?type=all&per_page=1000&sort=updated', function(err, res) {
cb(err, res);
});
};
// List user organizations
// -------
this.orgs = function(cb) {
_request("GET", '/user/orgs', null, function(err, res) {
cb(err, res);
});
};
// List authenticated user's gists
// -------
this.gists = function(cb) {
_request("GET", '/gists', null, function(err, res) {
cb(err,res);
});
};
// List authenticated user's unread notifications
// -------
this.notifications = function(cb) {
_request("GET", '/notifications', null, function(err, res) {
cb(err,res);
});
};
// Show user information
// -------
this.show = function(username, cb) {
var command = username ? '/users/' + username : '/user';
_request('GET', command, null, function(err, res) {
cb(err, res);
});
};
// List user repositories
// -------
this.userRepos = function(username, cb) {
// Github does not always honor the 1000 limit so we want to iterate over the data set.
_requestAllPages('/users/' + username + '/repos?type=all&per_page=1000&sort=updated', function(err, res) {
cb(err, res);
});
};
// List a user's gists
// -------
this.userGists = function(username, cb) {
_request('GET', '/users/' + username + '/gists', null, function(err, res) {
cb(err,res);
});
};
// List organization repositories
// -------
this.orgRepos = function(orgname, cb) {
// Github does not always honor the 1000 limit so we want to iterate over the data set.
_requestAllPages('/orgs/' + orgname + '/repos?type=all&&page_num=1000&sort=updated&direction=desc', function(err, res) {
cb(err, res);
});
};
// Follow user
// -------
this.follow = function(username, cb) {
_request('PUT', '/user/following/' + username, null, function(err, res) {
cb(err, res);
});
};
// Unfollow user
// -------
this.unfollow = function(username, cb) {
_request('DELETE', '/user/following/' + username, null, function(err, res) {
cb(err, res);
});
};
// Create a repo
// -------
this.createRepo = function(options, cb) {
_request('POST', '/user/repos', options, cb);
};
};
// Repository API
// =======
Github.Repository = function(options) {
var repo = options.name;
var user = options.user;
var that = this;
var repoPath = '/repos/' + user + '/' + repo;
var currentTree = {
'branch': null,
'sha': null
};
// Delete a repo
// --------
this.deleteRepo = function(cb) {
_request('DELETE', repoPath, options, cb);
};
// Uses the cache if branch has not been changed
// -------
function updateTree(branch, cb) {
if (branch === currentTree.branch && currentTree.sha) {
return cb(null, currentTree.sha);
}
that.getRef('heads/' + branch, function(err, sha) {
currentTree.branch = branch;
currentTree.sha = sha;
cb(err, sha);
});
}
// Get a particular reference
// -------
this.getRef = function(ref, cb) {
_request('GET', repoPath + '/git/refs/' + ref, null, function(err, res) {
if (err) {
return cb(err);
}
cb(null, res.object.sha);
});
};
// Create a new reference
// --------
//
// {
// "ref": "refs/heads/my-new-branch-name",
// "sha": "827efc6d56897b048c772eb4087f854f46256132"
// }
this.createRef = function(options, cb) {
_request('POST', repoPath + '/git/refs', options, cb);
};
// Delete a reference
// --------
//
// repo.deleteRef('heads/gh-pages')
// repo.deleteRef('tags/v1.0')
this.deleteRef = function(ref, cb) {
_request('DELETE', repoPath + '/git/refs/' + ref, options, cb);
};
// Create a repo
// -------
this.createRepo = function(options, cb) {
_request('POST', '/user/repos', options, cb);
};
// Delete a repo
// --------
this.deleteRepo = function(cb) {
_request('DELETE', repoPath, options, cb);
};
// List all tags of a repository
// -------
this.listTags = function(cb) {
_request('GET', repoPath + '/tags', null, function(err, tags) {
if (err) {
return cb(err);
}
cb(null, tags);
});
};
// List all pull requests of a respository
// -------
this.listPulls = function(state, cb) {
_request('GET', repoPath + "/pulls" + (state ? '?state=' + state : ''), null, function(err, pulls) {
if (err) return cb(err);
cb(null, pulls);
});
};
// Gets details for a specific pull request
// -------
this.getPull = function(number, cb) {
_request("GET", repoPath + "/pulls/" + number, null, function(err, pull) {
if (err) return cb(err);
cb(null, pull);
});
};
// Retrieve the changes made between base and head
// -------
this.compare = function(base, head, cb) {
_request("GET", repoPath + "/compare/" + base + "..." + head, null, function(err, diff) {
if (err) return cb(err);
cb(null, diff);
});
};
// List all branches of a repository
// -------
this.listBranches = function(cb) {
_request("GET", repoPath + "/git/refs/heads", null, function(err, heads) {
if (err) return cb(err);
cb(null, _.map(heads, function(head) { return _.last(head.ref.split('/')); }));
});
};
// Retrieve the contents of a blob
// -------
this.getBlob = function(sha, cb) {
_request("GET", repoPath + "/git/blobs/" + sha, null, cb, 'raw');
};
// For a given file path, get the corresponding sha (blob for files, tree for dirs)
// -------
this.getCommit = function(branch, sha, cb) {
_request("GET", repoPath + "/git/commits/"+sha, null, function(err, commit) {
if (err) return cb(err);
cb(null, commit);
});
};
// For a given file path, get the corresponding sha (blob for files, tree for dirs)
// -------
this.getSha = function(branch, path, cb) {
if (!path || path === "") return that.getRef("heads/"+branch, cb);
_request("GET", repoPath + "/contents/"+path, {ref: branch}, function(err, pathContent) {
if (err) return cb(err);
cb(null, pathContent.sha);
});
};
// Retrieve the tree a commit points to
// -------
this.getTree = function(tree, cb) {
_request("GET", repoPath + "/git/trees/"+tree, null, function(err, res) {
if (err) return cb(err);
cb(null, res.tree);
});
};
// Post a new blob object, getting a blob SHA back
// -------
this.postBlob = function(content, cb) {
if (typeof(content) === "string") {
content = {
"content": content,
"encoding": "utf-8"
};
} else {
content = {
"content": btoa(String.fromCharCode.apply(null, new Uint8Array(content))),
"encoding": "base64"
};
}
_request("POST", repoPath + "/git/blobs", content, function(err, res) {
if (err) return cb(err);
cb(null, res.sha);
});
};
// Update an existing tree adding a new blob object getting a tree SHA back
// -------
this.updateTree = function(baseTree, path, blob, cb) {
var data = {
"base_tree": baseTree,
"tree": [
{
"path": path,
"mode": "100644",
"type": "blob",
"sha": blob
}
]
};
_request("POST", repoPath + "/git/trees", data, function(err, res) {
if (err) return cb(err);
cb(null, res.sha);
});
};
// Post a new tree object having a file path pointer replaced
// with a new blob SHA getting a tree SHA back
// -------
this.postTree = function(tree, cb) {
_request("POST", repoPath + "/git/trees", { "tree": tree }, function(err, res) {
if (err) return cb(err);
cb(null, res.sha);
});
};
// Create a new commit object with the current commit SHA as the parent
// and the new tree SHA, getting a commit SHA back
// -------
this.commit = function(parent, tree, message, cb) {
var user = new Github.User();
user.show(null, function(err, userData){
if (err) return cb(err);
var data = {
"message": message,
"author": {
"name": options.user,
"email": userData.email
},
"parents": [
parent
],
"tree": tree
};
_request("POST", repoPath + "/git/commits", data, function(err, res) {
if (err) return cb(err);
currentTree.sha = res.sha; // update latest commit
cb(null, res.sha);
});
});
};
// Update the reference of your head to point to the new commit SHA
// -------
this.updateHead = function(head, commit, cb) {
_request("PATCH", repoPath + "/git/refs/heads/" + head, { "sha": commit }, function(err) {
cb(err);
});
};
// Show repository information
// -------
this.show = function(cb) {
_request("GET", repoPath, null, cb);
};
// Show repository contributors
// -------
this.contributors = function (cb, retry) {
retry = retry || 1000;
var self = this;
_request("GET", repoPath + "/stats/contributors", null, function (err, data, response) {
if (err) return cb(err);
if (response.status === 202) {
setTimeout(
function () {
self.contributors(cb, retry);
},
retry
);
} else {
cb(err, data);
}
});
};
// Get contents
// --------
this.contents = function(ref, path, cb) {
_request("GET", repoPath + "/contents" + (path ? "/" + path : ""), { ref: ref }, cb);
};
// Fork repository
// -------
this.fork = function(cb) {
_request("POST", repoPath + "/forks", null, cb);
};
// Branch repository
// --------
this.branch = function(oldBranch,newBranch,cb) {
if(arguments.length === 2 && typeof arguments[1] === "function") {
cb = newBranch;
newBranch = oldBranch;
oldBranch = "master";
}
this.getRef("heads/" + oldBranch, function(err,ref) {
if(err && cb) return cb(err);
that.createRef({
ref: "refs/heads/" + newBranch,
sha: ref
},cb);
});
};
// Create pull request
// --------
this.createPullRequest = function(options, cb) {
_request("POST", repoPath + "/pulls", options, cb);
};
// List hooks
// --------
this.listHooks = function(cb) {
_request("GET", repoPath + "/hooks", null, cb);
};
// Get a hook
// --------
this.getHook = function(id, cb) {
_request("GET", repoPath + "/hooks/" + id, null, cb);
};
// Create a hook
// --------
this.createHook = function(options, cb) {
_request("POST", repoPath + "/hooks", options, cb);
};
// Edit a hook
// --------
this.editHook = function(id, options, cb) {
_request("PATCH", repoPath + "/hooks/" + id, options, cb);
};
// Delete a hook
// --------
this.deleteHook = function(id, cb) {
_request("DELETE", repoPath + "/hooks/" + id, null, cb);
};
// Read file at given path
// -------
this.read = function(branch, path, cb) {
_request("GET", repoPath + "/contents/"+path, {ref: branch}, function(err, obj) {
if (err && err.error === 404) return cb("not found", null, null);
if (err) return cb(err);
cb(null, obj);
}, true);
};
// Remove a file
// -------
this.remove = function(branch, path, cb) {
that.getSha(branch, path, function(err, sha) {
if (err) return cb(err);
_request("DELETE", repoPath + "/contents/" + path, {
message: path + " is removed",
sha: sha,
branch: branch
}, cb);
});
};
// Delete a file from the tree
// -------
this.delete = function(branch, path, cb) {
that.getSha(branch, path, function(err, sha) {
if (!sha) return cb("not found", null);
var delPath = repoPath + "/contents/" + path;
var params = {
"message": "Deleted " + path,
"sha": sha
};
delPath += "?message=" + encodeURIComponent(params.message);
delPath += "&sha=" + encodeURIComponent(params.sha);
delPath += '&branch=' + encodeURIComponent(branch);
_request("DELETE", delPath, null, cb);
});
};
// Move a file to a new location
// -------
this.move = function(branch, path, newPath, cb) {
updateTree(branch, function(err, latestCommit) {
that.getTree(latestCommit+"?recursive=true", function(err, tree) {
// Update Tree
_.each(tree, function(ref) {
if (ref.path === path) ref.path = newPath;
if (ref.type === "tree") delete ref.sha;
});
that.postTree(tree, function(err, rootTree) {
that.commit(latestCommit, rootTree, 'Deleted '+path , function(err, commit) {
that.updateHead(branch, commit, function(err) {
cb(err);
});
});
});
});
});
};
// Write file contents to a given branch and path
// -------
this.write = function(branch, path, content, message, cb) {
that.getSha(branch, path, function(err, sha) {
if (err && err.error !== 404) return cb(err);
_request("PUT", repoPath + "/contents/" + path, {
message: message,
content: btoa(content),
branch: branch,
sha: sha
}, cb);
});
};
// List commits on a repository. Takes an object of optional paramaters:
// sha: SHA or branch to start listing commits from
// path: Only commits containing this file path will be returned
// since: ISO 8601 date - only commits after this date will be returned
// until: ISO 8601 date - only commits before this date will be returned
// -------
this.getCommits = function(options, cb) {
options = options || {};
var url = repoPath + "/commits";
var params = [];
if (options.sha) {
params.push("sha=" + encodeURIComponent(options.sha));
}
if (options.path) {
params.push("path=" + encodeURIComponent(options.path));
}
if (options.since) {
var since = options.since;
if (since.constructor === Date) {
since = since.toISOString();
}
params.push("since=" + encodeURIComponent(since));
}
if (options.until) {
var until = options.until;
if (until.constructor === Date) {
until = until.toISOString();
}
params.push("until=" + encodeURIComponent(until));
}
if (options.page) {
params.push("page=" + options.page);
}
if (options.perpage) {
params.push("per_page=" + options.perpage);
}
if (params.length > 0) {
url += "?" + params.join("&");
}
_request("GET", url, null, cb);
};
};
// Gists API
// =======
Github.Gist = function(options) {
var id = options.id;
var gistPath = "/gists/"+id;
// Read the gist
// --------
this.read = function(cb) {
_request("GET", gistPath, null, function(err, gist) {
cb(err, gist);
});
};
// Create the gist
// --------
// {
// "description": "the description for this gist",
// "public": true,
// "files": {
// "file1.txt": {
// "content": "String file contents"
// }
// }
// }
this.create = function(options, cb){
_request("POST","/gists", options, cb);
};
// Delete the gist
// --------
this.delete = function(cb) {
_request("DELETE", gistPath, null, function(err,res) {
cb(err,res);
});
};
// Fork a gist
// --------
this.fork = function(cb) {
_request("POST", gistPath+"/fork", null, function(err,res) {
cb(err,res);
});
};
// Update a gist with the new stuff
// --------
this.update = function(options, cb) {
_request("PATCH", gistPath, options, function(err,res) {
cb(err,res);
});
};
// Star a gist
// --------
this.star = function(cb) {
_request("PUT", gistPath+"/star", null, function(err,res) {
cb(err,res);
});
};
// Untar a gist
// --------
this.unstar = function(cb) {
_request("DELETE", gistPath+"/star", null, function(err,res) {
cb(err,res);
});
};
// Check if a gist is starred
// --------
this.isStarred = function(cb) {
_request("GET", gistPath+"/star", null, function(err,res) {
cb(err,res);
});
};
};
// Issues API
// ==========
Github.Issue = function(options) {
var path = "/repos/" + options.user + "/" + options.repo + "/issues";
this.list = function(options, cb) {
var query = [];
for (var key in options) {
if (options.hasOwnProperty(key)) {
query.push(encodeURIComponent(key) + "=" + encodeURIComponent(options[key]));
}
}
_requestAllPages(path + '?' + query.join("&"), cb);
};
};
// Top Level API
// -------
this.getIssues = function(user, repo) {
return new Github.Issue({user: user, repo: repo});
};
this.getRepo = function(user, repo) {
return new Github.Repository({user: user, name: repo});
};
this.getUser = function() {
return new Github.User();
};
this.getGist = function(id) {
return new Github.Gist({id: id});
};
};
/* istanbul ignore else */
if (typeof exports !== 'undefined') {
module.exports = Github;
} else {
window.Github = Github;
}
}).call(this);

5
modules/github/lib/underscore-min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,59 @@
{
"name": "github-api",
"version": "0.10.6",
"description": "A higher-level wrapper around the Github API.",
"main": "github.js",
"dependencies": {
"atob": "^1.1.2",
"btoa": "^1.1.2",
"underscore": "~1.6.0",
"xmlhttprequest": "~1.6.0"
},
"devDependencies": {
"argg": "0.0.1",
"istanbul": "^0.3.13",
"jshint": "^2.5.8",
"plato": "^1.4.0",
"tape": "^3.0.3",
"testling": "^1.7.1"
},
"scripts": {
"test": "node node_modules/argg test/*.js && node node_modules/jshint/bin/jshint github.js test/*.js",
"jshint": "node node_modules/jshint/bin/jshint github.js test/*.js"
},
"repository": {
"type": "git",
"url": "git://github.com/michael/github.git"
},
"keywords": [
"github",
"api"
],
"contributors": [
"Sergey Klimov <sergey.v.klimov@gmail.com> (http://darvin.github.com/)",
"Michael Aufreiter (http://substance.io)",
"Ændrew Rininsland <aendrew.rininsland@thetimes.co.uk> (http://www.aendrew.com)"
],
"license": "BSD",
"readmeFilename": "README.md",
"gitHead": "aa8aa3c8cd5ce5240373d4fd1d06a7ab4af41a36",
"bugs": {
"url": "https://github.com/michael/github/issues"
},
"browser": {
"xmlhttprequest": false
},
"testling": {
"files": "test/test.*.js",
"browsers": [
"iexplore/9.0..latest",
"chrome/18.0..latest",
"firefox/15.0..latest",
"opera/11.0..latest",
"safari/5.0.5..latest",
"iphone/6.0..latest",
"ipad/6.0..latest",
"android-browser/4.2..latest"
]
}
}