diff --git a/src/base.ts b/src/base.ts index 862250901..0ee339563 100644 --- a/src/base.ts +++ b/src/base.ts @@ -206,6 +206,7 @@ export const base = createBase({ getEmailFromCodeOfConduct, getEmailFromGit, getEmailFromNpm, + getPackageAuthor, ), ); diff --git a/src/options/readAuthor.test.ts b/src/options/readAuthor.test.ts index f7bab09db..af1c70f75 100644 --- a/src/options/readAuthor.test.ts +++ b/src/options/readAuthor.test.ts @@ -4,16 +4,16 @@ import { readAuthor } from "./readAuthor.js"; describe(readAuthor, () => { it("returns package author when it exists", async () => { - const author = "test-author"; + const name = "test-author"; const getNpmDefaults = vi.fn(); const actual = await readAuthor( - () => Promise.resolve({ author }), + () => Promise.resolve({ name }), getNpmDefaults, undefined, ); - expect(actual).toBe(author); + expect(actual).toBe(name); expect(getNpmDefaults).not.toHaveBeenCalled(); }); diff --git a/src/options/readAuthor.ts b/src/options/readAuthor.ts index 56fb67f3f..8f44095d9 100644 --- a/src/options/readAuthor.ts +++ b/src/options/readAuthor.ts @@ -1,9 +1,11 @@ +import { PackageAuthor } from "./readPackageAuthor.js"; + export async function readAuthor( - getPackageAuthor: () => Promise<{ author?: string }>, + getPackageAuthor: () => Promise, getNpmDefaults: () => Promise, owner: string | undefined, ) { return ( - (await getPackageAuthor()).author ?? (await getNpmDefaults())?.name ?? owner + (await getPackageAuthor()).name ?? (await getNpmDefaults())?.name ?? owner ); } diff --git a/src/options/readEmailFromNpm.ts b/src/options/readEmailFromNpm.ts index 7f7233688..83f385436 100644 --- a/src/options/readEmailFromNpm.ts +++ b/src/options/readEmailFromNpm.ts @@ -1,8 +1,10 @@ import { UserInfo } from "npm-user"; +import { PackageAuthor } from "./readPackageAuthor.js"; + export async function readEmailFromNpm( getNpmDefaults: () => Promise, - getPackageAuthor: () => Promise<{ email: string | undefined }>, + getPackageAuthor: () => Promise, ) { return (await getNpmDefaults())?.email ?? (await getPackageAuthor()).email; } diff --git a/src/options/readEmails.test.ts b/src/options/readEmails.test.ts index 34b2cdc17..01eff5496 100644 --- a/src/options/readEmails.test.ts +++ b/src/options/readEmails.test.ts @@ -12,6 +12,7 @@ describe(readEmails, () => { () => Promise.resolve(undefined), () => Promise.resolve(undefined), () => Promise.resolve(undefined), + () => Promise.resolve({}), ); expect(actual).toBeUndefined(); @@ -22,6 +23,7 @@ describe(readEmails, () => { () => Promise.resolve(emailCoC), () => Promise.resolve(undefined), () => Promise.resolve(undefined), + () => Promise.resolve({}), ); expect(actual).toEqual({ github: emailCoC, npm: emailCoC }); @@ -32,6 +34,7 @@ describe(readEmails, () => { () => Promise.resolve(undefined), () => Promise.resolve(undefined), () => Promise.resolve(emailNpm), + () => Promise.resolve({}), ); expect(actual).toEqual({ github: emailNpm, npm: emailNpm }); @@ -42,6 +45,7 @@ describe(readEmails, () => { () => Promise.resolve(emailCoC), () => Promise.resolve(undefined), () => Promise.resolve(emailNpm), + () => Promise.resolve({}), ); expect(actual).toEqual({ github: emailCoC, npm: emailNpm }); @@ -52,8 +56,20 @@ describe(readEmails, () => { () => Promise.resolve(undefined), () => Promise.resolve(emailGit), () => Promise.resolve(emailNpm), + () => Promise.resolve({}), ); expect(actual).toEqual({ github: emailGit, npm: emailNpm }); }); + + it("resolves package author email as the github and npm emails when only the package author email exists", async () => { + const actual = await readEmails( + () => Promise.resolve(undefined), + () => Promise.resolve(undefined), + () => Promise.resolve(undefined), + () => Promise.resolve({ email: emailNpm }), + ); + + expect(actual).toEqual({ github: emailNpm, npm: emailNpm }); + }); }); diff --git a/src/options/readEmails.ts b/src/options/readEmails.ts index 9b9e84f91..c074e9951 100644 --- a/src/options/readEmails.ts +++ b/src/options/readEmails.ts @@ -1,11 +1,15 @@ +import { PackageAuthor } from "./readPackageAuthor.js"; + export async function readEmails( getEmailFromCodeOfConduct: () => Promise, getEmailFromGit: () => Promise, getEmailFromNpm: () => Promise, + getPackageAuthor: () => Promise, ) { const github = (await getEmailFromCodeOfConduct()) ?? (await getEmailFromGit()); - const npm = (await getEmailFromNpm()) ?? github; + const npm = + (await getPackageAuthor()).email ?? (await getEmailFromNpm()) ?? github; return npm ? { github: github || npm, npm } : undefined; } diff --git a/src/options/readOwner.test.ts b/src/options/readOwner.test.ts index 1608f101f..a250b2896 100644 --- a/src/options/readOwner.test.ts +++ b/src/options/readOwner.test.ts @@ -7,24 +7,24 @@ describe(readOwner, () => { const take = vi.fn(); const organization = "test-organization"; const getGitDefaults = vi.fn().mockResolvedValueOnce({ organization }); - const getPackageDataFull = vi.fn(); + const getPackageAuthor = vi.fn(); - const actual = await readOwner(take, getGitDefaults, getPackageDataFull); + const actual = await readOwner(take, getGitDefaults, getPackageAuthor); expect(actual).toBe(organization); expect(take).not.toHaveBeenCalled(); - expect(getPackageDataFull).not.toHaveBeenCalled(); + expect(getPackageAuthor).not.toHaveBeenCalled(); }); it("returns package data author when only it exists", async () => { const take = vi.fn(); - const author = "test-author"; + const name = "test-author"; const getGitDefaults = vi.fn(); - const getPackageDataFull = vi.fn().mockResolvedValueOnce({ author }); + const getPackageAuthor = vi.fn().mockResolvedValueOnce({ name }); - const actual = await readOwner(take, getGitDefaults, getPackageDataFull); + const actual = await readOwner(take, getGitDefaults, getPackageAuthor); - expect(actual).toBe(author); + expect(actual).toBe(name); expect(take).not.toHaveBeenCalled(); }); @@ -32,9 +32,9 @@ describe(readOwner, () => { const user = "test-user"; const take = vi.fn().mockResolvedValueOnce({ stdout: user }); const getGitDefaults = vi.fn(); - const getPackageDataFull = vi.fn().mockResolvedValueOnce({}); + const getPackageAuthor = vi.fn().mockResolvedValueOnce({}); - const actual = await readOwner(take, getGitDefaults, getPackageDataFull); + const actual = await readOwner(take, getGitDefaults, getPackageAuthor); expect(actual).toBe(user); }); @@ -42,9 +42,9 @@ describe(readOwner, () => { it("returns undefined when no values exist", async () => { const take = vi.fn().mockResolvedValueOnce({}); const getGitDefaults = vi.fn(); - const getPackageDataFull = vi.fn().mockResolvedValueOnce({}); + const getPackageAuthor = vi.fn().mockResolvedValueOnce({}); - const actual = await readOwner(take, getGitDefaults, getPackageDataFull); + const actual = await readOwner(take, getGitDefaults, getPackageAuthor); expect(actual).toBe(undefined); }); diff --git a/src/options/readOwner.ts b/src/options/readOwner.ts index 66d7c8fd8..c990a72ed 100644 --- a/src/options/readOwner.ts +++ b/src/options/readOwner.ts @@ -2,14 +2,16 @@ import { TakeInput } from "bingo"; import { GitUrl } from "git-url-parse"; import { inputFromScript } from "input-from-script"; +import { PackageAuthor } from "./readPackageAuthor.js"; + export async function readOwner( take: TakeInput, getGitDefaults: () => Promise, - getPackageAuthor: () => Promise<{ author?: string }>, + getPackageAuthor: () => Promise, ) { return ( (await getGitDefaults())?.organization ?? - (await getPackageAuthor()).author ?? + (await getPackageAuthor()).name ?? ( await take(inputFromScript, { command: "gh config get user -h github.com", diff --git a/src/options/readPackageAuthor.test.ts b/src/options/readPackageAuthor.test.ts index d48268c38..7625d0a13 100644 --- a/src/options/readPackageAuthor.test.ts +++ b/src/options/readPackageAuthor.test.ts @@ -5,17 +5,17 @@ import { readPackageAuthor } from "./readPackageAuthor.js"; describe(readPackageAuthor, () => { it.each([ [{}, {}], - [{ author: "abc123" }, { author: "abc123" }], + [{ name: "abc123" }, { author: "abc123" }], [ - { author: "abc123", email: "def@ghi.com" }, + { email: "def@ghi.com", name: "abc123" }, { author: "abc123 " }, ], [ - { author: "abc123", email: "def@ghi.com" }, + { email: "def@ghi.com", name: "abc123" }, { author: "abc123 " }, ], [ - { author: "abc123", email: "def@ghi.com" }, + { email: "def@ghi.com", name: "abc123" }, { author: { email: "def@ghi.com", name: "abc123" } }, ], ])("returns %s when given %s", async (expected, packageDataFull) => { diff --git a/src/options/readPackageAuthor.ts b/src/options/readPackageAuthor.ts index 948d70876..ec1b5a149 100644 --- a/src/options/readPackageAuthor.ts +++ b/src/options/readPackageAuthor.ts @@ -2,24 +2,24 @@ import parse from "parse-author"; import { PartialPackageData } from "../types.js"; +export interface PackageAuthor { + email?: string | undefined; + name?: string | undefined; +} + export async function readPackageAuthor( getPackageDataFull: () => Promise, -) { +): Promise { const packageData = await getPackageDataFull(); - let packageAuthor: string | undefined; - let packageEmail: string | undefined; - if (typeof packageData.author === "string") { - const parsedAuthor = parse(packageData.author); - packageAuthor = parsedAuthor.name; - packageEmail = parsedAuthor.email; - } else if (packageData.author) { - packageAuthor = packageData.author.name; - packageEmail = packageData.author.email; - } + switch (typeof packageData.author) { + case "object": + return packageData.author; - return { - author: packageAuthor, - email: packageEmail, - }; + case "string": + return parse(packageData.author); + + default: + return {}; + } } diff --git a/src/types.ts b/src/types.ts index 8c424447d..ea0349ea1 100644 --- a/src/types.ts +++ b/src/types.ts @@ -11,7 +11,7 @@ export interface AllContributorsData { } export interface PartialPackageData { - author?: string | { email: string; name: string }; + author?: string | { email?: string; name?: string }; bin?: Record | string; dependencies?: Record; description?: string;