Merge branch 'master' of https://github.com/lowlighter/metrics
This commit is contained in:
34
.github/scripts/build.mjs
vendored
34
.github/scripts/build.mjs
vendored
@@ -1,12 +1,12 @@
|
|||||||
//Imports
|
//Imports
|
||||||
import ejs from "ejs"
|
|
||||||
import fs from "fs/promises"
|
import fs from "fs/promises"
|
||||||
|
import ejs from "ejs"
|
||||||
import fss from "fs"
|
import fss from "fs"
|
||||||
import paths from "path"
|
|
||||||
import url from "url"
|
|
||||||
import sgit from "simple-git"
|
|
||||||
import metadata from "../../source/app/metrics/metadata.mjs"
|
|
||||||
import yaml from "js-yaml"
|
import yaml from "js-yaml"
|
||||||
|
import paths from "path"
|
||||||
|
import sgit from "simple-git"
|
||||||
|
import url from "url"
|
||||||
|
import metadata from "../../source/app/metrics/metadata.mjs"
|
||||||
|
|
||||||
//Mode
|
//Mode
|
||||||
const [mode = "dryrun"] = process.argv.slice(2)
|
const [mode = "dryrun"] = process.argv.slice(2)
|
||||||
@@ -49,10 +49,12 @@ for (const id of Object.keys(plugins)) {
|
|||||||
const { examples, options, readme, tests, header } = await plugin(id)
|
const { examples, options, readme, tests, header } = await plugin(id)
|
||||||
|
|
||||||
//Readme
|
//Readme
|
||||||
await fs.writeFile(readme.path, readme.content
|
await fs.writeFile(
|
||||||
|
readme.path,
|
||||||
|
readme.content
|
||||||
.replace(/(<!--header-->)[\s\S]*(<!--\/header-->)/g, `$1\n${header}\n$2`)
|
.replace(/(<!--header-->)[\s\S]*(<!--\/header-->)/g, `$1\n${header}\n$2`)
|
||||||
.replace(/(<!--examples-->)[\s\S]*(<!--\/examples-->)/g, `$1\n${examples.map(({ test, prod, ...step }) => ["```yaml", yaml.dump(step), "```"].join("\n")).join("\n")}\n$2`)
|
.replace(/(<!--examples-->)[\s\S]*(<!--\/examples-->)/g, `$1\n${examples.map(({ test, prod, ...step }) => ["```yaml", yaml.dump(step), "```"].join("\n")).join("\n")}\n$2`)
|
||||||
.replace(/(<!--options-->)[\s\S]*(<!--\/options-->)/g, `$1\n${options}\n$2`)
|
.replace(/(<!--options-->)[\s\S]*(<!--\/options-->)/g, `$1\n${options}\n$2`),
|
||||||
)
|
)
|
||||||
console.log(`Generating source/plugins/${id}/README.md`)
|
console.log(`Generating source/plugins/${id}/README.md`)
|
||||||
|
|
||||||
@@ -67,9 +69,11 @@ for (const id of Object.keys(templates)) {
|
|||||||
const { examples, readme, tests, header } = await template(id)
|
const { examples, readme, tests, header } = await template(id)
|
||||||
|
|
||||||
//Readme
|
//Readme
|
||||||
await fs.writeFile(readme.path, readme.content
|
await fs.writeFile(
|
||||||
|
readme.path,
|
||||||
|
readme.content
|
||||||
.replace(/(<!--header-->)[\s\S]*(<!--\/header-->)/g, `$1\n${header}\n$2`)
|
.replace(/(<!--header-->)[\s\S]*(<!--\/header-->)/g, `$1\n${header}\n$2`)
|
||||||
.replace(/(<!--examples-->)[\s\S]*(<!--\/examples-->)/g, `$1\n${examples.map(({test, prod, ...step}) => ["```yaml", yaml.dump(step), "```"].join("\n")).join("\n")}\n$2`)
|
.replace(/(<!--examples-->)[\s\S]*(<!--\/examples-->)/g, `$1\n${examples.map(({ test, prod, ...step }) => ["```yaml", yaml.dump(step), "```"].join("\n")).join("\n")}\n$2`),
|
||||||
)
|
)
|
||||||
console.log(`Generating source/templates/${id}/README.md`)
|
console.log(`Generating source/templates/${id}/README.md`)
|
||||||
|
|
||||||
@@ -116,14 +120,14 @@ async function plugin(id) {
|
|||||||
return {
|
return {
|
||||||
readme: {
|
readme: {
|
||||||
path: readme,
|
path: readme,
|
||||||
content:`${await fs.readFile(readme)}`
|
content: `${await fs.readFile(readme)}`,
|
||||||
},
|
},
|
||||||
tests: {
|
tests: {
|
||||||
path:tests
|
path: tests,
|
||||||
},
|
},
|
||||||
examples: fss.existsSync(examples) ? yaml.load(await fs.readFile(examples), "utf8") ?? [] : [],
|
examples: fss.existsSync(examples) ? yaml.load(await fs.readFile(examples), "utf8") ?? [] : [],
|
||||||
options: plugins[id].readme.table,
|
options: plugins[id].readme.table,
|
||||||
header:plugins[id].readme.header
|
header: plugins[id].readme.header,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,13 +140,13 @@ async function template(id) {
|
|||||||
return {
|
return {
|
||||||
readme: {
|
readme: {
|
||||||
path: readme,
|
path: readme,
|
||||||
content:`${await fs.readFile(readme)}`
|
content: `${await fs.readFile(readme)}`,
|
||||||
},
|
},
|
||||||
tests: {
|
tests: {
|
||||||
path:tests
|
path: tests,
|
||||||
},
|
},
|
||||||
examples: fss.existsSync(examples) ? yaml.load(await fs.readFile(examples), "utf8") ?? [] : [],
|
examples: fss.existsSync(examples) ? yaml.load(await fs.readFile(examples), "utf8") ?? [] : [],
|
||||||
header:templates[id].readme.header
|
header: templates[id].readme.header,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
10
.github/scripts/preview.mjs
vendored
10
.github/scripts/preview.mjs
vendored
@@ -21,10 +21,11 @@ const __preview_about = paths.join(__preview, "about/.statics")
|
|||||||
//Extract from web server
|
//Extract from web server
|
||||||
const { conf, Templates } = await setup({ nosettings: true, log: false })
|
const { conf, Templates } = await setup({ nosettings: true, log: false })
|
||||||
const templates = Object.entries(Templates).map(([name]) => ({ name, enabled: true }))
|
const templates = Object.entries(Templates).map(([name]) => ({ name, enabled: true }))
|
||||||
const metadata = Object.fromEntries(Object.entries(conf.metadata.plugins)
|
const metadata = Object.fromEntries(
|
||||||
|
Object.entries(conf.metadata.plugins)
|
||||||
.map(([key, value]) => [key, Object.fromEntries(Object.entries(value).filter(([key]) => ["name", "icon", "category", "web", "supports"].includes(key)))])
|
.map(([key, value]) => [key, Object.fromEntries(Object.entries(value).filter(([key]) => ["name", "icon", "category", "web", "supports"].includes(key)))])
|
||||||
.map(([key, value]) => [key, key === "core" ? {...value, web:Object.fromEntries(Object.entries(value.web).filter(([key]) => /^config[.]/.test(key)).map(([key, value]) => [key.replace(/^config[.]/, ""), value]))} : value]))
|
.map(([key, value]) => [key, key === "core" ? { ...value, web: Object.fromEntries(Object.entries(value.web).filter(([key]) => /^config[.]/.test(key)).map(([key, value]) => [key.replace(/^config[.]/, ""), value])) } : value]),
|
||||||
|
)
|
||||||
|
|
||||||
//Directories
|
//Directories
|
||||||
await fs.mkdir(__preview, { recursive: true })
|
await fs.mkdir(__preview, { recursive: true })
|
||||||
@@ -74,6 +75,7 @@ fs.writeFile(paths.join(__preview, ".version"), JSON.stringify(`${conf.package.v
|
|||||||
fs.writeFile(paths.join(__preview, ".hosted"), JSON.stringify({ by: "metrics", link: "https://github.com/lowlighter/metrics" }))
|
fs.writeFile(paths.join(__preview, ".hosted"), JSON.stringify({ by: "metrics", link: "https://github.com/lowlighter/metrics" }))
|
||||||
//About
|
//About
|
||||||
fs.copyFile(paths.join(__web, "about", "index.html"), paths.join(__preview, "about", "index.html"))
|
fs.copyFile(paths.join(__web, "about", "index.html"), paths.join(__preview, "about", "index.html"))
|
||||||
for (const file of await fs.readdir(__web_about))
|
for (const file of await fs.readdir(__web_about)) {
|
||||||
if (file !== ".statics")
|
if (file !== ".statics")
|
||||||
fs.copyFile(paths.join(__web_about, file), paths.join(__preview_about, file))
|
fs.copyFile(paths.join(__web_about, file), paths.join(__preview_about, file))
|
||||||
|
}
|
||||||
|
|||||||
4
.github/scripts/release.mjs
vendored
4
.github/scripts/release.mjs
vendored
@@ -1,8 +1,8 @@
|
|||||||
//Imports
|
//Imports
|
||||||
import github from "@actions/github"
|
import github from "@actions/github"
|
||||||
import paths from "path"
|
import paths from "path"
|
||||||
import url from "url"
|
|
||||||
import sgit from "simple-git"
|
import sgit from "simple-git"
|
||||||
|
import url from "url"
|
||||||
|
|
||||||
//Git setup
|
//Git setup
|
||||||
const __metrics = paths.join(paths.dirname(url.fileURLToPath(import.meta.url)), "../..")
|
const __metrics = paths.join(paths.dirname(url.fileURLToPath(import.meta.url)), "../..")
|
||||||
@@ -27,7 +27,7 @@ console.log(`Version: ${version}`)
|
|||||||
|
|
||||||
//Load related pr
|
//Load related pr
|
||||||
const { data: { items: prs } } = await rest.search.issuesAndPullRequests({
|
const { data: { items: prs } } = await rest.search.issuesAndPullRequests({
|
||||||
q:`repo:${repository.owner}/${repository.name} is:pr is:merged author:${maintainer} assignee:${maintainer} Release ${version} in:title`
|
q: `repo:${repository.owner}/${repository.name} is:pr is:merged author:${maintainer} assignee:${maintainer} Release ${version} in:title`,
|
||||||
})
|
})
|
||||||
|
|
||||||
//Ensure that there is exactly one pr matching
|
//Ensure that there is exactly one pr matching
|
||||||
|
|||||||
14
package-lock.json
generated
14
package-lock.json
generated
@@ -27,7 +27,7 @@
|
|||||||
"jimp": "^0.16.1",
|
"jimp": "^0.16.1",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"linguist-js": "^2.2.0",
|
"linguist-js": "^2.2.0",
|
||||||
"marked": "^4.0.3",
|
"marked": "^4.0.10",
|
||||||
"memory-cache": "^0.2.0",
|
"memory-cache": "^0.2.0",
|
||||||
"minimatch": "^3.0.4",
|
"minimatch": "^3.0.4",
|
||||||
"node-chartist": "^1.0.5",
|
"node-chartist": "^1.0.5",
|
||||||
@@ -6526,9 +6526,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/marked": {
|
"node_modules/marked": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.10.tgz",
|
||||||
"integrity": "sha512-vSwKKtw+lCA0uFK/02JT4tBfNxEREpoTg21NoXqcmX0ySBIEyLMYWmt8WPsM61QNFaDBZkggupyNXLsV7uPuRg==",
|
"integrity": "sha512-+QvuFj0nGgO970fySghXGmuw+Fd0gD2x3+MqCWLIPf5oxdv1Ka6b2q+z9RP01P/IaKPMEramy+7cNy/Lw8c3hw==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"marked": "bin/marked.js"
|
"marked": "bin/marked.js"
|
||||||
},
|
},
|
||||||
@@ -15032,9 +15032,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"marked": {
|
"marked": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.10.tgz",
|
||||||
"integrity": "sha512-vSwKKtw+lCA0uFK/02JT4tBfNxEREpoTg21NoXqcmX0ySBIEyLMYWmt8WPsM61QNFaDBZkggupyNXLsV7uPuRg=="
|
"integrity": "sha512-+QvuFj0nGgO970fySghXGmuw+Fd0gD2x3+MqCWLIPf5oxdv1Ka6b2q+z9RP01P/IaKPMEramy+7cNy/Lw8c3hw=="
|
||||||
},
|
},
|
||||||
"matchmedia": {
|
"matchmedia": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
"jimp": "^0.16.1",
|
"jimp": "^0.16.1",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"linguist-js": "^2.2.0",
|
"linguist-js": "^2.2.0",
|
||||||
"marked": "^4.0.3",
|
"marked": "^4.0.10",
|
||||||
"memory-cache": "^0.2.0",
|
"memory-cache": "^0.2.0",
|
||||||
"minimatch": "^3.0.4",
|
"minimatch": "^3.0.4",
|
||||||
"node-chartist": "^1.0.5",
|
"node-chartist": "^1.0.5",
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import core from "@actions/core"
|
|||||||
import github from "@actions/github"
|
import github from "@actions/github"
|
||||||
import octokit from "@octokit/graphql"
|
import octokit from "@octokit/graphql"
|
||||||
import fs from "fs/promises"
|
import fs from "fs/promises"
|
||||||
|
import processes from "child_process"
|
||||||
import paths from "path"
|
import paths from "path"
|
||||||
import sgit from "simple-git"
|
import sgit from "simple-git"
|
||||||
import processes from "child_process"
|
import mocks from "../../../tests/mocks/index.mjs"
|
||||||
import metrics from "../metrics/index.mjs"
|
import metrics from "../metrics/index.mjs"
|
||||||
import setup from "../metrics/setup.mjs"
|
import setup from "../metrics/setup.mjs"
|
||||||
import mocks from "../../../tests/mocks/index.mjs"
|
|
||||||
process.on("unhandledRejection", error => {
|
process.on("unhandledRejection", error => {
|
||||||
throw error
|
throw error
|
||||||
})
|
})
|
||||||
@@ -485,6 +485,7 @@ async function retry(func, {retries = 1, delay = 0} = {}) {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw error
|
throw error
|
||||||
|
|
||||||
}
|
}
|
||||||
info("Pull request number", number)
|
info("Pull request number", number)
|
||||||
}, {retries:retries_output_action, delay:retries_delay_output_action})
|
}, {retries:retries_output_action, delay:retries_delay_output_action})
|
||||||
|
|||||||
@@ -227,9 +227,18 @@ metrics.insights = async function({login}, {graphql, rest, conf}, {Plugins, Temp
|
|||||||
"habits.days":7,
|
"habits.days":7,
|
||||||
"habits.facts":false,
|
"habits.facts":false,
|
||||||
"habits.charts":true,
|
"habits.charts":true,
|
||||||
introduction:true
|
introduction:true,
|
||||||
|
}
|
||||||
|
const plugins = {
|
||||||
|
achievements:{enabled:true},
|
||||||
|
isocalendar:{enabled:true},
|
||||||
|
languages:{enabled:true, extras:false},
|
||||||
|
activity:{enabled:true, markdown:"extended"},
|
||||||
|
notable:{enabled:true},
|
||||||
|
followup:{enabled:true},
|
||||||
|
habits:{enabled:true, extras:false},
|
||||||
|
introduction:{enabled:true},
|
||||||
}
|
}
|
||||||
const plugins = {achievements:{enabled:true}, isocalendar:{enabled:true}, languages:{enabled:true, extras:false}, activity:{enabled:true, markdown:"extended"}, notable:{enabled:true}, followup:{enabled:true}, habits:{enabled:true, extras:false}, introduction:{enabled:true}}
|
|
||||||
return metrics({login, q}, {graphql, rest, plugins, conf, convert:"json"}, {Plugins, Templates})
|
return metrics({login, q}, {graphql, rest, plugins, conf, convert:"json"}, {Plugins, Templates})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
//Imports
|
//Imports
|
||||||
import fs from "fs"
|
import fs from "fs"
|
||||||
import yaml from "js-yaml"
|
import yaml from "js-yaml"
|
||||||
|
import {marked} from "marked"
|
||||||
|
import fetch from "node-fetch"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import url from "url"
|
import url from "url"
|
||||||
import fetch from "node-fetch"
|
|
||||||
import {marked} from "marked"
|
|
||||||
|
|
||||||
//Defined categories
|
//Defined categories
|
||||||
const categories = ["core", "github", "social", "community"]
|
const categories = ["core", "github", "social", "community"]
|
||||||
@@ -293,23 +293,25 @@ metadata.plugin = async function({__plugins, __templates, name, logger}) {
|
|||||||
` <td>${Object.entries(compatibility).filter(([_, value]) => value).map(([id]) => `<a href="/source/templates/${id}"><code>${templates[id].name ?? ""}</code></a>`).join(" ")}</td>`,
|
` <td>${Object.entries(compatibility).filter(([_, value]) => value).map(([id]) => `<a href="/source/templates/${id}"><code>${templates[id].name ?? ""}</code></a>`).join(" ")}</td>`,
|
||||||
" </tr>",
|
" </tr>",
|
||||||
" <tr>",
|
" <tr>",
|
||||||
` <td>${[
|
` <td>${
|
||||||
|
[
|
||||||
meta.supports?.includes("user") ? "<code>👤 Users</code>" : "",
|
meta.supports?.includes("user") ? "<code>👤 Users</code>" : "",
|
||||||
meta.supports?.includes("organization") ? "<code>👥 Organizations</code>" : "",
|
meta.supports?.includes("organization") ? "<code>👥 Organizations</code>" : "",
|
||||||
meta.supports?.includes("repository") ? "<code>📓 Repositories</code>" : ""
|
meta.supports?.includes("repository") ? "<code>📓 Repositories</code>" : "",
|
||||||
].filter(v => v).join(" ")}</td>`,
|
].filter(v => v).join(" ")
|
||||||
|
}</td>`,
|
||||||
" </tr>",
|
" </tr>",
|
||||||
" <tr>",
|
" <tr>",
|
||||||
` <td>${[
|
` <td>${[
|
||||||
...(meta.scopes ?? []).map(scope => `<code>🔑 ${{public_access:"(scopeless)"}[scope] ?? scope}</code>`),
|
...(meta.scopes ?? []).map(scope => `<code>🔑 ${{public_access:"(scopeless)"}[scope] ?? scope}</code>`),
|
||||||
...Object.entries(inputs).filter(([_, {type}]) => type === "token").map(([token]) => `<code>🗝️ ${token}</code>`),
|
...Object.entries(inputs).filter(([_, {type}]) => type === "token").map(([token]) => `<code>🗝️ ${token}</code>`),
|
||||||
...(meta.scopes?.length ? ["read:org", "read:user", "repo"].map(scope => !meta.scopes.includes(scope) ? `<code>${scope} (optional)</code>` : null).filter(v => v) : [])
|
...(meta.scopes?.length ? ["read:org", "read:user", "repo"].map(scope => !meta.scopes.includes(scope) ? `<code>${scope} (optional)</code>` : null).filter(v => v) : []),
|
||||||
].filter(v => v).join(" ") || "<i>No tokens are required for this plugin</i>"}</td>`,
|
].filter(v => v).join(" ") || "<i>No tokens are required for this plugin</i>"}</td>`,
|
||||||
" </tr>",
|
" </tr>",
|
||||||
" <tr>",
|
" <tr>",
|
||||||
demos({colspan:2, wrap:name === "base", examples:meta.examples}),
|
demos({colspan:2, wrap:name === "base", examples:meta.examples}),
|
||||||
" </tr>",
|
" </tr>",
|
||||||
"</table>"
|
"</table>",
|
||||||
].join("\n")
|
].join("\n")
|
||||||
|
|
||||||
//Options table
|
//Options table
|
||||||
@@ -414,26 +416,30 @@ metadata.template = async function({__templates, name, plugins, logger}) {
|
|||||||
` <td>${Object.entries(compatibility).filter(([_, value]) => value).map(([id]) => `<a href="/source/plugins/${id}" title="${plugins[id].name}">${plugins[id].icon}</a>`).join(" ")}${meta.formats?.includes("markdown") ? " <code>✓ embed()</code>" : ""}</td>`,
|
` <td>${Object.entries(compatibility).filter(([_, value]) => value).map(([id]) => `<a href="/source/plugins/${id}" title="${plugins[id].name}">${plugins[id].icon}</a>`).join(" ")}${meta.formats?.includes("markdown") ? " <code>✓ embed()</code>" : ""}</td>`,
|
||||||
" </tr>",
|
" </tr>",
|
||||||
" <tr>",
|
" <tr>",
|
||||||
` <td>${[
|
` <td>${
|
||||||
|
[
|
||||||
meta.supports?.includes("user") ? "<code>👤 Users</code>" : "",
|
meta.supports?.includes("user") ? "<code>👤 Users</code>" : "",
|
||||||
meta.supports?.includes("organization") ? "<code>👥 Organizations</code>" : "",
|
meta.supports?.includes("organization") ? "<code>👥 Organizations</code>" : "",
|
||||||
meta.supports?.includes("repository") ? "<code>📓 Repositories</code>" : ""
|
meta.supports?.includes("repository") ? "<code>📓 Repositories</code>" : "",
|
||||||
].filter(v => v).join(" ")}</td>`,
|
].filter(v => v).join(" ")
|
||||||
|
}</td>`,
|
||||||
" </tr>",
|
" </tr>",
|
||||||
" <tr>",
|
" <tr>",
|
||||||
` <td>${[
|
` <td>${
|
||||||
|
[
|
||||||
meta.formats?.includes("svg") ? "<code>*️⃣ SVG</code>" : "",
|
meta.formats?.includes("svg") ? "<code>*️⃣ SVG</code>" : "",
|
||||||
meta.formats?.includes("png") ? "<code>*️⃣ PNG</code>" : "",
|
meta.formats?.includes("png") ? "<code>*️⃣ PNG</code>" : "",
|
||||||
meta.formats?.includes("jpeg") ? "<code>*️⃣ JPEG</code>" : "",
|
meta.formats?.includes("jpeg") ? "<code>*️⃣ JPEG</code>" : "",
|
||||||
meta.formats?.includes("json") ? "<code>#️⃣ JSON</code>" : "",
|
meta.formats?.includes("json") ? "<code>#️⃣ JSON</code>" : "",
|
||||||
meta.formats?.includes("markdown") ? "<code>🔠 Markdown</code>" : "",
|
meta.formats?.includes("markdown") ? "<code>🔠 Markdown</code>" : "",
|
||||||
meta.formats?.includes("markdown-pdf") ? "<code>🔠 Markdown (PDF)</code>" : "",
|
meta.formats?.includes("markdown-pdf") ? "<code>🔠 Markdown (PDF)</code>" : "",
|
||||||
].filter(v => v).join(" ")}</td>`,
|
].filter(v => v).join(" ")
|
||||||
|
}</td>`,
|
||||||
" </tr>",
|
" </tr>",
|
||||||
" <tr>",
|
" <tr>",
|
||||||
demos({colspan:2, examples:meta.examples}),
|
demos({colspan:2, examples:meta.examples}),
|
||||||
" </tr>",
|
" </tr>",
|
||||||
"</table>"
|
"</table>",
|
||||||
].join("\n")
|
].join("\n")
|
||||||
|
|
||||||
//Result
|
//Result
|
||||||
@@ -448,9 +454,9 @@ metadata.template = async function({__templates, name, plugins, logger}) {
|
|||||||
compatibility:{
|
compatibility:{
|
||||||
...Object.fromEntries(Object.entries(compatibility).filter(([_, value]) => value)),
|
...Object.fromEntries(Object.entries(compatibility).filter(([_, value]) => value)),
|
||||||
...Object.fromEntries(Object.entries(compatibility).filter(([_, value]) => !value).map(([key, value]) => [key, meta.formats?.includes("markdown") ? "embed" : value])),
|
...Object.fromEntries(Object.entries(compatibility).filter(([_, value]) => !value).map(([key, value]) => [key, meta.formats?.includes("markdown") ? "embed" : value])),
|
||||||
base:true
|
base:true,
|
||||||
},
|
},
|
||||||
header
|
header,
|
||||||
},
|
},
|
||||||
check({q, account = "bypass", format = null}) {
|
check({q, account = "bypass", format = null}) {
|
||||||
//Support check
|
//Support check
|
||||||
@@ -495,7 +501,8 @@ function demos({colspan = null, wrap = false, examples = {}} = {}) {
|
|||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
` <td ${colspan ? `colspan="${colspan}"` : ""} align="center">`,
|
` <td ${colspan ? `colspan="${colspan}"` : ""} align="center">`,
|
||||||
`${Object.entries(examples).map(([text, link]) => {
|
`${
|
||||||
|
Object.entries(examples).map(([text, link]) => {
|
||||||
let img = `<img src="${link}" alt=""></img>`
|
let img = `<img src="${link}" alt=""></img>`
|
||||||
if (text !== "default") {
|
if (text !== "default") {
|
||||||
const open = text.charAt(0) === "+" ? " open" : ""
|
const open = text.charAt(0) === "+" ? " open" : ""
|
||||||
@@ -504,8 +511,9 @@ function demos({colspan = null, wrap = false, examples = {}} = {}) {
|
|||||||
img = `<details${open}><summary>${text}</summary>${img}</details>`
|
img = `<details${open}><summary>${text}</summary>${img}</details>`
|
||||||
}
|
}
|
||||||
return ` ${img}`
|
return ` ${img}`
|
||||||
}).join("\n")}`,
|
}).join("\n")
|
||||||
|
}`,
|
||||||
' <img width="900" height="1" alt="">',
|
' <img width="900" height="1" alt="">',
|
||||||
" </td>"
|
" </td>",
|
||||||
].filter(v => v).join("\n")
|
].filter(v => v).join("\n")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,38 +3,38 @@ import fs from "fs/promises"
|
|||||||
import prism_lang from "prismjs/components/index.js"
|
import prism_lang from "prismjs/components/index.js"
|
||||||
import axios from "axios"
|
import axios from "axios"
|
||||||
import processes from "child_process"
|
import processes from "child_process"
|
||||||
|
import crypto from "crypto"
|
||||||
|
import {minify as csso} from "csso"
|
||||||
|
import emoji from "emoji-name-map"
|
||||||
import fss from "fs"
|
import fss from "fs"
|
||||||
import GIFEncoder from "gifencoder"
|
import GIFEncoder from "gifencoder"
|
||||||
import jimp from "jimp"
|
import jimp from "jimp"
|
||||||
|
import linguist from "linguist-js"
|
||||||
import {marked} from "marked"
|
import {marked} from "marked"
|
||||||
|
import minimatch from "minimatch"
|
||||||
import nodechartist from "node-chartist"
|
import nodechartist from "node-chartist"
|
||||||
|
import fetch from "node-fetch"
|
||||||
import opengraph from "open-graph-scraper"
|
import opengraph from "open-graph-scraper"
|
||||||
import os from "os"
|
import os from "os"
|
||||||
import paths from "path"
|
import paths from "path"
|
||||||
import PNG from "png-js"
|
import PNG from "png-js"
|
||||||
import prism from "prismjs"
|
import prism from "prismjs"
|
||||||
import _puppeteer from "puppeteer"
|
import _puppeteer from "puppeteer"
|
||||||
|
import purgecss from "purgecss"
|
||||||
|
import readline from "readline"
|
||||||
import rss from "rss-parser"
|
import rss from "rss-parser"
|
||||||
import htmlsanitize from "sanitize-html"
|
import htmlsanitize from "sanitize-html"
|
||||||
import git from "simple-git"
|
import git from "simple-git"
|
||||||
|
import SVGO from "svgo"
|
||||||
import twemojis from "twemoji-parser"
|
import twemojis from "twemoji-parser"
|
||||||
import url from "url"
|
import url from "url"
|
||||||
import util from "util"
|
import util from "util"
|
||||||
import fetch from "node-fetch"
|
|
||||||
import readline from "readline"
|
|
||||||
import emoji from "emoji-name-map"
|
|
||||||
import minimatch from "minimatch"
|
|
||||||
import crypto from "crypto"
|
|
||||||
import linguist from "linguist-js"
|
|
||||||
import purgecss from "purgecss"
|
|
||||||
import {minify as csso} from "csso"
|
|
||||||
import SVGO from "svgo"
|
|
||||||
import xmlformat from "xml-formatter"
|
import xmlformat from "xml-formatter"
|
||||||
|
|
||||||
prism_lang()
|
prism_lang()
|
||||||
|
|
||||||
//Exports
|
//Exports
|
||||||
export {axios, fs, git, jimp, opengraph, os, paths, processes, rss, url, fetch, util, emoji, minimatch}
|
export {axios, emoji, fetch, fs, git, jimp, minimatch, opengraph, os, paths, processes, rss, url, util}
|
||||||
|
|
||||||
/**Returns module __dirname */
|
/**Returns module __dirname */
|
||||||
export function __module(module) {
|
export function __module(module) {
|
||||||
@@ -433,7 +433,7 @@ export const svg = {
|
|||||||
console.debug(`bounds after applying padding width=${width} (*${padding.width}+${padding.absolute.width}), height=${height} (*${padding.height}+${padding.absolute.height})`)
|
console.debug(`bounds after applying padding width=${width} (*${padding.width}+${padding.absolute.width}), height=${height} (*${padding.height}+${padding.absolute.height})`)
|
||||||
//Resize svg
|
//Resize svg
|
||||||
if (document.querySelector("svg").getAttribute("height") === "auto")
|
if (document.querySelector("svg").getAttribute("height") === "auto")
|
||||||
console.debug("skipped height resizing because it was set to \"auto\"")
|
console.debug('skipped height resizing because it was set to "auto"')
|
||||||
else
|
else
|
||||||
document.querySelector("svg").setAttribute("height", height)
|
document.querySelector("svg").setAttribute("height", height)
|
||||||
//Enable animations
|
//Enable animations
|
||||||
@@ -575,8 +575,8 @@ export const svg = {
|
|||||||
if (error)
|
if (error)
|
||||||
throw new Error(`Could not optimize SVG: \n${error}`)
|
throw new Error(`Could not optimize SVG: \n${error}`)
|
||||||
return optimized
|
return optimized
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Wait */
|
/**Wait */
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import express from "express"
|
|||||||
import ratelimit from "express-rate-limit"
|
import ratelimit from "express-rate-limit"
|
||||||
import cache from "memory-cache"
|
import cache from "memory-cache"
|
||||||
import util from "util"
|
import util from "util"
|
||||||
|
import mocks from "../../../tests/mocks/index.mjs"
|
||||||
import metrics from "../metrics/index.mjs"
|
import metrics from "../metrics/index.mjs"
|
||||||
import setup from "../metrics/setup.mjs"
|
import setup from "../metrics/setup.mjs"
|
||||||
import mocks from "../../../tests/mocks/index.mjs"
|
|
||||||
|
|
||||||
/**App */
|
/**App */
|
||||||
export default async function({mock, nosettings} = {}) {
|
export default async function({mock, nosettings} = {}) {
|
||||||
|
|||||||
@@ -68,8 +68,10 @@
|
|||||||
tab: {
|
tab: {
|
||||||
immediate: true,
|
immediate: true,
|
||||||
handler(current) {
|
handler(current) {
|
||||||
if (current === 'action') this.clipboard = new ClipboardJS('.copy-action')
|
if (current === "action")
|
||||||
else this.clipboard?.destroy()
|
this.clipboard = new ClipboardJS(".copy-action")
|
||||||
|
else
|
||||||
|
this.clipboard?.destroy()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
palette: {
|
palette: {
|
||||||
@@ -181,7 +183,7 @@
|
|||||||
scopes() {
|
scopes() {
|
||||||
return new Set([
|
return new Set([
|
||||||
...Object.entries(this.plugins.enabled).filter(([key, value]) => (key !== "base") && (value)).flatMap(([key]) => metadata[key].scopes),
|
...Object.entries(this.plugins.enabled).filter(([key, value]) => (key !== "base") && (value)).flatMap(([key]) => metadata[key].scopes),
|
||||||
...(Object.entries(this.plugins.enabled.base).filter(([key, value]) => value).length ? metadata.base.scopes : [])
|
...(Object.entries(this.plugins.enabled.base).filter(([key, value]) => value).length ? metadata.base.scopes : []),
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
//GitHub action auto-generated code
|
//GitHub action auto-generated code
|
||||||
@@ -201,15 +203,17 @@
|
|||||||
` steps:`,
|
` steps:`,
|
||||||
` - uses: lowlighter/metrics@latest`,
|
` - uses: lowlighter/metrics@latest`,
|
||||||
` with:`,
|
` with:`,
|
||||||
...(this.scopes.size ? [
|
...(this.scopes.size
|
||||||
|
? [
|
||||||
` # Your GitHub token`,
|
` # Your GitHub token`,
|
||||||
` # The following scopes are required:`,
|
` # The following scopes are required:`,
|
||||||
...[...this.scopes].map(scope => ` # - ${scope}${scope === "public_access" ? " (default scope)" : ""}`),
|
...[...this.scopes].map(scope => ` # - ${scope}${scope === "public_access" ? " (default scope)" : ""}`),
|
||||||
` # The following additional scopes may be required:`,
|
` # The following additional scopes may be required:`,
|
||||||
` # - read:org (for organization related metrics)`,
|
` # - read:org (for organization related metrics)`,
|
||||||
` # - read:user (for user related data)`,
|
` # - read:user (for user related data)`,
|
||||||
` # - repo (optional, if you want to include private repositories)`
|
` # - repo (optional, if you want to include private repositories)`,
|
||||||
] : [
|
]
|
||||||
|
: [
|
||||||
` # Current configuration doesn't require a GitHub token`,
|
` # Current configuration doesn't require a GitHub token`,
|
||||||
]),
|
]),
|
||||||
` token: ${this.scopes.size ? `${"$"}{{ secrets.METRICS_TOKEN }}` : "NOT_NEEDED"}`,
|
` token: ${this.scopes.size ? `${"$"}{{ secrets.METRICS_TOKEN }}` : "NOT_NEEDED"}`,
|
||||||
|
|||||||
@@ -193,7 +193,7 @@
|
|||||||
drafts: faker.datatype.number(this.drafts),
|
drafts: faker.datatype.number(this.drafts),
|
||||||
skipped: faker.datatype.number(this.skipped),
|
skipped: faker.datatype.number(this.skipped),
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
pr: {
|
pr: {
|
||||||
get count() {
|
get count() {
|
||||||
@@ -210,7 +210,7 @@
|
|||||||
merged: faker.datatype.number(this.skipped),
|
merged: faker.datatype.number(this.skipped),
|
||||||
drafts: faker.datatype.number(this.drafts),
|
drafts: faker.datatype.number(this.drafts),
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
user: {
|
user: {
|
||||||
issues: {
|
issues: {
|
||||||
@@ -232,7 +232,7 @@
|
|||||||
drafts: faker.datatype.number(100),
|
drafts: faker.datatype.number(100),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
indepth:options["followup.indepth"] ? {} : null
|
indepth: options["followup.indepth"] ? {} : null,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
: null),
|
: null),
|
||||||
@@ -240,7 +240,10 @@
|
|||||||
...(set.plugins.enabled.notable
|
...(set.plugins.enabled.notable
|
||||||
? ({
|
? ({
|
||||||
notable: {
|
notable: {
|
||||||
contributions: new Array(2 + faker.datatype.number(2)).fill(null).map(_ => ({ name: `${options["notable.repositories"] ? `${faker.lorem.slug()}/` : ""}${faker.lorem.slug()}`, avatar: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOcOnfpfwAGfgLYttYINwAAAABJRU5ErkJggg==" })),
|
contributions: new Array(2 + faker.datatype.number(2)).fill(null).map(_ => ({
|
||||||
|
name: `${options["notable.repositories"] ? `${faker.lorem.slug()}/` : ""}${faker.lorem.slug()}`,
|
||||||
|
avatar: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOcOnfpfwAGfgLYttYINwAAAABJRU5ErkJggg==",
|
||||||
|
})),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
: null),
|
: null),
|
||||||
@@ -368,14 +371,15 @@
|
|||||||
snippet: {
|
snippet: {
|
||||||
sha: faker.git.shortSha(),
|
sha: faker.git.shortSha(),
|
||||||
message: faker.lorem.sentence(),
|
message: faker.lorem.sentence(),
|
||||||
filename: 'docs/specifications.html',
|
filename: "docs/specifications.html",
|
||||||
status: "modified",
|
status: "modified",
|
||||||
additions: faker.datatype.number(50),
|
additions: faker.datatype.number(50),
|
||||||
deletions: faker.datatype.number(50),
|
deletions: faker.datatype.number(50),
|
||||||
patch: `<span class="token coord">@@ -0,0 +1,5 @@</span><br> //Imports<br><span class="token inserted">+ import app from "./src/app.mjs"</span><br><span class="token deleted">- import app from "./src/app.js"</span><br> //Start app<br> await app()<br>\\ No newline at end of file`,
|
patch:
|
||||||
|
`<span class="token coord">@@ -0,0 +1,5 @@</span><br> //Imports<br><span class="token inserted">+ import app from "./src/app.mjs"</span><br><span class="token deleted">- import app from "./src/app.js"</span><br> //Start app<br> await app()<br>\\ No newline at end of file`,
|
||||||
repo: `${faker.random.word()}/${faker.random.word()}`,
|
repo: `${faker.random.word()}/${faker.random.word()}`,
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
: null),
|
: null),
|
||||||
//Sponsors
|
//Sponsors
|
||||||
@@ -393,9 +397,9 @@
|
|||||||
goal: {
|
goal: {
|
||||||
progress: faker.datatype.number(100),
|
progress: faker.datatype.number(100),
|
||||||
title: `$${faker.datatype.number(100) * 10} per month`,
|
title: `$${faker.datatype.number(100) * 10} per month`,
|
||||||
description: "Invest in the software that powers your world"
|
description: "Invest in the software that powers your world",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
: null),
|
: null),
|
||||||
//Languages
|
//Languages
|
||||||
@@ -422,7 +426,7 @@
|
|||||||
},
|
},
|
||||||
commits: faker.datatype.number(500),
|
commits: faker.datatype.number(500),
|
||||||
files: faker.datatype.number(1000),
|
files: faker.datatype.number(1000),
|
||||||
days:Number(options["languages.recent.days"])
|
days: Number(options["languages.recent.days"]),
|
||||||
},
|
},
|
||||||
favorites: distribution(7).map((value, index, array) => ({ name: faker.lorem.word(), color: faker.internet.color(), value, size: faker.datatype.number(1000000), x: array.slice(0, index).reduce((a, b) => a + b, 0) })),
|
favorites: distribution(7).map((value, index, array) => ({ name: faker.lorem.word(), color: faker.internet.color(), value, size: faker.datatype.number(1000000), x: array.slice(0, index).reduce((a, b) => a + b, 0) })),
|
||||||
recent: distribution(7).map((value, index, array) => ({ name: faker.lorem.word(), color: faker.internet.color(), value, size: faker.datatype.number(1000000), x: array.slice(0, index).reduce((a, b) => a + b, 0) })),
|
recent: distribution(7).map((value, index, array) => ({ name: faker.lorem.word(), color: faker.internet.color(), value, size: faker.datatype.number(1000000), x: array.slice(0, index).reduce((a, b) => a + b, 0) })),
|
||||||
@@ -471,7 +475,7 @@
|
|||||||
lines: {
|
lines: {
|
||||||
average: {
|
average: {
|
||||||
chars: faker.datatype.number(1000) / 10,
|
chars: faker.datatype.number(1000) / 10,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
commits: {
|
commits: {
|
||||||
get hour() {
|
get hour() {
|
||||||
@@ -655,8 +659,8 @@
|
|||||||
? ({
|
? ({
|
||||||
discussions: {
|
discussions: {
|
||||||
categories: {
|
categories: {
|
||||||
stats: { '🙏 Q&A': faker.datatype.number(100), '📣 Announcements': faker.datatype.number(100), '💡 Ideas': faker.datatype.number(100), '💬 General': faker.datatype.number(100) },
|
stats: { "🙏 Q&A": faker.datatype.number(100), "📣 Announcements": faker.datatype.number(100), "💡 Ideas": faker.datatype.number(100), "💬 General": faker.datatype.number(100) },
|
||||||
favorite: '📣 Announcements'
|
favorite: "📣 Announcements",
|
||||||
},
|
},
|
||||||
upvotes: { discussions: faker.datatype.number(1000), comments: faker.datatype.number(1000) },
|
upvotes: { discussions: faker.datatype.number(1000), comments: faker.datatype.number(1000) },
|
||||||
started: faker.datatype.number(1000),
|
started: faker.datatype.number(1000),
|
||||||
@@ -753,9 +757,11 @@
|
|||||||
description: faker.lorem.sentence(),
|
description: faker.lorem.sentence(),
|
||||||
count: faker.datatype.number(100),
|
count: faker.datatype.number(100),
|
||||||
repositories: new Array(Number(options["starlists.limit.repositories"])).fill(null).map((_, i) => ({
|
repositories: new Array(Number(options["starlists.limit.repositories"])).fill(null).map((_, i) => ({
|
||||||
description: !i ? "📊 An image generator with 20+ metrics about your GitHub account such as activity, community, repositories, coding habits, website performances, music played, starred topics, etc. that you can put on your profile or elsewhere !" : faker.lorem.sentence(),
|
description: !i
|
||||||
|
? "📊 An image generator with 20+ metrics about your GitHub account such as activity, community, repositories, coding habits, website performances, music played, starred topics, etc. that you can put on your profile or elsewhere !"
|
||||||
|
: faker.lorem.sentence(),
|
||||||
name: !i ? "lowlighter/metrics" : `${faker.random.word()}/${faker.random.word()}`,
|
name: !i ? "lowlighter/metrics" : `${faker.random.word()}/${faker.random.word()}`,
|
||||||
}))
|
})),
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -1062,7 +1068,7 @@
|
|||||||
? ({
|
? ({
|
||||||
support: {
|
support: {
|
||||||
stats: { solutions: faker.datatype.number(100), posts: faker.datatype.number(1000), topics: faker.datatype.number(1000), received: faker.datatype.number(1000), hearts: faker.datatype.number(1000) },
|
stats: { solutions: faker.datatype.number(100), posts: faker.datatype.number(1000), topics: faker.datatype.number(1000), received: faker.datatype.number(1000), hearts: faker.datatype.number(1000) },
|
||||||
badges: { uniques: [ ], multiples: [], count: faker.datatype.number(1000) }
|
badges: { uniques: [], multiples: [], count: faker.datatype.number(1000) },
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
: null),
|
: null),
|
||||||
@@ -1084,7 +1090,7 @@
|
|||||||
animation: "data:image/jpg;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOcOnfpfwAGfgLYttYINwAAAABJRU5ErkJggg==",
|
animation: "data:image/jpg;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOcOnfpfwAGfgLYttYINwAAAABJRU5ErkJggg==",
|
||||||
width: 454,
|
width: 454,
|
||||||
height: 284,
|
height: 284,
|
||||||
compatibility: false
|
compatibility: false,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
: null),
|
: null),
|
||||||
|
|||||||
@@ -25,15 +25,22 @@ export default async function({login, q, imports, data, rest, account}, {enabled
|
|||||||
try {
|
try {
|
||||||
for (let page = 1; page <= pages; page++) {
|
for (let page = 1; page <= pages; page++) {
|
||||||
console.debug(`metrics/compute/${login}/plugins > code > loading page ${page}/${pages}`)
|
console.debug(`metrics/compute/${login}/plugins > code > loading page ${page}/${pages}`)
|
||||||
events.push(...[...await Promise.all([...(context.mode === "repository" ? await rest.activity.listRepoEvents({owner:context.owner, repo:context.repo}) : await rest.activity.listEventsForAuthenticatedUser({username:login, per_page:100, page})).data
|
events.push(
|
||||||
|
...[
|
||||||
|
...await Promise.all([
|
||||||
|
...(context.mode === "repository"
|
||||||
|
? await rest.activity.listRepoEvents({owner:context.owner, repo:context.repo})
|
||||||
|
: await rest.activity.listEventsForAuthenticatedUser({username:login, per_page:100, page})).data
|
||||||
.filter(({type}) => type === "PushEvent")
|
.filter(({type}) => type === "PushEvent")
|
||||||
.filter(({actor}) => account === "organization" ? true : actor.login?.toLocaleLowerCase() === login.toLocaleLowerCase())
|
.filter(({actor}) => account === "organization" ? true : actor.login?.toLocaleLowerCase() === login.toLocaleLowerCase())
|
||||||
.filter(({repo:{name:repo}}) => !((skipped.includes(repo.split("/").pop())) || (skipped.includes(repo))))
|
.filter(({repo:{name:repo}}) => !((skipped.includes(repo.split("/").pop())) || (skipped.includes(repo))))
|
||||||
.filter(event => visibility === "public" ? event.public : true)
|
.filter(event => visibility === "public" ? event.public : true)
|
||||||
.flatMap(({payload}) => Promise.all(payload.commits.map(async commit => (await rest.request(commit.url)).data)))])]
|
.flatMap(({payload}) => Promise.all(payload.commits.map(async commit => (await rest.request(commit.url)).data))),
|
||||||
|
]),
|
||||||
|
]
|
||||||
.flat()
|
.flat()
|
||||||
.filter(({parents}) => parents.length <= 1)
|
.filter(({parents}) => parents.length <= 1)
|
||||||
.filter(({author}) => data.shared["commits.authoring"].filter(authoring => author?.login?.toLocaleLowerCase().includes(authoring)||author?.email?.toLocaleLowerCase().includes(authoring)||author?.name?.toLocaleLowerCase().includes(authoring)).length)
|
.filter(({author}) => data.shared["commits.authoring"].filter(authoring => author?.login?.toLocaleLowerCase().includes(authoring) || author?.email?.toLocaleLowerCase().includes(authoring) || author?.name?.toLocaleLowerCase().includes(authoring)).length),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,10 +90,11 @@ export default async function({login, q, imports, data, rest, graphql, queries,
|
|||||||
stdout(line) {
|
stdout(line) {
|
||||||
if (line.trim().length)
|
if (line.trim().length)
|
||||||
files.push(line)
|
files.push(line)
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
//Search for contributions type in specified categories
|
//Search for contributions type in specified categories
|
||||||
filesloop: for (const file of files) {
|
filesloop:
|
||||||
|
for (const file of files) {
|
||||||
for (const [category, globs] of Object.entries(categories)) {
|
for (const [category, globs] of Object.entries(categories)) {
|
||||||
for (const glob of [globs].flat(Infinity)) {
|
for (const glob of [globs].flat(Infinity)) {
|
||||||
if (imports.minimatch(file, glob, {nocase:true})) {
|
if (imports.minimatch(file, glob, {nocase:true})) {
|
||||||
|
|||||||
@@ -16,7 +16,13 @@ export default async function({login, q}, {conf, data, rest, graphql, plugins, q
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Init
|
//Init
|
||||||
const computed = {commits:0, sponsorships:0, licenses:{favorite:"", used:{}, about:{}}, token:{}, repositories:{watchers:0, stargazers:0, issues_open:0, issues_closed:0, pr_open:0, pr_closed:0, pr_merged:0, forks:0, forked:0, releases:0, deployments:0, environments:0}}
|
const computed = {
|
||||||
|
commits:0,
|
||||||
|
sponsorships:0,
|
||||||
|
licenses:{favorite:"", used:{}, about:{}},
|
||||||
|
token:{},
|
||||||
|
repositories:{watchers:0, stargazers:0, issues_open:0, issues_closed:0, pr_open:0, pr_closed:0, pr_merged:0, forks:0, forked:0, releases:0, deployments:0, environments:0},
|
||||||
|
}
|
||||||
const avatar = imports.imgb64(data.user.avatarUrl)
|
const avatar = imports.imgb64(data.user.avatarUrl)
|
||||||
data.computed = computed
|
data.computed = computed
|
||||||
console.debug(`metrics/compute/${login} > formatting common metrics`)
|
console.debug(`metrics/compute/${login} > formatting common metrics`)
|
||||||
@@ -38,6 +44,7 @@ export default async function({login, q}, {conf, data, rest, graphql, plugins, q
|
|||||||
else if (process?.env?.TZ)
|
else if (process?.env?.TZ)
|
||||||
data.config.timezone = {name:process.env.TZ, offset}
|
data.config.timezone = {name:process.env.TZ, offset}
|
||||||
|
|
||||||
|
|
||||||
//Display
|
//Display
|
||||||
data.large = display === "large"
|
data.large = display === "large"
|
||||||
data.columns = display === "columns"
|
data.columns = display === "columns"
|
||||||
@@ -124,7 +131,7 @@ export default async function({login, q}, {conf, data, rest, graphql, plugins, q
|
|||||||
data.meta = {
|
data.meta = {
|
||||||
version:conf.package.version,
|
version:conf.package.version,
|
||||||
author:conf.package.author,
|
author:conf.package.author,
|
||||||
generated:imports.format.date(new Date(), {date:true, time:true})
|
generated:imports.format.date(new Date(), {date:true, time:true}),
|
||||||
}
|
}
|
||||||
|
|
||||||
//Debug flags
|
//Debug flags
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export default async function({login, data, computed, imports, q, graphql, queri
|
|||||||
closed:0,
|
closed:0,
|
||||||
drafts:0,
|
drafts:0,
|
||||||
skipped:0,
|
skipped:0,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
pr:{
|
pr:{
|
||||||
get count() {
|
get count() {
|
||||||
@@ -50,13 +50,12 @@ export default async function({login, data, computed, imports, q, graphql, queri
|
|||||||
closed:0,
|
closed:0,
|
||||||
merged:0,
|
merged:0,
|
||||||
drafts:0,
|
drafts:0,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
//Extras features
|
//Extras features
|
||||||
if (extras) {
|
if (extras) {
|
||||||
|
|
||||||
//Indepth mode
|
//Indepth mode
|
||||||
if (indepth) {
|
if (indepth) {
|
||||||
console.debug(`metrics/compute/${login}/plugins > followup > indepth`)
|
console.debug(`metrics/compute/${login}/plugins > followup > indepth`)
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ export default async function({login, data, rest, imports, q, account}, {enabled
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
console.debug(`metrics/compute/${login}/plugins > habits > linguist not available`)
|
console.debug(`metrics/compute/${login}/plugins > habits > linguist not available`)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Results
|
//Results
|
||||||
|
|||||||
@@ -65,11 +65,12 @@ export async function recent({login, data, imports, rest, account}, {skipped = [
|
|||||||
try {
|
try {
|
||||||
for (let page = 1; page <= pages; page++) {
|
for (let page = 1; page <= pages; page++) {
|
||||||
console.debug(`metrics/compute/${login}/plugins > languages > loading page ${page}`)
|
console.debug(`metrics/compute/${login}/plugins > languages > loading page ${page}`)
|
||||||
commits.push(...(await rest.activity.listEventsForAuthenticatedUser({username:login, per_page:100, page})).data
|
commits.push(
|
||||||
|
...(await rest.activity.listEventsForAuthenticatedUser({username:login, per_page:100, page})).data
|
||||||
.filter(({type}) => type === "PushEvent")
|
.filter(({type}) => type === "PushEvent")
|
||||||
.filter(({actor}) => account === "organization" ? true : actor.login?.toLocaleLowerCase() === login.toLocaleLowerCase())
|
.filter(({actor}) => account === "organization" ? true : actor.login?.toLocaleLowerCase() === login.toLocaleLowerCase())
|
||||||
.filter(({repo:{name:repo}}) => (!skipped.includes(repo.toLocaleLowerCase())) && (!skipped.includes(repo.toLocaleLowerCase().split("/").pop())))
|
.filter(({repo:{name:repo}}) => (!skipped.includes(repo.toLocaleLowerCase())) && (!skipped.includes(repo.toLocaleLowerCase().split("/").pop())))
|
||||||
.filter(({created_at}) => new Date(created_at) > new Date(Date.now() - days * 24 * 60 * 60 * 1000))
|
.filter(({created_at}) => new Date(created_at) > new Date(Date.now() - days * 24 * 60 * 60 * 1000)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,7 +90,7 @@ export async function recent({login, data, imports, rest, account}, {skipped = [
|
|||||||
.filter(({author}) => data.shared["commits.authoring"].filter(authoring => author?.login?.toLocaleLowerCase().includes(authoring) || author?.email?.toLocaleLowerCase().includes(authoring) || author?.name?.toLocaleLowerCase().includes(authoring)).length)
|
.filter(({author}) => data.shared["commits.authoring"].filter(authoring => author?.login?.toLocaleLowerCase().includes(authoring) || author?.email?.toLocaleLowerCase().includes(authoring) || author?.name?.toLocaleLowerCase().includes(authoring)).length)
|
||||||
.map(commit => commit.url)
|
.map(commit => commit.url)
|
||||||
.map(async commit => (await rest.request(commit)).data),
|
.map(async commit => (await rest.request(commit)).data),
|
||||||
)
|
),
|
||||||
]
|
]
|
||||||
.filter(({status}) => status === "fulfilled")
|
.filter(({status}) => status === "fulfilled")
|
||||||
.map(({value}) => value)
|
.map(({value}) => value)
|
||||||
@@ -203,7 +204,7 @@ async function analyze({login, imports, data}, {results, path, categories = ["pr
|
|||||||
catch (error) {
|
catch (error) {
|
||||||
console.debug(`metrics/compute/${login}/plugins > languages > indepth > an error occured while processing line (${error.message}), skipping...`)
|
console.debug(`metrics/compute/${login}/plugins > languages > indepth > an error occured while processing line (${error.message}), skipping...`)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
if (empty) {
|
if (empty) {
|
||||||
console.debug(`metrics/compute/${login}/plugins > languages > indepth > no more commits`)
|
console.debug(`metrics/compute/${login}/plugins > languages > indepth > no more commits`)
|
||||||
|
|||||||
@@ -17,7 +17,11 @@ export default async function({login, data, imports, q, rest, account}, {enabled
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Load inputs
|
//Load inputs
|
||||||
let {ignored, skipped, colors, aliases, details, threshold, limit, indepth, "analysis.timeout":timeout, sections, categories, "recent.categories":_recent_categories, "recent.load":_recent_load, "recent.days":_recent_days} = imports.metadata.plugins.languages.inputs({data, account, q})
|
let {ignored, skipped, colors, aliases, details, threshold, limit, indepth, "analysis.timeout":timeout, sections, categories, "recent.categories":_recent_categories, "recent.load":_recent_load, "recent.days":_recent_days} = imports.metadata.plugins.languages.inputs({
|
||||||
|
data,
|
||||||
|
account,
|
||||||
|
q,
|
||||||
|
})
|
||||||
threshold = (Number(threshold.replace(/%$/, "")) || 0) / 100
|
threshold = (Number(threshold.replace(/%$/, "")) || 0) / 100
|
||||||
skipped.push(...data.shared["repositories.skipped"])
|
skipped.push(...data.shared["repositories.skipped"])
|
||||||
if (!limit)
|
if (!limit)
|
||||||
@@ -102,7 +106,8 @@ export default async function({login, data, imports, q, rest, account}, {enabled
|
|||||||
//Compute languages stats
|
//Compute languages stats
|
||||||
for (const {section, stats = {}, lines = {}, total = 0} of [{section:"favorites", stats:languages.stats, lines:languages.lines, total:languages.total}, {section:"recent", ...languages["stats.recent"]}]) {
|
for (const {section, stats = {}, lines = {}, total = 0} of [{section:"favorites", stats:languages.stats, lines:languages.lines, total:languages.total}, {section:"recent", ...languages["stats.recent"]}]) {
|
||||||
console.debug(`metrics/compute/${login}/plugins > languages > computing stats ${section}`)
|
console.debug(`metrics/compute/${login}/plugins > languages > computing stats ${section}`)
|
||||||
languages[section] = Object.entries(stats).filter(([name]) => !ignored.includes(name.toLocaleLowerCase())).sort(([_an, a], [_bn, b]) => b - a).slice(0, limit).map(([name, value]) => ({name, value, size:value, color:languages.colors[name], x:0})).filter(({value}) => value / total > threshold)
|
languages[section] = Object.entries(stats).filter(([name]) => !ignored.includes(name.toLocaleLowerCase())).sort(([_an, a], [_bn, b]) => b - a).slice(0, limit).map(([name, value]) => ({name, value, size:value, color:languages.colors[name], x:0})).filter(({value}) => value / total > threshold
|
||||||
|
)
|
||||||
const visible = {total:Object.values(languages[section]).map(({size}) => size).reduce((a, b) => a + b, 0)}
|
const visible = {total:Object.values(languages[section]).map(({size}) => size).reduce((a, b) => a + b, 0)}
|
||||||
for (let i = 0; i < languages[section].length; i++) {
|
for (let i = 0; i < languages[section].length; i++) {
|
||||||
const {name} = languages[section][i]
|
const {name} = languages[section][i]
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ export default async function({login, data, imports, rest, q, account}, {enabled
|
|||||||
//Get contributors stats from repositories
|
//Get contributors stats from repositories
|
||||||
console.debug(`metrics/compute/${login}/plugins > lines > querying api`)
|
console.debug(`metrics/compute/${login}/plugins > lines > querying api`)
|
||||||
const lines = {added:0, deleted:0}
|
const lines = {added:0, deleted:0}
|
||||||
const response = [...await Promise.allSettled(repositories.map(({repo, owner}) => (skipped.includes(repo.toLocaleLowerCase())) || (skipped.includes(`${owner}/${repo}`.toLocaleLowerCase())) ? {} : rest.repos.getContributorsStats({owner, repo})))].filter(({status}) => status === "fulfilled").map(({value}) => value)
|
const response = [...await Promise.allSettled(repositories.map(({repo, owner}) => (skipped.includes(repo.toLocaleLowerCase())) || (skipped.includes(`${owner}/${repo}`.toLocaleLowerCase())) ? {} : rest.repos.getContributorsStats({owner, repo})))].filter(({status}) => status === "fulfilled"
|
||||||
|
).map(({value}) => value)
|
||||||
|
|
||||||
//Compute changed lines
|
//Compute changed lines
|
||||||
console.debug(`metrics/compute/${login}/plugins > lines > computing total diff`)
|
console.debug(`metrics/compute/${login}/plugins > lines > computing total diff`)
|
||||||
|
|||||||
@@ -135,8 +135,8 @@ export default async function({login, imports, data, q, account}, {enabled = fal
|
|||||||
name:item.querySelector("yt-formatted-string.title > a")?.innerText ?? "",
|
name:item.querySelector("yt-formatted-string.title > a")?.innerText ?? "",
|
||||||
artist:item.querySelector(".secondary-flex-columns > yt-formatted-string > a")?.innerText ?? "",
|
artist:item.querySelector(".secondary-flex-columns > yt-formatted-string > a")?.innerText ?? "",
|
||||||
artwork:item.querySelector("img").src,
|
artwork:item.querySelector("img").src,
|
||||||
})
|
}))
|
||||||
)),
|
),
|
||||||
]
|
]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -257,12 +257,11 @@ export default async function({login, imports, data, q, account}, {enabled = fal
|
|||||||
try {
|
try {
|
||||||
//Request access token
|
//Request access token
|
||||||
console.debug(`metrics/compute/${login}/plugins > music > requesting access token with youtube refresh token`)
|
console.debug(`metrics/compute/${login}/plugins > music > requesting access token with youtube refresh token`)
|
||||||
const res = await imports.axios.post("https://music.youtube.com/youtubei/v1/browse?alt=json&key=AIzaSyC9XL3ZjWddXya6X74dJoCTL-WEYFDNX30",
|
const res = await imports.axios.post("https://music.youtube.com/youtubei/v1/browse?alt=json&key=AIzaSyC9XL3ZjWddXya6X74dJoCTL-WEYFDNX30", {
|
||||||
{
|
|
||||||
browseEndpointContextSupportedConfigs:{
|
browseEndpointContextSupportedConfigs:{
|
||||||
browseEndpointContextMusicConfig:{
|
browseEndpointContextMusicConfig:{
|
||||||
pageType:"MUSIC_PAGE_TYPE_PLAYLIST",
|
pageType:"MUSIC_PAGE_TYPE_PLAYLIST",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
context:{
|
context:{
|
||||||
client:{
|
client:{
|
||||||
@@ -272,9 +271,8 @@ export default async function({login, imports, data, q, account}, {enabled = fal
|
|||||||
hl:"en",
|
hl:"en",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
browseId:"FEmusic_history"
|
browseId:"FEmusic_history",
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
headers:{
|
headers:{
|
||||||
Authorization:SAPISIDHASH,
|
Authorization:SAPISIDHASH,
|
||||||
Cookie:token,
|
Cookie:token,
|
||||||
@@ -337,14 +335,14 @@ export default async function({login, imports, data, q, account}, {enabled = fal
|
|||||||
Object.defineProperty(modes, "top", {
|
Object.defineProperty(modes, "top", {
|
||||||
get() {
|
get() {
|
||||||
return `Top played artists ${time_msg}`
|
return `Top played artists ${time_msg}`
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Object.defineProperty(modes, "top", {
|
Object.defineProperty(modes, "top", {
|
||||||
get() {
|
get() {
|
||||||
return `Top played tracks ${time_msg}`
|
return `Top played tracks ${time_msg}`
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,8 +370,7 @@ export default async function({login, imports, data, q, account}, {enabled = fal
|
|||||||
//Retrieve tracks
|
//Retrieve tracks
|
||||||
console.debug(`metrics/compute/${login}/plugins > music > querying spotify api`)
|
console.debug(`metrics/compute/${login}/plugins > music > querying spotify api`)
|
||||||
tracks = []
|
tracks = []
|
||||||
const loaded =
|
const loaded = top_type === "artists"
|
||||||
top_type === "artists"
|
|
||||||
? (
|
? (
|
||||||
await imports.axios.get(
|
await imports.axios.get(
|
||||||
`https://api.spotify.com/v1/me/top/artists?time_range=${time_range}_term&limit=${limit}`,
|
`https://api.spotify.com/v1/me/top/artists?time_range=${time_range}_term&limit=${limit}`,
|
||||||
@@ -383,7 +380,7 @@ export default async function({login, imports, data, q, account}, {enabled = fal
|
|||||||
Accept:"application/json",
|
Accept:"application/json",
|
||||||
Authorization:`Bearer ${access}`,
|
Authorization:`Bearer ${access}`,
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
).data.items.map(({name, genres, images}) => ({
|
).data.items.map(({name, genres, images}) => ({
|
||||||
name,
|
name,
|
||||||
@@ -399,7 +396,7 @@ export default async function({login, imports, data, q, account}, {enabled = fal
|
|||||||
Accept:"application/json",
|
Accept:"application/json",
|
||||||
Authorization:`Bearer ${access}`,
|
Authorization:`Bearer ${access}`,
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
).data.items.map(({name, artists, album}) => ({
|
).data.items.map(({name, artists, album}) => ({
|
||||||
name,
|
name,
|
||||||
@@ -431,8 +428,7 @@ export default async function({login, imports, data, q, account}, {enabled = fal
|
|||||||
try {
|
try {
|
||||||
console.debug(`metrics/compute/${login}/plugins > music > querying lastfm api`)
|
console.debug(`metrics/compute/${login}/plugins > music > querying lastfm api`)
|
||||||
const period = time_range === "short" ? "1month" : time_range === "medium" ? "6month" : "overall"
|
const period = time_range === "short" ? "1month" : time_range === "medium" ? "6month" : "overall"
|
||||||
tracks =
|
tracks = top_type === "artists"
|
||||||
top_type === "artists"
|
|
||||||
? (
|
? (
|
||||||
await imports.axios.get(
|
await imports.axios.get(
|
||||||
`https://ws.audioscrobbler.com/2.0/?method=user.gettopartists&user=${user}&api_key=${token}&limit=${limit}&period=${period}&format=json`,
|
`https://ws.audioscrobbler.com/2.0/?method=user.gettopartists&user=${user}&api_key=${token}&limit=${limit}&period=${period}&format=json`,
|
||||||
@@ -441,7 +437,7 @@ export default async function({login, imports, data, q, account}, {enabled = fal
|
|||||||
"User-Agent":"lowlighter/metrics",
|
"User-Agent":"lowlighter/metrics",
|
||||||
Accept:"application/json",
|
Accept:"application/json",
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
).data.topartists.artist.map(artist => ({
|
).data.topartists.artist.map(artist => ({
|
||||||
name:artist.name,
|
name:artist.name,
|
||||||
@@ -456,7 +452,7 @@ export default async function({login, imports, data, q, account}, {enabled = fal
|
|||||||
"User-Agent":"lowlighter/metrics",
|
"User-Agent":"lowlighter/metrics",
|
||||||
Accept:"application/json",
|
Accept:"application/json",
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
).data.toptracks.track.map(track => ({
|
).data.toptracks.track.map(track => ({
|
||||||
name:track.name,
|
name:track.name,
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export default async function({login, q, imports, rest, graphql, data, account,
|
|||||||
maintainer:maintainers.includes(login),
|
maintainer:maintainers.includes(login),
|
||||||
get stars() {
|
get stars() {
|
||||||
return this.maintainer ? stars : this.percentage * stars
|
return this.maintainer ? stars : this.percentage * stars
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
console.debug(`metrics/compute/${login}/plugins > notable > indepth > successfully processed ${owner}/${repo}`)
|
console.debug(`metrics/compute/${login}/plugins > notable > indepth > successfully processed ${owner}/${repo}`)
|
||||||
}
|
}
|
||||||
@@ -91,6 +91,7 @@ export default async function({login, q, imports, rest, graphql, data, account,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
aggregated.set(key, {name:key, handle, avatar, organization, stars, aggregated:1, ..._extras})
|
aggregated.set(key, {name:key, handle, avatar, organization, stars, aggregated:1, ..._extras})
|
||||||
|
|
||||||
}
|
}
|
||||||
contributions = [...aggregated.values()]
|
contributions = [...aggregated.values()]
|
||||||
if (extras) {
|
if (extras) {
|
||||||
@@ -100,7 +101,6 @@ export default async function({login, q, imports, rest, graphql, data, account,
|
|||||||
contributions = contributions.sort((a, b) => ((b.user?.percentage + b.user?.maintainer) || 0) - ((a.user?.percentage + a.user?.maintainer) || 0))
|
contributions = contributions.sort((a, b) => ((b.user?.percentage + b.user?.maintainer) || 0) - ((a.user?.percentage + a.user?.maintainer) || 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Results
|
//Results
|
||||||
return {contributions}
|
return {contributions}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ export default async function({q, imports, data, account}, {enabled = false, tok
|
|||||||
if ((!enabled) || (!q.poopmap))
|
if ((!enabled) || (!q.poopmap))
|
||||||
return null
|
return null
|
||||||
|
|
||||||
if (!token) return {poops:[], days:7}
|
if (!token)
|
||||||
|
return {poops:[], days:7}
|
||||||
|
|
||||||
const {days} = imports.metadata.plugins.poopmap.inputs({data, account, q})
|
const {days} = imports.metadata.plugins.poopmap.inputs({data, account, q})
|
||||||
const {data:{poops}} = await imports.axios.get(`https://api.poopmap.net/api/v1/public_links/${token}`)
|
const {data:{poops}} = await imports.axios.get(`https://api.poopmap.net/api/v1/public_links/${token}`)
|
||||||
|
|||||||
@@ -23,8 +23,9 @@ export default async function({login, q, imports, data, account}, {enabled = fal
|
|||||||
name:element.querySelector("h3")?.innerText ?? "",
|
name:element.querySelector("h3")?.innerText ?? "",
|
||||||
description:element.querySelector("span")?.innerText ?? "",
|
description:element.querySelector("span")?.innerText ?? "",
|
||||||
count:Number(element.querySelector("div")?.innerText.match(/(?<count>\d+)/)?.groups.count),
|
count:Number(element.querySelector("div")?.innerText.match(/(?<count>\d+)/)?.groups.count),
|
||||||
repositories:[]
|
repositories:[],
|
||||||
}))))
|
}))
|
||||||
|
))
|
||||||
const count = lists.length
|
const count = lists.length
|
||||||
console.debug(`metrics/compute/${login}/plugins > starlists > found [${lists.map(({name}) => name)}]`)
|
console.debug(`metrics/compute/${login}/plugins > starlists > found [${lists.map(({name}) => name)}]`)
|
||||||
lists = lists
|
lists = lists
|
||||||
@@ -40,8 +41,9 @@ export default async function({login, q, imports, data, account}, {enabled = fal
|
|||||||
await page.goto(list.link)
|
await page.goto(list.link)
|
||||||
const repositories = await page.evaluate(() => [...document.querySelectorAll("#user-list-repositories > div")].map(element => ({
|
const repositories = await page.evaluate(() => [...document.querySelectorAll("#user-list-repositories > div")].map(element => ({
|
||||||
name:element.querySelector("div:first-child")?.innerText.replace(" / ", "/") ?? "",
|
name:element.querySelector("div:first-child")?.innerText.replace(" / ", "/") ?? "",
|
||||||
description:element.querySelector(".py-1")?.innerText ?? ""
|
description:element.querySelector(".py-1")?.innerText ?? "",
|
||||||
})))
|
}))
|
||||||
|
)
|
||||||
list.repositories.push(...repositories)
|
list.repositories.push(...repositories)
|
||||||
if (_shuffle)
|
if (_shuffle)
|
||||||
list.repositories = imports.shuffle(list.repositories)
|
list.repositories = imports.shuffle(list.repositories)
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ export default async function({login, imports, data, rest, q, account}, {enabled
|
|||||||
//Get views stats from repositories
|
//Get views stats from repositories
|
||||||
console.debug(`metrics/compute/${login}/plugins > traffic > querying api`)
|
console.debug(`metrics/compute/${login}/plugins > traffic > querying api`)
|
||||||
const views = {count:0, uniques:0}
|
const views = {count:0, uniques:0}
|
||||||
const response = [...await Promise.allSettled(repositories.map(({repo, owner}) => (skipped.includes(repo.toLocaleLowerCase())) || (skipped.includes(`${owner}/${repo}`.toLocaleLowerCase())) ? {} : rest.repos.getViews({owner, repo})))].filter(({status}) => status === "fulfilled").map(({value}) => value)
|
const response = [...await Promise.allSettled(repositories.map(({repo, owner}) => (skipped.includes(repo.toLocaleLowerCase())) || (skipped.includes(`${owner}/${repo}`.toLocaleLowerCase())) ? {} : rest.repos.getViews({owner, repo})))].filter(({status}) => status === "fulfilled"
|
||||||
|
).map(({value}) => value)
|
||||||
|
|
||||||
//Compute views
|
//Compute views
|
||||||
console.debug(`metrics/compute/${login}/plugins > traffic > computing stats`)
|
console.debug(`metrics/compute/${login}/plugins > traffic > computing stats`)
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ export default function({faker, url, options, login = faker.internet.userName()}
|
|||||||
place: "",
|
place: "",
|
||||||
rating: faker.datatype.number(5),
|
rating: faker.datatype.number(5),
|
||||||
followers_count: faker.datatype.number(100),
|
followers_count: faker.datatype.number(100),
|
||||||
comments_count:faker.datatype.number(12)
|
comments_count: faker.datatype.number(12),
|
||||||
}))
|
})),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,29 +22,28 @@ export default function({faker, url, options, login = faker.internet.userName()}
|
|||||||
thumbnail: {
|
thumbnail: {
|
||||||
thumbnails: [{
|
thumbnails: [{
|
||||||
url: artwork,
|
url: artwork,
|
||||||
}]
|
}],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
flexColumns: [{
|
flexColumns: [{
|
||||||
musicResponsiveListItemFlexColumnRenderer: {
|
musicResponsiveListItemFlexColumnRenderer: {
|
||||||
text: {
|
text: {
|
||||||
runs: [{
|
runs: [{
|
||||||
text: track,
|
text: track,
|
||||||
}]
|
}],
|
||||||
},
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
}, {
|
||||||
musicResponsiveListItemFlexColumnRenderer: {
|
musicResponsiveListItemFlexColumnRenderer: {
|
||||||
text: {
|
text: {
|
||||||
runs: [{
|
runs: [{
|
||||||
text: artist,
|
text: artist,
|
||||||
}]
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}],
|
}],
|
||||||
}
|
},
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
},
|
||||||
}],
|
}],
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ export default function({faker, query, login = faker.internet.userName()}) {
|
|||||||
repositoryDiscussions: {
|
repositoryDiscussions: {
|
||||||
edges: [],
|
edges: [],
|
||||||
nodes: [],
|
nodes: [],
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
: ({
|
: ({
|
||||||
user: {
|
user: {
|
||||||
@@ -17,11 +17,10 @@ export default function({faker, query, login = faker.internet.userName()}) {
|
|||||||
nodes: new Array(100).fill(null).map(_ => ({
|
nodes: new Array(100).fill(null).map(_ => ({
|
||||||
category: {
|
category: {
|
||||||
emoji: faker.random.arrayElement([":chart_with_upwards_trend:", ":chart_with_downwards_trend:", ":bar_char:"]),
|
emoji: faker.random.arrayElement([":chart_with_upwards_trend:", ":chart_with_downwards_trend:", ":bar_char:"]),
|
||||||
name:faker.lorem.slug()
|
name: faker.lorem.slug(),
|
||||||
}
|
},
|
||||||
}))
|
})),
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,16 +7,15 @@ export default function({faker, query, login = faker.internet.userName()}) {
|
|||||||
repositoryDiscussionsComments: {
|
repositoryDiscussionsComments: {
|
||||||
edges: [],
|
edges: [],
|
||||||
nodes: [],
|
nodes: [],
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
: ({
|
: ({
|
||||||
user: {
|
user: {
|
||||||
repositoryDiscussionsComments: {
|
repositoryDiscussionsComments: {
|
||||||
edges: new Array(100).fill(null).map(_ => ({ cursor: "MOCKED_CURSOR" })),
|
edges: new Array(100).fill(null).map(_ => ({ cursor: "MOCKED_CURSOR" })),
|
||||||
nodes:new Array(100).fill(null).map(_ => ({upvoteCount: faker.datatype.number(10)}))
|
nodes: new Array(100).fill(null).map(_ => ({ upvoteCount: faker.datatype.number(10) })),
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ export default function({faker, query, login = faker.internet.userName()}) {
|
|||||||
user: {
|
user: {
|
||||||
started: { totalCount: faker.datatype.number(1000) },
|
started: { totalCount: faker.datatype.number(1000) },
|
||||||
comments: { totalCount: faker.datatype.number(1000) },
|
comments: { totalCount: faker.datatype.number(1000) },
|
||||||
answers:{totalCount:faker.datatype.number(1000)}
|
answers: { totalCount: faker.datatype.number(1000) },
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -4,8 +4,8 @@ export default function({faker, query, login = faker.internet.userName()}) {
|
|||||||
return ({
|
return ({
|
||||||
repository: {
|
repository: {
|
||||||
collaborators: {
|
collaborators: {
|
||||||
nodes:["github-user"]
|
nodes: ["github-user"],
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export default function({faker, query, login = faker.internet.userName()}) {
|
|||||||
percentComplete: faker.datatype.number(100),
|
percentComplete: faker.datatype.number(100),
|
||||||
title: faker.lorem.sentence(),
|
title: faker.lorem.sentence(),
|
||||||
description: faker.lorem.sentence(),
|
description: faker.lorem.sentence(),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
sponsorshipsAsMaintainer: {
|
sponsorshipsAsMaintainer: {
|
||||||
totalCount: faker.datatype.number(100),
|
totalCount: faker.datatype.number(100),
|
||||||
@@ -20,9 +20,9 @@ export default function({faker, query, login = faker.internet.userName()}) {
|
|||||||
},
|
},
|
||||||
tier: {
|
tier: {
|
||||||
monthlyPriceInDollars: faker.datatype.number(10),
|
monthlyPriceInDollars: faker.datatype.number(10),
|
||||||
}
|
},
|
||||||
}))
|
})),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -26,9 +26,9 @@ export default async function({graphql, rest}) {
|
|||||||
mocks[entry] = {}
|
mocks[entry] = {}
|
||||||
await mock({ directory: paths.join(directory, entry), mocks: mocks[entry] })
|
await mock({ directory: paths.join(directory, entry), mocks: mocks[entry] })
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
mocks[entry.replace(/[.]mjs$/, "")] = (await import(urls.pathToFileURL(paths.join(directory, entry)).href)).default
|
mocks[entry.replace(/[.]mjs$/, "")] = (await import(urls.pathToFileURL(paths.join(directory, entry)).href)).default
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return mocks
|
return mocks
|
||||||
}
|
}
|
||||||
@@ -71,9 +71,9 @@ export default async function({graphql, rest}) {
|
|||||||
unmocked[path] = value
|
unmocked[path] = value
|
||||||
mocked[key] = new Proxy(unmocked[path], { apply: value.bind(null, { faker }) })
|
mocked[key] = new Proxy(unmocked[path], { apply: value.bind(null, { faker }) })
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
mocker({ path: `${path}.${key}`, mocks: mocks[key], mocked: mocked[key] })
|
mocker({ path: `${path}.${key}`, mocks: mocks[key], mocked: mocked[key] })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mocker({ mocks: mocks.github.rest, mocked: rest })
|
mocker({ mocks: mocks.github.rest, mocked: rest })
|
||||||
|
|||||||
Reference in New Issue
Block a user