diff --git a/source/app/mocks/api/github/graphql/repositories.repository.mjs b/source/app/mocks/api/github/graphql/repositories.repository.mjs new file mode 100644 index 00000000..488dd422 --- /dev/null +++ b/source/app/mocks/api/github/graphql/repositories.repository.mjs @@ -0,0 +1,29 @@ +/**Mocked data */ +export default function({faker, query, login = faker.internet.userName()}) { + console.debug("metrics/compute/mocks > mocking graphql api result > stars/default") + return ({ + repository:{ + createdAt: faker.date.past(), + description:"📊 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 !", + forkCount:faker.datatype.number(100), + isFork:false, + issues:{ + totalCount:faker.datatype.number(100), + }, + nameWithOwner:"lowlighter/metrics", + openGraphImageUrl:"https://repository-images.githubusercontent.com/293860197/7fd72080-496d-11eb-8fe0-238b38a0746a", + pullRequests:{ + totalCount:faker.datatype.number(100), + }, + stargazerCount:faker.datatype.number(10000), + licenseInfo:{ + nickname:null, + name:"MIT License", + }, + primaryLanguage:{ + color:"#f1e05a", + name:"JavaScript", + }, + }, + }) +} diff --git a/source/app/web/statics/app.placeholder.js b/source/app/web/statics/app.placeholder.js index 2c327712..aa3761ec 100644 --- a/source/app/web/statics/app.placeholder.js +++ b/source/app/web/statics/app.placeholder.js @@ -678,7 +678,31 @@ }, }) : null), - //Stars + //Repositories + ...(set.plugins.enabled.repositories + ? ({ + repositories: { + list: new Array(Number(options["repositories.featured"].split(",").length) - 1).fill(null).map((_, i) => ({ + created: faker.date.past(), + description: faker.lorem.sentence(), + forkCount: faker.datatype.number(100), + isFork: faker.datatype.boolean(), + issues: { + totalCount: faker.datatype.number(100), + }, + nameWithOwner: `${faker.random.word()}/${faker.random.word()}`, + openGraphImageUrl: faker.internet.url(), + pullRequests: { + totalCount: faker.datatype.number(100), + }, + stargazerCount: faker.datatype.number(10000), + licenseInfo: { nickname: null, name: "License" }, + primaryLanguage: { color: faker.internet.color(), name: faker.lorem.word() }, + })), + }, + }) + : null), + //Stargazers ...(set.plugins.enabled.stargazers ? ({ get stargazers() { diff --git a/source/plugins/repositories/README.md b/source/plugins/repositories/README.md new file mode 100644 index 00000000..826f64d9 --- /dev/null +++ b/source/plugins/repositories/README.md @@ -0,0 +1,26 @@ +### 📓 Repositories + +The *repositories* plugin can display a list of chosen featured repositories. + + + +
+ + +
+ +It is mostly intended for external usage as [pinned repositories](https://www.google.com/search?client=firefox-b-d&q=github+pinned+repositories) is probably a better alternative if you want to embed them on your profile. + +Because of limitations of using SVG inside of `` tags, people won't be able to click on it. + +#### â„šī¸ Examples workflows + +[âžĄī¸ Available options for this plugin](metadata.yml) + +```yaml +- uses: lowlighter/metrics@latest + with: + # ... other options + plugin_repositories: yes + plugin_repositories_list: lowlighter/metrics, denoland/deno # List of repositories you want to feature +``` \ No newline at end of file diff --git a/source/plugins/repositories/index.mjs b/source/plugins/repositories/index.mjs new file mode 100644 index 00000000..163bdd46 --- /dev/null +++ b/source/plugins/repositories/index.mjs @@ -0,0 +1,38 @@ +//Setup +export default async function({login, q, imports, graphql, queries, data, account}, {enabled = false} = {}) { + //Plugin execution + try { + //Check if plugin is enabled and requirements are met + if ((!enabled)||(!q.repositories)) + return null + + //Load inputs + let {featured} = imports.metadata.plugins.repositories.inputs({data, account, q}) + + //Initialization + const repositories = {list:[]} + + //Fetch repositories informations + for (const repo of featured) { + const {owner = login, name} = repo.match(/^(?:(?[\s\S]*)[/])?(?[\s\S]+)$/)?.groups ?? {} + const {repository} = await graphql(queries.repositories.repository({owner, name})) + repositories.list.push(repository) + + //Format date + const time = (Date.now() - new Date(repository.createdAt).getTime()) / (24 * 60 * 60 * 1000) + let created = new Date(repository.createdAt).toDateString().substring(4) + if (time < 1) + created = `${Math.ceil(time * 24)} hour${Math.ceil(time * 24) >= 2 ? "s" : ""} ago` + else if (time < 30) + created = `${Math.floor(time)} day${time >= 2 ? "s" : ""} ago` + repository.created = created + } + + //Results + return repositories + } + //Handle errors + catch (error) { + throw {error:{message:"An error occured", instance:error}} + } +} \ No newline at end of file diff --git a/source/plugins/repositories/metadata.yml b/source/plugins/repositories/metadata.yml new file mode 100644 index 00000000..d18bca69 --- /dev/null +++ b/source/plugins/repositories/metadata.yml @@ -0,0 +1,22 @@ +name: "📓 Repositories" +cost: 1 GraphQL request per repository +category: github +supports: + - user + - organization +inputs: + + # Enable or disable plugin + plugin_repositories: + description: Display chosen featured repositories + type: boolean + default: no + + # Featured repositories to display + # If no owner is specified, it will implicitly use the current account login as owner + plugin_repositories_featured: + description: List of repositories to display + type: array + format: comma-separated + default: "" + example: lowlighter/metrics diff --git a/source/plugins/repositories/queries/repository.graphql b/source/plugins/repositories/queries/repository.graphql new file mode 100644 index 00000000..b4bcb788 --- /dev/null +++ b/source/plugins/repositories/queries/repository.graphql @@ -0,0 +1,26 @@ +query RepositoriesRepository { + repository(owner: "$owner", name: "$name") { + createdAt + description + forkCount + isFork + issues { + totalCount + } + nameWithOwner + openGraphImageUrl + licenseInfo { + nickname + spdxId + name + } + pullRequests { + totalCount + } + stargazerCount + primaryLanguage { + color + name + } + } +} diff --git a/source/plugins/repositories/tests.yml b/source/plugins/repositories/tests.yml new file mode 100644 index 00000000..77f25749 --- /dev/null +++ b/source/plugins/repositories/tests.yml @@ -0,0 +1,6 @@ +- name: Repositories plugin (default) + uses: lowlighter/metrics@latest + with: + token: MOCKED_TOKEN + plugin_repositories: yes + plugin_repositories_list: metrics \ No newline at end of file diff --git a/source/templates/classic/partials/_.json b/source/templates/classic/partials/_.json index 0834249c..f88ec37e 100644 --- a/source/templates/classic/partials/_.json +++ b/source/templates/classic/partials/_.json @@ -7,6 +7,7 @@ "languages", "notable", "projects", + "repositories", "gists", "pagespeed", "habits", diff --git a/source/templates/classic/partials/repositories.ejs b/source/templates/classic/partials/repositories.ejs new file mode 100644 index 00000000..879e2aa2 --- /dev/null +++ b/source/templates/classic/partials/repositories.ejs @@ -0,0 +1,78 @@ +<% if (plugins.repositories) { %> +
+

+ + Featured repositories +

+
+
+ <% if (plugins.repositories.error) { %> +
+ + <%= plugins.repositories.error.message %> +
+ <% } else if (plugins.repositories.list.length) { %> + <% for (const repository of plugins.repositories.list) { %> +
+
+
+ <% if (repository.isFork) { %> + + <% } else { %> + + <% } %> +
+ <%= repository.nameWithOwner %> + created <%= repository.created %> +
+
+
+ <%= repository.description %> +
+
+ <% if (repository.primaryLanguage) { %> +
+ + <%= repository.primaryLanguage.name %> +
+ <% } %> + <% if (repository.licenseInfo) { %> +
+ + <%= f.license(repository.licenseInfo) %> +
+ <% } %> +
+ + <%= f(repository.stargazerCount) %> +
+
+ + <%= f(repository.forkCount) %> +
+
+ + <%= f(repository.issues.totalCount) %> +
+
+ + <%= f(repository.pullRequests.totalCount) %> +
+
+
+
+ <% } %> + <% } else { %> +
+
+
+ + Configure this plugin with repositories you want to feature! +
+
+
+ <% } %> +
+
+
+<% } %> \ No newline at end of file