all-contributors-for-repository
Advanced tools
Comparing version 0.1.0 to 0.1.1
@@ -1,12 +0,14 @@ | ||
import { Octokit } from "octokit"; | ||
export interface RequestDefaults { | ||
import { Octokit } from 'octokit'; | ||
interface RequestDefaults { | ||
owner: string; | ||
repo: string; | ||
} | ||
export declare function createOctokit(auth: string | undefined): Octokit; | ||
export interface RequestOptionsWithPage extends RequestDefaults { | ||
declare function createOctokit(auth: string | undefined): Octokit; | ||
interface RequestOptionsWithPage extends RequestDefaults { | ||
page: number; | ||
per_page: number; | ||
} | ||
export declare function paginate<T>(defaults: RequestDefaults, request: (options: RequestOptionsWithPage) => Promise<T[]>): Promise<T[]>; | ||
//# sourceMappingURL=api.d.ts.map | ||
declare function paginate<T>(defaults: RequestDefaults, request: (options: RequestOptionsWithPage) => Promise<T[]>): Promise<T[]>; | ||
export { type RequestDefaults, type RequestOptionsWithPage, createOctokit, paginate }; |
import { Octokit } from "octokit"; | ||
const perPage = 100; | ||
export function createOctokit(auth) { | ||
return new (Octokit.defaults({ | ||
headers: { | ||
"X-GitHub-Api-Version": "2022-11-28", | ||
}, | ||
per_page: perPage, | ||
}))({ auth }); | ||
function createOctokit(auth) { | ||
return new (Octokit.defaults({ | ||
headers: { | ||
"X-GitHub-Api-Version": "2022-11-28" | ||
}, | ||
per_page: perPage | ||
}))({ auth }); | ||
} | ||
export async function paginate(defaults, request) { | ||
const items = []; | ||
for (let i = 0; i < 10; i += 1) { | ||
const response = await request({ page: i, per_page: perPage, ...defaults }); | ||
items.push(...response); | ||
if (response.length < 100) { | ||
break; | ||
} | ||
async function paginate(defaults, request) { | ||
const items = []; | ||
for (let i = 0; i < 10; i += 1) { | ||
const response = await request({ page: i, per_page: perPage, ...defaults }); | ||
items.push(...response); | ||
if (response.length < 100) { | ||
break; | ||
} | ||
return items; | ||
} | ||
return items; | ||
} | ||
export { | ||
createOctokit, | ||
paginate | ||
}; | ||
//# sourceMappingURL=api.js.map |
@@ -1,4 +0,5 @@ | ||
import { Octokit } from "octokit"; | ||
import { RequestDefaults } from "./api.js"; | ||
export declare function collectAcceptedIssues(defaults: RequestDefaults, octokit: Octokit, labelAcceptingPrs: string): Promise<{ | ||
import { Octokit } from 'octokit'; | ||
import { RequestDefaults } from './api.js'; | ||
declare function collectAcceptedIssues(defaults: RequestDefaults, octokit: Octokit, labelAcceptingPrs: string): Promise<{ | ||
[k: string]: { | ||
@@ -510,2 +511,3 @@ id: number; | ||
}>; | ||
//# sourceMappingURL=collectAcceptedIssues.d.ts.map | ||
export { collectAcceptedIssues }; |
import { paginate } from "./api.js"; | ||
export async function collectAcceptedIssues(defaults, octokit, labelAcceptingPrs) { | ||
const issues = await paginate(defaults, async (options) => { | ||
const response = await octokit.request("GET /repos/{owner}/{repo}/issues", { | ||
...options, | ||
labels: labelAcceptingPrs, | ||
state: "all", | ||
}); | ||
return response.data; | ||
async function collectAcceptedIssues(defaults, octokit, labelAcceptingPrs) { | ||
const issues = await paginate(defaults, async (options) => { | ||
const response = await octokit.request("GET /repos/{owner}/{repo}/issues", { | ||
...options, | ||
labels: labelAcceptingPrs, | ||
state: "all" | ||
}); | ||
return Object.fromEntries(issues.map((issue) => [issue.number, issue])); | ||
return response.data; | ||
}); | ||
return Object.fromEntries(issues.map((issue) => [issue.number, issue])); | ||
} | ||
export { | ||
collectAcceptedIssues | ||
}; | ||
//# sourceMappingURL=collectAcceptedIssues.js.map |
@@ -1,5 +0,6 @@ | ||
import { Octokit } from "octokit"; | ||
import { RequestDefaults } from "./api.js"; | ||
export type RepoEvent = Awaited<ReturnType<typeof collectEvents>>[number]; | ||
export declare function collectEvents(defaults: RequestDefaults, octokit: Octokit): Promise<{ | ||
import { Octokit } from 'octokit'; | ||
import { RequestDefaults } from './api.js'; | ||
type RepoEvent = Awaited<ReturnType<typeof collectEvents>>[number]; | ||
declare function collectEvents(defaults: RequestDefaults, octokit: Octokit): Promise<{ | ||
id: string; | ||
@@ -643,2 +644,3 @@ type: string | null; | ||
}[]>; | ||
//# sourceMappingURL=collectEvents.d.ts.map | ||
export { type RepoEvent, collectEvents }; |
import { paginate } from "./api.js"; | ||
export async function collectEvents(defaults, octokit) { | ||
const events = await paginate(defaults, async (options) => { | ||
const eventsResponse = await octokit.request("GET /repos/{owner}/{repo}/events", { | ||
...options, | ||
state: "all", | ||
}); | ||
return eventsResponse.data; | ||
}); | ||
return events; | ||
async function collectEvents(defaults, octokit) { | ||
const events = await paginate(defaults, async (options) => { | ||
const eventsResponse = await octokit.request( | ||
"GET /repos/{owner}/{repo}/events", | ||
{ | ||
...options, | ||
state: "all" | ||
} | ||
); | ||
return eventsResponse.data; | ||
}); | ||
return events; | ||
} | ||
export { | ||
collectEvents | ||
}; | ||
//# sourceMappingURL=collectEvents.js.map |
@@ -1,4 +0,5 @@ | ||
import { Octokit } from "octokit"; | ||
import { RequestDefaults } from "./api.js"; | ||
export declare function collectIssueEvents(defaults: RequestDefaults, octokit: Octokit): Promise<{ | ||
import { Octokit } from 'octokit'; | ||
import { RequestDefaults } from './api.js'; | ||
declare function collectIssueEvents(defaults: RequestDefaults, octokit: Octokit): Promise<{ | ||
id: number; | ||
@@ -743,2 +744,3 @@ node_id: string; | ||
}[]>; | ||
//# sourceMappingURL=collectIssueEvents.d.ts.map | ||
export { collectIssueEvents }; |
import { paginate } from "./api.js"; | ||
const relevantIssueEvents = new Set([ | ||
"assigned", | ||
"locked", | ||
"merged", | ||
"pinned", | ||
"unlocked", | ||
const relevantIssueEvents = /* @__PURE__ */ new Set([ | ||
"assigned", | ||
"locked", | ||
"merged", | ||
"pinned", | ||
"unlocked" | ||
]); | ||
export async function collectIssueEvents(defaults, octokit) { | ||
const issueEvents = await paginate(defaults, async (options) => { | ||
const response = await octokit.request("GET /repos/{owner}/{repo}/issues/events", { | ||
...options, | ||
state: "all", | ||
}); | ||
return response.data; | ||
}); | ||
return issueEvents.filter((issueEvent) => relevantIssueEvents.has(issueEvent.event)); | ||
async function collectIssueEvents(defaults, octokit) { | ||
const issueEvents = await paginate(defaults, async (options) => { | ||
const response = await octokit.request( | ||
"GET /repos/{owner}/{repo}/issues/events", | ||
{ | ||
...options, | ||
state: "all" | ||
} | ||
); | ||
return response.data; | ||
}); | ||
return issueEvents.filter( | ||
(issueEvent) => relevantIssueEvents.has(issueEvent.event) | ||
); | ||
} | ||
export { | ||
collectIssueEvents | ||
}; | ||
//# sourceMappingURL=collectIssueEvents.js.map |
@@ -1,4 +0,5 @@ | ||
import { Octokit } from "octokit"; | ||
import { RequestDefaults } from "./api.js"; | ||
export declare function collectMergedPulls(defaults: RequestDefaults, octokit: Octokit): Promise<{ | ||
import { Octokit } from 'octokit'; | ||
import { RequestDefaults } from './api.js'; | ||
declare function collectMergedPulls(defaults: RequestDefaults, octokit: Octokit): Promise<{ | ||
url: string; | ||
@@ -496,2 +497,3 @@ repository_url: string; | ||
}[]>; | ||
//# sourceMappingURL=collectMergedPulls.d.ts.map | ||
export { collectMergedPulls }; |
import { paginate } from "./api.js"; | ||
export async function collectMergedPulls(defaults, octokit) { | ||
return await paginate(defaults, async (options) => { | ||
const response = await octokit.request("GET /search/issues", { | ||
...options, | ||
q: `repo:${defaults.owner}/${defaults.repo}+is:pr+is:merged`, | ||
}); | ||
return response.data.items; | ||
async function collectMergedPulls(defaults, octokit) { | ||
return await paginate(defaults, async (options) => { | ||
const response = await octokit.request("GET /search/issues", { | ||
...options, | ||
q: `repo:${defaults.owner}/${defaults.repo}+is:pr+is:merged` | ||
}); | ||
return response.data.items; | ||
}); | ||
} | ||
export { | ||
collectMergedPulls | ||
}; | ||
//# sourceMappingURL=collectMergedPulls.js.map |
@@ -1,2 +0,5 @@ | ||
import { RepoEvent } from "./collectEvents.js"; | ||
import { RepoEvent } from './collectEvents.js'; | ||
import 'octokit'; | ||
import './api.js'; | ||
type PullRequestReviewEvent = RepoEvent & { | ||
@@ -7,4 +10,4 @@ issue: { | ||
}; | ||
export declare function eventIsPullRequestReviewEvent(event: Pick<RepoEvent, "type">): event is PullRequestReviewEvent; | ||
export {}; | ||
//# sourceMappingURL=eventIsPullRequestReviewEvent.d.ts.map | ||
declare function eventIsPullRequestReviewEvent(event: Pick<RepoEvent, "type">): event is PullRequestReviewEvent; | ||
export { eventIsPullRequestReviewEvent }; |
@@ -1,5 +0,7 @@ | ||
export function eventIsPullRequestReviewEvent(event) { | ||
return (event.type === "PullRequestReviewEvent" && | ||
!!event.issue?.number); | ||
function eventIsPullRequestReviewEvent(event) { | ||
return event.type === "PullRequestReviewEvent" && !!event.issue?.number; | ||
} | ||
export { | ||
eventIsPullRequestReviewEvent | ||
}; | ||
//# sourceMappingURL=eventIsPullRequestReviewEvent.js.map |
@@ -1,4 +0,6 @@ | ||
import { ContributorsContributions } from "../ContributorsCollection.js"; | ||
import { AllContributorsForRepositoryOptions } from "../options.js"; | ||
export declare function collect(options: AllContributorsForRepositoryOptions): Promise<ContributorsContributions>; | ||
//# sourceMappingURL=index.d.ts.map | ||
import { ContributorsContributions } from '../ContributorsCollection.js'; | ||
import { AllContributorsForRepositoryOptions } from '../options.js'; | ||
declare function collect(options: AllContributorsForRepositoryOptions): Promise<ContributorsContributions>; | ||
export { collect }; |
@@ -1,3 +0,5 @@ | ||
import { CachingMap } from "../CachingMap.js"; | ||
import { ContributorsCollection, } from "../ContributorsCollection.js"; | ||
import { createCachingCoAuthorToUsername } from "co-author-to-username"; | ||
import { | ||
ContributorsCollection | ||
} from "../ContributorsCollection.js"; | ||
import { createOctokit } from "./api.js"; | ||
@@ -9,57 +11,65 @@ import { collectAcceptedIssues } from "./collectAcceptedIssues.js"; | ||
import { eventIsPullRequestReviewEvent } from "./eventIsPullRequestReviewEvent.js"; | ||
import { collectUserByEmail } from "./parsing/collectUserByEmail.js"; | ||
import { parseMergedPullAuthors } from "./parsing/parseMergedPullAuthors.js"; | ||
import { parseMergedPullType } from "./parsing/parseMergedPullType.js"; | ||
export async function collect(options) { | ||
const contributors = new ContributorsCollection(options.ignoredLogins); | ||
const defaults = { owner: options.owner, repo: options.repo }; | ||
const octokit = createOctokit(options.auth); | ||
const [acceptedIssues, events, issueEvents, mergedPulls] = await Promise.all([ | ||
collectAcceptedIssues(defaults, octokit, options.labelAcceptingPrs), | ||
collectEvents(defaults, octokit), | ||
collectIssueEvents(defaults, octokit), | ||
collectMergedPulls(defaults, octokit), | ||
]); | ||
for (const acceptedIssue of Object.values(acceptedIssues)) { | ||
const labels = acceptedIssue.labels.map((label) => typeof label === "string" ? label : label.name); | ||
for (const [labelType, contribution] of [ | ||
// 🐛 `bug`: anybody who filed an issue labeled as accepting PRs and a bug | ||
[options.labelTypeBug, "bug"], | ||
// - 📖 `doc`: authors of merged PRs that address issues labeled as docs | ||
[options.labelTypeDocs, "docs"], | ||
// - 🔧 `tool`: authors of merged PRs that address issues labeled as tooling | ||
[options.labelTypeTool, "tool"], | ||
]) { | ||
if (labels.some((label) => label === labelType)) { | ||
contributors.add(acceptedIssue.user?.login, acceptedIssue.number, contribution); | ||
} | ||
} | ||
async function collect(options) { | ||
const contributors = new ContributorsCollection(options.ignoredLogins); | ||
const defaults = { owner: options.owner, repo: options.repo }; | ||
const octokit = createOctokit(options.auth); | ||
const [acceptedIssues, events, issueEvents, mergedPulls] = await Promise.all([ | ||
collectAcceptedIssues(defaults, octokit, options.labelAcceptingPrs), | ||
collectEvents(defaults, octokit), | ||
collectIssueEvents(defaults, octokit), | ||
collectMergedPulls(defaults, octokit) | ||
]); | ||
for (const acceptedIssue of Object.values(acceptedIssues)) { | ||
const labels = acceptedIssue.labels.map( | ||
(label) => typeof label === "string" ? label : label.name | ||
); | ||
for (const [labelType, contribution] of [ | ||
// 🐛 `bug`: anybody who filed an issue labeled as accepting PRs and a bug | ||
[options.labelTypeBug, "bug"], | ||
// - 📖 `doc`: authors of merged PRs that address issues labeled as docs | ||
[options.labelTypeDocs, "docs"], | ||
// - 🔧 `tool`: authors of merged PRs that address issues labeled as tooling | ||
[options.labelTypeTool, "tool"] | ||
]) { | ||
if (labels.some((label) => label === labelType)) { | ||
contributors.add( | ||
acceptedIssue.user?.login, | ||
acceptedIssue.number, | ||
contribution | ||
); | ||
} | ||
} | ||
// 💻 `code` & others: all PR authors and co-authors | ||
const authorsByEmailCache = new CachingMap(async (email) => await collectUserByEmail(email, octokit)); | ||
for (const mergedPull of mergedPulls) { | ||
const authors = await parseMergedPullAuthors(mergedPull, authorsByEmailCache); | ||
const type = parseMergedPullType(mergedPull.title); | ||
for (const author of authors) { | ||
contributors.add(author, mergedPull.number, type); | ||
} | ||
} | ||
const cachingCoAuthorToUsername = createCachingCoAuthorToUsername({ | ||
fetcher: octokit | ||
}); | ||
for (const mergedPull of mergedPulls) { | ||
const authors = await parseMergedPullAuthors( | ||
mergedPull, | ||
cachingCoAuthorToUsername | ||
); | ||
const type = parseMergedPullType(mergedPull.title); | ||
for (const author of authors) { | ||
contributors.add(author, mergedPull.number, type); | ||
} | ||
// 🚧 `maintenance`: adding labels to issues and PRs, and merging PRs | ||
const maintainers = new Set(); | ||
for (const event of issueEvents) { | ||
if (event.actor && event.issue) { | ||
contributors.add(event.actor.login, event.issue.number, "maintenance"); | ||
maintainers.add(event.actor.login); | ||
} | ||
} | ||
const maintainers = /* @__PURE__ */ new Set(); | ||
for (const event of issueEvents) { | ||
if (event.actor && event.issue) { | ||
contributors.add(event.actor.login, event.issue.number, "maintenance"); | ||
maintainers.add(event.actor.login); | ||
} | ||
// 👀 `review`: submitting a review for a PR | ||
// (restricted just to users marked as maintainers) | ||
for (const event of events) { | ||
if (eventIsPullRequestReviewEvent(event) && | ||
maintainers.has(event.actor.login)) { | ||
contributors.add(event.actor.login, event.issue.number, "review"); | ||
} | ||
} | ||
for (const event of events) { | ||
if (eventIsPullRequestReviewEvent(event) && maintainers.has(event.actor.login)) { | ||
contributors.add(event.actor.login, event.issue.number, "review"); | ||
} | ||
return contributors.collect(); | ||
} | ||
return contributors.collect(); | ||
} | ||
export { | ||
collect | ||
}; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,3 @@ | ||
import { CachingMap } from "../../CachingMap.js"; | ||
import { CachingCoAuthorToUsername } from 'co-author-to-username'; | ||
interface MergedPullForAuthors { | ||
@@ -8,4 +9,4 @@ body?: string; | ||
} | ||
export declare function parseMergedPullAuthors(mergedPull: MergedPullForAuthors, authorsCache: CachingMap<string, Promise<string | undefined>>): Promise<string[]>; | ||
export {}; | ||
//# sourceMappingURL=parseMergedPullAuthors.d.ts.map | ||
declare function parseMergedPullAuthors(mergedPull: MergedPullForAuthors, cachingCoAuthorToUsername: CachingCoAuthorToUsername): Promise<string[]>; | ||
export { parseMergedPullAuthors }; |
@@ -1,18 +0,22 @@ | ||
export async function parseMergedPullAuthors(mergedPull, authorsCache) { | ||
const authors = []; | ||
authors.push(mergedPull.user?.login); | ||
for (const match of mergedPull.body?.match(/co-authored-by:.+/gi) ?? []) { | ||
const split = match.split(/\s+/); | ||
if (/@\w+/.test(split[1])) { | ||
authors.push(split[1].slice(1)); | ||
continue; | ||
} | ||
const email = split.length > 2 && split[split.length - 1].match(/<(.+)>/)?.[1]; | ||
if (email) { | ||
const newLocal = await authorsCache.get(email); | ||
authors.push(newLocal); | ||
} | ||
import { commitToCoAuthors } from "commit-to-co-authors"; | ||
async function parseMergedPullAuthors(mergedPull, cachingCoAuthorToUsername) { | ||
const authors = []; | ||
authors.push(mergedPull.user?.login); | ||
if (mergedPull.body) { | ||
const coAuthors = commitToCoAuthors(mergedPull.body); | ||
for (const coAuthor of coAuthors) { | ||
authors.push(await cachingCoAuthorToUsername(coAuthor)); | ||
} | ||
return Array.from(new Set(authors.filter((author) => !!author))); | ||
} | ||
return Array.from( | ||
new Set( | ||
authors.filter( | ||
(author) => !!author | ||
) | ||
) | ||
); | ||
} | ||
export { | ||
parseMergedPullAuthors | ||
}; | ||
//# sourceMappingURL=parseMergedPullAuthors.js.map |
@@ -1,2 +0,3 @@ | ||
export declare function parseMergedPullType(title: string): string; | ||
//# sourceMappingURL=parseMergedPullType.d.ts.map | ||
declare function parseMergedPullType(title: string): string; | ||
export { parseMergedPullType }; |
import conventionalCommitsParser from "conventional-commits-parser"; | ||
const allContributorsTypes = new Map([ | ||
["build", "infra"], | ||
["ci", "infra"], | ||
["docs", "doc"], | ||
["test", "test"], | ||
const allContributorsTypes = /* @__PURE__ */ new Map([ | ||
["build", "infra"], | ||
["ci", "infra"], | ||
["docs", "doc"], | ||
["test", "test"] | ||
]); | ||
export function parseMergedPullType(title) { | ||
const { type } = conventionalCommitsParser.sync(title); | ||
return (type && allContributorsTypes.get(type)) || "code"; | ||
function parseMergedPullType(title) { | ||
const { type } = conventionalCommitsParser.sync(title); | ||
return (type && allContributorsTypes.get(type)) ?? "code"; | ||
} | ||
export { | ||
parseMergedPullType | ||
}; | ||
//# sourceMappingURL=parseMergedPullType.js.map |
@@ -1,5 +0,6 @@ | ||
export declare class Contributor { | ||
declare class Contributor { | ||
readonly contributions: Record<string, Set<number>>; | ||
add(number: number, type: string): void; | ||
} | ||
//# sourceMappingURL=Contributor.d.ts.map | ||
export { Contributor }; |
@@ -1,9 +0,10 @@ | ||
export class Contributor { | ||
constructor() { | ||
this.contributions = {}; | ||
} | ||
add(number, type) { | ||
(this.contributions[type] ??= new Set()).add(number); | ||
} | ||
class Contributor { | ||
contributions = {}; | ||
add(number, type) { | ||
(this.contributions[type] ??= /* @__PURE__ */ new Set()).add(number); | ||
} | ||
} | ||
export { | ||
Contributor | ||
}; | ||
//# sourceMappingURL=Contributor.js.map |
/** | ||
* For a set of logins, the contributions under those users. | ||
*/ | ||
export type ContributorsContributions = Record<string, ContributorContributions>; | ||
type ContributorsContributions = Record<string, ContributorContributions>; | ||
/** | ||
* For each contribution under a login, the issue/PR numbers that count as that type. | ||
*/ | ||
export type ContributorContributions = Record<string, number[]>; | ||
export declare class ContributorsCollection { | ||
type ContributorContributions = Record<string, number[]>; | ||
declare class ContributorsCollection { | ||
#private; | ||
@@ -15,2 +15,3 @@ constructor(ignoredLogins: Set<string>); | ||
} | ||
//# sourceMappingURL=ContributorsCollection.d.ts.map | ||
export { type ContributorContributions, ContributorsCollection, type ContributorsContributions }; |
@@ -1,38 +0,37 @@ | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
if (kind === "m") throw new TypeError("Private method is not writable"); | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); | ||
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; | ||
}; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
var _ContributorsCollection_contributors, _ContributorsCollection_ignoredLogins; | ||
import { Contributor } from "./Contributor.js"; | ||
export class ContributorsCollection { | ||
constructor(ignoredLogins) { | ||
_ContributorsCollection_contributors.set(this, {}); | ||
_ContributorsCollection_ignoredLogins.set(this, void 0); | ||
__classPrivateFieldSet(this, _ContributorsCollection_ignoredLogins, ignoredLogins, "f"); | ||
class ContributorsCollection { | ||
#contributors = {}; | ||
#ignoredLogins; | ||
constructor(ignoredLogins) { | ||
this.#ignoredLogins = ignoredLogins; | ||
} | ||
add(login, number, type) { | ||
if (login && !this.#ignoredLogins.has(login)) { | ||
(this.#contributors[login.toLowerCase()] ??= new Contributor()).add( | ||
number, | ||
type | ||
); | ||
} | ||
add(login, number, type) { | ||
if (login && !__classPrivateFieldGet(this, _ContributorsCollection_ignoredLogins, "f").has(login)) { | ||
(__classPrivateFieldGet(this, _ContributorsCollection_contributors, "f")[login.toLowerCase()] ??= new Contributor()).add(number, type); | ||
} | ||
} | ||
collect() { | ||
return Object.fromEntries(Object.entries(__classPrivateFieldGet(this, _ContributorsCollection_contributors, "f")) | ||
.map(([login, contributor]) => [ | ||
login, | ||
Object.fromEntries(Object.entries(contributor.contributions).map(([type, numbers]) => [ | ||
} | ||
collect() { | ||
return Object.fromEntries( | ||
Object.entries(this.#contributors).map( | ||
([login, contributor]) => [ | ||
login, | ||
Object.fromEntries( | ||
Object.entries(contributor.contributions).map( | ||
([type, numbers]) => [ | ||
type, | ||
Array.from(numbers).sort((a, b) => a - b), | ||
])), | ||
]) | ||
.sort(([a], [b]) => a.localeCompare(b))); | ||
} | ||
Array.from(numbers).sort((a, b) => a - b) | ||
] | ||
) | ||
) | ||
] | ||
).sort(([a], [b]) => a.localeCompare(b)) | ||
); | ||
} | ||
} | ||
_ContributorsCollection_contributors = new WeakMap(), _ContributorsCollection_ignoredLogins = new WeakMap(); | ||
export { | ||
ContributorsCollection | ||
}; | ||
//# sourceMappingURL=ContributorsCollection.js.map |
@@ -1,3 +0,6 @@ | ||
import { RawAllContributorsForRepositoryOptions } from "./options.js"; | ||
export declare function getAllContributorsForRepository(rawOptions: RawAllContributorsForRepositoryOptions): Promise<import("./ContributorsCollection.js").ContributorsContributions>; | ||
//# sourceMappingURL=getAllContributorsForRepository.d.ts.map | ||
import { ContributorsContributions } from './ContributorsCollection.js'; | ||
import { RawAllContributorsForRepositoryOptions } from './options.js'; | ||
declare function getAllContributorsForRepository(rawOptions: RawAllContributorsForRepositoryOptions): Promise<ContributorsContributions>; | ||
export { getAllContributorsForRepository }; |
import { collect } from "./collect/index.js"; | ||
import { fillInOptions, } from "./options.js"; | ||
export async function getAllContributorsForRepository(rawOptions) { | ||
const options = fillInOptions(rawOptions); | ||
return await collect(options); | ||
import { | ||
fillInOptions | ||
} from "./options.js"; | ||
async function getAllContributorsForRepository(rawOptions) { | ||
const options = fillInOptions(rawOptions); | ||
return await collect(options); | ||
} | ||
export { | ||
getAllContributorsForRepository | ||
}; | ||
//# sourceMappingURL=getAllContributorsForRepository.js.map |
@@ -1,3 +0,3 @@ | ||
export { ContributorContributions, ContributorsContributions, } from "./ContributorsCollection.js"; | ||
export { getAllContributorsForRepository } from "./getAllContributorsForRepository.js"; | ||
//# sourceMappingURL=index.d.ts.map | ||
export { ContributorContributions, ContributorsContributions } from './ContributorsCollection.js'; | ||
export { getAllContributorsForRepository } from './getAllContributorsForRepository.js'; | ||
import './options.js'; |
@@ -1,2 +0,5 @@ | ||
export { getAllContributorsForRepository } from "./getAllContributorsForRepository.js"; | ||
import { getAllContributorsForRepository } from "./getAllContributorsForRepository.js"; | ||
export { | ||
getAllContributorsForRepository | ||
}; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,2 @@ | ||
export interface RawAllContributorsForRepositoryOptions { | ||
interface RawAllContributorsForRepositoryOptions { | ||
/** | ||
@@ -35,3 +35,3 @@ * GitHub auth token to query the API with, if necessary for private repositories and/or to avoid rate limiting. | ||
} | ||
export interface AllContributorsForRepositoryOptions { | ||
interface AllContributorsForRepositoryOptions { | ||
auth?: string; | ||
@@ -46,3 +46,4 @@ ignoredLogins: Set<string>; | ||
} | ||
export declare function fillInOptions(rawOptions: RawAllContributorsForRepositoryOptions): AllContributorsForRepositoryOptions; | ||
//# sourceMappingURL=options.d.ts.map | ||
declare function fillInOptions(rawOptions: RawAllContributorsForRepositoryOptions): AllContributorsForRepositoryOptions; | ||
export { type AllContributorsForRepositoryOptions, type RawAllContributorsForRepositoryOptions, fillInOptions }; |
const defaultOptions = { | ||
ignoredLogins: [ | ||
"allcontributors", | ||
"allcontributors[bot]", | ||
"dependabot", | ||
"dependabot[bot]", | ||
"renovate", | ||
"renovate[bot]", | ||
], | ||
labelAcceptingPrs: "status: accepting prs", | ||
labelTypeBug: "type: bug", | ||
labelTypeDocs: "type: documentation", | ||
labelTypeTool: "area: tooling", | ||
ignoredLogins: [ | ||
"allcontributors", | ||
"allcontributors[bot]", | ||
"dependabot", | ||
"dependabot[bot]", | ||
"renovate", | ||
"renovate[bot]" | ||
], | ||
labelAcceptingPrs: "status: accepting prs", | ||
labelTypeBug: "type: bug", | ||
labelTypeDocs: "type: documentation", | ||
labelTypeTool: "area: tooling" | ||
}; | ||
export function fillInOptions(rawOptions) { | ||
return { | ||
auth: rawOptions.auth, | ||
ignoredLogins: new Set(rawOptions.ignoredLogins ?? defaultOptions.ignoredLogins), | ||
labelAcceptingPrs: rawOptions.labelAcceptingPrs ?? defaultOptions.labelAcceptingPrs, | ||
labelTypeBug: rawOptions.labelTypeBug ?? defaultOptions.labelTypeBug, | ||
labelTypeDocs: rawOptions.labelTypeDocs ?? defaultOptions.labelTypeDocs, | ||
labelTypeTool: rawOptions.labelTypeTool ?? defaultOptions.labelTypeTool, | ||
owner: rawOptions.owner, | ||
repo: rawOptions.repo, | ||
}; | ||
function fillInOptions(rawOptions) { | ||
return { | ||
auth: rawOptions.auth, | ||
ignoredLogins: new Set( | ||
rawOptions.ignoredLogins ?? defaultOptions.ignoredLogins | ||
), | ||
labelAcceptingPrs: rawOptions.labelAcceptingPrs ?? defaultOptions.labelAcceptingPrs, | ||
labelTypeBug: rawOptions.labelTypeBug ?? defaultOptions.labelTypeBug, | ||
labelTypeDocs: rawOptions.labelTypeDocs ?? defaultOptions.labelTypeDocs, | ||
labelTypeTool: rawOptions.labelTypeTool ?? defaultOptions.labelTypeTool, | ||
owner: rawOptions.owner, | ||
repo: rawOptions.repo | ||
}; | ||
} | ||
export { | ||
fillInOptions | ||
}; | ||
//# sourceMappingURL=options.js.map |
{ | ||
"name": "all-contributors-for-repository", | ||
"version": "0.1.0", | ||
"description": "Generates an allcontributors list for an existing repository.", | ||
"version": "0.1.1", | ||
"description": "Generates an allcontributors list for an existing repository. 🤝", | ||
"repository": { | ||
@@ -10,3 +10,6 @@ "type": "git", | ||
"license": "MIT", | ||
"author": "Josh Goldberg <npm@joshuakgoldberg.com>", | ||
"author": { | ||
"name": "JoshuaKGoldberg", | ||
"email": "npm@joshuakgoldberg.com" | ||
}, | ||
"type": "module", | ||
@@ -21,9 +24,8 @@ "main": "./lib/index.js", | ||
"scripts": { | ||
"build": "tsc", | ||
"build": "tsup", | ||
"format": "prettier \"**/*\" --ignore-unknown", | ||
"format:write": "pnpm format --write", | ||
"lint": "eslint . --max-warnings 0 --report-unused-disable-directives", | ||
"lint": "eslint . .*js --max-warnings 0 --report-unused-disable-directives", | ||
"lint:knip": "knip", | ||
"lint:md": "markdownlint \"**/*.md\" \".github/**/*.md\" --rules sentences-per-line", | ||
"lint:package": "npmPkgJsonLint .", | ||
"lint:package-json": "npmPkgJsonLint .", | ||
"lint:packages": "pnpm dedupe --check", | ||
@@ -33,3 +35,4 @@ "lint:spelling": "cspell \"**\" \".github/**/*\"", | ||
"should-semantic-release": "should-semantic-release --verbose", | ||
"test": "vitest" | ||
"test": "vitest", | ||
"tsc": "tsc" | ||
}, | ||
@@ -40,47 +43,54 @@ "lint-staged": { | ||
"dependencies": { | ||
"conventional-commits-parser": "^4.0.0", | ||
"co-author-to-username": "^0.1.0", | ||
"commit-to-co-authors": "^0.1.0", | ||
"conventional-commits-parser": "^5.0.0", | ||
"octokit": "^3.0.0" | ||
}, | ||
"devDependencies": { | ||
"@release-it/conventional-changelog": "^8.0.0", | ||
"@types/conventional-commits-parser": "^3.0.3", | ||
"@types/eslint": "^8.21.1", | ||
"@typescript-eslint/eslint-plugin": "^6.0.0", | ||
"@typescript-eslint/parser": "^6.0.0", | ||
"@vitest/coverage-istanbul": "^0.33.0", | ||
"console-fail-test": "^0.2.0", | ||
"cspell": "^6.19.2", | ||
"eslint": "^8.32.0", | ||
"eslint-config-prettier": "^9.0.0", | ||
"eslint-plugin-deprecation": "^1.3.3", | ||
"@types/eslint": "^8.44.3", | ||
"@typescript-eslint/eslint-plugin": "^6.7.3", | ||
"@typescript-eslint/parser": "^6.7.3", | ||
"@vitest/coverage-v8": "^0.34.6", | ||
"console-fail-test": "^0.2.3", | ||
"cspell": "^8.0.0", | ||
"eslint": "^8.50.0", | ||
"eslint-plugin-deprecation": "^2.0.0", | ||
"eslint-plugin-eslint-comments": "^3.2.0", | ||
"eslint-plugin-import": "^2.27.5", | ||
"eslint-plugin-jsonc": "^2.6.0", | ||
"eslint-plugin-markdown": "^3.0.0", | ||
"eslint-plugin-jsdoc": "^46.8.2", | ||
"eslint-plugin-jsonc": "^2.9.0", | ||
"eslint-plugin-markdown": "^3.0.1", | ||
"eslint-plugin-n": "^16.1.0", | ||
"eslint-plugin-no-only-tests": "^3.1.0", | ||
"eslint-plugin-regexp": "^1.12.0", | ||
"eslint-plugin-simple-import-sort": "^10.0.0", | ||
"eslint-plugin-typescript-sort-keys": "^2.1.0", | ||
"eslint-plugin-vitest": "^0.2.0", | ||
"eslint-plugin-yml": "^1.5.0", | ||
"eslint-plugin-perfectionist": "^2.1.0", | ||
"eslint-plugin-regexp": "^2.0.0", | ||
"eslint-plugin-vitest": "^0.3.1", | ||
"eslint-plugin-yml": "^1.9.0", | ||
"husky": "^8.0.3", | ||
"jsonc-eslint-parser": "^2.1.0", | ||
"knip": "2.19.7", | ||
"lint-staged": "^13.1.0", | ||
"markdownlint": "^0.30.0", | ||
"markdownlint-cli": "^0.35.0", | ||
"npm-package-json-lint": "^6.4.0", | ||
"jsonc-eslint-parser": "^2.3.0", | ||
"knip": "2.42.0", | ||
"lint-staged": "^15.0.0", | ||
"markdownlint": "^0.32.0", | ||
"markdownlint-cli": "^0.37.0", | ||
"npm-package-json-lint": "^7.0.0", | ||
"npm-package-json-lint-config-default": "^6.0.0", | ||
"prettier": "^2.8.3", | ||
"prettier-plugin-packagejson": "^2.4.2", | ||
"release-it": "^15.6.0", | ||
"prettier": "^3.0.3", | ||
"prettier-plugin-curly": "^0.1.3", | ||
"prettier-plugin-packagejson": "^2.4.6", | ||
"release-it": "^17.0.0", | ||
"sentences-per-line": "^0.2.1", | ||
"should-semantic-release": "^0.1.0", | ||
"typescript": "^5.0.0", | ||
"vitest": "^0.29.0", | ||
"yaml-eslint-parser": "^1.2.0" | ||
"should-semantic-release": "^0.2.1", | ||
"tsup": "^8.0.0", | ||
"typescript": "^5.2.2", | ||
"vitest": "^0.34.6", | ||
"yaml-eslint-parser": "^1.2.2" | ||
}, | ||
"packageManager": "pnpm@8.6.12", | ||
"packageManager": "pnpm@8.10.5", | ||
"engines": { | ||
"node": ">=18" | ||
}, | ||
"publishConfig": { | ||
"provenance": true | ||
} | ||
} |
<h1 align="center">All Contributors For Repository</h1> | ||
<p align="center">Generates an allcontributors list for an existing repository.</p> | ||
<p align="center">Generates an allcontributors list for an existing repository. 🤝</p> | ||
@@ -12,5 +12,5 @@ <p align="center"> | ||
<!-- prettier-ignore-end --> | ||
</a> | ||
</a> | ||
<a href="https://codecov.io/gh/JoshuaKGoldberg/all-contributors-for-repository" target="_blank"> | ||
<img alt="Codecov Test Coverage" src="https://codecov.io/gh/JoshuaKGoldberg/all-contributors-for-repository/branch/main/graph/badge.svg?token=eVIFY4MhfQ"/> | ||
<img alt="Codecov Test Coverage" src="https://codecov.io/gh/JoshuaKGoldberg/all-contributors-for-repository/branch/main/graph/badge.svg"/> | ||
</a> | ||
@@ -21,9 +21,11 @@ <a href="https://github.com/JoshuaKGoldberg/all-contributors-for-repository/blob/main/.github/CODE_OF_CONDUCT.md" target="_blank"> | ||
<a href="https://github.com/JoshuaKGoldberg/all-contributors-for-repository/blob/main/LICENSE.md" target="_blank"> | ||
<img alt="License: MIT" src="https://img.shields.io/github/license/JoshuaKGoldberg/all-contributors-for-repository?color=21bb42"> | ||
</a> | ||
<img alt="License: MIT" src="https://img.shields.io/github/license/JoshuaKGoldberg/all-contributors-for-repository?color=21bb42"> | ||
</a> | ||
<a href="https://github.com/sponsors/JoshuaKGoldberg" target="_blank"> | ||
<img alt="Sponsor: On GitHub" src="https://img.shields.io/badge/sponsor-on_github-21bb42.svg" /> | ||
</a> | ||
<img alt="Sponsor: On GitHub" src="https://img.shields.io/badge/sponsor-on_github-21bb42.svg" /> | ||
</a> | ||
<img alt="Style: Prettier" src="https://img.shields.io/badge/style-prettier-21bb42.svg" /> | ||
<img alt="TypeScript: Strict" src="https://img.shields.io/badge/typescript-strict-21bb42.svg" /> | ||
<img alt="TypeScript: Strict" src="https://img.shields.io/badge/typescript-strict-21bb42.svg" /> | ||
<img alt="npm package version" src="https://img.shields.io/npm/v/all-contributors-for-repository?color=21bb42" /> | ||
<img alt="Sponsor: On GitHub" src="https://img.shields.io/badge/sponsor-on_github-21bb42.svg" /> | ||
</p> | ||
@@ -50,2 +52,3 @@ | ||
}); | ||
/* | ||
@@ -57,2 +60,3 @@ { | ||
*/ | ||
console.log(contributors); | ||
``` | ||
@@ -107,3 +111,3 @@ | ||
```js | ||
```ts | ||
import { getAllContributorsForRepository } from "all-contributors-for-repository"; | ||
@@ -135,3 +139,3 @@ | ||
<tr> | ||
<td align="center" valign="top" width="14.28%"><a href="http://www.joshuakgoldberg.com"><img src="https://avatars.githubusercontent.com/u/3335181?v=4?s=100" width="100px;" alt="Josh Goldberg"/><br /><sub><b>Josh Goldberg</b></sub></a><br /><a href="#tool-JoshuaKGoldberg" title="Tools">🔧</a> <a href="https://github.com/JoshuaKGoldberg/all-contributors-for-repository/issues?q=author%3AJoshuaKGoldberg" title="Bug reports">🐛</a> <a href="https://github.com/JoshuaKGoldberg/all-contributors-for-repository/commits?author=JoshuaKGoldberg" title="Code">💻</a> <a href="#maintenance-JoshuaKGoldberg" title="Maintenance">🚧</a> <a href="https://github.com/JoshuaKGoldberg/all-contributors-for-repository/pulls?q=is%3Apr+reviewed-by%3AJoshuaKGoldberg" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/JoshuaKGoldberg/all-contributors-for-repository/commits?author=JoshuaKGoldberg" title="Documentation">📖</a></td> | ||
<td align="center" valign="top" width="14.28%"><a href="http://www.joshuakgoldberg.com"><img src="https://avatars.githubusercontent.com/u/3335181?v=4?s=100" width="100px;" alt="Josh Goldberg"/><br /><sub><b>Josh Goldberg</b></sub></a><br /><a href="#tool-JoshuaKGoldberg" title="Tools">🔧</a> <a href="https://github.com/JoshuaKGoldberg/all-contributors-for-repository/issues?q=author%3AJoshuaKGoldberg" title="Bug reports">🐛</a> <a href="https://github.com/JoshuaKGoldberg/all-contributors-for-repository/commits?author=JoshuaKGoldberg" title="Code">💻</a> <a href="#maintenance-JoshuaKGoldberg" title="Maintenance">🚧</a> <a href="https://github.com/JoshuaKGoldberg/all-contributors-for-repository/pulls?q=is%3Apr+reviewed-by%3AJoshuaKGoldberg" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/JoshuaKGoldberg/all-contributors-for-repository/commits?author=JoshuaKGoldberg" title="Documentation">📖</a> <a href="#infra-JoshuaKGoldberg" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td> | ||
</tr> | ||
@@ -147,4 +151,2 @@ </tbody> | ||
<!-- You can remove this notice if you don't want it 🙂 no worries! --> | ||
> 💙 This package is based on [@JoshuaKGoldberg](https://github.com/JoshuaKGoldberg)'s [template-typescript-node-package](https://github.com/JoshuaKGoldberg/template-typescript-node-package). | ||
> 💙 This package is based on [@JoshuaKGoldberg](https://github.com/JoshuaKGoldberg)'s [create-typescript-app](https://github.com/JoshuaKGoldberg/create-typescript-app). |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
146
135992
4
38
45
2803
+ Addedco-author-to-username@^0.1.0
+ Addedcommit-to-co-authors@^0.1.0
+ Added@octokit/app@15.1.2(transitive)
+ Added@octokit/auth-app@7.1.4(transitive)
+ Added@octokit/auth-oauth-app@8.1.2(transitive)
+ Added@octokit/auth-oauth-device@7.1.2(transitive)
+ Added@octokit/auth-oauth-user@5.1.2(transitive)
+ Added@octokit/auth-token@5.1.1(transitive)
+ Added@octokit/auth-unauthenticated@6.1.1(transitive)
+ Added@octokit/core@6.1.3(transitive)
+ Added@octokit/endpoint@10.1.2(transitive)
+ Added@octokit/graphql@8.1.2(transitive)
+ Added@octokit/oauth-app@7.1.5(transitive)
+ Added@octokit/oauth-authorization-url@7.1.1(transitive)
+ Added@octokit/oauth-methods@5.1.3(transitive)
+ Added@octokit/openapi-webhooks-types@8.5.1(transitive)
+ Added@octokit/plugin-paginate-graphql@5.2.4(transitive)
+ Added@octokit/plugin-paginate-rest@11.4.0(transitive)
+ Added@octokit/plugin-rest-endpoint-methods@13.3.0(transitive)
+ Added@octokit/plugin-retry@7.1.3(transitive)
+ Added@octokit/plugin-throttling@9.4.0(transitive)
+ Added@octokit/request@9.2.0(transitive)
+ Added@octokit/request-error@6.1.6(transitive)
+ Added@octokit/webhooks@13.4.2(transitive)
+ Added@octokit/webhooks-methods@5.1.0(transitive)
+ Addedbefore-after-hook@3.0.2(transitive)
+ Addedcached-factory@0.0.2(transitive)
+ Addedco-author-to-username@0.1.1(transitive)
+ Addedcommit-to-co-authors@0.1.0(transitive)
+ Addedconventional-commits-parser@5.0.0(transitive)
+ Addedfast-content-type-parse@2.0.1(transitive)
+ Addedis-text-path@2.0.0(transitive)
+ Addedmeow@12.1.1(transitive)
+ Addedoctokit@4.1.0(transitive)
+ Addedsplit2@4.2.0(transitive)
+ Addedtext-extensions@2.4.0(transitive)
+ Addedtoad-cache@3.7.0(transitive)
+ Addeduniversal-github-app-jwt@2.2.0(transitive)
+ Addeduniversal-user-agent@7.0.2(transitive)
- Removed@babel/code-frame@7.26.2(transitive)
- Removed@babel/helper-validator-identifier@7.25.9(transitive)
- Removed@types/minimist@1.2.5(transitive)
- Removed@types/normalize-package-data@2.4.4(transitive)
- Removedarrify@1.0.1(transitive)
- Removedcamelcase@5.3.1(transitive)
- Removedcamelcase-keys@6.2.2(transitive)
- Removedconventional-commits-parser@4.0.0(transitive)
- Removeddecamelize@1.2.0(transitive)
- Removeddecamelize-keys@1.1.1(transitive)
- Removederror-ex@1.3.2(transitive)
- Removedfind-up@4.1.0(transitive)
- Removedfunction-bind@1.1.2(transitive)
- Removedhard-rejection@2.1.0(transitive)
- Removedhasown@2.0.2(transitive)
- Removedhosted-git-info@2.8.94.1.0(transitive)
- Removedinherits@2.0.4(transitive)
- Removedis-arrayish@0.2.1(transitive)
- Removedis-core-module@2.16.1(transitive)
- Removedis-plain-obj@1.1.0(transitive)
- Removedis-text-path@1.0.1(transitive)
- Removedjs-tokens@4.0.0(transitive)
- Removedjson-parse-even-better-errors@2.3.1(transitive)
- Removedkind-of@6.0.3(transitive)
- Removedlines-and-columns@1.2.4(transitive)
- Removedlocate-path@5.0.0(transitive)
- Removedlru-cache@6.0.0(transitive)
- Removedmap-obj@1.0.14.3.0(transitive)
- Removedmeow@8.1.2(transitive)
- Removedmin-indent@1.0.1(transitive)
- Removedminimist-options@4.1.0(transitive)
- Removednormalize-package-data@2.5.03.0.3(transitive)
- Removedp-limit@2.3.0(transitive)
- Removedp-locate@4.1.0(transitive)
- Removedp-try@2.2.0(transitive)
- Removedparse-json@5.2.0(transitive)
- Removedpath-exists@4.0.0(transitive)
- Removedpath-parse@1.0.7(transitive)
- Removedpicocolors@1.1.1(transitive)
- Removedquick-lru@4.0.1(transitive)
- Removedread-pkg@5.2.0(transitive)
- Removedread-pkg-up@7.0.1(transitive)
- Removedreadable-stream@3.6.2(transitive)
- Removedredent@3.0.0(transitive)
- Removedresolve@1.22.10(transitive)
- Removedsemver@5.7.2(transitive)
- Removedspdx-correct@3.2.0(transitive)
- Removedspdx-exceptions@2.5.0(transitive)
- Removedspdx-expression-parse@3.0.1(transitive)
- Removedspdx-license-ids@3.0.21(transitive)
- Removedsplit2@3.2.2(transitive)
- Removedstring_decoder@1.3.0(transitive)
- Removedstrip-indent@3.0.0(transitive)
- Removedsupports-preserve-symlinks-flag@1.0.0(transitive)
- Removedtext-extensions@1.9.0(transitive)
- Removedtrim-newlines@3.0.1(transitive)
- Removedtype-fest@0.18.10.6.00.8.1(transitive)
- Removedutil-deprecate@1.0.2(transitive)
- Removedvalidate-npm-package-license@3.0.4(transitive)
- Removedyallist@4.0.0(transitive)
- Removedyargs-parser@20.2.9(transitive)