ghteams 0.2.1 → 1.0.0
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 +9 -0
- package/README.md +61 -54
- package/ghteams.js +38 -73
- package/package.json +101 -8
- package/test.js +118 -178
- package/.jshintrc +0 -59
- package/.npmignore +0 -1
- 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
|
|
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
|
|
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,9 @@
|
|
|
1
|
+
## [1.0.0](https://github.com/rvagg/ghteams/compare/v0.3.0...v1.0.0) (2026-01-27)
|
|
2
|
+
|
|
3
|
+
### ⚠ BREAKING CHANGES
|
|
4
|
+
|
|
5
|
+
* modernise, ESM, promises, update deps, GHA, auto-release (#1)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* modernise, ESM, promises, update deps, GHA, auto-release ([#1](https://github.com/rvagg/ghteams/issues/1)) ([ca8a576](https://github.com/rvagg/ghteams/commit/ca8a576841101a846abbd0999ca96ff59d0bd8be))
|
package/README.md
CHANGED
|
@@ -1,86 +1,93 @@
|
|
|
1
1
|
# ghteams
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**A Node.js library to interact with the GitHub organisation teams API**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://nodei.co/npm/ghteams/)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
- Node.js >= 20
|
|
8
10
|
|
|
9
11
|
## Example usage
|
|
10
12
|
|
|
11
13
|
```js
|
|
12
|
-
|
|
13
|
-
, authOptions = { user: 'rvagg', token: '24d5dee258c64aef38a66c0c5eca459c379901c2' }
|
|
14
|
-
// note the auth token needs the 'user' scope to deal with org teams
|
|
14
|
+
import * as ghteams from 'ghteams'
|
|
15
15
|
|
|
16
|
+
const auth = { token: 'your-github-token' }
|
|
17
|
+
// note: the auth token needs the 'user' scope to deal with org teams
|
|
16
18
|
|
|
17
19
|
// list all teams in an organisation
|
|
20
|
+
const teams = await ghteams.list(auth, 'myorg')
|
|
21
|
+
console.log(teams)
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
})
|
|
23
|
+
// get team data by team name in an organisation
|
|
24
|
+
const team = await ghteams.get(auth, 'myorg', 'myteam')
|
|
25
|
+
console.log(team)
|
|
23
26
|
|
|
27
|
+
// get team data by team id (quicker)
|
|
28
|
+
const teamById = await ghteams.get(auth, 123456)
|
|
29
|
+
console.log(teamById)
|
|
24
30
|
|
|
25
|
-
// get team
|
|
31
|
+
// get team members by team name in an organisation
|
|
32
|
+
const members = await ghteams.members(auth, 'myorg', 'myteam')
|
|
33
|
+
console.log(members)
|
|
26
34
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
// get team members by team id (quicker)
|
|
36
|
+
const membersById = await ghteams.members(auth, 123456)
|
|
37
|
+
console.log(membersById)
|
|
38
|
+
|
|
39
|
+
// get teams the authenticated user belongs to
|
|
40
|
+
const myTeams = await ghteams.userTeams(auth)
|
|
41
|
+
console.log(myTeams)
|
|
42
|
+
```
|
|
31
43
|
|
|
44
|
+
The auth data is compatible with [ghauth](https://github.com/rvagg/ghauth) so you can connect them together:
|
|
32
45
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
46
|
+
```js
|
|
47
|
+
import ghauth from 'ghauth'
|
|
48
|
+
import * as ghteams from 'ghteams'
|
|
49
|
+
|
|
50
|
+
const auth = await ghauth({
|
|
51
|
+
configName: 'team-lister',
|
|
52
|
+
scopes: ['user']
|
|
37
53
|
})
|
|
38
54
|
|
|
55
|
+
const teams = await ghteams.list(auth, 'myorg')
|
|
56
|
+
console.log('Teams in "myorg":', teams.map((t) => t.name).join(', '))
|
|
57
|
+
```
|
|
39
58
|
|
|
40
|
-
|
|
59
|
+
## API
|
|
41
60
|
|
|
42
|
-
|
|
43
|
-
// Array containing full list of team members for myorg/myteam
|
|
44
|
-
console.log(members)
|
|
45
|
-
})
|
|
61
|
+
All methods return Promises.
|
|
46
62
|
|
|
63
|
+
### ghteams.list(auth, org, options)
|
|
47
64
|
|
|
48
|
-
|
|
49
|
-
ghteams.members(authOptions, 123456, function (err, members) {
|
|
50
|
-
// Array containing full list of team members team #123456
|
|
51
|
-
console.log(members)
|
|
52
|
-
})
|
|
65
|
+
List all teams in an organisation.
|
|
53
66
|
|
|
67
|
+
### ghteams.get(auth, org, name, options)
|
|
54
68
|
|
|
55
|
-
|
|
56
|
-
ghteams.userTeams(authOptions, function (err, teams) {
|
|
57
|
-
// Array cotnaining full list of teams to which the current
|
|
58
|
-
// authenticated user belongs
|
|
59
|
-
console.log(teams)
|
|
60
|
-
})
|
|
61
|
-
```
|
|
69
|
+
Get team data by team name in an organisation. If `name` is omitted and `org` is a numeric team ID, fetches the team directly by ID (quicker).
|
|
62
70
|
|
|
71
|
+
### ghteams.members(auth, org, name, options)
|
|
63
72
|
|
|
64
|
-
|
|
73
|
+
Get team members by team name in an organisation. If `name` is omitted and `org` is a numeric team ID, fetches members directly by ID (quicker).
|
|
65
74
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
ghteams.list(authData, 'myorg', function (err, list) {
|
|
76
|
-
console.log('Teams in "myorg": ', list.map(function (t) {
|
|
77
|
-
return t.name
|
|
78
|
-
}).join(', '))
|
|
79
|
-
})
|
|
80
|
-
})
|
|
81
|
-
```
|
|
75
|
+
### ghteams.userTeams(auth, options)
|
|
76
|
+
|
|
77
|
+
Get all teams the authenticated user belongs to.
|
|
78
|
+
|
|
79
|
+
## Authentication
|
|
80
|
+
|
|
81
|
+
See [ghauth](https://github.com/rvagg/ghauth) for an easy way to obtain and cache GitHub authentication tokens. The `auth` object returned by ghauth is directly compatible with all ghteams methods.
|
|
82
|
+
|
|
83
|
+
## See also
|
|
82
84
|
|
|
85
|
+
* [ghissues](https://github.com/rvagg/ghissues) - interact with the GitHub issues API
|
|
86
|
+
* [ghusers](https://github.com/rvagg/ghusers) - interact with the GitHub users API
|
|
87
|
+
* [ghpulls](https://github.com/rvagg/ghpulls) - interact with the GitHub pull requests API
|
|
88
|
+
* [ghrepos](https://github.com/rvagg/ghrepos) - interact with the GitHub repos API
|
|
89
|
+
* [ghauth](https://github.com/rvagg/ghauth) - GitHub authentication
|
|
83
90
|
|
|
84
91
|
## License
|
|
85
92
|
|
|
86
|
-
**ghteams** 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.
|
|
93
|
+
**ghteams** 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/ghteams.js
CHANGED
|
@@ -1,88 +1,53 @@
|
|
|
1
|
-
|
|
1
|
+
import { ghget, lister } from 'ghutils'
|
|
2
2
|
|
|
3
|
+
const defaultApiUrl = 'https://api.github.com'
|
|
3
4
|
|
|
4
|
-
function
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
jsonist.get(url, options, function (err, data) {
|
|
11
|
-
if (err)
|
|
12
|
-
return callback(err)
|
|
13
|
-
|
|
14
|
-
if (data.error || data.message)
|
|
15
|
-
return callback(new Error('Error from GitHub: ' + (data.error || data.message)))
|
|
16
|
-
|
|
17
|
-
callback(null, data)
|
|
18
|
-
})
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
function list (auth, org, callback) {
|
|
23
|
-
ghget(auth, 'https://api.github.com/orgs/' + org + '/teams', callback)
|
|
5
|
+
export async function list (auth, org, options = {}) {
|
|
6
|
+
const apiUrl = options._apiUrl || defaultApiUrl
|
|
7
|
+
const url = `${apiUrl}/orgs/${org}/teams`
|
|
8
|
+
return lister(auth, url, options)
|
|
24
9
|
}
|
|
25
10
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return team.name == name
|
|
34
|
-
})[0]
|
|
35
|
-
|
|
36
|
-
if (!team)
|
|
37
|
-
return callback(new Error('No such team [' + name + '] for org [' + org + ']'))
|
|
38
|
-
|
|
39
|
-
callback(null, team.id)
|
|
40
|
-
})
|
|
11
|
+
async function teamIdByName (auth, org, name, options = {}) {
|
|
12
|
+
const teams = await list(auth, org, options)
|
|
13
|
+
const team = teams.find((t) => t.name === name)
|
|
14
|
+
if (!team) {
|
|
15
|
+
throw new Error(`No such team [${name}] for org [${org}]`)
|
|
16
|
+
}
|
|
17
|
+
return team.id
|
|
41
18
|
}
|
|
42
19
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
20
|
+
async function getById (auth, id, options = {}) {
|
|
21
|
+
const apiUrl = options._apiUrl || defaultApiUrl
|
|
22
|
+
const url = `${apiUrl}/teams/${id}`
|
|
23
|
+
const { data } = await ghget(auth, url, options)
|
|
24
|
+
return data
|
|
46
25
|
}
|
|
47
26
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (err)
|
|
55
|
-
return callback(err)
|
|
56
|
-
|
|
57
|
-
getById(auth, id, callback)
|
|
58
|
-
})
|
|
27
|
+
export async function get (auth, org, name, options = {}) {
|
|
28
|
+
if (name === undefined) {
|
|
29
|
+
return getById(auth, org, options)
|
|
30
|
+
}
|
|
31
|
+
const id = await teamIdByName(auth, org, name, options)
|
|
32
|
+
return getById(auth, id, options)
|
|
59
33
|
}
|
|
60
34
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
35
|
+
async function membersById (auth, id, options = {}) {
|
|
36
|
+
const apiUrl = options._apiUrl || defaultApiUrl
|
|
37
|
+
const url = `${apiUrl}/teams/${id}/members`
|
|
38
|
+
return lister(auth, url, options)
|
|
64
39
|
}
|
|
65
40
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (err)
|
|
73
|
-
return callback(err)
|
|
74
|
-
|
|
75
|
-
membersById(auth, id, callback)
|
|
76
|
-
})
|
|
41
|
+
export async function members (auth, org, name, options = {}) {
|
|
42
|
+
if (name === undefined) {
|
|
43
|
+
return membersById(auth, org, options)
|
|
44
|
+
}
|
|
45
|
+
const id = await teamIdByName(auth, org, name, options)
|
|
46
|
+
return membersById(auth, id, options)
|
|
77
47
|
}
|
|
78
48
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
49
|
+
export async function userTeams (auth, options = {}) {
|
|
50
|
+
const apiUrl = options._apiUrl || defaultApiUrl
|
|
51
|
+
const url = `${apiUrl}/user/teams`
|
|
52
|
+
return lister(auth, url, options)
|
|
82
53
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
module.exports.list = list
|
|
86
|
-
module.exports.get = get
|
|
87
|
-
module.exports.members = members
|
|
88
|
-
module.exports.userTeams = userTeams
|
package/package.json
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ghteams",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Interact with the GitHub organisation teams API",
|
|
5
|
-
"
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": "./ghteams.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",
|
|
@@ -23,12 +30,98 @@
|
|
|
23
30
|
},
|
|
24
31
|
"homepage": "https://github.com/rvagg/ghteams",
|
|
25
32
|
"dependencies": {
|
|
26
|
-
"
|
|
33
|
+
"ghutils": "^5.0.0"
|
|
27
34
|
},
|
|
28
35
|
"devDependencies": {
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
36
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
37
|
+
"@semantic-release/commit-analyzer": "^13.0.0",
|
|
38
|
+
"@semantic-release/git": "^10.0.1",
|
|
39
|
+
"@semantic-release/github": "^12.0.0",
|
|
40
|
+
"@semantic-release/npm": "^13.0.0",
|
|
41
|
+
"@semantic-release/release-notes-generator": "^14.0.1",
|
|
42
|
+
"conventional-changelog-conventionalcommits": "^9.0.0",
|
|
43
|
+
"semantic-release": "^25.0.0",
|
|
44
|
+
"standard": "^17.1.2"
|
|
45
|
+
},
|
|
46
|
+
"release": {
|
|
47
|
+
"branches": [
|
|
48
|
+
"master"
|
|
49
|
+
],
|
|
50
|
+
"plugins": [
|
|
51
|
+
[
|
|
52
|
+
"@semantic-release/commit-analyzer",
|
|
53
|
+
{
|
|
54
|
+
"preset": "conventionalcommits",
|
|
55
|
+
"releaseRules": [
|
|
56
|
+
{
|
|
57
|
+
"breaking": true,
|
|
58
|
+
"release": "major"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"revert": true,
|
|
62
|
+
"release": "patch"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"type": "feat",
|
|
66
|
+
"release": "minor"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"type": "fix",
|
|
70
|
+
"release": "patch"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"type": "chore",
|
|
74
|
+
"release": "patch"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"type": "docs",
|
|
78
|
+
"release": "patch"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"type": "test",
|
|
82
|
+
"release": "patch"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"scope": "no-release",
|
|
86
|
+
"release": false
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
],
|
|
91
|
+
[
|
|
92
|
+
"@semantic-release/release-notes-generator",
|
|
93
|
+
{
|
|
94
|
+
"preset": "conventionalcommits",
|
|
95
|
+
"presetConfig": {
|
|
96
|
+
"types": [
|
|
97
|
+
{
|
|
98
|
+
"type": "feat",
|
|
99
|
+
"section": "Features"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"type": "fix",
|
|
103
|
+
"section": "Bug Fixes"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"type": "chore",
|
|
107
|
+
"section": "Trivial Changes"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"type": "docs",
|
|
111
|
+
"section": "Trivial Changes"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"type": "test",
|
|
115
|
+
"section": "Tests"
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
],
|
|
121
|
+
"@semantic-release/changelog",
|
|
122
|
+
"@semantic-release/npm",
|
|
123
|
+
"@semantic-release/github",
|
|
124
|
+
"@semantic-release/git"
|
|
125
|
+
]
|
|
33
126
|
}
|
|
34
127
|
}
|
package/test.js
CHANGED
|
@@ -1,199 +1,139 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return hyperget.apply(this, arguments)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function makeServer (data) {
|
|
18
|
-
var ee = new EE()
|
|
19
|
-
, i = 0
|
|
20
|
-
, server = http.createServer(function (req, res) {
|
|
21
|
-
ee.emit('request', req)
|
|
22
|
-
|
|
23
|
-
var _data = Array.isArray(data) ? data[i++] : data
|
|
24
|
-
res.end(JSON.stringify(_data))
|
|
25
|
-
|
|
26
|
-
if (!Array.isArray(data) || i == data.length)
|
|
27
|
-
server.close()
|
|
28
|
-
})
|
|
29
|
-
.listen(0, function (err) {
|
|
30
|
-
if (err)
|
|
31
|
-
return ee.emit('error', err)
|
|
32
|
-
|
|
33
|
-
hyperget = function (url, opts) {
|
|
34
|
-
ee.emit('get', url, opts)
|
|
35
|
-
return _hyperquest('http://localhost:' + server.address().port, opts)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
ee.emit('ready')
|
|
39
|
-
})
|
|
40
|
-
.on('close', ee.emit.bind(ee, 'close'))
|
|
41
|
-
|
|
42
|
-
return ee
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
function toAuth (auth) {
|
|
47
|
-
return 'Basic ' + (new Buffer(auth.user + ':' + auth.token).toString('base64'))
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
function verifyRequest (t, auth) {
|
|
52
|
-
return function (req) {
|
|
53
|
-
t.ok(true, 'got request')
|
|
54
|
-
t.equal(req.headers['authorization'], toAuth(auth), 'got auth header')
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
function verifyUrl (t, url) {
|
|
60
|
-
return function (_url) {
|
|
61
|
-
t.equal(_url, url, 'correct url')
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
function verifyClose (t) {
|
|
67
|
-
return function () {
|
|
68
|
-
t.ok(true, 'got close')
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
function verifyData (t, data) {
|
|
74
|
-
return function (err, _data) {
|
|
75
|
-
t.notOk(err, 'no error')
|
|
76
|
-
t.ok(_data, 'got data')
|
|
77
|
-
t.deepEqual(_data, data, 'got expected data')
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
test('test list teams', function (t) {
|
|
83
|
-
t.plan(7)
|
|
84
|
-
|
|
85
|
-
var auth = { user: 'authuser', token: 'authtoken' }
|
|
86
|
-
, org = 'testorg'
|
|
87
|
-
, testData = { test: 'data' }
|
|
88
|
-
|
|
89
|
-
makeServer(testData)
|
|
90
|
-
.on('ready', function () {
|
|
91
|
-
ghteams.list(xtend(auth), org, verifyData(t, testData))
|
|
1
|
+
import { test } from 'node:test'
|
|
2
|
+
import assert from 'node:assert'
|
|
3
|
+
import { createMockServer, createMockServerWithHandler } from 'ghutils/test-util'
|
|
4
|
+
import * as ghteams from './ghteams.js'
|
|
5
|
+
|
|
6
|
+
test('list teams', async () => {
|
|
7
|
+
const auth = { token: 'test-token' }
|
|
8
|
+
const testData = [{ id: 1, name: 'Team A' }, { id: 2, name: 'Team B' }]
|
|
9
|
+
|
|
10
|
+
const server = await createMockServer({ response: testData })
|
|
11
|
+
try {
|
|
12
|
+
const results = await ghteams.list(auth, 'testorg', {
|
|
13
|
+
_apiUrl: server.baseUrl
|
|
92
14
|
})
|
|
93
|
-
.
|
|
94
|
-
.
|
|
95
|
-
|
|
15
|
+
assert.deepStrictEqual(results, testData)
|
|
16
|
+
assert.ok(server.requests[0].url.includes('/orgs/testorg/teams'))
|
|
17
|
+
} finally {
|
|
18
|
+
await server.close()
|
|
19
|
+
}
|
|
96
20
|
})
|
|
97
21
|
|
|
22
|
+
test('get team by id', async () => {
|
|
23
|
+
const auth = { token: 'test-token' }
|
|
24
|
+
const testData = { id: 101, name: 'My Team' }
|
|
98
25
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
, teamId = 101
|
|
104
|
-
, testData = { test: 'team data' }
|
|
105
|
-
|
|
106
|
-
makeServer(testData)
|
|
107
|
-
.on('ready', function () {
|
|
108
|
-
ghteams.get(xtend(auth), teamId, verifyData(t, testData))
|
|
26
|
+
const server = await createMockServer({ response: testData })
|
|
27
|
+
try {
|
|
28
|
+
const result = await ghteams.get(auth, 101, undefined, {
|
|
29
|
+
_apiUrl: server.baseUrl
|
|
109
30
|
})
|
|
110
|
-
.
|
|
111
|
-
.
|
|
112
|
-
|
|
31
|
+
assert.deepStrictEqual(result, testData)
|
|
32
|
+
assert.ok(server.requests[0].url.includes('/teams/101'))
|
|
33
|
+
} finally {
|
|
34
|
+
await server.close()
|
|
35
|
+
}
|
|
113
36
|
})
|
|
114
37
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
38
|
+
test('get team by org and name', async () => {
|
|
39
|
+
const auth = { token: 'test-token' }
|
|
40
|
+
const teamList = [{ id: 101, name: 'foo' }, { id: 202, name: 'myteam' }, { id: 303, name: 'bar' }]
|
|
41
|
+
const teamData = { id: 202, name: 'myteam', description: 'My Team' }
|
|
42
|
+
|
|
43
|
+
let requestCount = 0
|
|
44
|
+
const mock = await createMockServerWithHandler((req, res) => {
|
|
45
|
+
requestCount++
|
|
46
|
+
if (requestCount === 1) {
|
|
47
|
+
res.end(JSON.stringify(teamList))
|
|
48
|
+
} else {
|
|
49
|
+
res.end(JSON.stringify(teamData))
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
const result = await ghteams.get(auth, 'myorg', 'myteam', {
|
|
55
|
+
_apiUrl: mock.baseUrl
|
|
126
56
|
})
|
|
127
|
-
.
|
|
128
|
-
.
|
|
129
|
-
|
|
57
|
+
assert.deepStrictEqual(result, teamData)
|
|
58
|
+
assert.strictEqual(requestCount, 2)
|
|
59
|
+
} finally {
|
|
60
|
+
await mock.close()
|
|
61
|
+
}
|
|
130
62
|
})
|
|
131
63
|
|
|
64
|
+
test('get team by name throws for unknown team', async () => {
|
|
65
|
+
const auth = { token: 'test-token' }
|
|
66
|
+
const teamList = [{ id: 101, name: 'foo' }]
|
|
67
|
+
|
|
68
|
+
const server = await createMockServer({ response: teamList })
|
|
69
|
+
try {
|
|
70
|
+
await assert.rejects(
|
|
71
|
+
ghteams.get(auth, 'myorg', 'nonexistent', { _apiUrl: server.baseUrl }),
|
|
72
|
+
(err) => {
|
|
73
|
+
assert.ok(err.message.includes('No such team'))
|
|
74
|
+
assert.ok(err.message.includes('nonexistent'))
|
|
75
|
+
return true
|
|
76
|
+
}
|
|
77
|
+
)
|
|
78
|
+
} finally {
|
|
79
|
+
await server.close()
|
|
80
|
+
}
|
|
81
|
+
})
|
|
132
82
|
|
|
133
|
-
test('
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
var auth = { user: 'authuser2', token: 'authtoken2' }
|
|
137
|
-
, org = 'myorg'
|
|
138
|
-
, name = 'myteamname'
|
|
139
|
-
, teamId = 202
|
|
140
|
-
, testData = [
|
|
141
|
-
[ { name: 'foo', id: 101 }, { name: name, id: teamId }, { name: 'bar', id: 303 } ]
|
|
142
|
-
, { test: 'team data' }
|
|
143
|
-
]
|
|
83
|
+
test('get members by id', async () => {
|
|
84
|
+
const auth = { token: 'test-token' }
|
|
85
|
+
const memberData = [{ id: 1, login: 'user1' }, { id: 2, login: 'user2' }]
|
|
144
86
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
.on('request', verifyRequest(t, auth))
|
|
150
|
-
.once('get' , function (url) {
|
|
151
|
-
verifyUrl(t, 'https://api.github.com/orgs/' + org + '/teams')(url)
|
|
152
|
-
// second GET:
|
|
153
|
-
server.on('get', verifyUrl(t, 'https://api.github.com/teams/' + teamId))
|
|
87
|
+
const server = await createMockServer({ response: memberData })
|
|
88
|
+
try {
|
|
89
|
+
const results = await ghteams.members(auth, 101, undefined, {
|
|
90
|
+
_apiUrl: server.baseUrl
|
|
154
91
|
})
|
|
155
|
-
.
|
|
92
|
+
assert.deepStrictEqual(results, memberData)
|
|
93
|
+
assert.ok(server.requests[0].url.includes('/teams/101/members'))
|
|
94
|
+
} finally {
|
|
95
|
+
await server.close()
|
|
96
|
+
}
|
|
156
97
|
})
|
|
157
98
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
.once('get' , function (url) {
|
|
177
|
-
verifyUrl(t, 'https://api.github.com/orgs/' + org + '/teams')(url)
|
|
178
|
-
// second GET:
|
|
179
|
-
server.on('get', verifyUrl(t, 'https://api.github.com/teams/' + teamId + '/members'))
|
|
99
|
+
test('get members by org and name', async () => {
|
|
100
|
+
const auth = { token: 'test-token' }
|
|
101
|
+
const teamList = [{ id: 202, name: 'myteam' }]
|
|
102
|
+
const memberData = [{ id: 1, login: 'user1' }]
|
|
103
|
+
|
|
104
|
+
let requestCount = 0
|
|
105
|
+
const mock = await createMockServerWithHandler((req, res) => {
|
|
106
|
+
requestCount++
|
|
107
|
+
if (requestCount === 1) {
|
|
108
|
+
res.end(JSON.stringify(teamList))
|
|
109
|
+
} else {
|
|
110
|
+
res.end(JSON.stringify(memberData))
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
const results = await ghteams.members(auth, 'myorg', 'myteam', {
|
|
116
|
+
_apiUrl: mock.baseUrl
|
|
180
117
|
})
|
|
181
|
-
.
|
|
118
|
+
assert.deepStrictEqual(results, memberData)
|
|
119
|
+
assert.strictEqual(requestCount, 2)
|
|
120
|
+
} finally {
|
|
121
|
+
await mock.close()
|
|
122
|
+
}
|
|
182
123
|
})
|
|
183
124
|
|
|
125
|
+
test('user teams', async () => {
|
|
126
|
+
const auth = { token: 'test-token' }
|
|
127
|
+
const testData = [{ id: 1, name: 'Team A' }]
|
|
184
128
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
, teamId = 101
|
|
190
|
-
, testData = { test: 'team data' }
|
|
191
|
-
|
|
192
|
-
makeServer(testData)
|
|
193
|
-
.on('ready', function () {
|
|
194
|
-
ghteams.userTeams(xtend(auth), verifyData(t, testData))
|
|
129
|
+
const server = await createMockServer({ response: testData })
|
|
130
|
+
try {
|
|
131
|
+
const results = await ghteams.userTeams(auth, {
|
|
132
|
+
_apiUrl: server.baseUrl
|
|
195
133
|
})
|
|
196
|
-
.
|
|
197
|
-
.
|
|
198
|
-
|
|
134
|
+
assert.deepStrictEqual(results, testData)
|
|
135
|
+
assert.ok(server.requests[0].url.includes('/user/teams'))
|
|
136
|
+
} finally {
|
|
137
|
+
await server.close()
|
|
138
|
+
}
|
|
199
139
|
})
|
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
|
-
}
|
package/.npmignore
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
node_modules/
|