From 6715963e8699c0861b5d59a137d0e065aa244a38 Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Fri, 14 Apr 2023 23:48:34 +0200 Subject: [PATCH 1/5] enabled ts-prune on api and removed dead code --- api/package.json | 3 +- api/src/_test/mocks.ts | 16 ------- api/src/app/endpoints.ts | 1 + api/src/app/types/legacy.ts | 40 ----------------- api/src/contribution/mock.ts | 71 ------------------------------ data/package.json | 2 +- packages/tooling/setup-ts-prune.ts | 10 +++++ packages/ui/.ts-prunerc | 4 -- packages/ui/package.json | 2 +- web/.ts-prunerc | 4 -- web/package.json | 2 +- 11 files changed, 16 insertions(+), 139 deletions(-) delete mode 100644 api/src/contribution/mock.ts create mode 100644 packages/tooling/setup-ts-prune.ts delete mode 100644 packages/ui/.ts-prunerc delete mode 100644 web/.ts-prunerc diff --git a/api/package.json b/api/package.json index ce402c7ec..d7b2f8f93 100644 --- a/api/package.json +++ b/api/package.json @@ -74,11 +74,12 @@ "generate:bundle-info": "ts-node ../packages/tooling/bundle-info.ts", "generate:sentry-release": "ts-node ../packages/tooling/sentry-release.ts api dist", "lint": "yarn build && yarn lint:alone", - "lint:alone": "yarn lint:eslint . && yarn lint:prettier --check . && yarn lint:tsc", + "lint:alone": "yarn lint:eslint . && yarn lint:prettier --check . && yarn lint:tsc && yarn lint:ts-prune", "lint:eslint": "eslint --config ../packages/tooling/.eslintrc.json --ignore-path ../packages/tooling/.eslintignore --report-unused-disable-directives", "lint:fix": "yarn build && yarn lint:fix:alone", "lint:fix:alone": "yarn lint:eslint --fix . && yarn lint:prettier --write .", "lint:prettier": "prettier --config ../packages/tooling/.prettierrc --ignore-path ../packages/tooling/.prettierignore --loglevel warn", + "lint:ts-prune": "ts-node ../packages/tooling/setup-ts-prune.ts && ts-prune --error", "lint:tsc": "tsc --noEmit", "start": "node dist/app/index.js", "start:dev": "ts-node ../packages/tooling/nodemon.ts @dzcode.io/api && nodemon dist/app/index.js", diff --git a/api/src/_test/mocks.ts b/api/src/_test/mocks.ts index 69f353eae..7ec6472cb 100644 --- a/api/src/_test/mocks.ts +++ b/api/src/_test/mocks.ts @@ -7,19 +7,3 @@ export const githubUserMock: GithubUser = { login: "login", type: "type", }; - -export const githubUserMock2: GithubUser = { - avatar_url: "avatar_url2", // eslint-disable-line camelcase - html_url: "html_url2", // eslint-disable-line camelcase - id: 2, - login: "login2", - type: "type2", -}; - -export const githubUserMock3: GithubUser = { - avatar_url: "avatar_url3", // eslint-disable-line camelcase - html_url: "html_url3", // eslint-disable-line camelcase - id: 3, - login: "login3", - type: "type3", -}; diff --git a/api/src/app/endpoints.ts b/api/src/app/endpoints.ts index c0b623525..0cf5e8fa6 100644 --- a/api/src/app/endpoints.ts +++ b/api/src/app/endpoints.ts @@ -5,6 +5,7 @@ import { GetMilestonesResponseDto } from "src/milestone/types"; import { GetProjectsResponseDto } from "src/project/types"; import { GetTeamResponseDto } from "src/team/types"; +// ts-prune-ignore-next export interface Endpoints { "api:Articles": { response: GetArticlesResponseDto; diff --git a/api/src/app/types/legacy.ts b/api/src/app/types/legacy.ts index 62440ff6e..175f7bd6d 100644 --- a/api/src/app/types/legacy.ts +++ b/api/src/app/types/legacy.ts @@ -1,43 +1,3 @@ -import { RepositoryReferenceEntity } from "@dzcode.io/models/dist/repository-reference"; -import { LOADABLE } from "@dzcode.io/utils/dist/loadable"; - -// @TODO-ZM: delete -export interface Document { - slug: string; - image?: string; - title: string; - description?: string; - content?: string; - authors?: string[]; - githubAuthors: LOADABLE; - contributors: LOADABLE; - views?: number; -} - -// @TODO-ZM: delete -export interface Article { - slug: string; - image?: string; - title: string; - description?: string; - content?: string; - authors?: string[]; - githubAuthors: LOADABLE; - contributors: LOADABLE; - views?: number; -} - -// @TODO-ZM: delete -export interface Project { - slug: string; - name: string; - repositories: Array<{ - provider: RepositoryReferenceEntity["provider"]; - owner: string; - repository: string; - }>; -} - export interface GithubUser { login: string; id: number; diff --git a/api/src/contribution/mock.ts b/api/src/contribution/mock.ts deleted file mode 100644 index 212147369..000000000 --- a/api/src/contribution/mock.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { ContributionEntity } from "@dzcode.io/models/dist/contribution"; -import { lorem } from "faker"; - -import { FilterDto, OptionDto } from "./types"; - -export const generateContributionMock = (index: number): ContributionEntity => { - const projectName = `${lorem.word()}/${lorem.word()}`; - - return { - id: `${index}`, - labels: lorem.sentence().split(" "), - languages: lorem.sentence().split(" "), - project: { - slug: `github/${projectName}`, - name: projectName, - }, - title: lorem.sentence(), - type: index % 2 ? "pullRequest" : "issue", - url: `https://github.com/${projectName}/issues/${index}`, - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), - commentsCount: Math.round(Math.random() * 50), - }; -}; - -export const bulkGenerateContributionMock = (from: number, to: number) => { - const contributionsMock: ContributionEntity[] = []; - const filtersMock: FilterDto[] = [ - { name: "projects", options: [] }, - { name: "languages", options: [] }, - { name: "labels", options: [] }, - ]; - - const pushUniqueOption = (options: OptionDto[], filterOptions: OptionDto[]) => { - const uniqueOptions = options.filter( - (_option) => !filterOptions.some(({ name }) => _option.name === name), - ); - filterOptions.push(...uniqueOptions); - }; - - for (let i = from; i <= to; i++) { - const contributionMock = generateContributionMock(i); - contributionsMock.push(contributionMock); - pushUniqueOption( - [ - { - name: contributionMock.project.slug, - label: contributionMock.project.name, - }, - ], - filtersMock[0].options, - ); - pushUniqueOption( - contributionMock.languages.map((language) => ({ - name: language, - label: language, - })), - filtersMock[1].options, - ); - - pushUniqueOption( - contributionMock.labels.map((label) => ({ - name: label, - label: label, - })), - filtersMock[2].options, - ); - } - - return { contributions: contributionsMock, filters: filtersMock }; -}; diff --git a/data/package.json b/data/package.json index 00959b656..3fa103b0b 100644 --- a/data/package.json +++ b/data/package.json @@ -50,7 +50,7 @@ "lint:fix": "yarn build && yarn lint:fix:alone", "lint:fix:alone": "yarn lint:eslint --fix . && yarn lint:prettier --write .", "lint:prettier": "prettier --config ../packages/tooling/.prettierrc --ignore-path ../packages/tooling/.prettierignore --loglevel warn", - "lint:ts-prune": "ts-prune --error", + "lint:ts-prune": "ts-node ../packages/tooling/setup-ts-prune.ts && ts-prune --error", "lint:tsc": "tsc --noEmit", "test": "jest src", "test:cov": "jest src --coverage", diff --git a/packages/tooling/setup-ts-prune.ts b/packages/tooling/setup-ts-prune.ts new file mode 100644 index 000000000..127cd9f05 --- /dev/null +++ b/packages/tooling/setup-ts-prune.ts @@ -0,0 +1,10 @@ +import { writeFileSync } from "fs"; +import { join } from "path"; + +console.log("Setting up .ts-prunerc ..."); + +const paths = ["node_modules", "coverage", "dist", "oracle-cloud/build", "firebase", "bundle"]; +const tsPruneJson = { ignore: paths.join("|") }; + +writeFileSync(join(process.cwd(), ".ts-prunerc"), JSON.stringify(tsPruneJson, null, 2)); +console.log("Done setting up .ts-prunerc"); diff --git a/packages/ui/.ts-prunerc b/packages/ui/.ts-prunerc deleted file mode 100644 index 630f4c6ab..000000000 --- a/packages/ui/.ts-prunerc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "@TODO-ZM": "@TODO-ZM: move this to packages/tooling", - "ignore": "node_modules|coverage|dist|oracle-cloud/build|firebase|bundle" -} diff --git a/packages/ui/package.json b/packages/ui/package.json index 7cd55088f..d507dfb54 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -62,7 +62,7 @@ "lint:fix": "yarn build && yarn lint:fix:alone", "lint:fix:alone": "yarn lint:eslint --fix . && yarn lint:prettier --write .", "lint:prettier": "prettier --config ../tooling/.prettierrc --ignore-path ../tooling/.prettierignore --loglevel warn", - "lint:ts-prune": "ts-prune --error || echo \"@TODO-ZM: enabled this\"", + "lint:ts-prune": "ts-node ../tooling/setup-ts-prune.ts && ts-prune --error || echo \"@TODO-ZM: enable ts-prune on /ui\"", "test": "yarn build && yarn test:alone", "test:alone": "jest --config ../tooling/jest.config.ts --rootDir . --env=jsdom", "test:watch": "npm-run-all build --parallel build:watch \"test:alone --watch {@}\" --" diff --git a/web/.ts-prunerc b/web/.ts-prunerc deleted file mode 100644 index 630f4c6ab..000000000 --- a/web/.ts-prunerc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "@TODO-ZM": "@TODO-ZM: move this to packages/tooling", - "ignore": "node_modules|coverage|dist|oracle-cloud/build|firebase|bundle" -} diff --git a/web/package.json b/web/package.json index 36e4e1443..0f7cc1ccf 100644 --- a/web/package.json +++ b/web/package.json @@ -99,7 +99,7 @@ "lint:fix": "yarn build && yarn lint:fix:alone", "lint:fix:alone": "yarn lint:eslint --fix . && yarn lint:prettier --write .", "lint:prettier": "prettier --config ../packages/tooling/.prettierrc --ignore-path ../packages/tooling/.prettierignore --loglevel warn", - "lint:ts-prune": "ts-prune --error", + "lint:ts-prune": "ts-node ../packages/tooling/setup-ts-prune.ts && ts-prune --error", "lint:tsc": "tsc --noEmit", "start:dev": "craco start", "test": "yarn build && yarn test:alone", From 4d333d3ab6b1185ddedd7c5ed41160d58a249817 Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Fri, 14 Apr 2023 23:53:12 +0200 Subject: [PATCH 2/5] added .ts-prunerc to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5f6bde014..1c45eedf3 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ yarn-error.log .env .husky +.ts-prunerc dist coverage From 9206f7568ef65ddc6ac8d00d3d3ca17c5c639fa0 Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Sat, 15 Apr 2023 00:32:03 +0200 Subject: [PATCH 3/5] moved Github types under Github module --- api/src/_test/mocks.ts | 40 +++++++++++++--- api/src/app/types/legacy.ts | 41 ---------------- api/src/article/controller.ts | 6 +-- api/src/documentation/controller.ts | 12 ++--- api/src/github/service.spec.ts | 8 ++-- api/src/github/service.ts | 20 ++++---- api/src/github/types.ts | 73 +++++++++++++++++++++-------- 7 files changed, 109 insertions(+), 91 deletions(-) delete mode 100644 api/src/app/types/legacy.ts diff --git a/api/src/_test/mocks.ts b/api/src/_test/mocks.ts index 7ec6472cb..41804e497 100644 --- a/api/src/_test/mocks.ts +++ b/api/src/_test/mocks.ts @@ -1,9 +1,37 @@ -import { GithubUser } from "src/app/types/legacy"; +/* eslint-disable camelcase */ +import { GithubUser } from "src/github/types"; export const githubUserMock: GithubUser = { - avatar_url: "avatar_url", // eslint-disable-line camelcase - html_url: "html_url", // eslint-disable-line camelcase - id: 1, - login: "login", - type: "type", + login: "zibanpirate", + id: 20110076, + node_id: "MDQ6VXNlcjEzNjIwMg==", + avatar_url: "https://avatars.githubusercontent.com/u/20110076?v=4", + gravatar_id: "", + url: "https://api.github.com/users/zibanpirate", + html_url: "https://github.com/zibanpirate", + followers_url: "https://api.github.com/users/zibanpirate/followers", + following_url: "https://api.github.com/users/zibanpirate/following{/other_user}", + gists_url: "https://api.github.com/users/zibanpirate/gists{/gist_id}", + starred_url: "https://api.github.com/users/zibanpirate/starred{/owner}{/repo}", + subscriptions_url: "https://api.github.com/users/zibanpirate/subscriptions", + organizations_url: "https://api.github.com/users/zibanpirate/orgs", + repos_url: "https://api.github.com/users/zibanpirate/repos", + events_url: "https://api.github.com/users/zibanpirate/events{/privacy}", + received_events_url: "https://api.github.com/users/zibanpirate/received_events", + type: "User", + site_admin: false, + name: "", + company: "", + blog: "", + location: "", + email: "", + hireable: false, + bio: "", + twitter_username: "", + public_repos: 0, + public_gists: 0, + followers: 0, + following: 0, + created_at: "2009-10-08T14:04:40Z", + updated_at: "2018-05-11T15:44:00Z", }; diff --git a/api/src/app/types/legacy.ts b/api/src/app/types/legacy.ts deleted file mode 100644 index 175f7bd6d..000000000 --- a/api/src/app/types/legacy.ts +++ /dev/null @@ -1,41 +0,0 @@ -export interface GithubUser { - login: string; - id: number; - avatar_url: string; - html_url: string; - type: string; -} - -export interface GithubIssue { - html_url: string; - number: number; - title: string; - user: GithubUser; - body: string; - labels: Array<{ - name: string; - }>; - state: "closed" | "open"; - assignees: GithubUser[]; - comments: number; - created_at: string; - updated_at: string; - closed_at: string | null; - pull_request?: { - html_url: "https://github.com/ZibanPirate/l2t/pull/9"; - }; -} - -export interface GithubMilestone { - html_url: string; - number: number; - title: string; - description: string; - state: "closed" | "open"; - open_issues: number; - closed_issues: number; - created_at: string; - updated_at: string; - closed_at: string | null; - due_on: string | null; -} diff --git a/api/src/article/controller.ts b/api/src/article/controller.ts index e3b9156dd..f410b94b8 100644 --- a/api/src/article/controller.ts +++ b/api/src/article/controller.ts @@ -1,8 +1,8 @@ import { Controller, Get, Param } from "routing-controllers"; import { OpenAPI, ResponseSchema } from "routing-controllers-openapi"; -import { GithubUser } from "src/app/types/legacy"; import { DataService } from "src/data/service"; import { GithubService } from "src/github/service"; +import { GithubUser } from "src/github/types"; import { Service } from "typedi"; import { GetArticleResponseDto, GetArticlesResponseDto } from "./types"; @@ -53,13 +53,13 @@ export class ArticleController { const contributorsBatches = await Promise.all([ // current place for data: - this.githubService.listContributors({ + this.githubService.listPathCommitters({ owner: "dzcode-io", repository: "dzcode.io", path: `data/models/articles/${slug}`, }), // also check old place for data, to not lose contribution effort: - this.githubService.listContributors({ + this.githubService.listPathCommitters({ owner: "dzcode-io", repository: "dzcode.io", path: `data/articles/${slug}`, diff --git a/api/src/documentation/controller.ts b/api/src/documentation/controller.ts index d972d32f5..cbf41d8b7 100644 --- a/api/src/documentation/controller.ts +++ b/api/src/documentation/controller.ts @@ -1,8 +1,8 @@ import { Controller, Get, Param } from "routing-controllers"; import { OpenAPI, ResponseSchema } from "routing-controllers-openapi"; -import { GithubUser } from "src/app/types/legacy"; import { DataService } from "src/data/service"; import { GithubService } from "src/github/service"; +import { GithubUser } from "src/github/types"; import { Service } from "typedi"; import { GetADocumentationResponseDto, GetDocumentationResponseDto } from "./types"; @@ -53,15 +53,15 @@ export class DocumentationController { }), ); - const contributorsBatches = await Promise.all([ + const committersBatches = await Promise.all([ // current place for data: - this.githubService.listContributors({ + this.githubService.listPathCommitters({ owner: "dzcode-io", repository: "dzcode.io", path: `data/models/documentation/${slug}`, }), // also check old place for data, to not lose contribution effort: - this.githubService.listContributors({ + this.githubService.listPathCommitters({ owner: "dzcode-io", repository: "dzcode.io", path: `data/documentation/${slug}`, @@ -71,8 +71,8 @@ export class DocumentationController { // filter and sort contributors: const uniqUsernames: Record = {}; const contributors: GetADocumentationResponseDto["documentation"]["contributors"] = [ - ...contributorsBatches[0], - ...contributorsBatches[1], + ...committersBatches[0], + ...committersBatches[1], ] .reduce((pV, cV) => { if (uniqUsernames[cV.login]) { diff --git a/api/src/github/service.spec.ts b/api/src/github/service.spec.ts index 7a4392149..ddc826306 100644 --- a/api/src/github/service.spec.ts +++ b/api/src/github/service.spec.ts @@ -4,7 +4,7 @@ import { ConfigService } from "src/config/service"; import { FetchService } from "src/fetch/service"; import { GithubService } from "./service"; -import { GeneralGithubQuery, ListContributorsResponse } from "./types"; +import { GeneralGithubQuery, ListPathCommittersResponse } from "./types"; describe("GithubService", () => { const githubQuery: GeneralGithubQuery = { @@ -12,7 +12,7 @@ describe("GithubService", () => { repository: "test-repo", path: "test/path", }; - const contributorsMock: ListContributorsResponse = [ + const contributorsMock: ListPathCommittersResponse = [ { author: githubUserMock, committer: githubUserMock, @@ -34,7 +34,7 @@ describe("GithubService", () => { const githubService = new GithubService(configService, fetchService); let errorThrown: unknown; try { - await githubService.listContributors(githubQuery); + await githubService.listPathCommitters(githubQuery); } catch (error) { errorThrown = error; } @@ -44,7 +44,7 @@ describe("GithubService", () => { it("should return list of contributors when api call succeed", async () => { fetchService.get.mockResolvedValue(contributorsMock); const githubService = new GithubService(configService, fetchService); - const contributors = await githubService.listContributors(githubQuery); + const contributors = await githubService.listPathCommitters(githubQuery); expect(contributors).toMatchObject([githubUserMock]); }); diff --git a/api/src/github/service.ts b/api/src/github/service.ts index c7ddfdd29..9d997af8f 100644 --- a/api/src/github/service.ts +++ b/api/src/github/service.ts @@ -1,4 +1,3 @@ -import { GithubIssue, GithubMilestone, GithubUser } from "src/app/types/legacy"; import { ConfigService } from "src/config/service"; import { FetchService } from "src/fetch/service"; import { Service } from "typedi"; @@ -6,12 +5,15 @@ import { Service } from "typedi"; import { GeneralGithubQuery, GetUserInput, + GithubIssue, GitHubListRepositoryIssuesInput, GitHubListRepositoryLanguagesInput, GitHubListRepositoryMilestonesInput, + GithubMilestone, GitHubRateLimitApiResponse, + GithubUser, GitHubUserApiResponse, - ListContributorsResponse, + ListPathCommittersResponse, ListRepositoryContributorsResponse, } from "./types"; @@ -22,12 +24,12 @@ export class GithubService { private readonly fetchService: FetchService, ) {} - public listContributors = async ({ + public listPathCommitters = async ({ owner, repository, path, }: GeneralGithubQuery): Promise => { - const commits = await this.fetchService.get( + const commits = await this.fetchService.get( `${this.apiURL}/repos/${owner}/${repository}/commits`, { headers: this.githubToken ? { Authorization: `Token ${this.githubToken}` } : {}, @@ -35,16 +37,10 @@ export class GithubService { }, ); const contributors = commits + // @TODO-ZM: dry to a user block-list // excluding github.com/web-flow user .filter((item) => item.committer && item.committer.id !== 19864447) - // eslint-disable-next-line camelcase - .map(({ committer: { login, avatar_url, html_url, type, id } }) => ({ - id, - login, - avatar_url, // eslint-disable-line camelcase - html_url, // eslint-disable-line camelcase - type, - })); + .map(({ committer }) => committer); return contributors; }; diff --git a/api/src/github/types.ts b/api/src/github/types.ts index 51f9f4826..504863d2b 100644 --- a/api/src/github/types.ts +++ b/api/src/github/types.ts @@ -1,24 +1,6 @@ import { IsNumber } from "class-validator"; -import { GithubUser } from "src/app/types/legacy"; -export type ListContributorsResponse = Array<{ - author: GithubUser; - committer: GithubUser; -}>; - -export type ListRepositoryContributorsResponse = Array; - -export interface GeneralGithubQuery { - owner: string; - repository: string; - path: string; -} - -export interface GetUserInput { - username: string; -} - -export interface GitHubUserApiResponse { +export interface GithubUser { login: string; id: number; node_id: string; @@ -53,15 +35,68 @@ export interface GitHubUserApiResponse { updated_at: string; } +export type ListPathCommittersResponse = Array<{ + author: GithubUser; + committer: GithubUser; +}>; + +export type ListRepositoryContributorsResponse = Array; + +export interface GeneralGithubQuery { + owner: string; + repository: string; + path: string; +} + +export interface GetUserInput { + username: string; +} + +export type GitHubUserApiResponse = GithubUser; + export interface GitHubListRepositoryIssuesInput { owner: string; repository: string; } +export interface GithubIssue { + html_url: string; + number: number; + title: string; + user: GithubUser; + body: string; + labels: Array<{ + name: string; + }>; + state: "closed" | "open"; + assignees: GithubUser[]; + comments: number; + created_at: string; + updated_at: string; + closed_at: string | null; + pull_request?: { + html_url: string; + }; +} + export type GitHubListRepositoryLanguagesInput = GitHubListRepositoryIssuesInput; export type GitHubListRepositoryMilestonesInput = GitHubListRepositoryIssuesInput; +export interface GithubMilestone { + html_url: string; + number: number; + title: string; + description: string; + state: "closed" | "open"; + open_issues: number; + closed_issues: number; + created_at: string; + updated_at: string; + closed_at: string | null; + due_on: string | null; +} + export interface GitHubRateLimitApiResponse { resources: { core: { From 7024fa8ab33dfa724f2f5ba824c0667beca58aa4 Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Sat, 15 Apr 2023 12:57:11 +0200 Subject: [PATCH 4/5] replaced ContributorEntity with AccountEntity --- api/src/_test/mocks.ts | 52 +++++------ api/src/article/controller.ts | 20 +--- api/src/documentation/controller.ts | 14 +-- api/src/github/service.ts | 13 +++ api/src/github/types.ts | 27 +++++- api/src/project/controller.ts | 18 ++-- api/src/team/repository.ts | 93 +++++++++++-------- api/src/team/types.ts | 6 +- .../articles/article-details/index.tsx | 8 +- .../account/__snapshots__/index.spec.ts.snap | 32 +++++-- packages/models/src/account/index.spec.ts | 11 ++- packages/models/src/account/index.ts | 20 +++- .../__snapshots__/index.spec.ts.snap | 56 ----------- packages/models/src/contributor/index.spec.ts | 15 --- packages/models/src/contributor/index.ts | 20 ---- packages/models/src/repository/index.ts | 7 +- packages/ui/package.json | 4 +- .../ui/src/__mocks__/create-contributors.ts | 11 ++- packages/ui/src/article/index.tsx | 24 ++--- packages/ui/src/card/contributor/index.tsx | 7 +- yarn.lock | 5 - 21 files changed, 212 insertions(+), 251 deletions(-) delete mode 100644 packages/models/src/contributor/__snapshots__/index.spec.ts.snap delete mode 100644 packages/models/src/contributor/index.spec.ts delete mode 100644 packages/models/src/contributor/index.ts diff --git a/api/src/_test/mocks.ts b/api/src/_test/mocks.ts index 41804e497..34c50b2a5 100644 --- a/api/src/_test/mocks.ts +++ b/api/src/_test/mocks.ts @@ -2,36 +2,36 @@ import { GithubUser } from "src/github/types"; export const githubUserMock: GithubUser = { - login: "zibanpirate", + login: "ZibanPirate", id: 20110076, - node_id: "MDQ6VXNlcjEzNjIwMg==", + node_id: "MDQ6VXNlcjIwMTEwMDc2", avatar_url: "https://avatars.githubusercontent.com/u/20110076?v=4", gravatar_id: "", - url: "https://api.github.com/users/zibanpirate", - html_url: "https://github.com/zibanpirate", - followers_url: "https://api.github.com/users/zibanpirate/followers", - following_url: "https://api.github.com/users/zibanpirate/following{/other_user}", - gists_url: "https://api.github.com/users/zibanpirate/gists{/gist_id}", - starred_url: "https://api.github.com/users/zibanpirate/starred{/owner}{/repo}", - subscriptions_url: "https://api.github.com/users/zibanpirate/subscriptions", - organizations_url: "https://api.github.com/users/zibanpirate/orgs", - repos_url: "https://api.github.com/users/zibanpirate/repos", - events_url: "https://api.github.com/users/zibanpirate/events{/privacy}", - received_events_url: "https://api.github.com/users/zibanpirate/received_events", + url: "https://api.github.com/users/ZibanPirate", + html_url: "https://github.com/ZibanPirate", + followers_url: "https://api.github.com/users/ZibanPirate/followers", + following_url: "https://api.github.com/users/ZibanPirate/following{/other_user}", + gists_url: "https://api.github.com/users/ZibanPirate/gists{/gist_id}", + starred_url: "https://api.github.com/users/ZibanPirate/starred{/owner}{/repo}", + subscriptions_url: "https://api.github.com/users/ZibanPirate/subscriptions", + organizations_url: "https://api.github.com/users/ZibanPirate/orgs", + repos_url: "https://api.github.com/users/ZibanPirate/repos", + events_url: "https://api.github.com/users/ZibanPirate/events{/privacy}", + received_events_url: "https://api.github.com/users/ZibanPirate/received_events", type: "User", site_admin: false, - name: "", - company: "", - blog: "", - location: "", + name: "Zakaria Mansouri", + company: "@dzcode-io @avimedical", + blog: "zak.dzcode.io", + location: "Algeria", email: "", - hireable: false, - bio: "", - twitter_username: "", - public_repos: 0, - public_gists: 0, - followers: 0, - following: 0, - created_at: "2009-10-08T14:04:40Z", - updated_at: "2018-05-11T15:44:00Z", + hireable: true, + bio: "One-man-army lone programmer", + twitter_username: "ZibanPirate", + public_repos: 18, + public_gists: 2, + followers: 130, + following: 92, + created_at: "2016-06-23T12:41:14Z", + updated_at: "2023-04-10T21:31:26Z", }; diff --git a/api/src/article/controller.ts b/api/src/article/controller.ts index f410b94b8..295f269fe 100644 --- a/api/src/article/controller.ts +++ b/api/src/article/controller.ts @@ -42,16 +42,11 @@ export class ArticleController { const authors = await Promise.all( article.authors.map(async (author) => { const githubUser = await this.githubService.getUser({ username: author }); - return { - id: `github/${githubUser.id}`, - name: githubUser.login, - link: githubUser.html_url, - image: githubUser.avatar_url, - }; + return this.githubService.githubUserToAccountEntity(githubUser); }), ); - const contributorsBatches = await Promise.all([ + const committersBatches = await Promise.all([ // current place for data: this.githubService.listPathCommitters({ owner: "dzcode-io", @@ -69,8 +64,8 @@ export class ArticleController { // filter and sort contributors: const uniqUsernames: Record = {}; const contributors: GetArticleResponseDto["article"]["contributors"] = [ - ...contributorsBatches[0], - ...contributorsBatches[1], + ...committersBatches[0], + ...committersBatches[1], ] .reduce((pV, cV) => { if (uniqUsernames[cV.login]) { @@ -82,12 +77,7 @@ export class ArticleController { } }, []) .sort((a, b) => uniqUsernames[b.login] - uniqUsernames[a.login]) - .map((contributor) => ({ - id: `github/${contributor.id}`, - name: contributor.login, - link: contributor.html_url, - image: contributor.avatar_url, - })) + .map((committer) => this.githubService.githubUserToAccountEntity(committer)) .filter(({ id }) => !authors.find((author) => author.id === id)); return { diff --git a/api/src/documentation/controller.ts b/api/src/documentation/controller.ts index cbf41d8b7..06fcf3708 100644 --- a/api/src/documentation/controller.ts +++ b/api/src/documentation/controller.ts @@ -44,12 +44,7 @@ export class DocumentationController { const authors = await Promise.all( documentation.authors.map(async (author) => { const githubUser = await this.githubService.getUser({ username: author }); - return { - id: `github/${githubUser.id}`, - name: githubUser.login, - link: githubUser.html_url, - image: githubUser.avatar_url, - }; + return this.githubService.githubUserToAccountEntity(githubUser); }), ); @@ -84,12 +79,7 @@ export class DocumentationController { } }, []) .sort((a, b) => uniqUsernames[b.login] - uniqUsernames[a.login]) - .map((contributor) => ({ - id: `github/${contributor.id}`, - name: contributor.login, - link: contributor.html_url, - image: contributor.avatar_url, - })) + .map((contributor) => this.githubService.githubUserToAccountEntity(contributor)) .filter(({ id }) => !authors.find((author) => author.id === id)); return { diff --git a/api/src/github/service.ts b/api/src/github/service.ts index 9d997af8f..07094503a 100644 --- a/api/src/github/service.ts +++ b/api/src/github/service.ts @@ -1,3 +1,5 @@ +import { Model } from "@dzcode.io/models/dist/_base"; +import { AccountEntity } from "@dzcode.io/models/dist/account"; import { ConfigService } from "src/config/service"; import { FetchService } from "src/fetch/service"; import { Service } from "typedi"; @@ -130,6 +132,17 @@ export class GithubService { return milestones; }; + public githubUserToAccountEntity = ( + user: Pick, + ): Model => ({ + id: `github/${user.id}`, + username: user.login, + name: user.name || user.login, + // @TODO-ZM: change this to `/Account/github/${user.id}` once we have a /Accounts page + profileUrl: user.html_url, + avatarUrl: user.avatar_url, + }); + private githubToken = this.configService.env().GITHUB_TOKEN; private apiURL = "https://api.github.com"; } diff --git a/api/src/github/types.ts b/api/src/github/types.ts index 504863d2b..3c9578890 100644 --- a/api/src/github/types.ts +++ b/api/src/github/types.ts @@ -35,12 +35,37 @@ export interface GithubUser { updated_at: string; } +export interface GithubRepositoryContributor + extends Pick< + GithubUser, + | "login" + | "id" + | "node_id" + | "avatar_url" + | "gravatar_id" + | "url" + | "html_url" + | "followers_url" + | "following_url" + | "gists_url" + | "starred_url" + | "subscriptions_url" + | "organizations_url" + | "repos_url" + | "events_url" + | "received_events_url" + | "type" + | "site_admin" + > { + contributions: number; +} + export type ListPathCommittersResponse = Array<{ author: GithubUser; committer: GithubUser; }>; -export type ListRepositoryContributorsResponse = Array; +export type ListRepositoryContributorsResponse = GithubRepositoryContributor[]; export interface GeneralGithubQuery { owner: string; diff --git a/api/src/project/controller.ts b/api/src/project/controller.ts index 1da8d00a7..e7ddbb92b 100644 --- a/api/src/project/controller.ts +++ b/api/src/project/controller.ts @@ -44,16 +44,14 @@ export class ProjectController { repository, }), }, - contributors: ( - await this.githubService.listRepositoryContributors({ - owner, - repository, - }) - ).map((contributor) => ({ - id: `github/${contributor.id}`, - username: contributor.login, - avatarUrl: contributor.avatar_url, - })), + contributors: await Promise.all( + ( + await this.githubService.listRepositoryContributors({ owner, repository }) + ).map(async ({ login }) => { + const githubUser = await this.githubService.getUser({ username: login }); + return this.githubService.githubUserToAccountEntity(githubUser); + }), + ), }; }), ), diff --git a/api/src/team/repository.ts b/api/src/team/repository.ts index d06bf20b7..378617d74 100644 --- a/api/src/team/repository.ts +++ b/api/src/team/repository.ts @@ -1,8 +1,9 @@ import { Model } from "@dzcode.io/models/dist/_base"; -import { ContributorEntity } from "@dzcode.io/models/dist/contributor"; +import { AccountEntity } from "@dzcode.io/models/dist/account"; import { RepositoryEntity } from "@dzcode.io/models/dist/repository"; import { DataService } from "src/data/service"; import { GithubService } from "src/github/service"; +import { GithubRepositoryContributor } from "src/github/types"; import { Service } from "typedi"; @Service() @@ -12,7 +13,7 @@ export class TeamRepository { private readonly dataService: DataService, ) {} - public async find(): Promise[]> { + public async find(): Promise[]> { const projects = await this.dataService.listProjects(); // flatten repositories into one array @@ -21,56 +22,70 @@ export class TeamRepository { [], ); - // we first store them in a Record (object with id as keys) so we can uniquify them easily - const contributorsRecord: Record< + // we first store them in a Record (object with id as keys) so we can uniquify and rank them + const contributorsUsernameRankedRecord: Record< string, - Model & { contributions: number } + Pick< + GithubRepositoryContributor & Model, + "login" | "contributions" | "repositories" + > > = {}; // get contributors from all the repos we have await Promise.all( repositories.map(async ({ provider, owner, repository }) => { - const committers = await this.githubService.listRepositoryContributors({ - owner, - repository, - }); - committers.forEach(({ avatar_url: avatarUrl, id, login, contributions }) => { - const uuid = `${provider}/${id}`; - // add new contributor if doesn't exists - if (!contributorsRecord[uuid]) { - contributorsRecord[`${provider}/${id}`] = { - id: `${provider}/${id}`, - avatarUrl, - username: login, - repositories: [{ provider, owner, repository }], - contributions, - }; - } else { - // if exists, increment commit counts - contributorsRecord[uuid].contributions += contributions; - // add repository if doesn't exists - if ( - !contributorsRecord[uuid].repositories.some( - (r) => r.provider === provider && r.owner === owner && r.repository === repository, - ) - ) { - contributorsRecord[uuid].repositories.push({ + if (provider === "github") { + const contributors = await this.githubService.listRepositoryContributors({ + owner, + repository, + }); + contributors.forEach((contributor) => { + const uuid = this.githubService.githubUserToAccountEntity({ + ...contributor, + name: "", + }).id; + const { login, contributions } = contributor; + // contributor first time appearing in the list + if (!contributorsUsernameRankedRecord[uuid]) { + contributorsUsernameRankedRecord[uuid] = { + login, + contributions, + repositories: [{ provider, owner, repository }], + }; + } else { + // contributor already exists in the list, and is a contributor to another repository + // - so we count additional contributions: + contributorsUsernameRankedRecord[uuid].contributions += contributor.contributions; + // - and add the other repository to the list of repositories he contributed to + contributorsUsernameRankedRecord[uuid].repositories.push({ provider, owner, repository, }); } - } - }); + }); + } else throw new Error(`Provider ${provider} is not supported yet`); }), ); - return Object.keys(contributorsRecord) - .sort((a, b) => contributorsRecord[b].contributions - contributorsRecord[a].contributions) // sort contributors by their commits count - .map((id) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { contributions, ...contributor } = contributorsRecord[id]; - return contributor; - }); + const contributors: Model[] = await Promise.all( + Object.keys(contributorsUsernameRankedRecord) + // sort contributors by their commits count + .sort( + (a, b) => + contributorsUsernameRankedRecord[b].contributions - + contributorsUsernameRankedRecord[a].contributions, + ) + // get the github user data for each contributor + .map(async (uuid) => { + const { repositories, login } = contributorsUsernameRankedRecord[uuid]; + const githubUser = await this.githubService.getUser({ username: login }); + const account = this.githubService.githubUserToAccountEntity(githubUser); + + return { ...account, repositories }; + }), + ); + + return contributors; } } diff --git a/api/src/team/types.ts b/api/src/team/types.ts index 62c0f2f41..96cf59212 100644 --- a/api/src/team/types.ts +++ b/api/src/team/types.ts @@ -1,11 +1,11 @@ import { Model } from "@dzcode.io/models/dist/_base"; -import { ContributorEntity } from "@dzcode.io/models/dist/contributor"; +import { AccountEntity } from "@dzcode.io/models/dist/account"; import { Type } from "class-transformer"; import { ValidateNested } from "class-validator"; import { GeneralResponseDto } from "src/app/types"; export class GetTeamResponseDto extends GeneralResponseDto { @ValidateNested({ each: true }) - @Type(() => ContributorEntity) - contributors!: Model[]; + @Type(() => AccountEntity) + contributors!: Model[]; } diff --git a/mobile/src/screens/articles/article-details/index.tsx b/mobile/src/screens/articles/article-details/index.tsx index d896972cb..82459a237 100644 --- a/mobile/src/screens/articles/article-details/index.tsx +++ b/mobile/src/screens/articles/article-details/index.tsx @@ -63,9 +63,9 @@ export const ArticleDetailsScreen: FC = ({ This article is written by {currentArticle.authors?.map((author) => ( - openLink(author.link)}> + openLink(author.profileUrl)}> @@ -80,10 +80,10 @@ export const ArticleDetailsScreen: FC = ({ {currentArticle.contributors?.map((contributor) => ( openLink(contributor.link)} + onPress={() => openLink(contributor.profileUrl)} > diff --git a/packages/models/src/account/__snapshots__/index.spec.ts.snap b/packages/models/src/account/__snapshots__/index.spec.ts.snap index f8ecae86a..9fe2b605a 100644 --- a/packages/models/src/account/__snapshots__/index.spec.ts.snap +++ b/packages/models/src/account/__snapshots__/index.spec.ts.snap @@ -4,10 +4,12 @@ exports[`should match snapshot when providing all fields: errors 1`] = `[]`; exports[`should match snapshot when providing all fields: output 1`] = ` AccountEntity { - "id": "20110076", - "image": "https://api.github.com/users/ZibanPirate.png", - "link": "https://github.com/ZibanPirate", + "avatarUrl": "https://avatars.githubusercontent.com/u/20110076?v=4", + "id": "github/20110076", "name": "Zakaria Mansouri", + "profileUrl": "/Account/github/20110076", + "repositories": [], + "username": "ZibanPirate", } `; @@ -15,10 +17,11 @@ exports[`should match snapshot when providing required fields only: errors 1`] = exports[`should match snapshot when providing required fields only: output 1`] = ` AccountEntity { - "id": "20110076", - "image": "https://api.github.com/users/ZibanPirate.png", - "link": "https://github.com/ZibanPirate", + "avatarUrl": "https://avatars.githubusercontent.com/u/20110076?v=4", + "id": "github/20110076", "name": "Zakaria Mansouri", + "profileUrl": "/Account/github/20110076", + "username": "ZibanPirate", } `; @@ -33,6 +36,15 @@ exports[`should show an error that matches snapshot when passing empty object: e "target": AccountEntity {}, "value": undefined, }, + ValidationError { + "children": [], + "constraints": { + "isString": "username must be a string", + }, + "property": "username", + "target": AccountEntity {}, + "value": undefined, + }, ValidationError { "children": [], "constraints": { @@ -45,18 +57,18 @@ exports[`should show an error that matches snapshot when passing empty object: e ValidationError { "children": [], "constraints": { - "isUrl": "link must be an URL address", + "isUrl": "profileUrl must be an URL address", }, - "property": "link", + "property": "profileUrl", "target": AccountEntity {}, "value": undefined, }, ValidationError { "children": [], "constraints": { - "isUrl": "image must be an URL address", + "isUrl": "avatarUrl must be an URL address", }, - "property": "image", + "property": "avatarUrl", "target": AccountEntity {}, "value": undefined, }, diff --git a/packages/models/src/account/index.spec.ts b/packages/models/src/account/index.spec.ts index b4fcc9cca..fd54565c0 100644 --- a/packages/models/src/account/index.spec.ts +++ b/packages/models/src/account/index.spec.ts @@ -5,10 +5,13 @@ import { AccountEntity } from "."; runDTOTestCases( AccountEntity, { - link: "https://github.com/ZibanPirate", - id: "20110076", + id: "github/20110076", + username: "ZibanPirate", name: "Zakaria Mansouri", - image: "https://api.github.com/users/ZibanPirate.png", + profileUrl: "/Account/github/20110076", + avatarUrl: "https://avatars.githubusercontent.com/u/20110076?v=4", + }, + { + repositories: [], }, - {}, ); diff --git a/packages/models/src/account/index.ts b/packages/models/src/account/index.ts index 1a4db1538..7f63f0980 100644 --- a/packages/models/src/account/index.ts +++ b/packages/models/src/account/index.ts @@ -1,16 +1,26 @@ -import { IsString, IsUrl } from "class-validator"; -import { BaseEntity } from "src/_base"; +import { Type } from "class-transformer"; +import { IsString, IsUrl, ValidateNested } from "class-validator"; +import { BaseEntity, Model } from "src/_base"; +import { RepositoryReferenceEntity } from "src/repository-reference"; export class AccountEntity extends BaseEntity { @IsString() id!: string; + @IsString() + username!: string; + @IsString() name!: string; - @IsUrl() - link!: string; + // eslint-disable-next-line camelcase + @IsUrl({ require_protocol: false, require_host: false }) + profileUrl!: string; @IsUrl() - image!: string; + avatarUrl!: string; + + @ValidateNested({ each: true }) + @Type(() => RepositoryReferenceEntity) + repositories?: Model[]; } diff --git a/packages/models/src/contributor/__snapshots__/index.spec.ts.snap b/packages/models/src/contributor/__snapshots__/index.spec.ts.snap deleted file mode 100644 index 5a303d7ca..000000000 --- a/packages/models/src/contributor/__snapshots__/index.spec.ts.snap +++ /dev/null @@ -1,56 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should match snapshot when providing all fields: errors 1`] = `[]`; - -exports[`should match snapshot when providing all fields: output 1`] = ` -ContributorEntity { - "avatarUrl": "https://avatars.githubusercontent.com/u/20110076?v=4", - "id": "github/20110076", - "repositories": [], - "username": "ZibanPirate", -} -`; - -exports[`should match snapshot when providing required fields only: errors 1`] = `[]`; - -exports[`should match snapshot when providing required fields only: output 1`] = ` -ContributorEntity { - "avatarUrl": "https://avatars.githubusercontent.com/u/20110076?v=4", - "id": "github/20110076", - "username": "ZibanPirate", -} -`; - -exports[`should show an error that matches snapshot when passing empty object: errors 1`] = ` -[ - ValidationError { - "children": [], - "constraints": { - "isString": "id must be a string", - }, - "property": "id", - "target": ContributorEntity {}, - "value": undefined, - }, - ValidationError { - "children": [], - "constraints": { - "isString": "username must be a string", - }, - "property": "username", - "target": ContributorEntity {}, - "value": undefined, - }, - ValidationError { - "children": [], - "constraints": { - "isUrl": "avatarUrl must be an URL address", - }, - "property": "avatarUrl", - "target": ContributorEntity {}, - "value": undefined, - }, -] -`; - -exports[`should show an error that matches snapshot when passing empty object: output 1`] = `ContributorEntity {}`; diff --git a/packages/models/src/contributor/index.spec.ts b/packages/models/src/contributor/index.spec.ts deleted file mode 100644 index 945a7677c..000000000 --- a/packages/models/src/contributor/index.spec.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { runDTOTestCases } from "src/_test"; - -import { ContributorEntity } from "."; - -runDTOTestCases( - ContributorEntity, - { - avatarUrl: "https://avatars.githubusercontent.com/u/20110076?v=4", - id: "github/20110076", - username: "ZibanPirate", - }, - { - repositories: [], - }, -); diff --git a/packages/models/src/contributor/index.ts b/packages/models/src/contributor/index.ts deleted file mode 100644 index 62a5c0f5f..000000000 --- a/packages/models/src/contributor/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Type } from "class-transformer"; -import { IsString, IsUrl, ValidateNested } from "class-validator"; -import { BaseEntity, Model } from "src/_base"; -import { RepositoryReferenceEntity } from "src/repository-reference"; - -// @TODO-ZM: remove this in favour of AccountEntity -export class ContributorEntity extends BaseEntity { - @IsString() - id!: string; - - @IsString() - username!: string; - - @IsUrl() - avatarUrl!: string; - - @ValidateNested({ each: true }) - @Type(() => RepositoryReferenceEntity) - repositories?: Model[]; -} diff --git a/packages/models/src/repository/index.ts b/packages/models/src/repository/index.ts index 1f9ca68c4..eddf07d57 100644 --- a/packages/models/src/repository/index.ts +++ b/packages/models/src/repository/index.ts @@ -1,8 +1,8 @@ import { Type } from "class-transformer"; import { IsIn, IsNumber, IsString, ValidateNested } from "class-validator"; import { BaseEntity, Model } from "src/_base"; +import { AccountEntity } from "src/account"; import { ContributionEntity } from "src/contribution"; -import { ContributorEntity } from "src/contributor"; export class RepositoryStatsEntity extends BaseEntity { @IsNumber() @@ -28,10 +28,9 @@ export class RepositoryEntity extends BaseEntity { @Type(() => RepositoryStatsEntity) stats?: Model; - // @TODO-ZM: use AccountEntity instead of ContributorEntity @ValidateNested({ each: true }) - @Type(() => ContributorEntity) - contributors?: Model[]; + @Type(() => AccountEntity) + contributors?: Model[]; @ValidateNested({ each: true }) @Type(() => ContributionEntity) diff --git a/packages/ui/package.json b/packages/ui/package.json index d507dfb54..7b342daee 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -36,9 +36,7 @@ "@types/markdown-to-jsx": "^6.11.3", "@types/react-router-dom": "^5.1.6", "@types/react-syntax-highlighter": "^13.5.0", - "@types/stylis": "^4.0.2", - "@types/uuid": "^8.3.3", - "uuid": "^3.4.0" + "@types/stylis": "^4.0.2" }, "license": "MIT", "lint-staged": { diff --git a/packages/ui/src/__mocks__/create-contributors.ts b/packages/ui/src/__mocks__/create-contributors.ts index e61d6d01c..fb02d9f77 100644 --- a/packages/ui/src/__mocks__/create-contributors.ts +++ b/packages/ui/src/__mocks__/create-contributors.ts @@ -1,13 +1,14 @@ -import { ContributorEntity } from "@dzcode.io/models/dist/contributor"; -import { v4 as uuid } from "uuid"; +import { AccountEntity } from "@dzcode.io/models/dist/account"; export const createContributors = (number: number) => { - const contributors: ContributorEntity[] = []; + const contributors: AccountEntity[] = []; for (let i = 0; i < number; i++) { contributors.push({ - id: uuid(), - avatarUrl: `mock-avatar-${i}`, + id: `github/${i}`, username: `mock-user-${i}`, + name: `mock-name-${i}`, + profileUrl: `mock-profile-${i}`, + avatarUrl: `mock-avatar-${i}`, repositories: [ { owner: `user-${i}`, diff --git a/packages/ui/src/article/index.tsx b/packages/ui/src/article/index.tsx index 46d42259d..811b35900 100644 --- a/packages/ui/src/article/index.tsx +++ b/packages/ui/src/article/index.tsx @@ -1,3 +1,5 @@ +import { Model } from "@dzcode.io/models/dist/_base"; +import { AccountEntity } from "@dzcode.io/models/dist/account"; import { Skeleton } from "@mui/material"; import { FC } from "react"; import { Divider } from "src/divider"; @@ -7,19 +9,17 @@ import { Markdown } from "src/markdown"; import { Stack, StackProps } from "src/stack"; import { Text } from "src/text"; -export interface ArticleAuthor { - name: string; - link: string; - image: string; -} - +export type MinimumAccountInfo = Pick< + Model, + "id" | "name" | "username" | "profileUrl" | "avatarUrl" +>; export interface ArticleProps extends Pick { article: { image: string; title: string; content: string; - authors: ArticleAuthor[]; - contributors: ArticleAuthor[]; + authors: MinimumAccountInfo[]; + contributors: MinimumAccountInfo[]; } | null; authorsText: string; contributorsText: string; @@ -44,8 +44,8 @@ export const Article: FC = ({ article, authorsText, contributorsTe {article.authors.map((author, index) => ( - - + + ))} @@ -58,8 +58,8 @@ export const Article: FC = ({ article, authorsText, contributorsTe {article.contributors.map((contributor, index) => ( - - + + ))} diff --git a/packages/ui/src/card/contributor/index.tsx b/packages/ui/src/card/contributor/index.tsx index 0dc8c6a00..fed719595 100644 --- a/packages/ui/src/card/contributor/index.tsx +++ b/packages/ui/src/card/contributor/index.tsx @@ -1,5 +1,5 @@ import { Model } from "@dzcode.io/models/dist/_base"; -import { ContributorEntity } from "@dzcode.io/models/dist/contributor"; +import { AccountEntity } from "@dzcode.io/models/dist/account"; import { getRepositoryURL } from "@dzcode.io/models/dist/repository-reference/utils"; import { FC } from "react"; import { useTranslation } from "src/_hooks/use-translation"; @@ -16,7 +16,7 @@ type ContributorCard = local?: never; } | { - contributor: Model; + contributor: Model; // @TODO-ZM: make local dynamic based on counts local: { repository: string; @@ -63,6 +63,9 @@ export const ContributorCard: FC = ({ contributor, local }) => + {contributor.name} + + {contributor.username} diff --git a/yarn.lock b/yarn.lock index f4a4daa9d..7f4021099 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6778,11 +6778,6 @@ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d" integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== -"@types/uuid@^8.3.3": - version "8.3.3" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.3.tgz#c6a60686d953dbd1b1d45e66f4ecdbd5d471b4d0" - integrity sha512-0LbEEx1zxrYB3pgpd1M5lEhLcXjKJnYghvhTRgaBeUivLHMDM1TzF3IJ6hXU2+8uA4Xz+5BA63mtZo5DjVT8iA== - "@types/webpack-bundle-analyzer@^4.4.2": version "4.4.2" resolved "https://registry.yarnpkg.com/@types/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.4.2.tgz#0083d5c4122ba22ebf0682d135e240a51cae42a0" From d224f3f5459477540e5e72021bcb0ac30d15af58 Mon Sep 17 00:00:00 2001 From: Zakaria Mansouri Date: Sat, 15 Apr 2023 13:03:30 +0200 Subject: [PATCH 5/5] moved patches under /tooling --- package.json | 3 ++- packages/tooling/.prettierignore | 1 + .../tooling/patches}/@sentry-internal+tracing+7.46.0.patch | 0 3 files changed, 3 insertions(+), 1 deletion(-) rename {patches => packages/tooling/patches}/@sentry-internal+tracing+7.46.0.patch (100%) diff --git a/package.json b/package.json index e6726bda2..de0ec99f4 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,8 @@ "lint:fix": "yarn build && yarn lint:fix:alone", "lint:fix:alone": "lerna run lint:fix:alone --parallel", "lint:staged": "lerna exec --since HEAD --concurrency 1 --stream -- lint-staged && lint-staged", - "postinstall": "patch-package && (husky install && husky set .husky/pre-commit \"yarn lint:staged\") || exit 0", + "patch-package": "patch-package --patch-dir packages/tooling/patches", + "postinstall": "yarn patch-package && (husky install && husky set .husky/pre-commit \"yarn lint:staged\") || exit 0", "prepare": "ts-patch install -s", "start:dev": "lerna run start:dev --parallel", "test": "yarn build && yarn test:alone", diff --git a/packages/tooling/.prettierignore b/packages/tooling/.prettierignore index 7f7f50337..d434014c3 100644 --- a/packages/tooling/.prettierignore +++ b/packages/tooling/.prettierignore @@ -31,3 +31,4 @@ nodemon.json *.eslintignore *.ttf *.ts-prunerc +*.patch diff --git a/patches/@sentry-internal+tracing+7.46.0.patch b/packages/tooling/patches/@sentry-internal+tracing+7.46.0.patch similarity index 100% rename from patches/@sentry-internal+tracing+7.46.0.patch rename to packages/tooling/patches/@sentry-internal+tracing+7.46.0.patch