-
-
Notifications
You must be signed in to change notification settings - Fork 8
/
index.js
176 lines (156 loc) · 4.44 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/*!
* github-content <https://github.com/doowb/github-content>
*
* Copyright (c) 2015-2017, Brian Woodward.
* Released under the MIT License.
*/
'use strict';
var GithubBase = require('github-base');
var extend = require('extend-shallow');
var each = require('each-parallel-async');
/**
* Create an instance of GithubContent to setup downloading of files.
*
* ```js
* var options = {
* owner: 'doowb',
* repo: 'github-content',
* branch: 'master' // defaults to master
* };
*
* var gc = new GithubContent(options);
* ```
* @param {Object} `options` Options to set on instance. Additional options passed to [github-base]
* @param {String} `options.owner` Set the owner to be used for each file.
* @param {String} `options.repo` Set the repository to be used for each file.
* @param {String} `options.branch` Set the branch to be used for each file. Defaults to `master`
* @api public
*/
function GithubContent(options) {
if (!(this instanceof GithubContent)) {
return new GithubContent(options);
}
// setup our specific options
var opts = extend({branch: 'master'}, options);
opts.json = false;
opts.apiurl = 'https://raw.githubusercontent.com';
GithubBase.call(this, opts);
this.options = extend({}, opts, this.options);
}
GithubBase.extend(GithubContent);
/**
* Download a single file given the file name and repository options.
* File object returned will contain a `.path` property with the file path passed in
* and a `.contents` property with the contents of the downloaded file.
*
* ```js
* gc.file('package.json', function(err, file) {
* if (err) return console.log(err);
* console.log(file.path);
* console.log(file.contents);
* });
* //=> package.json
* //=> {
* //=> "name": "github-content"
* //=> ...
* //=> }
* ```
*
* @param {String} `path` file path to download
* @param {Object} `options` Additional options to base to [github-base] `.get` method.
* @param {Function} `cb` Callback function taking `err` and `file`
* @return {Object} `this` to enable chaining
* @api public
*/
GithubContent.prototype.file = function(path, options, cb) {
if (typeof options === 'function') {
cb = options;
options = {};
}
if (typeof cb !== 'function') {
throw new TypeError('expected callback to be a function');
}
var opts = extend({branch: 'master', path: path}, this.options, options);
if (!opts.repo) {
cb(new Error('expected "options.repo" to be specified'));
return;
}
var segs = opts.repo.split('/');
if (segs.length > 1) {
opts.owner = segs[0];
opts.repo = segs[1];
}
this.get('/:owner/:repo/:branch/:path', opts, function(err, contents) {
if (err) return cb(err);
cb(null, {path: path, contents: contents});
});
return this;
};
/**
* Download an array of files using the previous settings and the passed in file names.
* File objects returned will contain a `.path` property with the file path passed in
* and a `.contents` property with the contents of the downloaded file.
*
* ```js
* gc.files(['package.json', 'index.js'], function(err, files) {
* if (err) return console.log(err);
* console.log(files.length);
* console.log(files[0].path);
* console.log(files[0].contents);
* });
* //=> 2
* //=> package.json
* //=> {
* //=> "name": "github-content"
* //=> ...
* //=> }
* ```
*
* @param {String|Array} `files` files to download
* @param {Object} `options` Additional options to base to [github-base] `.get` method.
* @param {Function} `cb` Callback function taking `err` and `files`
* @return {Object} `this` to enable chaining
* @api public
*/
GithubContent.prototype.files = function(files, options, cb) {
if (typeof options === 'function') {
cb = options;
options = {};
}
var opts = extend({}, options);
files = arrayify(files);
map(files, function(file, next) {
this.file(file, opts, next);
}.bind(this), cb);
return this;
};
function arrayify(val) {
if (val === null || typeof val === 'undefined') {
return [];
}
return Array.isArray(val) ? val : [val];
}
function map(arr, iterator, cb) {
var i = 0;
var res = new Array(arr.length);
each(arr, function(ele, next) {
iterator(ele, function(err, val) {
if (err) {
next(err);
return err;
}
res[i++] = val;
next();
});
}, function(err) {
if (err) {
cb(err);
return;
}
cb(null, res);
});
}
/**
* Exposes `GithubContent`
*/
module.exports = GithubContent;