Skip to content

Commit 6872f73

Browse files
fix: infer author email from package.json if available
1 parent 9a06364 commit 6872f73

11 files changed

+67
-40
lines changed

Diff for: src/base.ts

+1
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ export const base = createBase({
206206
getEmailFromCodeOfConduct,
207207
getEmailFromGit,
208208
getEmailFromNpm,
209+
getPackageAuthor,
209210
),
210211
);
211212

Diff for: src/options/readAuthor.test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@ import { readAuthor } from "./readAuthor.js";
44

55
describe(readAuthor, () => {
66
it("returns package author when it exists", async () => {
7-
const author = "test-author";
7+
const name = "test-author";
88
const getNpmDefaults = vi.fn();
99

1010
const actual = await readAuthor(
11-
() => Promise.resolve({ author }),
11+
() => Promise.resolve({ name }),
1212
getNpmDefaults,
1313
undefined,
1414
);
1515

16-
expect(actual).toBe(author);
16+
expect(actual).toBe(name);
1717
expect(getNpmDefaults).not.toHaveBeenCalled();
1818
});
1919

Diff for: src/options/readAuthor.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
import { PackageAuthor } from "./readPackageAuthor.js";
2+
13
export async function readAuthor(
2-
getPackageAuthor: () => Promise<{ author?: string }>,
4+
getPackageAuthor: () => Promise<PackageAuthor>,
35
getNpmDefaults: () => Promise<undefined | { name?: string }>,
46
owner: string | undefined,
57
) {
68
return (
7-
(await getPackageAuthor()).author ?? (await getNpmDefaults())?.name ?? owner
9+
(await getPackageAuthor()).name ?? (await getNpmDefaults())?.name ?? owner
810
);
911
}

Diff for: src/options/readEmailFromNpm.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { UserInfo } from "npm-user";
22

3+
import { PackageAuthor } from "./readPackageAuthor.js";
4+
35
export async function readEmailFromNpm(
46
getNpmDefaults: () => Promise<undefined | UserInfo>,
5-
getPackageAuthor: () => Promise<{ email: string | undefined }>,
7+
getPackageAuthor: () => Promise<PackageAuthor>,
68
) {
79
return (await getNpmDefaults())?.email ?? (await getPackageAuthor()).email;
810
}

Diff for: src/options/readEmails.test.ts

+16
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ describe(readEmails, () => {
1212
() => Promise.resolve(undefined),
1313
() => Promise.resolve(undefined),
1414
() => Promise.resolve(undefined),
15+
() => Promise.resolve({}),
1516
);
1617

1718
expect(actual).toBeUndefined();
@@ -22,6 +23,7 @@ describe(readEmails, () => {
2223
() => Promise.resolve(emailCoC),
2324
() => Promise.resolve(undefined),
2425
() => Promise.resolve(undefined),
26+
() => Promise.resolve({}),
2527
);
2628

2729
expect(actual).toEqual({ github: emailCoC, npm: emailCoC });
@@ -32,6 +34,7 @@ describe(readEmails, () => {
3234
() => Promise.resolve(undefined),
3335
() => Promise.resolve(undefined),
3436
() => Promise.resolve(emailNpm),
37+
() => Promise.resolve({}),
3538
);
3639

3740
expect(actual).toEqual({ github: emailNpm, npm: emailNpm });
@@ -42,6 +45,7 @@ describe(readEmails, () => {
4245
() => Promise.resolve(emailCoC),
4346
() => Promise.resolve(undefined),
4447
() => Promise.resolve(emailNpm),
48+
() => Promise.resolve({}),
4549
);
4650

4751
expect(actual).toEqual({ github: emailCoC, npm: emailNpm });
@@ -52,8 +56,20 @@ describe(readEmails, () => {
5256
() => Promise.resolve(undefined),
5357
() => Promise.resolve(emailGit),
5458
() => Promise.resolve(emailNpm),
59+
() => Promise.resolve({}),
5560
);
5661

5762
expect(actual).toEqual({ github: emailGit, npm: emailNpm });
5863
});
64+
65+
it("resolves package author email as the github and npm emails when only the package author email exists", async () => {
66+
const actual = await readEmails(
67+
() => Promise.resolve(undefined),
68+
() => Promise.resolve(undefined),
69+
() => Promise.resolve(undefined),
70+
() => Promise.resolve({ email: emailNpm }),
71+
);
72+
73+
expect(actual).toEqual({ github: emailNpm, npm: emailNpm });
74+
});
5975
});

Diff for: src/options/readEmails.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1+
import { PackageAuthor } from "./readPackageAuthor.js";
2+
13
export async function readEmails(
24
getEmailFromCodeOfConduct: () => Promise<string | undefined>,
35
getEmailFromGit: () => Promise<string | undefined>,
46
getEmailFromNpm: () => Promise<string | undefined>,
7+
getPackageAuthor: () => Promise<PackageAuthor>,
58
) {
69
const github =
710
(await getEmailFromCodeOfConduct()) ?? (await getEmailFromGit());
8-
const npm = (await getEmailFromNpm()) ?? github;
11+
const npm =
12+
(await getPackageAuthor()).email ?? (await getEmailFromNpm()) ?? github;
913

1014
return npm ? { github: github || npm, npm } : undefined;
1115
}

Diff for: src/options/readOwner.test.ts

+11-11
Original file line numberDiff line numberDiff line change
@@ -7,44 +7,44 @@ describe(readOwner, () => {
77
const take = vi.fn();
88
const organization = "test-organization";
99
const getGitDefaults = vi.fn().mockResolvedValueOnce({ organization });
10-
const getPackageDataFull = vi.fn();
10+
const getPackageAuthor = vi.fn();
1111

12-
const actual = await readOwner(take, getGitDefaults, getPackageDataFull);
12+
const actual = await readOwner(take, getGitDefaults, getPackageAuthor);
1313

1414
expect(actual).toBe(organization);
1515
expect(take).not.toHaveBeenCalled();
16-
expect(getPackageDataFull).not.toHaveBeenCalled();
16+
expect(getPackageAuthor).not.toHaveBeenCalled();
1717
});
1818

1919
it("returns package data author when only it exists", async () => {
2020
const take = vi.fn();
21-
const author = "test-author";
21+
const name = "test-author";
2222
const getGitDefaults = vi.fn();
23-
const getPackageDataFull = vi.fn().mockResolvedValueOnce({ author });
23+
const getPackageAuthor = vi.fn().mockResolvedValueOnce({ name });
2424

25-
const actual = await readOwner(take, getGitDefaults, getPackageDataFull);
25+
const actual = await readOwner(take, getGitDefaults, getPackageAuthor);
2626

27-
expect(actual).toBe(author);
27+
expect(actual).toBe(name);
2828
expect(take).not.toHaveBeenCalled();
2929
});
3030

3131
it("returns the gh config value when only it resolves", async () => {
3232
const user = "test-user";
3333
const take = vi.fn().mockResolvedValueOnce({ stdout: user });
3434
const getGitDefaults = vi.fn();
35-
const getPackageDataFull = vi.fn().mockResolvedValueOnce({});
35+
const getPackageAuthor = vi.fn().mockResolvedValueOnce({});
3636

37-
const actual = await readOwner(take, getGitDefaults, getPackageDataFull);
37+
const actual = await readOwner(take, getGitDefaults, getPackageAuthor);
3838

3939
expect(actual).toBe(user);
4040
});
4141

4242
it("returns undefined when no values exist", async () => {
4343
const take = vi.fn().mockResolvedValueOnce({});
4444
const getGitDefaults = vi.fn();
45-
const getPackageDataFull = vi.fn().mockResolvedValueOnce({});
45+
const getPackageAuthor = vi.fn().mockResolvedValueOnce({});
4646

47-
const actual = await readOwner(take, getGitDefaults, getPackageDataFull);
47+
const actual = await readOwner(take, getGitDefaults, getPackageAuthor);
4848

4949
expect(actual).toBe(undefined);
5050
});

Diff for: src/options/readOwner.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ import { TakeInput } from "bingo";
22
import { GitUrl } from "git-url-parse";
33
import { inputFromScript } from "input-from-script";
44

5+
import { PackageAuthor } from "./readPackageAuthor.js";
6+
57
export async function readOwner(
68
take: TakeInput,
79
getGitDefaults: () => Promise<GitUrl | undefined>,
8-
getPackageAuthor: () => Promise<{ author?: string }>,
10+
getPackageAuthor: () => Promise<PackageAuthor>,
911
) {
1012
return (
1113
(await getGitDefaults())?.organization ??
12-
(await getPackageAuthor()).author ??
14+
(await getPackageAuthor()).name ??
1315
(
1416
await take(inputFromScript, {
1517
command: "gh config get user -h github.com",

Diff for: src/options/readPackageAuthor.test.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@ import { readPackageAuthor } from "./readPackageAuthor.js";
55
describe(readPackageAuthor, () => {
66
it.each([
77
[{}, {}],
8-
[{ author: "abc123" }, { author: "abc123" }],
8+
[{ name: "abc123" }, { author: "abc123" }],
99
[
10-
{ author: "abc123", email: "[email protected]" },
10+
{ email: "[email protected]", name: "abc123" },
1111
{ author: "abc123 <[email protected]>" },
1212
],
1313
[
14-
{ author: "abc123", email: "[email protected]" },
14+
{ email: "[email protected]", name: "abc123" },
1515
{ author: "abc123 <[email protected]>" },
1616
],
1717
[
18-
{ author: "abc123", email: "[email protected]" },
18+
{ email: "[email protected]", name: "abc123" },
1919
{ author: { email: "[email protected]", name: "abc123" } },
2020
],
2121
])("returns %s when given %s", async (expected, packageDataFull) => {

Diff for: src/options/readPackageAuthor.ts

+15-15
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,24 @@ import parse from "parse-author";
22

33
import { PartialPackageData } from "../types.js";
44

5+
export interface PackageAuthor {
6+
email?: string | undefined;
7+
name?: string | undefined;
8+
}
9+
510
export async function readPackageAuthor(
611
getPackageDataFull: () => Promise<PartialPackageData>,
7-
) {
12+
): Promise<PackageAuthor> {
813
const packageData = await getPackageDataFull();
9-
let packageAuthor: string | undefined;
10-
let packageEmail: string | undefined;
1114

12-
if (typeof packageData.author === "string") {
13-
const parsedAuthor = parse(packageData.author);
14-
packageAuthor = parsedAuthor.name;
15-
packageEmail = parsedAuthor.email;
16-
} else if (packageData.author) {
17-
packageAuthor = packageData.author.name;
18-
packageEmail = packageData.author.email;
19-
}
15+
switch (typeof packageData.author) {
16+
case "object":
17+
return packageData.author;
2018

21-
return {
22-
author: packageAuthor,
23-
email: packageEmail,
24-
};
19+
case "string":
20+
return parse(packageData.author);
21+
22+
default:
23+
return {};
24+
}
2525
}

Diff for: src/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export interface AllContributorsData {
1111
}
1212

1313
export interface PartialPackageData {
14-
author?: string | { email: string; name: string };
14+
author?: string | { email?: string; name?: string };
1515
bin?: Record<string, string> | string;
1616
dependencies?: Record<string, string>;
1717
description?: string;

0 commit comments

Comments
 (0)