@pkgjs/statusboard 0.0.14 → 0.1.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/workflows/build.yml +47 -10
- package/.github/workflows/test.yml +51 -0
- package/CODE_OF_CONDUCT.md +4 -0
- package/CONTRIBUTING.md +36 -0
- package/LICENSE +5 -16
- package/README.md +3 -0
- package/lib/config.js +1 -1
- package/lib/db/build-index.js +13 -10
- package/lib/files.js +0 -1
- package/lib/github.js +45 -36
- package/lib/npm.js +3 -3
- package/lib/project.js +1 -1
- package/lib/template/index.js +1 -1
- package/package.json +19 -17
- package/template/css/index.css +66 -15
- package/template/css/page.css +4 -7
- package/template/css/project-list.css +14 -5
- package/template/indicies.js +1 -1
- package/template/js/index.js +21 -24
- package/template/js/page.js +1 -0
- package/template/js/project-list.js +66 -63
|
@@ -1,16 +1,53 @@
|
|
|
1
|
-
name:
|
|
2
|
-
|
|
1
|
+
name: Generate Statusboard
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
pages: write
|
|
12
|
+
id-token: write
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: "pages"
|
|
16
|
+
cancel-in-progress: false
|
|
17
|
+
|
|
3
18
|
jobs:
|
|
4
|
-
|
|
19
|
+
index:
|
|
20
|
+
environment:
|
|
21
|
+
name: github-pages
|
|
22
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
5
23
|
runs-on: ubuntu-latest
|
|
6
24
|
steps:
|
|
7
|
-
-
|
|
8
|
-
|
|
9
|
-
|
|
25
|
+
- name: Checkout
|
|
26
|
+
uses: actions/checkout@v4
|
|
27
|
+
- name: Setup Pages
|
|
28
|
+
uses: actions/configure-pages@v5
|
|
29
|
+
- uses: actions/setup-node@v4
|
|
10
30
|
with:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
31
|
+
node-version: 20
|
|
32
|
+
- uses: actions/cache@v4
|
|
33
|
+
id: cache
|
|
34
|
+
with:
|
|
35
|
+
path: |
|
|
36
|
+
~/.npm
|
|
37
|
+
~/.cache
|
|
38
|
+
./dist
|
|
39
|
+
./node_modules
|
|
40
|
+
key: ${{ runner.os }}-build-${{ github.sha }}
|
|
41
|
+
- if: steps.cache.outputs.cache-hit != 'true'
|
|
42
|
+
run: npm install
|
|
43
|
+
shell: bash
|
|
44
|
+
- run: npm run build
|
|
15
45
|
env:
|
|
16
46
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
47
|
+
- name: Upload artifact
|
|
48
|
+
uses: actions/upload-pages-artifact@v3
|
|
49
|
+
with:
|
|
50
|
+
path: './gh-pages'
|
|
51
|
+
- name: Deploy to GitHub Pages
|
|
52
|
+
id: deployment
|
|
53
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: Run Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
10
|
+
|
|
11
|
+
concurrency:
|
|
12
|
+
group: "${{ github.workflow }} ✨ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}"
|
|
13
|
+
cancel-in-progress: false
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
lint:
|
|
17
|
+
name: Lint
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- name: Setup Node.js
|
|
22
|
+
uses: actions/setup-node@v4
|
|
23
|
+
with:
|
|
24
|
+
node-version: 'lts/*'
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
run: npm install --ignore-scripts --only=dev
|
|
28
|
+
|
|
29
|
+
- name: Run lint
|
|
30
|
+
run: npm run lint
|
|
31
|
+
|
|
32
|
+
test:
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
strategy:
|
|
35
|
+
matrix:
|
|
36
|
+
node-version: [18, 19, 20, 21, 22, 23]
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@v4
|
|
39
|
+
|
|
40
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
41
|
+
uses: actions/setup-node@v4
|
|
42
|
+
with:
|
|
43
|
+
node-version: ${{ matrix.node-version }}
|
|
44
|
+
|
|
45
|
+
- name: Install dependencies
|
|
46
|
+
run: npm install
|
|
47
|
+
|
|
48
|
+
- name: Run tests
|
|
49
|
+
env:
|
|
50
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
51
|
+
run: npm test
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
## Code of Conduct
|
|
4
|
+
|
|
5
|
+
The Node.js project has a
|
|
6
|
+
[Code of Conduct](https://github.com/nodejs/admin/blob/master/CODE_OF_CONDUCT.md)
|
|
7
|
+
to which all contributors must adhere.
|
|
8
|
+
|
|
9
|
+
See [details on our policy on Code of Conduct](https://github.com/nodejs/node/blob/master/doc/guides/contributing/code-of-conduct.md).
|
|
10
|
+
|
|
11
|
+
<a id="developers-certificate-of-origin"></a>
|
|
12
|
+
## Developer's Certificate of Origin 1.1
|
|
13
|
+
|
|
14
|
+
By making a contribution to this project, I certify that:
|
|
15
|
+
|
|
16
|
+
* (a) The contribution was created in whole or in part by me and I
|
|
17
|
+
have the right to submit it under the open source license
|
|
18
|
+
indicated in the file; or
|
|
19
|
+
|
|
20
|
+
* (b) The contribution is based upon previous work that, to the best
|
|
21
|
+
of my knowledge, is covered under an appropriate open source
|
|
22
|
+
license and I have the right under that license to submit that
|
|
23
|
+
work with modifications, whether created in whole or in part
|
|
24
|
+
by me, under the same open source license (unless I am
|
|
25
|
+
permitted to submit under a different license), as indicated
|
|
26
|
+
in the file; or
|
|
27
|
+
|
|
28
|
+
* (c) The contribution was provided directly to me by some other
|
|
29
|
+
person who certified (a), (b) or (c) and I have not modified
|
|
30
|
+
it.
|
|
31
|
+
|
|
32
|
+
* (d) I understand and agree that this project and the contribution
|
|
33
|
+
are public and that a record of the contribution (including all
|
|
34
|
+
personal information I submit with it, including my sign-off) is
|
|
35
|
+
maintained indefinitely and may be redistributed consistent with
|
|
36
|
+
this project or the open source license(s) involved.
|
package/LICENSE
CHANGED
|
@@ -1,21 +1,10 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright
|
|
3
|
+
Copyright (c) 2020 Contributors https://github.com/pkgjs/statusboard/graphs/contributors
|
|
4
4
|
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
11
6
|
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
14
10
|
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -5,6 +5,9 @@ of GitHub projects. When you have work spread across multiple repos
|
|
|
5
5
|
and multiple orginizations, it is often hard to track things. This
|
|
6
6
|
is what `@pkgjs/statusboard` aims to solve.
|
|
7
7
|
|
|
8
|
+
This repository is managed by the [Package Maintenance Working Group](https://github.com/nodejs/package-maintenance), see [Governance](https://github.com/nodejs/package-maintenance/blob/master/Governance.md).
|
|
9
|
+
|
|
10
|
+
|
|
8
11
|
## Example
|
|
9
12
|
|
|
10
13
|
https://expressjs.github.io/statusboard/
|
package/lib/config.js
CHANGED
|
@@ -16,7 +16,7 @@ const DEFAULTS = {
|
|
|
16
16
|
baseUrl: '',
|
|
17
17
|
port: 5005,
|
|
18
18
|
template: builder,
|
|
19
|
-
indicies
|
|
19
|
+
indicies,
|
|
20
20
|
title: 'StatusBoard',
|
|
21
21
|
description: 'Project StatusBoard',
|
|
22
22
|
issueLabels: ['top priority', 'good first issue', 'help wanted', 'discussion', 'meeting']
|
package/lib/db/build-index.js
CHANGED
|
@@ -6,8 +6,8 @@ const { Project } = require('../project')
|
|
|
6
6
|
|
|
7
7
|
module.exports = async function buildIndex (config, db) {
|
|
8
8
|
// Loop projects
|
|
9
|
-
for await (
|
|
10
|
-
|
|
9
|
+
for await (const evt of iterateProjects(config)) {
|
|
10
|
+
const { type, project, detail } = evt
|
|
11
11
|
let key = `${project.repoOwner}:${project.repoName}:${type}`
|
|
12
12
|
switch (type) {
|
|
13
13
|
case 'ISSUE':
|
|
@@ -32,21 +32,21 @@ async function * iterateProjects (config) {
|
|
|
32
32
|
const [octokit, graphQL] = await github(config.github)
|
|
33
33
|
|
|
34
34
|
// Load projects
|
|
35
|
-
for (
|
|
36
|
-
for await (
|
|
35
|
+
for (const proj of config.projects) {
|
|
36
|
+
for await (const evt of loadProject(octokit, graphQL, proj, config)) {
|
|
37
37
|
yield evt
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
// Load projects for org
|
|
42
|
-
for (
|
|
42
|
+
for (const org of config.orgs) {
|
|
43
43
|
try {
|
|
44
|
-
for await (
|
|
44
|
+
for await (const repo of github.getOrgRepos(graphQL, org.name)) {
|
|
45
45
|
const proj = new Project({
|
|
46
46
|
repoOwner: repo.owner,
|
|
47
47
|
repoName: repo.name
|
|
48
48
|
})
|
|
49
|
-
for await (
|
|
49
|
+
for await (const evt of loadProject(octokit, graphQL, proj, config, repo)) {
|
|
50
50
|
yield evt
|
|
51
51
|
}
|
|
52
52
|
}
|
|
@@ -67,6 +67,9 @@ async function * loadProject (octokit, graphQL, project, config, _repo) {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
// Check config for repoBranch
|
|
71
|
+
project.repoBranch = project.repoBranch ?? repo.branch
|
|
72
|
+
|
|
70
73
|
let pkg
|
|
71
74
|
try {
|
|
72
75
|
pkg = await files.getPackageJson(project)
|
|
@@ -130,7 +133,7 @@ async function * loadProject (octokit, graphQL, project, config, _repo) {
|
|
|
130
133
|
}
|
|
131
134
|
|
|
132
135
|
try {
|
|
133
|
-
for await (
|
|
136
|
+
for await (const issue of github.getRepoIssues(graphQL, project.repoOwner, project.repoName)) {
|
|
134
137
|
yield projectDetail('ISSUE', project, issue)
|
|
135
138
|
}
|
|
136
139
|
} catch (e) {
|
|
@@ -138,7 +141,7 @@ async function * loadProject (octokit, graphQL, project, config, _repo) {
|
|
|
138
141
|
}
|
|
139
142
|
|
|
140
143
|
try {
|
|
141
|
-
for await (
|
|
144
|
+
for await (const activity of github.getRepoActivity(octokit, project.repoOwner, project.repoName)) {
|
|
142
145
|
yield projectDetail('ACTIVITY', project, activity)
|
|
143
146
|
}
|
|
144
147
|
} catch (e) {
|
|
@@ -146,7 +149,7 @@ async function * loadProject (octokit, graphQL, project, config, _repo) {
|
|
|
146
149
|
}
|
|
147
150
|
|
|
148
151
|
try {
|
|
149
|
-
for await (
|
|
152
|
+
for await (const commit of github.getRepoCommits(graphQL, project.repoOwner, project.repoName, project.repoBranch)) {
|
|
150
153
|
yield projectDetail('COMMIT', project, commit)
|
|
151
154
|
}
|
|
152
155
|
} catch (e) {
|
package/lib/files.js
CHANGED
package/lib/github.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
const inquirer = require('inquirer')
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
const { retry } = require('@octokit/plugin-retry')
|
|
4
|
+
const { throttling } = require('@octokit/plugin-throttling')
|
|
5
|
+
const { Octokit } = require('@octokit/rest')
|
|
6
|
+
|
|
7
|
+
const OctokitRest = Octokit
|
|
8
|
+
.plugin(retry, throttling)
|
|
6
9
|
|
|
7
10
|
const { graphql } = require('@octokit/graphql')
|
|
8
11
|
|
|
@@ -32,6 +35,9 @@ const repoQuerySnip = `{
|
|
|
32
35
|
name
|
|
33
36
|
}
|
|
34
37
|
homepageUrl
|
|
38
|
+
defaultBranchRef {
|
|
39
|
+
name
|
|
40
|
+
}
|
|
35
41
|
}`
|
|
36
42
|
|
|
37
43
|
const issueQuerySnip = `pageInfo {
|
|
@@ -75,7 +81,7 @@ async function getOctokit (opts = {}) {
|
|
|
75
81
|
let {
|
|
76
82
|
token,
|
|
77
83
|
log,
|
|
78
|
-
|
|
84
|
+
onSecondaryRateLimit,
|
|
79
85
|
onRateLimit
|
|
80
86
|
} = opts
|
|
81
87
|
|
|
@@ -94,10 +100,10 @@ async function getOctokit (opts = {}) {
|
|
|
94
100
|
|
|
95
101
|
log = log || console
|
|
96
102
|
|
|
97
|
-
const octokit =
|
|
103
|
+
const octokit = new OctokitRest({
|
|
98
104
|
auth,
|
|
99
105
|
throttle: {
|
|
100
|
-
|
|
106
|
+
onSecondaryRateLimit: onSecondaryRateLimit || ((err) => {
|
|
101
107
|
log.error(err)
|
|
102
108
|
}),
|
|
103
109
|
onRateLimit: onRateLimit || ((err, options) => {
|
|
@@ -133,6 +139,7 @@ class Repo {
|
|
|
133
139
|
this.license = repo.licenseInfo && (repo.licenseInfo.spdx_id || repo.licenseInfo.name)
|
|
134
140
|
this.language = repo.primaryLanguage ? repo.primaryLanguage.name : repo.primaryLanguage
|
|
135
141
|
this.homepage = repo.homepageUrl
|
|
142
|
+
this.branch = repo.defaultBranchRef.name
|
|
136
143
|
}
|
|
137
144
|
}
|
|
138
145
|
|
|
@@ -145,7 +152,7 @@ module.exports.getRepo =
|
|
|
145
152
|
${repoQuerySnip}
|
|
146
153
|
}`,
|
|
147
154
|
org: owner,
|
|
148
|
-
repo
|
|
155
|
+
repo
|
|
149
156
|
})
|
|
150
157
|
return new Repo(owner, resp.repository)
|
|
151
158
|
} catch (error) {
|
|
@@ -203,8 +210,8 @@ async function getRemainingPullRequests (graphQL, owner, repo, cursor) {
|
|
|
203
210
|
}
|
|
204
211
|
`,
|
|
205
212
|
org: owner,
|
|
206
|
-
repo
|
|
207
|
-
cursor
|
|
213
|
+
repo,
|
|
214
|
+
cursor
|
|
208
215
|
})
|
|
209
216
|
const { pageInfo, edges } = resp.organization.repository.pullRequests
|
|
210
217
|
const pullRequests = !pageInfo.hasNextPage ? edges : edges.concat(await getRemainingPullRequests(graphQL, owner, repo, pageInfo.endCursor))
|
|
@@ -229,7 +236,7 @@ async function getPullRequests (graphQL, owner, repo) {
|
|
|
229
236
|
}
|
|
230
237
|
}`,
|
|
231
238
|
org: owner,
|
|
232
|
-
repo
|
|
239
|
+
repo
|
|
233
240
|
})
|
|
234
241
|
const { pageInfo, edges } = resp.organization.repository.pullRequests
|
|
235
242
|
const pullRequests = !pageInfo.hasNextPage ? edges : edges.concat(await getRemainingPullRequests(graphQL, owner, repo, pageInfo.endCursor))
|
|
@@ -255,8 +262,8 @@ async function getRemainingIssues (graphQL, owner, repo, cursor) {
|
|
|
255
262
|
}
|
|
256
263
|
`,
|
|
257
264
|
org: owner,
|
|
258
|
-
repo
|
|
259
|
-
cursor
|
|
265
|
+
repo,
|
|
266
|
+
cursor
|
|
260
267
|
})
|
|
261
268
|
const { pageInfo, edges } = resp.organization.repository.issues
|
|
262
269
|
const issues = !pageInfo.hasNextPage ? edges : edges.concat(await getRemainingIssues(graphQL, owner, repo, pageInfo.endCursor))
|
|
@@ -271,7 +278,7 @@ async function getRemainingIssues (graphQL, owner, repo, cursor) {
|
|
|
271
278
|
module.exports.getRepoIssues =
|
|
272
279
|
async function * getRepoIssues (graphQL, owner, repo) {
|
|
273
280
|
try {
|
|
274
|
-
|
|
281
|
+
const resp = await graphQL({
|
|
275
282
|
query: `query ($org: String!, $repo: String!) {
|
|
276
283
|
organization(login: $org) {
|
|
277
284
|
repository(name: $repo) {
|
|
@@ -282,14 +289,14 @@ module.exports.getRepoIssues =
|
|
|
282
289
|
}
|
|
283
290
|
}`,
|
|
284
291
|
org: owner,
|
|
285
|
-
repo
|
|
292
|
+
repo
|
|
286
293
|
})
|
|
287
294
|
const { pageInfo, edges } = resp.organization.repository.issues
|
|
288
295
|
const issues = !pageInfo.hasNextPage ? edges : edges.concat(await getRemainingIssues(graphQL, owner, repo, pageInfo.endCursor))
|
|
289
296
|
|
|
290
297
|
issues.push.apply(issues, await getPullRequests(graphQL, owner, repo))
|
|
291
298
|
|
|
292
|
-
for (
|
|
299
|
+
for (const i of issues) {
|
|
293
300
|
yield new Issue(owner, repo, i.node)
|
|
294
301
|
}
|
|
295
302
|
} catch (error) {
|
|
@@ -330,7 +337,7 @@ async function * getRepoActivity (octokit, owner, repo) {
|
|
|
330
337
|
throw e
|
|
331
338
|
}
|
|
332
339
|
|
|
333
|
-
for (
|
|
340
|
+
for (const a of resp.data) {
|
|
334
341
|
yield new Activity(owner, repo, a)
|
|
335
342
|
}
|
|
336
343
|
}
|
|
@@ -361,7 +368,7 @@ module.exports.getReadme =
|
|
|
361
368
|
}
|
|
362
369
|
`,
|
|
363
370
|
org: owner,
|
|
364
|
-
repo
|
|
371
|
+
repo
|
|
365
372
|
})
|
|
366
373
|
let readmeText
|
|
367
374
|
Object.values(resp.repository).forEach(element => {
|
|
@@ -393,8 +400,8 @@ async function getRemainingRepos (graphQL, org, cursor) {
|
|
|
393
400
|
}
|
|
394
401
|
}
|
|
395
402
|
}`,
|
|
396
|
-
org
|
|
397
|
-
cursor
|
|
403
|
+
org,
|
|
404
|
+
cursor
|
|
398
405
|
})
|
|
399
406
|
|
|
400
407
|
const { pageInfo, nodes } = resp.organization.repositories
|
|
@@ -411,7 +418,7 @@ async function getRemainingRepos (graphQL, org, cursor) {
|
|
|
411
418
|
module.exports.getOrgRepos =
|
|
412
419
|
async function * getOrgRepos (graphQL, org) {
|
|
413
420
|
try {
|
|
414
|
-
|
|
421
|
+
const resp = await graphQL({
|
|
415
422
|
query: `query($org: String!)
|
|
416
423
|
{
|
|
417
424
|
organization(login: $org) {
|
|
@@ -425,13 +432,13 @@ module.exports.getOrgRepos =
|
|
|
425
432
|
}
|
|
426
433
|
}
|
|
427
434
|
}`,
|
|
428
|
-
org
|
|
435
|
+
org
|
|
429
436
|
})
|
|
430
437
|
|
|
431
438
|
const { pageInfo, nodes } = resp.organization.repositories
|
|
432
439
|
const repos = !pageInfo.hasNextPage ? nodes : nodes.concat(await getRemainingRepos(graphQL, org, pageInfo.endCursor))
|
|
433
440
|
|
|
434
|
-
for (
|
|
441
|
+
for (const r of repos) {
|
|
435
442
|
yield new Repo(org, r)
|
|
436
443
|
}
|
|
437
444
|
} catch (error) {
|
|
@@ -462,12 +469,12 @@ class Commit {
|
|
|
462
469
|
}
|
|
463
470
|
}
|
|
464
471
|
|
|
465
|
-
async function getRemainingCommits (graphQL, owner, repo, cursor) {
|
|
472
|
+
async function getRemainingCommits (graphQL, owner, repo, cursor, branch) {
|
|
466
473
|
try {
|
|
467
|
-
|
|
468
|
-
query: `query ($org: String!, $repo: String!, $cursor: String!) {
|
|
474
|
+
const resp = await graphQL({
|
|
475
|
+
query: `query ($org: String!, $repo: String!, $cursor: String!, $branch: String!) {
|
|
469
476
|
repository(name: $repo, owner: $org) {
|
|
470
|
-
object(expression:
|
|
477
|
+
object(expression: $branch) {
|
|
471
478
|
... on Commit {
|
|
472
479
|
history(first: 100, after: $cursor) {
|
|
473
480
|
nodes {
|
|
@@ -498,11 +505,12 @@ async function getRemainingCommits (graphQL, owner, repo, cursor) {
|
|
|
498
505
|
}
|
|
499
506
|
`,
|
|
500
507
|
org: owner,
|
|
501
|
-
repo
|
|
502
|
-
cursor
|
|
508
|
+
repo,
|
|
509
|
+
cursor,
|
|
510
|
+
branch
|
|
503
511
|
})
|
|
504
512
|
const { pageInfo, nodes } = resp.repository.object.history
|
|
505
|
-
const commits = !pageInfo.hasNextPage ? nodes : nodes.concat(await getRemainingCommits(graphQL, owner, repo, pageInfo.endCursor))
|
|
513
|
+
const commits = !pageInfo.hasNextPage ? nodes : nodes.concat(await getRemainingCommits(graphQL, owner, repo, pageInfo.endCursor, branch))
|
|
506
514
|
|
|
507
515
|
return commits
|
|
508
516
|
} catch (error) {
|
|
@@ -512,12 +520,12 @@ async function getRemainingCommits (graphQL, owner, repo, cursor) {
|
|
|
512
520
|
}
|
|
513
521
|
|
|
514
522
|
module.exports.getRepoCommits =
|
|
515
|
-
async function * getRepoCommits (graphQL, owner, repo) {
|
|
523
|
+
async function * getRepoCommits (graphQL, owner, repo, branch) {
|
|
516
524
|
try {
|
|
517
|
-
|
|
518
|
-
query: `query ($org: String!, $repo: String!) {
|
|
525
|
+
const resp = await graphQL({
|
|
526
|
+
query: `query ($org: String!, $repo: String!, $branch: String!) {
|
|
519
527
|
repository(name: $repo, owner: $org) {
|
|
520
|
-
object(expression:
|
|
528
|
+
object(expression: $branch) {
|
|
521
529
|
... on Commit {
|
|
522
530
|
history(first: 100) {
|
|
523
531
|
nodes {
|
|
@@ -548,12 +556,13 @@ async function * getRepoCommits (graphQL, owner, repo) {
|
|
|
548
556
|
}
|
|
549
557
|
`,
|
|
550
558
|
org: owner,
|
|
551
|
-
repo
|
|
559
|
+
repo,
|
|
560
|
+
branch
|
|
552
561
|
})
|
|
553
562
|
const { pageInfo, nodes } = resp.repository.object.history
|
|
554
|
-
const commits = !pageInfo.hasNextPage ? nodes : nodes.concat(await getRemainingCommits(graphQL, owner, repo, pageInfo.endCursor))
|
|
563
|
+
const commits = !pageInfo.hasNextPage ? nodes : nodes.concat(await getRemainingCommits(graphQL, owner, repo, pageInfo.endCursor, branch))
|
|
555
564
|
|
|
556
|
-
for (
|
|
565
|
+
for (const c of commits) {
|
|
557
566
|
yield new Commit(owner, repo, c)
|
|
558
567
|
}
|
|
559
568
|
} catch (error) {
|
package/lib/npm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
-
const
|
|
2
|
+
const pacote = require('pacote')
|
|
3
3
|
|
|
4
4
|
const Packument = module.exports.Packument =
|
|
5
5
|
class Packument {
|
|
@@ -12,7 +12,7 @@ class Packument {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
module.exports.getPackument = async function getNpmPackument (packageName) {
|
|
15
|
-
const resp = await
|
|
15
|
+
const resp = await pacote.packument(packageName)
|
|
16
16
|
return new Packument(resp)
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -30,6 +30,6 @@ class Manifest {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
module.exports.getManifest = async function getNpmManifest (packageName) {
|
|
33
|
-
const resp = await
|
|
33
|
+
const resp = await pacote.manifest(packageName)
|
|
34
34
|
return new Manifest(resp)
|
|
35
35
|
}
|
package/lib/project.js
CHANGED
|
@@ -23,7 +23,7 @@ module.exports.Project = class Project {
|
|
|
23
23
|
this.repo = repo
|
|
24
24
|
this.repoOwner = repoOwner
|
|
25
25
|
this.repoName = repoName
|
|
26
|
-
this.repoBranch = proj.repoBranch
|
|
26
|
+
this.repoBranch = proj.repoBranch
|
|
27
27
|
this.repoDirectory = proj.repoDirectory || '/'
|
|
28
28
|
this.packageName = null
|
|
29
29
|
}
|
package/lib/template/index.js
CHANGED
|
@@ -6,7 +6,7 @@ module.exports = async function (config, db) {
|
|
|
6
6
|
const accumulator = {}
|
|
7
7
|
|
|
8
8
|
// Read full index
|
|
9
|
-
for await (
|
|
9
|
+
for await (const { key, value } of readFullIndex(db)) {
|
|
10
10
|
await Promise.all(Object.keys(indicies).map(async (index) => {
|
|
11
11
|
accumulator[index] = await indicies[index](accumulator[index], config, key, value)
|
|
12
12
|
}))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pkgjs/statusboard",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "A dashboard for project status",
|
|
5
5
|
"author": "Wes Todd <wes@wesleytodd.com>",
|
|
6
6
|
"keywords": [
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"statusboard": "./bin/statusboard"
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
|
-
"
|
|
22
|
+
"lint": "standard",
|
|
23
|
+
"test": "mocha",
|
|
23
24
|
"prepublushOnly": "npm t",
|
|
24
25
|
"postpublish": "git push origin && git push origin --tags",
|
|
25
26
|
"clean": "./bin/statusboard clean -C ./test/fixtures/config -d ./gh-pages/data.db",
|
|
@@ -29,34 +30,35 @@
|
|
|
29
30
|
"serve": "./bin/statusboard serve -o ./gh-pages -C ./test/fixtures/config -d ./gh-pages/data.db"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
|
-
"mocha": "^
|
|
33
|
-
"
|
|
34
|
-
"standard": "^12.0.1"
|
|
33
|
+
"mocha": "^10.8.2",
|
|
34
|
+
"standard": "^17.1.2"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@octokit/graphql": "^
|
|
38
|
-
"@octokit/plugin-retry": "^
|
|
39
|
-
"@octokit/plugin-throttling": "^2.
|
|
40
|
-
"@octokit/rest": "^
|
|
37
|
+
"@octokit/graphql": "^7.1.0",
|
|
38
|
+
"@octokit/plugin-retry": "^6.0.1",
|
|
39
|
+
"@octokit/plugin-throttling": "^8.2.0",
|
|
40
|
+
"@octokit/rest": "^20.1.1",
|
|
41
41
|
"@primer/octicons": "^9.1.1",
|
|
42
|
-
"@wesleytodd/buildcss": "0.0.
|
|
42
|
+
"@wesleytodd/buildcss": "0.0.6",
|
|
43
43
|
"@wesleytodd/buildjs": "0.0.8",
|
|
44
44
|
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
|
|
45
45
|
"cptmpl": "0.0.4",
|
|
46
|
-
"dotenv": "^
|
|
46
|
+
"dotenv": "^16.4.7",
|
|
47
47
|
"es5-lit-element": "^2.2.1",
|
|
48
|
+
"es5-lit-html": "^1.1.1",
|
|
48
49
|
"express": "^4.17.1",
|
|
49
50
|
"fs-extra": "^8.1.0",
|
|
50
|
-
"inquirer": "^
|
|
51
|
+
"inquirer": "^12.4.2",
|
|
51
52
|
"install": "^0.13.0",
|
|
52
53
|
"js-yaml": "^3.13.1",
|
|
53
54
|
"level": "^5.0.1",
|
|
54
|
-
"libnpm": "^2.0.1",
|
|
55
55
|
"lit-element": "^2.2.1",
|
|
56
56
|
"nighthawk": "^2.3.0-1",
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
|
|
57
|
+
"pacote": "^20.0.0",
|
|
58
|
+
"regenerator-runtime": "^0.14.1",
|
|
59
|
+
"yargs": "^17.7.2"
|
|
60
|
+
},
|
|
61
|
+
"engines": {
|
|
62
|
+
"node": ">=18"
|
|
61
63
|
}
|
|
62
64
|
}
|
package/template/css/index.css
CHANGED
|
@@ -1,12 +1,63 @@
|
|
|
1
1
|
@import './normalize.css';
|
|
2
2
|
@import './normalize-content.css';
|
|
3
3
|
|
|
4
|
+
body {
|
|
5
|
+
background-color: rgb(249, 250, 251);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
main {
|
|
9
|
+
width: 100vw;
|
|
10
|
+
max-width: 100vw;
|
|
11
|
+
padding: 1.5rem;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
#main-index {
|
|
15
|
+
display: grid;
|
|
16
|
+
gap: 1.5rem;
|
|
17
|
+
grid-template-areas: "issues issues users";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.issues-list {
|
|
21
|
+
grid-area: issues;
|
|
22
|
+
display: flex;
|
|
23
|
+
gap: 1.5rem;
|
|
24
|
+
flex-direction: column;
|
|
25
|
+
|
|
26
|
+
a {
|
|
27
|
+
color: rgb(113, 113, 122);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
h1 {
|
|
31
|
+
margin-bottom: 0;
|
|
32
|
+
color: rgb(9, 9, 11);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
ul {
|
|
36
|
+
li {
|
|
37
|
+
border: 1px solid #ddd;
|
|
38
|
+
border-radius: .5rem;
|
|
39
|
+
display: flex;
|
|
40
|
+
flex-direction: column;
|
|
41
|
+
gap: 0.5rem;
|
|
42
|
+
padding: 1rem;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.issue-title {
|
|
47
|
+
font-weight: 600;
|
|
48
|
+
color: rgb(9, 9, 11);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
.users-list {
|
|
52
|
+
grid-area: users;
|
|
53
|
+
}
|
|
54
|
+
|
|
4
55
|
.users-list li {
|
|
5
56
|
display: flex;
|
|
6
57
|
align-items: center;
|
|
7
58
|
|
|
8
59
|
a {
|
|
9
|
-
display: flex;
|
|
60
|
+
display: flex;
|
|
10
61
|
align-items: center;
|
|
11
62
|
}
|
|
12
63
|
}
|
|
@@ -27,24 +78,24 @@
|
|
|
27
78
|
|
|
28
79
|
.issues-list,
|
|
29
80
|
.users-list {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
81
|
+
background-color: #fff;
|
|
82
|
+
border-radius: .5rem;
|
|
83
|
+
height: 100%;
|
|
84
|
+
padding: 1.5rem;
|
|
85
|
+
font-size: 13px;
|
|
33
86
|
|
|
34
87
|
ul {
|
|
35
|
-
list-style:
|
|
88
|
+
list-style: none;
|
|
36
89
|
padding: 0;
|
|
37
90
|
margin: 0;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
91
|
+
display: flex;
|
|
92
|
+
gap: 1.5rem;
|
|
93
|
+
flex-direction: column;
|
|
42
94
|
}
|
|
43
95
|
}
|
|
44
96
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
97
|
+
@media screen and (max-width: 690px) {
|
|
98
|
+
#main-index {
|
|
99
|
+
grid-template-areas: "issues" "users";
|
|
100
|
+
}
|
|
101
|
+
}
|
package/template/css/page.css
CHANGED
|
@@ -3,14 +3,13 @@
|
|
|
3
3
|
header {
|
|
4
4
|
display: flex;
|
|
5
5
|
align-items: center;
|
|
6
|
-
position:
|
|
6
|
+
position: sticky;
|
|
7
7
|
top: 0;
|
|
8
8
|
left: 0;
|
|
9
9
|
width: 100%;
|
|
10
10
|
min-height: 2.75rem;
|
|
11
|
-
background
|
|
12
|
-
|
|
13
|
-
border-bottom: 1px solid #ddd;
|
|
11
|
+
background: #fff;
|
|
12
|
+
border-bottom: 1px solid rgb(228, 228, 231);
|
|
14
13
|
padding: 0 1rem;
|
|
15
14
|
|
|
16
15
|
.logo {
|
|
@@ -52,6 +51,4 @@ header {
|
|
|
52
51
|
}
|
|
53
52
|
}
|
|
54
53
|
|
|
55
|
-
|
|
56
|
-
padding: 4.75rem 2rem 2rem;
|
|
57
|
-
}
|
|
54
|
+
|
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
@import './normalize-content.css';
|
|
2
2
|
|
|
3
|
+
main {
|
|
4
|
+
width: 100vw;
|
|
5
|
+
max-width: 100vw;
|
|
6
|
+
padding: 1.5rem;
|
|
7
|
+
}
|
|
8
|
+
|
|
3
9
|
.project-list {
|
|
10
|
+
background-color: #fff;
|
|
11
|
+
border-inline: 1px solid #ddd;
|
|
4
12
|
width: 100%;
|
|
5
13
|
border-spacing: 0;
|
|
6
14
|
border-collapse: collapse;
|
|
7
15
|
|
|
8
|
-
|
|
9
|
-
padding: .5rem;
|
|
16
|
+
tr {
|
|
10
17
|
border-top: 1px solid #ddd;
|
|
11
|
-
border-bottom: 1px solid #
|
|
18
|
+
border-bottom: 1px solid #ddd;
|
|
12
19
|
}
|
|
13
|
-
|
|
14
|
-
|
|
20
|
+
|
|
21
|
+
td {
|
|
22
|
+
padding: .5rem;
|
|
15
23
|
}
|
|
24
|
+
|
|
16
25
|
tr td:nth-child(1) {
|
|
17
26
|
min-width: 8rem;
|
|
18
27
|
max-width: 12rem;
|
package/template/indicies.js
CHANGED
package/template/js/index.js
CHANGED
|
@@ -54,17 +54,13 @@ require('nighthawk')({
|
|
|
54
54
|
|
|
55
55
|
render(html`
|
|
56
56
|
<statusboard-page .config="${config}">
|
|
57
|
-
<
|
|
58
|
-
|
|
59
|
-
main section { padding: 0 1rem; }
|
|
60
|
-
</style>
|
|
61
|
-
<main>
|
|
62
|
-
<section>
|
|
57
|
+
<main id="main-index">
|
|
58
|
+
<section class="issues-list">
|
|
63
59
|
<h1><a href="${config.baseUrl}/issues">Top Issues</a></h1>
|
|
64
60
|
|
|
65
61
|
${res.locals.issues.map(([tag, issues]) => {
|
|
66
62
|
return html`
|
|
67
|
-
<div
|
|
63
|
+
<div>
|
|
68
64
|
<h3><a href="${config.baseUrl}/issues/${tag.name}">${tag.name}</a></h3>
|
|
69
65
|
<ul>
|
|
70
66
|
${issues.map((issue) => {
|
|
@@ -74,7 +70,7 @@ require('nighthawk')({
|
|
|
74
70
|
<a href="https://www.github.com/${issue.project.repoOwner}" target="_blank">${issue.project.repoOwner}</a>
|
|
75
71
|
/ <a href="https://www.github.com/${issue.project.repo}" target="_blank">${issue.project.repoName}</a>
|
|
76
72
|
</span>
|
|
77
|
-
|
|
73
|
+
<a href="${issue.issue.url}" target="_blank" class="issue-title">${issue.issue.title}</a>
|
|
78
74
|
</li>
|
|
79
75
|
`
|
|
80
76
|
})}
|
|
@@ -118,10 +114,9 @@ require('nighthawk')({
|
|
|
118
114
|
<statusboard-page .config="${config}">
|
|
119
115
|
<main>
|
|
120
116
|
${res.locals.issues.map(([tag, issues]) => html`
|
|
121
|
-
<section>
|
|
117
|
+
<section class="issues-list">
|
|
122
118
|
<h1><a href="${config.baseUrl}/issues/${tag.name}">${tag.name}</a></h1>
|
|
123
|
-
|
|
124
|
-
<div class="issues-list">
|
|
119
|
+
<div >
|
|
125
120
|
<ul>
|
|
126
121
|
${issues.map((issue) => html`
|
|
127
122
|
<li>
|
|
@@ -129,7 +124,7 @@ require('nighthawk')({
|
|
|
129
124
|
<a href="https://www.github.com/${issue.project.repoOwner}" target="_blank">${issue.project.repoOwner}</a>
|
|
130
125
|
/ <a href="${issue.project.repo}" target="_blank">${issue.project.repoName}</a>
|
|
131
126
|
</span>
|
|
132
|
-
|
|
127
|
+
<a href="${issue.issue.url}" target="_blank" class="issue-title">${issue.issue.title}</a>
|
|
133
128
|
</li>
|
|
134
129
|
`)}
|
|
135
130
|
</ul>
|
|
@@ -146,19 +141,21 @@ require('nighthawk')({
|
|
|
146
141
|
}, null)
|
|
147
142
|
render(html`
|
|
148
143
|
<statusboard-page .config="${config}">
|
|
149
|
-
<h1>Issues: ${req.params.label}</h1>
|
|
150
144
|
<div class="issues-list">
|
|
151
|
-
<
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
145
|
+
<h1>Issues: ${req.params.label}</h1>
|
|
146
|
+
<div>
|
|
147
|
+
<ul>
|
|
148
|
+
${issues.map((issue) => html`
|
|
149
|
+
<li>
|
|
150
|
+
<span class="project-link">
|
|
151
|
+
<a href="https://www.github.com/${issue.project.repoOwner}" target="_blank">${issue.project.repoOwner}</a>
|
|
152
|
+
/ <a href="${issue.project.repo}" target="_blank">${issue.project.repoName}</a>
|
|
153
|
+
</span>
|
|
154
|
+
<a href="${issue.issue.url}" target="_blank" class="issue-title">${issue.issue.title}</a>
|
|
155
|
+
</li>
|
|
156
|
+
`)}
|
|
157
|
+
</ul>
|
|
158
|
+
</div>
|
|
162
159
|
</div>
|
|
163
160
|
</statusboard-page>
|
|
164
161
|
`, document.body)
|
package/template/js/page.js
CHANGED
|
@@ -9,76 +9,79 @@ class ProjectList extends LitElement {
|
|
|
9
9
|
projects: { type: Object }
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
+
|
|
12
13
|
render () {
|
|
13
14
|
return html`
|
|
14
15
|
<link rel="stylesheet" href="${this.config.files.css.projectList}" />
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<
|
|
25
|
-
<img src="https://badgen.net/github/stars/${project.repo}?color=yellow" />
|
|
26
|
-
</a>
|
|
27
|
-
</td>
|
|
28
|
-
<td title="Watchers">
|
|
29
|
-
<a href="https://www.github.com/${project.repo}">
|
|
30
|
-
<img src="https://badgen.net/github/watchers/${project.repo}" />
|
|
31
|
-
</a>
|
|
32
|
-
</td>
|
|
33
|
-
<td title="Issues">
|
|
34
|
-
<a href="https://www.github.com/${project.repo}">
|
|
35
|
-
<img src="https://badgen.net/github/open-issues/${project.repo}" />
|
|
36
|
-
</a>
|
|
37
|
-
</td>
|
|
38
|
-
<td title="PRs">
|
|
39
|
-
<a href="https://www.github.com/${project.repo}">
|
|
40
|
-
<img src="https://badgen.net/github/open-prs/${project.repo}" />
|
|
41
|
-
</a>
|
|
42
|
-
</td>
|
|
43
|
-
<td title="commits">
|
|
44
|
-
<a href="https://www.github.com/${project.repo}">
|
|
45
|
-
<img src="https://badgen.net/github/commits/${project.repo}" />
|
|
46
|
-
</a>
|
|
47
|
-
</td>
|
|
48
|
-
<td title="License">
|
|
49
|
-
<a href="https://www.github.com/${project.repo}">
|
|
50
|
-
<img src="https://badgen.net/github/license/${project.repo}" />
|
|
51
|
-
</a>
|
|
52
|
-
</td>
|
|
53
|
-
<td title="Contributors">
|
|
54
|
-
<a href="https://www.github.com/${project.repo}">
|
|
55
|
-
<img src="https://badgen.net/github/contributors/${project.repo}" />
|
|
56
|
-
</a>
|
|
57
|
-
</td>
|
|
58
|
-
<td>
|
|
59
|
-
${project.packageJson && (html`
|
|
16
|
+
<main>
|
|
17
|
+
<h2>Projects</h2>
|
|
18
|
+
<table class="project-list">
|
|
19
|
+
${this.projects.map((project) => html`
|
|
20
|
+
<tr>
|
|
21
|
+
<td>
|
|
22
|
+
<a href="https://www.github.com/${project.repoOwner}" target="_blank">${project.repoOwner}</a>
|
|
23
|
+
/ <a href="${(project.repoDetails && project.repoDetails.url) || `https://www.github.com/${project.repoOwner}/${project.repoName}`}" target="_blank">${project.repoName}</a>
|
|
24
|
+
</td>
|
|
25
|
+
<td title="Stars">
|
|
60
26
|
<a href="https://npmjs.org/package/${project.packageName}">
|
|
61
|
-
<img src="https://badgen.net/
|
|
27
|
+
<img src="https://badgen.net/github/stars/${project.repo}?color=yellow" />
|
|
62
28
|
</a>
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
29
|
+
</td>
|
|
30
|
+
<td title="Watchers">
|
|
31
|
+
<a href="https://www.github.com/${project.repo}">
|
|
32
|
+
<img src="https://badgen.net/github/watchers/${project.repo}" />
|
|
33
|
+
</a>
|
|
34
|
+
</td>
|
|
35
|
+
<td title="Issues">
|
|
36
|
+
<a href="https://www.github.com/${project.repo}">
|
|
37
|
+
<img src="https://badgen.net/github/open-issues/${project.repo}" />
|
|
38
|
+
</a>
|
|
39
|
+
</td>
|
|
40
|
+
<td title="PRs">
|
|
41
|
+
<a href="https://www.github.com/${project.repo}">
|
|
42
|
+
<img src="https://badgen.net/github/open-prs/${project.repo}" />
|
|
43
|
+
</a>
|
|
44
|
+
</td>
|
|
45
|
+
<td title="commits">
|
|
46
|
+
<a href="https://www.github.com/${project.repo}">
|
|
47
|
+
<img src="https://badgen.net/github/commits/${project.repo}" />
|
|
48
|
+
</a>
|
|
49
|
+
</td>
|
|
50
|
+
<td title="License">
|
|
51
|
+
<a href="https://www.github.com/${project.repo}">
|
|
52
|
+
<img src="https://badgen.net/github/license/${project.repo}" />
|
|
69
53
|
</a>
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
<a href="https://travis-ci.org/${project.repo}">
|
|
75
|
-
<img src="https://badgen.net/travis/${project.repo}" />
|
|
54
|
+
</td>
|
|
55
|
+
<td title="Contributors">
|
|
56
|
+
<a href="https://www.github.com/${project.repo}">
|
|
57
|
+
<img src="https://badgen.net/github/contributors/${project.repo}" />
|
|
76
58
|
</a>
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
59
|
+
</td>
|
|
60
|
+
<td>
|
|
61
|
+
${project.packageJson && (html`
|
|
62
|
+
<a href="https://npmjs.org/package/${project.packageName}">
|
|
63
|
+
<img src="https://badgen.net/npm/v/${project.packageName}" />
|
|
64
|
+
</a>
|
|
65
|
+
`)}
|
|
66
|
+
</td>
|
|
67
|
+
<td>
|
|
68
|
+
${project.packageJson && (html`
|
|
69
|
+
<a href="https://npmjs.org/package/${project.packageName}">
|
|
70
|
+
<img src="https://badgen.net/npm/dm/${project.packageName}" />
|
|
71
|
+
</a>
|
|
72
|
+
`)}
|
|
73
|
+
</td>
|
|
74
|
+
<td>
|
|
75
|
+
${project.travis && (html`
|
|
76
|
+
<a href="https://travis-ci.org/${project.repo}">
|
|
77
|
+
<img src="https://badgen.net/travis/${project.repo}" />
|
|
78
|
+
</a>
|
|
79
|
+
`)}
|
|
80
|
+
</td>
|
|
81
|
+
</tr>
|
|
82
|
+
`)}
|
|
83
|
+
</table>
|
|
84
|
+
</main>
|
|
82
85
|
`
|
|
83
86
|
}
|
|
84
87
|
}
|