//Imports import axios from "axios" import urls from "url" import faker from "faker" //Mocked state let mocked = false //Mocking export default async function ({graphql, rest}) { //Check if already mocked if (mocked) return {graphql, rest} mocked = true console.debug(`metrics/compute/mocks > mocking`) //GraphQL API mocking { console.debug(`metrics/compute/mocks > mocking graphql api`) const unmocked = graphql graphql = new Proxy(unmocked, { apply(target, that, args) { //Arguments const [query] = args const login = query.match(/login: "(?.*?)"/)?.groups?.login ?? faker.internet.userName() //Common query if (/^query Metrics /.test(query)) { console.debug(`metrics/compute/mocks > mocking graphql api result > Metrics`) return ({ user: { databaseId:faker.random.number(10000000), name:faker.name.findName(), login, createdAt:`${faker.date.past(10)}`, avatarUrl:faker.image.people(), websiteUrl:faker.internet.url(), isHireable:faker.random.boolean(), twitterUsername:login, repositories:{totalCount:faker.random.number(100), totalDiskUsage:faker.random.number(100000), nodes:[]}, packages:{totalCount:faker.random.number(10)}, starredRepositories:{totalCount:faker.random.number(1000)}, watching:{totalCount:faker.random.number(100)}, sponsorshipsAsSponsor:{totalCount:faker.random.number(10)}, sponsorshipsAsMaintainer:{totalCount:faker.random.number(10)}, contributionsCollection:{ totalRepositoriesWithContributedCommits:faker.random.number(100), totalCommitContributions:faker.random.number(10000), restrictedContributionsCount:faker.random.number(10000), totalIssueContributions:faker.random.number(100), totalPullRequestContributions:faker.random.number(1000), totalPullRequestReviewContributions:faker.random.number(1000), }, calendar:{ contributionCalendar:{ weeks:[ { contributionDays:[ {color:faker.random.arrayElement(["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"])}, {color:faker.random.arrayElement(["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"])}, {color:faker.random.arrayElement(["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"])}, {color:faker.random.arrayElement(["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"])}, {color:faker.random.arrayElement(["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"])}, ] }, { contributionDays:[ {color:faker.random.arrayElement(["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"])}, {color:faker.random.arrayElement(["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"])}, {color:faker.random.arrayElement(["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"])}, {color:faker.random.arrayElement(["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"])}, {color:faker.random.arrayElement(["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"])}, {color:faker.random.arrayElement(["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"])}, {color:faker.random.arrayElement(["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"])}, ] }, { contributionDays:[ {color:faker.random.arrayElement(["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"])}, {color:faker.random.arrayElement(["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"])}, {color:faker.random.arrayElement(["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"])}, ] } ] } }, repositoriesContributedTo:{totalCount:faker.random.number(100)}, followers:{totalCount:faker.random.number(1000)}, following:{totalCount:faker.random.number(1000)}, issueComments:{totalCount:faker.random.number(1000)}, organizations:{totalCount:faker.random.number(10)} } }) } //Repositories query if (/^query Repositories /.test(query)) { console.debug(`metrics/compute/mocks > mocking graphql api result > Repositories`) return /after: "MOCKED_CURSOR"/m.test(query) ? ({ user:{ repositories:{ edges:[], nodes:[], } } }) : ({ user:{ repositories:{ edges:[ { cursor:"MOCKED_CURSOR" }, ], nodes:[ { name:faker.random.words(), watchers:{totalCount:faker.random.number(1000)}, stargazers:{totalCount:faker.random.number(10000)}, owner:{login}, languages:{ edges:[ {size:faker.random.number(100000), node:{color:faker.internet.color(), name:faker.lorem.word()}}, {size:faker.random.number(100000), node:{color:faker.internet.color(), name:faker.lorem.word()}}, {size:faker.random.number(100000), node:{color:faker.internet.color(), name:faker.lorem.word()}}, {size:faker.random.number(100000), node:{color:faker.internet.color(), name:faker.lorem.word()}}, {size:faker.random.number(100000), node:{color:faker.internet.color(), name:faker.lorem.word()}}, {size:faker.random.number(100000), node:{color:faker.internet.color(), name:faker.lorem.word()}}, {size:faker.random.number(100000), node:{color:faker.internet.color(), name:faker.lorem.word()}}, ] }, issues_open:{totalCount:faker.random.number(100)}, issues_closed:{totalCount:faker.random.number(100)}, pr_open:{totalCount:faker.random.number(100)}, pr_merged:{totalCount:faker.random.number(100)}, releases:{totalCount:faker.random.number(100)}, forkCount:faker.random.number(100), licenseInfo:{spdxId:"MIT"} }, ] } } }) } //Single repository query if (/^query Repository /.test(query)) { console.debug(`metrics/compute/mocks > mocking graphql api result > Repository`) return ({ user:{ repository:{ name:"metrics", owner:{login}, createdAt:new Date().toISOString(), diskUsage:Math.floor(Math.random()*10000), homepageUrl:faker.internet.url(), watchers:{totalCount:faker.random.number(1000)}, stargazers:{totalCount:faker.random.number(10000)}, languages:{ edges:[ {size:faker.random.number(100000), node:{color:faker.internet.color(), name:faker.lorem.word()}}, {size:faker.random.number(100000), node:{color:faker.internet.color(), name:faker.lorem.word()}}, {size:faker.random.number(100000), node:{color:faker.internet.color(), name:faker.lorem.word()}}, {size:faker.random.number(100000), node:{color:faker.internet.color(), name:faker.lorem.word()}}, {size:faker.random.number(100000), node:{color:faker.internet.color(), name:faker.lorem.word()}}, {size:faker.random.number(100000), node:{color:faker.internet.color(), name:faker.lorem.word()}}, {size:faker.random.number(100000), node:{color:faker.internet.color(), name:faker.lorem.word()}}, ] }, issues_open:{totalCount:faker.random.number(100)}, issues_closed:{totalCount:faker.random.number(100)}, pr_open:{totalCount:faker.random.number(100)}, pr_merged:{totalCount:faker.random.number(100)}, releases:{totalCount:faker.random.number(100)}, forkCount:faker.random.number(100), licenseInfo:{spdxId:"MIT"} }, } }) } //Calendar query if (/^query Calendar /.test(query)) { console.debug(`metrics/compute/mocks > mocking graphql api result > Calendar`) //Generate calendar const date = new Date(query.match(/from: "(?\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z)"/)?.groups?.date) const to = new Date(query.match(/to: "(?\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z)"/)?.groups?.date) const weeks = [] let contributionDays = [] for (; date <= to; date.setDate(date.getDate()+1)) { //Create new week on sunday if (date.getDay() === 0) { weeks.push({contributionDays}) contributionDays = [] } //Random contributions const contributionCount = Math.min(10, Math.max(0, faker.random.number(14)-4)) contributionDays.push({ contributionCount, color:["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"][Math.ceil(contributionCount/10/0.25)], date:date.toISOString().substring(0, 10) }) } return ({ user: { calendar:{ contributionCalendar:{ weeks } } } }) } //Gists query if (/^query Gists /.test(query)) { console.debug(`metrics/compute/mocks > mocking graphql api result > Gists`) return /after: "MOCKED_CURSOR"/m.test(query) ? ({ user:{ gists:{ edges:[], nodes:[], } } }) : ({ user:{ gists:{ edges:[ { cursor:"MOCKED_CURSOR" }, ], totalCount:faker.random.number(100), nodes:[ { stargazerCount:faker.random.number(10), isFork:false, forks:{totalCount:faker.random.number(10)}, files:[{name:faker.system.fileName()}], comments:{totalCount:faker.random.number(10)} }, { stargazerCount:faker.random.number(10), isFork:false, forks:{totalCount:faker.random.number(10)}, files:[{name:faker.system.fileName()}], comments:{totalCount:faker.random.number(10)} } ] } } }) } //Projects query if (/^query Projects /.test(query)) { console.debug(`metrics/compute/mocks > mocking graphql api result > Projects`) return ({ user:{ projects:{ totalCount:1, nodes:[ { name:"User-owned project", updatedAt:`${faker.date.recent()}`, body:faker.lorem.paragraph(), progress:{ doneCount:faker.random.number(10), inProgressCount:faker.random.number(10), todoCount:faker.random.number(10), enabled:true } } ] } } }) } //Repository project query if (/^query RepositoryProject /.test(query)) { console.debug(`metrics/compute/mocks > mocking graphql api result > RepositoryProject`) return ({ user:{ repository:{ project:{ name:"Repository project example", updatedAt:`${faker.date.recent()}`, body:faker.lorem.paragraph(), progress:{ doneCount:faker.random.number(10), inProgressCount:faker.random.number(10), todoCount:faker.random.number(10), enabled:true } } } } }) } //Starred repositories query if (/^query Starred /.test(query)) { console.debug(`metrics/compute/mocks > mocking graphql api result > Starred`) return ({ user:{ starredRepositories:{ edges:[ { starredAt:`${faker.date.recent(14)}`, node:{ 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.random.number(100), isFork:false, issues:{ totalCount:faker.random.number(100), }, nameWithOwner:"lowlighter/metrics", openGraphImageUrl:"https://repository-images.githubusercontent.com/293860197/7fd72080-496d-11eb-8fe0-238b38a0746a", pullRequests:{ totalCount:faker.random.number(100), }, stargazerCount:faker.random.number(10000), licenseInfo:{ nickname:null, name:"MIT License" }, primaryLanguage:{ color:"#f1e05a", name:"JavaScript" } } }, ] } } }) } //Stargazers query if (/^query Stargazers /.test(query)) { console.debug(`metrics/compute/mocks > mocking graphql api result > Stargazers`) return /after: "MOCKED_CURSOR"/m.test(query) ? ({ repository:{ stargazers:{ edges:[], } } }) : ({ repository:{ stargazers:{ edges:new Array(faker.random.number({min:50, max:100})).fill(null).map(() => ({ starredAt:`${faker.date.recent(30)}`, cursor:"MOCKED_CURSOR" })) } } }) } //People query if (/^query People /.test(query)) { console.debug(`metrics/compute/mocks > mocking graphql api result > People`) const type = query.match(/(?followers|following)[(]/)?.groups?.type ?? "(unknown type)" return /after: "MOCKED_CURSOR"/m.test(query) ? ({ user:{ [type]:{ edges:[], } } }) : ({ user:{ [type]:{ edges:new Array(Math.ceil(20+80*Math.random())).fill(null).map((login = faker.internet.userName()) => ({ cursor:"MOCKED_CURSOR", node:{ login, avatarUrl:null, } })) } } }) } //People query (repositories) if (/^query PeopleRepository /.test(query)) { console.debug(`metrics/compute/mocks > mocking graphql api result > People`) const type = query.match(/(?stargazers|watchers)[(]/)?.groups?.type ?? "(unknown type)" return /after: "MOCKED_CURSOR"/m.test(query) ? ({ user:{ repository:{ [type]:{ edges:[], } } } }) : ({ user:{ repository:{ [type]:{ edges:new Array(Math.ceil(20+80*Math.random())).fill(null).map((login = faker.internet.userName()) => ({ cursor:"MOCKED_CURSOR", node:{ login, avatarUrl:null, } })) } } } }) } //People sponsors query if (/^query PeopleSponsors /.test(query)) { console.debug(`metrics/compute/mocks > mocking graphql api result > People`) const type = query.match(/(?sponsorshipsAsSponsor|sponsorshipsAsMaintainer)[(]/)?.groups?.type ?? "(unknown type)" return /after: "MOCKED_CURSOR"/m.test(query) ? ({ user:{ login, [type]:{ edges:[] } } }) : ({ user:{ login, [type]:{ edges:new Array(Math.ceil(20+80*Math.random())).fill(null).map((login = faker.internet.userName()) => ({ cursor:"MOCKED_CURSOR", node:{ sponsorEntity:{ login:faker.internet.userName(), avatarUrl:null, }, sponsorable:{ login:faker.internet.userName(), avatarUrl:null, } } })) } } }) } //Unmocked call return target(...args) } }) } //Rest API mocking { console.debug(`metrics/compute/mocks > mocking rest api`) const unmocked = { request:rest.request, rateLimit:rest.rateLimit.get, listEventsForAuthenticatedUser:rest.activity.listEventsForAuthenticatedUser, getViews:rest.repos.getViews, getContributorsStats:rest.repos.getContributorsStats, listCommits:rest.repos.listCommits, listContributors:rest.repos.listContributors, getByUsername:rest.users.getByUsername, } //Raw request rest.request = new Proxy(unmocked.request, { apply:function(target, that, args) { //Arguments const [url] = args //Head request if (/^HEAD .$/.test(url)) { console.debug(`metrics/compute/mocks > mocking rest api result > rest.request HEAD`) return ({ status:200, url:"https://api.github.com/", headers:{ server:"GitHub.com", status:"200 OK", "x-oauth-scopes":"repo", }, data:undefined }) } //Commit content if (/^https:..api.github.com.repos.lowlighter.metrics.commits.MOCKED_SHA/.test(url)) { console.debug(`metrics/compute/mocks > mocking rest api result > rest.request ${url}`) return ({ status:200, url:"https://api.github.com/repos/lowlighter/metrics/commits/MOCKED_SHA", data:{ sha:"MOCKED_SHA", commit:{ author:{ name:faker.internet.userName(), email:faker.internet.email(), date:`${faker.date.recent(7)}`, }, committer:{ name:faker.internet.userName(), email:faker.internet.email(), date:`${faker.date.recent(7)}`, }, }, author:{ login:faker.internet.userName(), id:faker.random.number(100000000), }, committer:{ login:faker.internet.userName(), id:faker.random.number(100000000), }, files: [ { sha:"MOCKED_SHA", filename:faker.system.fileName(), patch:"@@ -0,0 +1,5 @@\n+//Imports\n+ import app from \"./src/app.mjs\"\n+\n+//Start app\n+ await app()\n\\ No newline at end of file" }, ] } }) } return target(...args) } }) //Rate limit rest.rateLimit.get = new Proxy(unmocked.rateLimit, { apply:function(target, that, args) { return ({ status:200, url:"https://api.github.com/rate_limit", headers:{ server:"GitHub.com", status:"200 OK", "x-oauth-scopes":"repo", }, data:{ resources:{ core:{limit:5000, used:0, remaining:5000, reset:0}, search:{limit:30, used:0, remaining:30, reset:0}, graphql:{limit:5000, used:0, remaining:5000, reset:0}, integration_manifest:{limit:5000, used:0, remaining:5000, reset:0}, source_import:{limit:100, used:0, remaining:100, reset:0}, code_scanning_upload:{limit:500, used:0, remaining:500, reset:0}, }, rate:{limit:5000, used:0, remaining:"MOCKED", reset:0} } }) } }) //Events list rest.activity.listEventsForAuthenticatedUser = new Proxy(unmocked.listEventsForAuthenticatedUser, { apply:function(target, that, [{username:login, page, per_page}]) { console.debug(`metrics/compute/mocks > mocking rest api result > rest.activity.listEventsForAuthenticatedUser`) return ({ status:200, url:`https://api.github.com/users/${login}/events?per_page=${per_page}&page=${page}`, headers:{ server:"GitHub.com", status:"200 OK", "x-oauth-scopes":"repo", }, data:page < 1 ? [] : [ { id:"10000000000", type:"CommitCommentEvent", actor:{ login, }, repo:{ name:`${faker.random.word()}/${faker.random.word()}`, }, payload:{ comment:{ user:{ login, }, path:faker.system.fileName(), commit_id:"MOCKED_SHA", body:faker.lorem.sentence(), } }, created_at:faker.date.recent(7), }, { id:"10000000001", type:"PullRequestReviewCommentEvent", actor:{ login, }, repo:{ name:`${faker.random.word()}/${faker.random.word()}`, }, payload:{ action:"created", comment:{ user:{ login, }, body:faker.lorem.paragraph(), }, pull_request:{ title:faker.lorem.sentence(), number:1, user:{ login:faker.internet.userName(), }, body:"", } }, created_at:faker.date.recent(7), }, { id:"10000000002", type:"IssuesEvent", actor:{ login, }, repo:{ name:`${faker.random.word()}/${faker.random.word()}`, }, payload:{ action:faker.random.arrayElement(["opened", "closed", "reopened"]), issue:{ number:2, title:faker.lorem.sentence(), user:{ login, }, body:faker.lorem.paragraph(), performed_via_github_app:null } }, created_at:faker.date.recent(7), }, { id:"10000000003", type:"GollumEvent", actor:{ login, }, repo:{ name:`${faker.random.word()}/${faker.random.word()}`, }, payload:{ pages:[ { page_name:faker.lorem.sentence(), title:faker.lorem.sentence(), summary:null, action:"created", sha:"MOCKED_SHA", } ] }, created_at:faker.date.recent(7), }, { id:"10000000004", type:"IssueCommentEvent", actor:{ login, }, repo:{ name:`${faker.random.word()}/${faker.random.word()}`, }, payload:{ action:"created", issue:{ number:3, title:faker.lorem.sentence(), user:{ login, }, labels:[ { name:"lorem ipsum", color:"d876e3", } ], state:"open", }, comment:{ body:faker.lorem.paragraph(), performed_via_github_app:null } }, created_at:faker.date.recent(7), }, { id:"10000000005", type:"ForkEvent", actor:{ login, }, repo:{ name:`${faker.random.word()}/${faker.random.word()}`, }, payload:{ forkee:{ name:faker.random.word(), full_name:`${faker.random.word()}/${faker.random.word()}`, } }, created_at:faker.date.recent(7), }, { id:"10000000006", type:"PullRequestReviewEvent", actor:{ login, }, repo:{ name:`${faker.random.word()}/${faker.random.word()}`, }, payload:{ action:"created", review:{ user:{ login, }, state:"approved", }, pull_request:{ state:"open", number:4, locked:false, title:faker.lorem.sentence(), user:{ login:faker.internet.userName(), }, } }, created_at:faker.date.recent(7), }, { id:"10000000007", type:"ReleaseEvent", actor:{ login, }, repo:{ name:`${faker.random.word()}/${faker.random.word()}`, }, payload:{ action:"published", release:{ tag_name:`v${faker.random.number()}.${faker.random.number()}`, name:faker.random.words(4), draft:faker.random.boolean(), prerelease:faker.random.boolean(), } }, created_at:faker.date.recent(7), }, { id:"10000000008", type:"CreateEvent", actor:{ login, }, repo:{ name:`${faker.random.word()}/${faker.random.word()}`, }, payload:{ ref:faker.lorem.slug(), ref_type:faker.random.arrayElement(["tag", "branch"]), master_branch:"master", }, created_at:faker.date.recent(7), }, { id:"100000000009", type:"WatchEvent", actor:{ login, }, repo:{ name:"lowlighter/metrics", }, payload:{action:"started"}, created_at:faker.date.recent(7), }, { id:"10000000010", type:"DeleteEvent", actor:{ login, }, repo:{ name:`${faker.random.word()}/${faker.random.word()}`, }, payload:{ ref:faker.lorem.slug(), ref_type:faker.random.arrayElement(["tag", "branch"]), }, created_at:faker.date.recent(7), }, { id:"10000000011", type:"PushEvent", actor:{ login, }, repo:{ name:`${faker.random.word()}/${faker.random.word()}`, }, payload:{ size:1, ref:"refs/heads/master", commits:[ { sha:"MOCKED_SHA", message:faker.lorem.sentence(), } ] }, created_at:faker.date.recent(7), }, { id:"10000000012", type:"PullRequestEvent", actor:{ login, }, repo:{ name:`${faker.random.word()}/${faker.random.word()}`, }, payload:{ action:faker.random.arrayElement(["opened", "closed"]), number:5, pull_request:{ user:{ login, }, state:"open", title:faker.lorem.sentence(), additions:faker.random.number(1000), deletions:faker.random.number(1000), changed_files:faker.random.number(10), } }, created_at:faker.date.recent(7), }, { id:"10000000013", type:"MemberEvent", actor:{ login, }, repo:{ name:`${faker.random.word()}/${faker.random.word()}`, }, payload:{ member:{ login:faker.internet.userName(), }, action:"added" }, created_at:faker.date.recent(7), }, { id:"10000000014", type:"PublicEvent", actor:{ login, }, repo:{ name:`${faker.random.word()}/${faker.random.word()}`, }, payload:{}, created_at:faker.date.recent(7), } ] }) } }) //Repository traffic rest.repos.getViews = new Proxy(unmocked.getViews, { apply:function(target, that, [{owner, repo}]) { console.debug(`metrics/compute/mocks > mocking rest api result > rest.repos.getViews`) const count = faker.random.number(10000)*2 const uniques = faker.random.number(count)*2 return ({ status:200, url:`https://api.github.com/repos/${owner}/${repo}/traffic/views`, headers:{ server:"GitHub.com", status:"200 OK", "x-oauth-scopes":"repo", }, data:{ count, uniques, views:[ {timestamp:`${faker.date.recent()}`, count:count/2, uniques:uniques/2}, {timestamp:`${faker.date.recent()}`, count:count/2, uniques:uniques/2}, ] } }) } }) //Repository contributions rest.repos.getContributorsStats = new Proxy(unmocked.getContributorsStats, { apply:function(target, that, [{owner, repo}]) { console.debug(`metrics/compute/mocks > mocking rest api result > rest.repos.getContributorsStats`) return ({ status:200, url:`https://api.github.com/repos/${owner}/${repo}/stats/contributors`, headers:{ server:"GitHub.com", status:"200 OK", "x-oauth-scopes":"repo", }, data:[ { total:faker.random.number(10000), weeks:[ {w:1, a:faker.random.number(10000), d:faker.random.number(10000), c:faker.random.number(10000)}, {w:2, a:faker.random.number(10000), d:faker.random.number(10000), c:faker.random.number(10000)}, {w:3, a:faker.random.number(10000), d:faker.random.number(10000), c:faker.random.number(10000)}, {w:4, a:faker.random.number(10000), d:faker.random.number(10000), c:faker.random.number(10000)}, ], author: { login:owner, } } ] }) } }) //Repository contributions rest.repos.listCommits = new Proxy(unmocked.listCommits, { apply:function(target, that, [{page, per_page, owner, repo}]) { console.debug(`metrics/compute/mocks > mocking rest api result > rest.repos.listCommits`) return ({ status:200, url:`https://api.github.com/repos/${owner}/${repo}/commits?per_page=${per_page}&page=${page}`, headers: { server:"GitHub.com", status:"200 OK", "x-oauth-scopes":"repo", }, data:page < 2 ? new Array(per_page).fill(null).map(() => ({ sha:"MOCKED_SHA", commit:{ author:{ name:owner, date:`${faker.date.recent(14)}` }, committer:{ name:owner, date:`${faker.date.recent(14)}` }, } }) ) : [] }) } }) //Repository contributors rest.repos.listContributors = new Proxy(unmocked.listContributors, { apply:function(target, that, [{owner, repo}]) { console.debug(`metrics/compute/mocks > mocking rest api result > rest.repos.listContributors`) return ({ status:200, url:`https://api.github.com/repos/${owner}/${repo}/contributors`, headers: { server:"GitHub.com", status:"200 OK", "x-oauth-scopes":"repo", }, data:new Array(40+faker.random.number(60)).fill(null).map(() => ({ login:faker.internet.userName(), avatar_url:null, contributions:faker.random.number(1000), })) }) } }) //User informations rest.users.getByUsername = new Proxy(unmocked.getByUsername, { apply:function(target, that, [{username}]) { console.debug(`metrics/compute/mocks > mocking rest api result > rest.repos.getByUsername`) return ({ status:200, url:`'https://api.github.com/users/${username}/`, headers: { server:"GitHub.com", status:"200 OK", "x-oauth-scopes":"repo", }, data:{ login:faker.internet.userName(), avatar_url:null, contributions:faker.random.number(1000), } }) } }) } //Axios mocking { console.debug(`metrics/compute/mocks > mocking axios`) const unmocked = { get:axios.get, post:axios.post, } //Post requests axios.post = new Proxy(unmocked.post, { apply:function(target, that, args) { //Arguments const [url, body] = args //Spotify api if (/^https:..accounts.spotify.com.api.token/.test(url)) { //Access token generator const params = new urls.URLSearchParams(body) if ((params.get("grant_type") === "refresh_token")&&(params.get("client_id") === "MOCKED_CLIENT_ID")&&(params.get("client_secret") === "MOCKED_CLIENT_SECRET")&&(params.get("refresh_token") === "MOCKED_REFRESH_TOKEN")) { console.debug(`metrics/compute/mocks > mocking spotify api result > ${url}`) return ({ status:200, data:{ access_token:"MOCKED_TOKEN_ACCESS", token_type:"Bearer", expires_in:3600, scope:"user-read-recently-played user-read-private", } }) } } //Anilist api if (/^https:..graphql.anilist.co/.test(url)) { //Initialization and media generator const query = body.query const media = ({type}) => ({ title:{romaji:faker.lorem.words(), english:faker.lorem.words(), native:faker.lorem.words()}, description:faker.lorem.paragraphs(), type, status:faker.random.arrayElement(["FINISHED", "RELEASING", "NOT_YET_RELEASED", "CANCELLED", "HIATUS"]), episodes:100+faker.random.number(100), volumes:faker.random.number(100), chapters:100+faker.random.number(1000), averageScore:faker.random.number(100), countryOfOrigin:"JP", genres:new Array(6).fill(null).map(_ => faker.lorem.word()), coverImage:{medium:null}, startDate:{year:faker.date.past(20).getFullYear()} }) //User statistics query if (/^query Statistics /.test(query)) { console.debug(`metrics/compute/mocks > mocking anilist api result > Statistics`) return ({ status:200, data:{ data:{ User:{ id:faker.random.number(100000), name:faker.internet.userName(), about:null, statistics:{ anime:{ count:faker.random.number(1000), minutesWatched:faker.random.number(100000), episodesWatched:faker.random.number(10000), genres:new Array(4).fill(null).map(_ => ({genre:faker.lorem.word()})), }, manga:{ count:faker.random.number(1000), chaptersRead:faker.random.number(100000), volumesRead:faker.random.number(10000), genres:new Array(4).fill(null).map(_ => ({genre:faker.lorem.word()})), }, } } } } }) } //Favorites characters if (/^query FavoritesCharacters /.test(query)) { console.debug(`metrics/compute/mocks > mocking anilist api result > Favorites characters`) return ({ status:200, data:{ data:{ User:{ favourites:{ characters:{ nodes:new Array(2+faker.random.number(16)).fill(null).map(_ => ({ name:{full:faker.name.findName(), native:faker.name.findName()}, image:{medium:null} }), ), pageInfo:{currentPage:1, hasNextPage:false} } } } } } }) } //Favorites anime/manga query if (/^query Favorites /.test(query)) { console.debug(`metrics/compute/mocks > mocking anilist api result > Favorites`) const type = /anime[(]/.test(query) ? "ANIME" : /manga[(]/.test(query) ? "MANGA" : "OTHER" return ({ status:200, data:{ data:{ User:{ favourites:{ [type.toLocaleLowerCase()]:{ nodes:new Array(16).fill(null).map(_ => media({type})), pageInfo:{currentPage:1, hasNextPage:false}, } } } } } }) } //Medias query if (/^query Medias /.test(query)) { console.debug(`metrics/compute/mocks > mocking anilist api result > Medias`) const type = body.variables.type return ({ status:200, data:{ data:{ MediaListCollection:{ lists:[ { name:{ANIME:"Watching", MANGA:"Reading", OTHER:"Completed"}[type], isCustomList:false, entries:new Array(16).fill(null).map(_ => ({ status:faker.random.arrayElement(["CURRENT", "PLANNING", "COMPLETED", "DROPPED", "PAUSED", "REPEATING"]), progress:faker.random.number(100), progressVolumes: null, score:0, startedAt:{year:null, month:null, day:null}, completedAt:{year:null, month:null, day:null}, media:media({type}) })), } ] } } } }) } } return target(...args) } }) //Get requests axios.get = new Proxy(unmocked.get, { apply:function(target, that, args) { //Arguments const [url, options] = args const tested = url.match(/&url=(?.*?)(?:&|$)/)?.groups?.tested ?? faker.internet.url() //Pagespeed api if (/^https:..www.googleapis.com.pagespeedonline.v5/.test(url)) { //Pagespeed result if (/v5.runPagespeed.*&key=MOCKED_TOKEN/.test(url)) { console.debug(`metrics/compute/mocks > mocking pagespeed api result > ${url}`) return ({ status:200, data:{ captchaResult:"CAPTCHA_NOT_NEEDED", id:tested, lighthouseResult:{ requestedUrl:tested, finalUrl:tested, lighthouseVersion:"6.3.0", audits:{ "final-screenshot":{ id:"final-screenshot", title:"Final Screenshot", score: null, details:{ data:"data:image/jpg;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOcOnfpfwAGfgLYttYINwAAAABJRU5ErkJggg==", type:"screenshot", timestamp:Date.now() } }, metrics:{ id:"metrics", title:"Metrics", score: null, details:{ items:[ { observedFirstContentfulPaint:faker.random.number(500), observedFirstVisualChangeTs:faker.time.recent(), observedFirstContentfulPaintTs:faker.time.recent(), firstContentfulPaint:faker.random.number(500), observedDomContentLoaded:faker.random.number(500), observedFirstMeaningfulPaint:faker.random.number(1000), maxPotentialFID:faker.random.number(500), observedLoad:faker.random.number(500), firstMeaningfulPaint:faker.random.number(500), observedCumulativeLayoutShift:faker.random.float({max:1}), observedSpeedIndex:faker.random.number(1000), observedSpeedIndexTs:faker.time.recent(), observedTimeOriginTs:faker.time.recent(), observedLargestContentfulPaint:faker.random.number(1000), cumulativeLayoutShift:faker.random.float({max:1}), observedFirstPaintTs:faker.time.recent(), observedTraceEndTs:faker.time.recent(), largestContentfulPaint:faker.random.number(2000), observedTimeOrigin:faker.random.number(10), speedIndex:faker.random.number(1000), observedTraceEnd:faker.random.number(2000), observedDomContentLoadedTs:faker.time.recent(), observedFirstPaint:faker.random.number(500), totalBlockingTime:faker.random.number(500), observedLastVisualChangeTs:faker.time.recent(), observedFirstVisualChange:faker.random.number(500), observedLargestContentfulPaintTs:faker.time.recent(), estimatedInputLatency:faker.random.number(100), observedLoadTs:faker.time.recent(), observedLastVisualChange:faker.random.number(1000), firstCPUIdle:faker.random.number(1000), interactive:faker.random.number(1000), observedNavigationStartTs:faker.time.recent(), observedNavigationStart:faker.random.number(10), observedFirstMeaningfulPaintTs:faker.time.recent() }, ] }, }, }, categories:{ "best-practices":{ id:"best-practices", title:"Best Practices", score:faker.random.float({max:1}), }, seo:{ id:"seo", title:"SEO", score:faker.random.float({max:1}), }, accessibility:{ id:"accessibility", title:"Accessibility", score:faker.random.float({max:1}), }, performance: { id:"performance", title:"Performance", score:faker.random.float({max:1}), } }, }, analysisUTCTimestamp:`${faker.date.recent()}`, } }) } } //Spotify api if (/^https:..api.spotify.com/.test(url)) { //Get recently played tracks if (/me.player.recently-played/.test(url)&&(options?.headers?.Authorization === "Bearer MOCKED_TOKEN_ACCESS")) { console.debug(`metrics/compute/mocks > mocking spotify api result > ${url}`) const artist = faker.random.words() const track = faker.random.words(5) return ({ status:200, data:{ items:[ { track:{ album:{ album_type:"single", artists:[ { name:artist, type:"artist", } ], images:[ { height:640, url:faker.image.abstract(), width:640 }, { height:300, url:faker.image.abstract(), width:300 }, { height:64, url:faker.image.abstract(), width:64 } ], name:track, release_date:`${faker.date.past()}`.substring(0, 10), type:"album", }, artists:[ { name:artist, type:"artist", } ], name:track, preview_url:faker.internet.url(), type:"track", }, played_at:`${faker.date.recent()}`, context:{ type:"album", } }, ], } }) } } //Last.fm api if (/^https:..ws.audioscrobbler.com.*$/.test(url)) { //Get recently played tracks if (/user.getrecenttracks/.test(url)) { console.debug(`metrics/compute/mocks > mocking lastfm api result > ${url}`) const artist = faker.random.word() const album = faker.random.words(3) const track = faker.random.words(5) const date = faker.date.recent() return ({ status:200, data:{ recenttracks:{ "@attr":{ page:"1", perPage:"1", user:"RJ", total:"100", pages:"100", }, track:[ { artist:{ mbid:"", "#text":artist, }, album:{ mbid:"", "#text":album, }, image:[ { size:"small", "#text":faker.image.abstract(), }, { size:"medium", "#text":faker.image.abstract(), }, { size:"large", "#text":faker.image.abstract(), }, { size:"extralarge", "#text":faker.image.abstract(), }, ], streamable:"0", date:{ uts:Math.floor(date.getTime() / 1000), "#text":date.toUTCString().slice(5, 22), }, url:faker.internet.url(), name:track, mbid:"", }, ], }, }, }) } } //Twitter api if (/^https:..api.twitter.com/.test(url)) { //Get user profile if ((/users.by.username/.test(url))&&(options?.headers?.Authorization === "Bearer MOCKED_TOKEN")) { console.debug(`metrics/compute/mocks > mocking twitter api result > ${url}`) const username = url.match(/username[/](?.*?)[?]/)?.groups?.username ?? faker.internet.userName() return ({ status:200, data:{ data:{ profile_image_url:faker.image.people(), name:faker.name.findName(), verified:faker.random.boolean(), id:faker.random.number(1000000).toString(), username, }, } }) } //Get recent tweets if ((/tweets.search.recent/.test(url))&&(options?.headers?.Authorization === "Bearer MOCKED_TOKEN")) { console.debug(`metrics/compute/mocks > mocking twitter api result > ${url}`) return ({ status:200, data:{ data:[ { id:faker.random.number(100000000000000).toString(), created_at:`${faker.date.recent()}`, entities:{ mentions:[ {start:22, end:33, username:"lowlighter"}, ], }, text:"Checkout metrics from @lowlighter ! #GitHub", }, { id:faker.random.number(100000000000000).toString(), created_at:`${faker.date.recent()}`, text:faker.lorem.paragraph(), } ], includes:{ users:[ { id:faker.random.number(100000000000000).toString(), name:"lowlighter", username:"lowlighter", }, ] }, meta:{ newest_id:faker.random.number(100000000000000).toString(), oldest_id:faker.random.number(100000000000000).toString(), result_count:2, next_token:"MOCKED_CURSOR", }, } }) } } return target(...args) } }) } //Return mocked elements return {graphql, rest} }