ghissues 1.1.4 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/dependabot.yml +20 -0
- package/.github/workflows/test-and-release.yml +56 -0
- package/CHANGELOG.md +19 -0
- package/README.md +57 -46
- package/ghissues.js +25 -47
- package/package.json +102 -9
- package/test.js +121 -224
- package/.jshintrc +0 -59
- package/.travis.yml +0 -10
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: 'github-actions'
|
|
4
|
+
directory: '/'
|
|
5
|
+
schedule:
|
|
6
|
+
interval: 'weekly'
|
|
7
|
+
commit-message:
|
|
8
|
+
prefix: 'chore'
|
|
9
|
+
include: 'scope'
|
|
10
|
+
cooldown:
|
|
11
|
+
default-days: 5
|
|
12
|
+
- package-ecosystem: 'npm'
|
|
13
|
+
directory: '/'
|
|
14
|
+
schedule:
|
|
15
|
+
interval: 'weekly'
|
|
16
|
+
commit-message:
|
|
17
|
+
prefix: 'chore'
|
|
18
|
+
include: 'scope'
|
|
19
|
+
cooldown:
|
|
20
|
+
default-days: 5
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
name: Test & Maybe Release
|
|
2
|
+
on: [push, pull_request]
|
|
3
|
+
|
|
4
|
+
jobs:
|
|
5
|
+
test:
|
|
6
|
+
strategy:
|
|
7
|
+
fail-fast: false
|
|
8
|
+
matrix:
|
|
9
|
+
node: [lts/*, current]
|
|
10
|
+
os: [macos-latest, ubuntu-latest, windows-latest]
|
|
11
|
+
runs-on: ${{ matrix.os }}
|
|
12
|
+
steps:
|
|
13
|
+
- name: Checkout Repository
|
|
14
|
+
uses: actions/checkout@v6
|
|
15
|
+
- name: Use Node.js ${{ matrix.node }}
|
|
16
|
+
uses: actions/setup-node@v6.3.0
|
|
17
|
+
with:
|
|
18
|
+
node-version: ${{ matrix.node }}
|
|
19
|
+
- name: Install Dependencies
|
|
20
|
+
run: npm install --no-progress
|
|
21
|
+
- name: Check build is up to date
|
|
22
|
+
run: |
|
|
23
|
+
npm run build
|
|
24
|
+
git diff --exit-code || (echo "::error::Build artifacts not committed. Run 'npm run build' and commit the changes." && exit 1)
|
|
25
|
+
- name: Run tests
|
|
26
|
+
run: npm test
|
|
27
|
+
|
|
28
|
+
release:
|
|
29
|
+
name: Release
|
|
30
|
+
needs: test
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
|
|
33
|
+
permissions:
|
|
34
|
+
contents: write
|
|
35
|
+
issues: write
|
|
36
|
+
pull-requests: write
|
|
37
|
+
id-token: write
|
|
38
|
+
steps:
|
|
39
|
+
- name: Checkout
|
|
40
|
+
uses: actions/checkout@v6
|
|
41
|
+
with:
|
|
42
|
+
fetch-depth: 0
|
|
43
|
+
- name: Setup Node.js
|
|
44
|
+
uses: actions/setup-node@v6.3.0
|
|
45
|
+
with:
|
|
46
|
+
node-version: lts/*
|
|
47
|
+
registry-url: 'https://registry.npmjs.org'
|
|
48
|
+
- name: Install dependencies
|
|
49
|
+
run: npm install --no-progress --no-package-lock --no-save
|
|
50
|
+
- name: Build
|
|
51
|
+
run: npm run build
|
|
52
|
+
- name: Release
|
|
53
|
+
env:
|
|
54
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
55
|
+
NPM_CONFIG_PROVENANCE: true
|
|
56
|
+
run: npx semantic-release
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
## [2.0.1](https://github.com/rvagg/ghissues/compare/v2.0.0...v2.0.1) (2026-04-28)
|
|
2
|
+
|
|
3
|
+
### Trivial Changes
|
|
4
|
+
|
|
5
|
+
* **deps:** bump actions/setup-node from 6 to 6.3.0 ([#7](https://github.com/rvagg/ghissues/issues/7)) ([8fd7b4d](https://github.com/rvagg/ghissues/commit/8fd7b4df8294e6f998a276f7e702cb8cbcd11d47))
|
|
6
|
+
|
|
7
|
+
## [2.0.0](https://github.com/rvagg/ghissues/compare/v1.1.4...v2.0.0) (2026-01-27)
|
|
8
|
+
|
|
9
|
+
### ⚠ BREAKING CHANGES
|
|
10
|
+
|
|
11
|
+
* modernise, ESM, promises, update deps, GHA, auto-release (#6)
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* add release config ([ddceb9b](https://github.com/rvagg/ghissues/commit/ddceb9be4abcccb6c4479d1ca92de11b9272ba7c))
|
|
16
|
+
|
|
17
|
+
### Trivial Changes
|
|
18
|
+
|
|
19
|
+
* modernise, ESM, promises, update deps, GHA, auto-release ([#6](https://github.com/rvagg/ghissues/issues/6)) ([e0b5cdf](https://github.com/rvagg/ghissues/commit/e0b5cdf113891e3f74577c47d66f962b1e744371))
|
package/README.md
CHANGED
|
@@ -1,75 +1,86 @@
|
|
|
1
1
|
# ghissues
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**A Node.js library to interact with the GitHub issues API**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://nodei.co/npm/ghissues/)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
- Node.js >= 20
|
|
8
10
|
|
|
9
11
|
## Example usage
|
|
10
12
|
|
|
11
13
|
```js
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
import * as ghissues from 'ghissues'
|
|
15
|
+
|
|
16
|
+
const auth = { token: 'your-github-token' }
|
|
14
17
|
|
|
15
18
|
// list all issues in a repo
|
|
16
|
-
ghissues.list(
|
|
17
|
-
|
|
18
|
-
console.log(issuelist)
|
|
19
|
-
})
|
|
19
|
+
const issues = await ghissues.list(auth, 'rvagg', 'jsonist')
|
|
20
|
+
console.log(issues)
|
|
20
21
|
|
|
21
22
|
// get issue data by number (not internal GitHub id)
|
|
22
|
-
ghissues.get(
|
|
23
|
-
|
|
24
|
-
console.log(issue)
|
|
25
|
-
})
|
|
23
|
+
const issue = await ghissues.get(auth, 'rvagg', 'nan', 123)
|
|
24
|
+
console.log(issue)
|
|
26
25
|
|
|
27
26
|
// create an issue
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
ghissues.create(authOptions, 'rvagg', 'jsonist', data, function (err, issue) {
|
|
33
|
-
// data for new issue
|
|
34
|
-
console.log(issue)
|
|
27
|
+
const newIssue = await ghissues.create(auth, 'rvagg', 'jsonist', {
|
|
28
|
+
title: 'New issue',
|
|
29
|
+
body: 'Pretty **slick** `markdown`'
|
|
35
30
|
})
|
|
31
|
+
console.log(newIssue)
|
|
36
32
|
|
|
37
33
|
// list all comments in an issue
|
|
38
|
-
ghissues.listComments(
|
|
39
|
-
|
|
40
|
-
console.log(commentlist)
|
|
41
|
-
})
|
|
34
|
+
const comments = await ghissues.listComments(auth, 'rvagg', 'jsonist', 47)
|
|
35
|
+
console.log(comments)
|
|
42
36
|
|
|
43
37
|
// create a comment
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
// data for new comment in 'rvagg/jsonist#101'
|
|
47
|
-
console.log(issue)
|
|
48
|
-
})
|
|
38
|
+
const comment = await ghissues.createComment(auth, 'rvagg', 'jsonist', 101, 'Whoa dude!')
|
|
39
|
+
console.log(comment)
|
|
49
40
|
```
|
|
50
41
|
|
|
51
|
-
|
|
52
|
-
The auth data is compatible with [ghauth](https://github.com/rvagg/ghauth) so you can just connect them together to make a simple command-line application:
|
|
42
|
+
The auth data is compatible with [ghauth](https://github.com/rvagg/ghauth) so you can connect them together:
|
|
53
43
|
|
|
54
44
|
```js
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
})
|
|
68
|
-
})
|
|
45
|
+
import ghauth from 'ghauth'
|
|
46
|
+
import * as ghissues from 'ghissues'
|
|
47
|
+
|
|
48
|
+
const auth = await ghauth({
|
|
49
|
+
configName: 'issue-lister',
|
|
50
|
+
scopes: ['user']
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
const issues = await ghissues.list(auth, 'rvagg', 'node-levelup')
|
|
54
|
+
console.log('Issues in rvagg/node-levelup:')
|
|
55
|
+
issues.forEach((i) => {
|
|
56
|
+
console.log('#%s: %s', i.number, i.title)
|
|
69
57
|
})
|
|
70
58
|
```
|
|
71
59
|
|
|
60
|
+
## API
|
|
61
|
+
|
|
62
|
+
All methods return Promises.
|
|
63
|
+
|
|
64
|
+
### ghissues.list(auth, org, repo, options)
|
|
65
|
+
|
|
66
|
+
List all issues in a repository. Returns an array of issue objects.
|
|
67
|
+
|
|
68
|
+
### ghissues.get(auth, org, repo, num, options)
|
|
69
|
+
|
|
70
|
+
Get a single issue by number. Returns the issue object.
|
|
71
|
+
|
|
72
|
+
### ghissues.create(auth, org, repo, data, options)
|
|
73
|
+
|
|
74
|
+
Create a new issue. `data` should contain `title` and optionally `body`. Returns the created issue.
|
|
75
|
+
|
|
76
|
+
### ghissues.listComments(auth, org, repo, num, options)
|
|
77
|
+
|
|
78
|
+
List all comments on an issue. Returns an array of comment objects.
|
|
79
|
+
|
|
80
|
+
### ghissues.createComment(auth, org, repo, num, body, options)
|
|
81
|
+
|
|
82
|
+
Create a comment on an issue. Returns the created comment.
|
|
72
83
|
|
|
73
84
|
## License
|
|
74
85
|
|
|
75
|
-
**ghissues** is Copyright (c) 2014 Rod Vagg [@rvagg](https://github.com/rvagg) and licensed under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.
|
|
86
|
+
**ghissues** is Copyright (c) 2014-2025 Rod Vagg [@rvagg](https://github.com/rvagg) and licensed under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.
|
package/ghissues.js
CHANGED
|
@@ -1,58 +1,36 @@
|
|
|
1
|
-
|
|
1
|
+
import { ghget, ghpost, lister } from 'ghutils'
|
|
2
2
|
|
|
3
|
+
const defaultApiUrl = 'https://api.github.com'
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
var url = 'https://api.github.com/repos/' + org + '/' + repo + '/issues?page=1'
|
|
11
|
-
ghutils.lister(auth, url, options, callback)
|
|
5
|
+
export async function list (auth, org, repo, options = {}) {
|
|
6
|
+
const apiUrl = options._apiUrl || defaultApiUrl
|
|
7
|
+
const url = `${apiUrl}/repos/${org}/${repo}/issues`
|
|
8
|
+
return lister(auth, url, options)
|
|
12
9
|
}
|
|
13
10
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
var url = 'https://api.github.com/repos/' + org + '/' + repo + '/issues/' + num
|
|
21
|
-
|
|
22
|
-
ghutils.ghget(auth, url, options, callback)
|
|
11
|
+
export async function get (auth, org, repo, num, options = {}) {
|
|
12
|
+
const apiUrl = options._apiUrl || defaultApiUrl
|
|
13
|
+
const url = `${apiUrl}/repos/${org}/${repo}/issues/${num}`
|
|
14
|
+
const { data } = await ghget(auth, url, options)
|
|
15
|
+
return data
|
|
23
16
|
}
|
|
24
17
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
var url = 'https://api.github.com/repos/' + org + '/' + repo + '/issues'
|
|
33
|
-
|
|
34
|
-
ghutils.ghpost(auth, url, data, options, callback)
|
|
18
|
+
export async function create (auth, org, repo, data, options = {}) {
|
|
19
|
+
const apiUrl = options._apiUrl || defaultApiUrl
|
|
20
|
+
const url = `${apiUrl}/repos/${org}/${repo}/issues`
|
|
21
|
+
const { data: result } = await ghpost(auth, url, data, options)
|
|
22
|
+
return result
|
|
35
23
|
}
|
|
36
24
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
options = {}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
var url = 'https://api.github.com/repos/' + org + '/' + repo + '/issues/' + num + '/comments?page=1'
|
|
45
|
-
ghutils.lister(auth, url, options, callback)
|
|
25
|
+
export async function listComments (auth, org, repo, num, options = {}) {
|
|
26
|
+
const apiUrl = options._apiUrl || defaultApiUrl
|
|
27
|
+
const url = `${apiUrl}/repos/${org}/${repo}/issues/${num}/comments`
|
|
28
|
+
return lister(auth, url, options)
|
|
46
29
|
}
|
|
47
30
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
var url = 'https://api.github.com/repos/' + org + '/' + repo + '/issues/' + num + '/comments'
|
|
56
|
-
|
|
57
|
-
ghutils.ghpost(auth, url, { body: body }, options, callback)
|
|
31
|
+
export async function createComment (auth, org, repo, num, body, options = {}) {
|
|
32
|
+
const apiUrl = options._apiUrl || defaultApiUrl
|
|
33
|
+
const url = `${apiUrl}/repos/${org}/${repo}/issues/${num}/comments`
|
|
34
|
+
const { data } = await ghpost(auth, url, { body }, options)
|
|
35
|
+
return data
|
|
58
36
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ghissues",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Interact with the GitHub
|
|
5
|
-
"
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"description": "Interact with the GitHub issues API",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": "./ghissues.js",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=20"
|
|
9
|
+
},
|
|
6
10
|
"scripts": {
|
|
7
|
-
"
|
|
11
|
+
"lint": "standard",
|
|
12
|
+
"build": "true",
|
|
13
|
+
"test:unit": "node --test test.js",
|
|
14
|
+
"test": "npm run lint && npm run test:unit"
|
|
8
15
|
},
|
|
9
16
|
"repository": {
|
|
10
17
|
"type": "git",
|
|
@@ -21,12 +28,98 @@
|
|
|
21
28
|
},
|
|
22
29
|
"homepage": "https://github.com/rvagg/ghissues",
|
|
23
30
|
"dependencies": {
|
|
24
|
-
"ghutils": "^
|
|
31
|
+
"ghutils": "^5.0.0"
|
|
25
32
|
},
|
|
26
33
|
"devDependencies": {
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
34
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
35
|
+
"@semantic-release/commit-analyzer": "^13.0.0",
|
|
36
|
+
"@semantic-release/git": "^10.0.1",
|
|
37
|
+
"@semantic-release/github": "^12.0.0",
|
|
38
|
+
"@semantic-release/npm": "^13.0.0",
|
|
39
|
+
"@semantic-release/release-notes-generator": "^14.0.1",
|
|
40
|
+
"conventional-changelog-conventionalcommits": "^9.0.0",
|
|
41
|
+
"semantic-release": "^25.0.0",
|
|
42
|
+
"standard": "^17.1.2"
|
|
43
|
+
},
|
|
44
|
+
"release": {
|
|
45
|
+
"branches": [
|
|
46
|
+
"master"
|
|
47
|
+
],
|
|
48
|
+
"plugins": [
|
|
49
|
+
[
|
|
50
|
+
"@semantic-release/commit-analyzer",
|
|
51
|
+
{
|
|
52
|
+
"preset": "conventionalcommits",
|
|
53
|
+
"releaseRules": [
|
|
54
|
+
{
|
|
55
|
+
"breaking": true,
|
|
56
|
+
"release": "major"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"revert": true,
|
|
60
|
+
"release": "patch"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"type": "feat",
|
|
64
|
+
"release": "minor"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"type": "fix",
|
|
68
|
+
"release": "patch"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"type": "chore",
|
|
72
|
+
"release": "patch"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"type": "docs",
|
|
76
|
+
"release": "patch"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"type": "test",
|
|
80
|
+
"release": "patch"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"scope": "no-release",
|
|
84
|
+
"release": false
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
],
|
|
89
|
+
[
|
|
90
|
+
"@semantic-release/release-notes-generator",
|
|
91
|
+
{
|
|
92
|
+
"preset": "conventionalcommits",
|
|
93
|
+
"presetConfig": {
|
|
94
|
+
"types": [
|
|
95
|
+
{
|
|
96
|
+
"type": "feat",
|
|
97
|
+
"section": "Features"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"type": "fix",
|
|
101
|
+
"section": "Bug Fixes"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"type": "chore",
|
|
105
|
+
"section": "Trivial Changes"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"type": "docs",
|
|
109
|
+
"section": "Trivial Changes"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"type": "test",
|
|
113
|
+
"section": "Tests"
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
],
|
|
119
|
+
"@semantic-release/changelog",
|
|
120
|
+
"@semantic-release/npm",
|
|
121
|
+
"@semantic-release/github",
|
|
122
|
+
"@semantic-release/git"
|
|
123
|
+
]
|
|
31
124
|
}
|
|
32
125
|
}
|
package/test.js
CHANGED
|
@@ -1,253 +1,150 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
, repo = 'testrepo'
|
|
15
|
-
, testData = [
|
|
16
|
-
{
|
|
17
|
-
response : [ { test1: 'data1' }, { test2: 'data2' } ]
|
|
18
|
-
, headers : { link: '<https://api.github.com/repos/testorg/testrepo/issues?page=2>; rel="next"' }
|
|
19
|
-
}
|
|
20
|
-
, { response: [] }
|
|
21
|
-
]
|
|
22
|
-
, server
|
|
23
|
-
|
|
24
|
-
server = ghutils.makeServer(testData)
|
|
25
|
-
.on('ready', function () {
|
|
26
|
-
ghissues.list(xtend(auth), org, repo, ghutils.verifyData(t, testData[0].response))
|
|
1
|
+
import { test } from 'node:test'
|
|
2
|
+
import assert from 'node:assert'
|
|
3
|
+
import { createMockServer, createMockServerWithHandler } from 'ghutils/test-util'
|
|
4
|
+
import * as ghissues from './ghissues.js'
|
|
5
|
+
|
|
6
|
+
test('list issues', async () => {
|
|
7
|
+
const auth = { token: 'test-token' }
|
|
8
|
+
const testData = [{ id: 1, title: 'Issue 1' }, { id: 2, title: 'Issue 2' }]
|
|
9
|
+
|
|
10
|
+
const server = await createMockServer({ response: testData })
|
|
11
|
+
try {
|
|
12
|
+
const results = await ghissues.list(auth, 'testorg', 'testrepo', {
|
|
13
|
+
_apiUrl: server.baseUrl
|
|
27
14
|
})
|
|
28
|
-
.
|
|
29
|
-
.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
.
|
|
15
|
+
assert.deepStrictEqual(results, testData)
|
|
16
|
+
assert.strictEqual(server.requests.length, 1)
|
|
17
|
+
assert.ok(server.requests[0].url.includes('/repos/testorg/testrepo/issues'))
|
|
18
|
+
assert.strictEqual(server.requests[0].headers.authorization, 'Bearer test-token')
|
|
19
|
+
} finally {
|
|
20
|
+
await server.close()
|
|
21
|
+
}
|
|
34
22
|
})
|
|
35
23
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
,
|
|
55
|
-
|
|
56
|
-
server = ghutils.makeServer(testData)
|
|
57
|
-
.on('ready', function () {
|
|
58
|
-
ghissues.list(xtend(auth), org, repo, ghutils.verifyData(t, testData[0].response.concat(testData[1].response)))
|
|
24
|
+
test('list issues with pagination', async () => {
|
|
25
|
+
const auth = { token: 'test-token' }
|
|
26
|
+
const page1 = [{ id: 1 }, { id: 2 }]
|
|
27
|
+
const page2 = [{ id: 3 }, { id: 4 }]
|
|
28
|
+
|
|
29
|
+
let requestCount = 0
|
|
30
|
+
const mock = await createMockServerWithHandler((req, res) => {
|
|
31
|
+
requestCount++
|
|
32
|
+
const port = mock.address().port
|
|
33
|
+
if (requestCount === 1) {
|
|
34
|
+
res.setHeader('link', `<http://127.0.0.1:${port}/page2>; rel="next"`)
|
|
35
|
+
res.end(JSON.stringify(page1))
|
|
36
|
+
} else {
|
|
37
|
+
res.end(JSON.stringify(page2))
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
const results = await ghissues.list(auth, 'testorg', 'testrepo', {
|
|
43
|
+
_apiUrl: mock.baseUrl
|
|
59
44
|
})
|
|
60
|
-
.
|
|
61
|
-
.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
]))
|
|
66
|
-
.on('close' , ghutils.verifyClose(t))
|
|
45
|
+
assert.deepStrictEqual(results, [...page1, ...page2])
|
|
46
|
+
assert.strictEqual(requestCount, 2)
|
|
47
|
+
} finally {
|
|
48
|
+
await mock.close()
|
|
49
|
+
}
|
|
67
50
|
})
|
|
68
51
|
|
|
52
|
+
test('get issue by number', async () => {
|
|
53
|
+
const auth = { token: 'test-token' }
|
|
54
|
+
const testData = { id: 101, title: 'Test Issue', body: 'Issue body' }
|
|
69
55
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
, org = 'testorg'
|
|
75
|
-
, repo = 'testrepo'
|
|
76
|
-
, testData = [ [] ]
|
|
77
|
-
, server
|
|
78
|
-
|
|
79
|
-
server = ghutils.makeServer(testData)
|
|
80
|
-
.on('ready', function () {
|
|
81
|
-
ghissues.list(xtend(auth), org, repo, ghutils.verifyData(t, []))
|
|
56
|
+
const server = await createMockServer({ response: testData })
|
|
57
|
+
try {
|
|
58
|
+
const result = await ghissues.get(auth, 'testorg', 'testrepo', 101, {
|
|
59
|
+
_apiUrl: server.baseUrl
|
|
82
60
|
})
|
|
83
|
-
.
|
|
84
|
-
.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
61
|
+
assert.deepStrictEqual(result, testData)
|
|
62
|
+
assert.ok(server.requests[0].url.includes('/repos/testorg/testrepo/issues/101'))
|
|
63
|
+
} finally {
|
|
64
|
+
await server.close()
|
|
65
|
+
}
|
|
88
66
|
})
|
|
89
67
|
|
|
68
|
+
test('create issue', async () => {
|
|
69
|
+
const auth = { token: 'test-token' }
|
|
70
|
+
const issueData = { title: 'New Issue', body: 'Issue description' }
|
|
71
|
+
const responseData = { id: 123, ...issueData }
|
|
90
72
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
, org = 'testorg'
|
|
96
|
-
, repo = 'testrepo'
|
|
97
|
-
, num = 101
|
|
98
|
-
, testData = { id: num, issue: 'body' }
|
|
99
|
-
, server
|
|
100
|
-
|
|
101
|
-
server = ghutils.makeServer(testData)
|
|
102
|
-
.on('ready', function () {
|
|
103
|
-
ghissues.get(xtend(auth), org, repo, num, ghutils.verifyData(t, testData))
|
|
73
|
+
const server = await createMockServer({ response: responseData })
|
|
74
|
+
try {
|
|
75
|
+
const result = await ghissues.create(auth, 'testorg', 'testrepo', issueData, {
|
|
76
|
+
_apiUrl: server.baseUrl
|
|
104
77
|
})
|
|
105
|
-
.
|
|
106
|
-
.
|
|
107
|
-
|
|
108
|
-
]))
|
|
109
|
-
|
|
78
|
+
assert.deepStrictEqual(result, responseData)
|
|
79
|
+
assert.strictEqual(server.requests[0].method, 'POST')
|
|
80
|
+
assert.deepStrictEqual(server.requests[0].body, issueData)
|
|
81
|
+
assert.ok(server.requests[0].url.includes('/repos/testorg/testrepo/issues'))
|
|
82
|
+
} finally {
|
|
83
|
+
await server.close()
|
|
84
|
+
}
|
|
110
85
|
})
|
|
111
86
|
|
|
87
|
+
test('list issue comments', async () => {
|
|
88
|
+
const auth = { token: 'test-token' }
|
|
89
|
+
const comments = [{ id: 1, body: 'Comment 1' }, { id: 2, body: 'Comment 2' }]
|
|
112
90
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
, org = 'testorg'
|
|
118
|
-
, repo = 'testrepo'
|
|
119
|
-
, testData = { title: 'issue title', body: 'issue body' }
|
|
120
|
-
, resp = 'derp'
|
|
121
|
-
, server
|
|
122
|
-
|
|
123
|
-
server = ghutils.makeServer(resp)
|
|
124
|
-
.on('ready', function () {
|
|
125
|
-
ghissues.create(xtend(auth), org, repo, testData, ghutils.verifyData(t, resp))
|
|
91
|
+
const server = await createMockServer({ response: comments })
|
|
92
|
+
try {
|
|
93
|
+
const results = await ghissues.listComments(auth, 'testorg', 'testrepo', 42, {
|
|
94
|
+
_apiUrl: server.baseUrl
|
|
126
95
|
})
|
|
127
|
-
.
|
|
128
|
-
.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}))
|
|
133
|
-
})
|
|
134
|
-
.on('post', ghutils.verifyUrl(t, [
|
|
135
|
-
'https://api.github.com/repos/testorg/testrepo/issues'
|
|
136
|
-
]))
|
|
137
|
-
.on('close' , ghutils.verifyClose(t))
|
|
96
|
+
assert.deepStrictEqual(results, comments)
|
|
97
|
+
assert.ok(server.requests[0].url.includes('/repos/testorg/testrepo/issues/42/comments'))
|
|
98
|
+
} finally {
|
|
99
|
+
await server.close()
|
|
100
|
+
}
|
|
138
101
|
})
|
|
139
102
|
|
|
103
|
+
test('create comment', async () => {
|
|
104
|
+
const auth = { token: 'test-token' }
|
|
105
|
+
const commentBody = 'This is a comment'
|
|
106
|
+
const responseData = { id: 456, body: commentBody }
|
|
140
107
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
, org = 'testorg'
|
|
146
|
-
, repo = 'testrepo'
|
|
147
|
-
, num = 48
|
|
148
|
-
, testData = [ [ { test1: 'data1' }, { test2: 'data2' } ], [] ]
|
|
149
|
-
, testData = [
|
|
150
|
-
{
|
|
151
|
-
response : [ { test1: 'data1' }, { test2: 'data2' } ]
|
|
152
|
-
, headers : { link: '<https://api.github.com/repos/testorg/testrepo/issues/' + num + '/comments?page=2>; rel="next"' }
|
|
153
|
-
}
|
|
154
|
-
, { response: [] }
|
|
155
|
-
]
|
|
156
|
-
, server
|
|
157
|
-
|
|
158
|
-
server = ghutils.makeServer(testData)
|
|
159
|
-
.on('ready', function () {
|
|
160
|
-
ghissues.listComments(xtend(auth), org, repo, num, ghutils.verifyData(t, testData[0].response))
|
|
108
|
+
const server = await createMockServer({ response: responseData })
|
|
109
|
+
try {
|
|
110
|
+
const result = await ghissues.createComment(auth, 'testorg', 'testrepo', 42, commentBody, {
|
|
111
|
+
_apiUrl: server.baseUrl
|
|
161
112
|
})
|
|
162
|
-
.
|
|
163
|
-
.
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
.
|
|
113
|
+
assert.deepStrictEqual(result, responseData)
|
|
114
|
+
assert.strictEqual(server.requests[0].method, 'POST')
|
|
115
|
+
assert.deepStrictEqual(server.requests[0].body, { body: commentBody })
|
|
116
|
+
assert.ok(server.requests[0].url.includes('/repos/testorg/testrepo/issues/42/comments'))
|
|
117
|
+
} finally {
|
|
118
|
+
await server.close()
|
|
119
|
+
}
|
|
168
120
|
})
|
|
169
121
|
|
|
122
|
+
test('list issues returns empty array', async () => {
|
|
123
|
+
const auth = { token: 'test-token' }
|
|
170
124
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
, org = 'testorg'
|
|
176
|
-
, repo = 'testrepo'
|
|
177
|
-
, num = 202
|
|
178
|
-
, testData = [
|
|
179
|
-
{
|
|
180
|
-
response : [ { test1: 'data1' }, { test2: 'data2' } ]
|
|
181
|
-
, headers : { link: '<https://api.github.com/repos/testorg/testrepo/issues/' + num + '/comments?page=2>; rel="next"' }
|
|
182
|
-
}
|
|
183
|
-
, {
|
|
184
|
-
response : [ { test1: 'data3' }, { test2: 'data4' } ]
|
|
185
|
-
, headers : { link: '<https://api.github.com/repos/testorg/testrepo/issues/' + num + '/comments?page=3>; rel="next"' }
|
|
186
|
-
}
|
|
187
|
-
, { response: [] }
|
|
188
|
-
]
|
|
189
|
-
, server
|
|
190
|
-
|
|
191
|
-
server = ghutils.makeServer(testData)
|
|
192
|
-
.on('ready', function () {
|
|
193
|
-
ghissues.listComments(xtend(auth), org, repo, num, ghutils.verifyData(t, testData[0].response.concat(testData[1].response)))
|
|
125
|
+
const server = await createMockServer({ response: [] })
|
|
126
|
+
try {
|
|
127
|
+
const results = await ghissues.list(auth, 'testorg', 'testrepo', {
|
|
128
|
+
_apiUrl: server.baseUrl
|
|
194
129
|
})
|
|
195
|
-
.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
, 'https://api.github.com/repos/testorg/testrepo/issues/' + num + '/comments?page=3'
|
|
200
|
-
]))
|
|
201
|
-
.on('close' , ghutils.verifyClose(t))
|
|
130
|
+
assert.deepStrictEqual(results, [])
|
|
131
|
+
} finally {
|
|
132
|
+
await server.close()
|
|
133
|
+
}
|
|
202
134
|
})
|
|
203
135
|
|
|
136
|
+
test('auth header is correctly set', async () => {
|
|
137
|
+
const auth = { token: 'my-secret-token' }
|
|
138
|
+
const testData = [{ id: 1 }]
|
|
204
139
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
, org = 'testorg'
|
|
210
|
-
, repo = 'testrepo'
|
|
211
|
-
, num = 1
|
|
212
|
-
, testData = [ [] ]
|
|
213
|
-
, server
|
|
214
|
-
|
|
215
|
-
server = ghutils.makeServer(testData)
|
|
216
|
-
.on('ready', function () {
|
|
217
|
-
ghissues.listComments(xtend(auth), org, repo, num, ghutils.verifyData(t, []))
|
|
218
|
-
})
|
|
219
|
-
.on('request', ghutils.verifyRequest(t, auth))
|
|
220
|
-
.on('get', ghutils.verifyUrl(t, [
|
|
221
|
-
'https://api.github.com/repos/testorg/testrepo/issues/' + num + '/comments?page=1'
|
|
222
|
-
]))
|
|
223
|
-
.on('close' , ghutils.verifyClose(t))
|
|
224
|
-
})
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
test('test create new comment', function (t) {
|
|
228
|
-
t.plan(9)
|
|
229
|
-
|
|
230
|
-
var auth = { user: 'authuser', token: 'authtoken' }
|
|
231
|
-
, org = 'testorg'
|
|
232
|
-
, repo = 'testrepo'
|
|
233
|
-
, testData = 'comment body'
|
|
234
|
-
, num = 303
|
|
235
|
-
, resp = 'herpderp'
|
|
236
|
-
, server
|
|
237
|
-
|
|
238
|
-
server = ghutils.makeServer(resp)
|
|
239
|
-
.on('ready', function () {
|
|
240
|
-
ghissues.createComment(xtend(auth), org, repo, num, testData, ghutils.verifyData(t, resp))
|
|
241
|
-
})
|
|
242
|
-
.on('request', ghutils.verifyRequest(t, auth))
|
|
243
|
-
.on('request', function (req) {
|
|
244
|
-
req.pipe(bl(function (err, data) {
|
|
245
|
-
t.notOk(err, 'no error')
|
|
246
|
-
t.deepEqual(JSON.parse(data.toString()), {body:testData}, 'got expected post data')
|
|
247
|
-
}))
|
|
140
|
+
const server = await createMockServer({ response: testData })
|
|
141
|
+
try {
|
|
142
|
+
await ghissues.list(auth, 'testorg', 'testrepo', {
|
|
143
|
+
_apiUrl: server.baseUrl
|
|
248
144
|
})
|
|
249
|
-
.
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
.
|
|
145
|
+
assert.strictEqual(server.requests[0].headers.authorization, 'Bearer my-secret-token')
|
|
146
|
+
assert.strictEqual(server.requests[0].headers.accept, 'application/vnd.github+json')
|
|
147
|
+
} finally {
|
|
148
|
+
await server.close()
|
|
149
|
+
}
|
|
253
150
|
})
|
package/.jshintrc
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"predef": [ ]
|
|
3
|
-
, "bitwise": false
|
|
4
|
-
, "camelcase": false
|
|
5
|
-
, "curly": false
|
|
6
|
-
, "eqeqeq": false
|
|
7
|
-
, "forin": false
|
|
8
|
-
, "immed": false
|
|
9
|
-
, "latedef": false
|
|
10
|
-
, "noarg": true
|
|
11
|
-
, "noempty": true
|
|
12
|
-
, "nonew": true
|
|
13
|
-
, "plusplus": false
|
|
14
|
-
, "quotmark": true
|
|
15
|
-
, "regexp": false
|
|
16
|
-
, "undef": true
|
|
17
|
-
, "unused": true
|
|
18
|
-
, "strict": false
|
|
19
|
-
, "trailing": true
|
|
20
|
-
, "maxlen": 120
|
|
21
|
-
, "asi": true
|
|
22
|
-
, "boss": true
|
|
23
|
-
, "debug": true
|
|
24
|
-
, "eqnull": true
|
|
25
|
-
, "esnext": true
|
|
26
|
-
, "evil": true
|
|
27
|
-
, "expr": true
|
|
28
|
-
, "funcscope": false
|
|
29
|
-
, "globalstrict": false
|
|
30
|
-
, "iterator": false
|
|
31
|
-
, "lastsemic": true
|
|
32
|
-
, "laxbreak": true
|
|
33
|
-
, "laxcomma": true
|
|
34
|
-
, "loopfunc": true
|
|
35
|
-
, "multistr": false
|
|
36
|
-
, "onecase": false
|
|
37
|
-
, "proto": false
|
|
38
|
-
, "regexdash": false
|
|
39
|
-
, "scripturl": true
|
|
40
|
-
, "smarttabs": false
|
|
41
|
-
, "shadow": false
|
|
42
|
-
, "sub": true
|
|
43
|
-
, "supernew": false
|
|
44
|
-
, "validthis": true
|
|
45
|
-
, "browser": true
|
|
46
|
-
, "couch": false
|
|
47
|
-
, "devel": false
|
|
48
|
-
, "dojo": false
|
|
49
|
-
, "mootools": false
|
|
50
|
-
, "node": true
|
|
51
|
-
, "nonstandard": true
|
|
52
|
-
, "prototypejs": false
|
|
53
|
-
, "rhino": false
|
|
54
|
-
, "worker": true
|
|
55
|
-
, "wsh": false
|
|
56
|
-
, "nomen": false
|
|
57
|
-
, "onevar": false
|
|
58
|
-
, "passfail": false
|
|
59
|
-
}
|