diff --git a/.release-it.json b/.release-it.json index 4d6dedffd..2b95facce 100644 --- a/.release-it.json +++ b/.release-it.json @@ -8,7 +8,7 @@ "release": true, "releaseName": "v${version}" }, - "npm": { "publishArgs": ["--provenance"] }, + "npm": { "publishArgs": ["--access public", "--provenance"] }, "plugins": { "@release-it/conventional-changelog": { "infile": "CHANGELOG.md", diff --git a/docs/Options.md b/docs/Options.md index 02f936073..1f4408fc5 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -49,6 +49,7 @@ That script will run completely autonomously, no prompted inputs required. ✨ The setup scripts also allow for optional overrides of the following inputs whose defaults are based on other options: +- `--access` _(`"public" | "restricted`)_: Which [`npm publish --access`](https://docs.npmjs.com/cli/commands/npm-publish#access) to release npm packages with (by default, `"public"`) - `--author` _(`string`)_: Username on npm to publish packages under (by default, an existing npm author, or the currently logged in npm user, or `owner.toLowerCase()`) - `--email` _(`string`)_: Email address to be listed as the point of contact in docs and packages (e.g. `example@joshuakgoldberg.com`) - Optionally, `--email-github` _(`string`)_ and/or `--email-npm` _(`string`)_ may be provided to use different emails in `.md` files and `package.json`, respectively diff --git a/src/create/createRerunSuggestion.test.ts b/src/create/createRerunSuggestion.test.ts index 60a0c9f73..4ae61e24d 100644 --- a/src/create/createRerunSuggestion.test.ts +++ b/src/create/createRerunSuggestion.test.ts @@ -4,6 +4,7 @@ import { Options } from "../shared/types.js"; import { createRerunSuggestion } from "./createRerunSuggestion.js"; const options = { + access: "public", author: "TestAuthor", base: "everything", createRepository: true, @@ -43,7 +44,7 @@ describe("createRerunSuggestion", () => { const actual = createRerunSuggestion("initialize", options); expect(actual).toMatchInlineSnapshot( - '"npx create-typescript-app --mode initialize --base everything --author TestAuthor --create-repository true --description \\"Test description.\\" --email-github github@email.com --email-npm npm@email.com --exclude-compliance true --exclude-contributors true --exclude-lint-jsdoc true --exclude-lint-json true --exclude-lint-knip true --exclude-lint-package-json true --exclude-lint-perfectionist true --owner TestOwner --repository test-repository --skip-github-api true --skip-install true --skip-removal true --title \\"Test Title\\""', + '"npx create-typescript-app --mode initialize --base everything --access public --author TestAuthor --create-repository true --description \\"Test description.\\" --email-github github@email.com --email-npm npm@email.com --exclude-compliance true --exclude-contributors true --exclude-lint-jsdoc true --exclude-lint-json true --exclude-lint-knip true --exclude-lint-package-json true --exclude-lint-perfectionist true --owner TestOwner --repository test-repository --skip-github-api true --skip-install true --skip-removal true --title \\"Test Title\\""', ); }); @@ -57,7 +58,7 @@ describe("createRerunSuggestion", () => { }); expect(actual).toMatchInlineSnapshot( - '"npx create-typescript-app --mode initialize --base everything --author TestAuthor --create-repository true --description \\"Test description.\\" --email-github github@email.com --email-npm npm@email.com --exclude-compliance true --exclude-contributors true --exclude-lint-jsdoc true --exclude-lint-json true --exclude-lint-knip true --exclude-lint-package-json true --exclude-lint-perfectionist true --logo test/src.png --logo-alt \\"Test alt.\\" --owner TestOwner --repository test-repository --skip-github-api true --skip-install true --skip-removal true --title \\"Test Title\\""', + '"npx create-typescript-app --mode initialize --base everything --access public --author TestAuthor --create-repository true --description \\"Test description.\\" --email-github github@email.com --email-npm npm@email.com --exclude-compliance true --exclude-contributors true --exclude-lint-jsdoc true --exclude-lint-json true --exclude-lint-knip true --exclude-lint-package-json true --exclude-lint-perfectionist true --logo test/src.png --logo-alt \\"Test alt.\\" --owner TestOwner --repository test-repository --skip-github-api true --skip-install true --skip-removal true --title \\"Test Title\\""', ); }); @@ -70,7 +71,7 @@ describe("createRerunSuggestion", () => { }); expect(actual).toMatchInlineSnapshot( - '"npx create-typescript-app --mode initialize --base everything --author TestAuthor --create-repository true --description \\"Test description.\\" --email-github github@email.com --email-npm npm@email.com --exclude-compliance true --exclude-contributors true --exclude-lint-jsdoc true --exclude-lint-json true --exclude-lint-knip true --exclude-lint-md true --exclude-lint-package-json true --exclude-lint-perfectionist true --exclude-lint-spelling true --owner TestOwner --repository test-repository --skip-github-api true --skip-install true --skip-removal true --title \\"Test Title\\""', + '"npx create-typescript-app --mode initialize --base everything --access public --author TestAuthor --create-repository true --description \\"Test description.\\" --email-github github@email.com --email-npm npm@email.com --exclude-compliance true --exclude-contributors true --exclude-lint-jsdoc true --exclude-lint-json true --exclude-lint-knip true --exclude-lint-md true --exclude-lint-package-json true --exclude-lint-perfectionist true --exclude-lint-spelling true --owner TestOwner --repository test-repository --skip-github-api true --skip-install true --skip-removal true --title \\"Test Title\\""', ); }); }); diff --git a/src/shared/options/args.ts b/src/shared/options/args.ts index dc37bbd6e..3a9d05de4 100644 --- a/src/shared/options/args.ts +++ b/src/shared/options/args.ts @@ -1,4 +1,5 @@ export const allArgOptions = { + access: { type: "string" }, author: { type: "string" }, base: { type: "string" }, "create-repository": { type: "boolean" }, diff --git a/src/shared/options/augmentOptionsWithExcludes.test.ts b/src/shared/options/augmentOptionsWithExcludes.test.ts index 954400de7..fcad32346 100644 --- a/src/shared/options/augmentOptionsWithExcludes.test.ts +++ b/src/shared/options/augmentOptionsWithExcludes.test.ts @@ -4,6 +4,7 @@ import { Options } from "../types.js"; import { augmentOptionsWithExcludes } from "./augmentOptionsWithExcludes.js"; const optionsBase = { + access: "public", author: undefined, base: undefined, createRepository: undefined, @@ -41,7 +42,7 @@ const optionsBase = { skipRestore: undefined, skipUninstall: undefined, title: "", -}; +} satisfies Options; describe("augmentOptionsWithExcludes", () => { it("returns options without exclusions and skips prompting when exclusions are provided manually", async () => { diff --git a/src/shared/options/augmentOptionsWithExcludes.ts b/src/shared/options/augmentOptionsWithExcludes.ts index 518652d4b..2e1c423a9 100644 --- a/src/shared/options/augmentOptionsWithExcludes.ts +++ b/src/shared/options/augmentOptionsWithExcludes.ts @@ -2,7 +2,7 @@ import * as prompts from "@clack/prompts"; import chalk from "chalk"; import { filterPromptCancel } from "../prompts.js"; -import { InputBase, Options } from "../types.js"; +import { Options, OptionsBase } from "../types.js"; interface ExclusionDescription { hint: string; @@ -134,9 +134,9 @@ export async function augmentOptionsWithExcludes( const base = options.base ?? - filterPromptCancel( + filterPromptCancel( await prompts.select({ - initialValue: "common" as InputBase, + initialValue: "common" as OptionsBase, message: `How much tooling would you like the template to set up for you?`, options: [ { diff --git a/src/shared/options/optionsSchema.ts b/src/shared/options/optionsSchema.ts index e30105cec..02807b75e 100644 --- a/src/shared/options/optionsSchema.ts +++ b/src/shared/options/optionsSchema.ts @@ -1,6 +1,7 @@ import { z } from "zod"; export const optionsSchemaShape = { + access: z.union([z.literal("public"), z.literal("restricted")]).optional(), author: z.string().optional(), base: z .union([ diff --git a/src/shared/options/readOptions.test.ts b/src/shared/options/readOptions.test.ts index a7e17803b..b00476ca7 100644 --- a/src/shared/options/readOptions.test.ts +++ b/src/shared/options/readOptions.test.ts @@ -5,6 +5,7 @@ import { optionsSchemaShape } from "./optionsSchema.js"; import { readOptions } from "./readOptions.js"; const emptyOptions = { + access: undefined, author: undefined, base: undefined, createRepository: undefined, diff --git a/src/shared/options/readOptions.ts b/src/shared/options/readOptions.ts index a220565f5..877d77e81 100644 --- a/src/shared/options/readOptions.ts +++ b/src/shared/options/readOptions.ts @@ -40,6 +40,7 @@ export async function readOptions(args: string[]): Promise { }); const mappedOptions = { + access: values.access, author: values.author, base: values.base, createRepository: values["create-repository"], @@ -186,6 +187,7 @@ export async function readOptions(args: string[]): Promise { const augmentedOptions = await augmentOptionsWithExcludes({ ...options, + access: options.access ?? "public", author: options.author ?? (await defaults.owner()), description: options.description, email: typeof email === "string" ? { github: email, npm: email } : email, diff --git a/src/shared/types.ts b/src/shared/types.ts index b147d06e7..dc550aca3 100644 --- a/src/shared/types.ts +++ b/src/shared/types.ts @@ -17,21 +17,24 @@ export interface PartialPackageData { repository?: { type: string; url: string } | string; } -export type InputBase = "common" | "everything" | "minimum" | "prompt"; +export type OptionsAccess = "public" | "restricted"; -export interface OptionsLogo { - alt: string; - src: string; -} +export type OptionsBase = "common" | "everything" | "minimum" | "prompt"; export interface OptionsEmail { github: string; npm: string; } +export interface OptionsLogo { + alt: string; + src: string; +} + export interface Options { + access: OptionsAccess; author?: string; - base?: InputBase; + base?: OptionsBase; createRepository?: boolean; description: string; email: OptionsEmail; diff --git a/src/steps/finalizeDependencies.test.ts b/src/steps/finalizeDependencies.test.ts index cbc748c5e..bb1aebc7d 100644 --- a/src/steps/finalizeDependencies.test.ts +++ b/src/steps/finalizeDependencies.test.ts @@ -17,6 +17,7 @@ vi.mock("../shared/packages.js", () => ({ })); const options = { + access: "public", author: undefined, base: "everything", createRepository: undefined, diff --git a/src/steps/updateLocalFiles.test.ts b/src/steps/updateLocalFiles.test.ts index 3f6fb9a33..453599734 100644 --- a/src/steps/updateLocalFiles.test.ts +++ b/src/steps/updateLocalFiles.test.ts @@ -20,6 +20,7 @@ vi.mock("../shared/readFileSafeAsJson.js", () => ({ })); const options = { + access: "public", author: undefined, base: "everything", createRepository: undefined, diff --git a/src/steps/writeReadme/generateTopContent.test.ts b/src/steps/writeReadme/generateTopContent.test.ts index 2cbe8feb8..e654015aa 100644 --- a/src/steps/writeReadme/generateTopContent.test.ts +++ b/src/steps/writeReadme/generateTopContent.test.ts @@ -1,8 +1,10 @@ import { describe, expect, it } from "vitest"; +import { Options } from "../../shared/types.js"; import { generateTopContent } from "./generateTopContent.js"; const optionsBase = { + access: "public", author: undefined, base: undefined, createRepository: undefined, @@ -34,7 +36,7 @@ const optionsBase = { skipRestore: undefined, skipUninstall: undefined, title: "", -}; +} satisfies Options; describe("findExistingBadges", () => { it("generates full contents when there are no existing badges", () => { diff --git a/src/steps/writeReadme/index.test.ts b/src/steps/writeReadme/index.test.ts index 97cec2323..4c3646bf3 100644 --- a/src/steps/writeReadme/index.test.ts +++ b/src/steps/writeReadme/index.test.ts @@ -24,6 +24,7 @@ vi.mock("../../shared/readFileSafe.js", () => ({ })); const options = { + access: "public", author: "Test Author", base: "everything", createRepository: false, diff --git a/src/steps/writing/creation/createESLintRC.test.ts b/src/steps/writing/creation/createESLintRC.test.ts index 1856697ce..7c4d7e52d 100644 --- a/src/steps/writing/creation/createESLintRC.test.ts +++ b/src/steps/writing/creation/createESLintRC.test.ts @@ -5,6 +5,7 @@ import { createESLintRC } from "./createESLintRC.js"; function fakeOptions(getExcludeValue: (exclusionName: string) => boolean) { return { + access: "public", author: "TestAuthor", base: "everything", createRepository: true, diff --git a/src/steps/writing/creation/dotGitHub/createDevelopment.test.ts b/src/steps/writing/creation/dotGitHub/createDevelopment.test.ts index 9a12976e7..80163acc9 100644 --- a/src/steps/writing/creation/dotGitHub/createDevelopment.test.ts +++ b/src/steps/writing/creation/dotGitHub/createDevelopment.test.ts @@ -4,6 +4,7 @@ import { Options } from "../../../../shared/types.js"; import { createDevelopment } from "./createDevelopment.js"; const options = { + access: "public", author: "Test Author", base: "everything", createRepository: false, diff --git a/src/steps/writing/creation/rootFiles.ts b/src/steps/writing/creation/rootFiles.ts index 7caef4196..719151bb3 100644 --- a/src/steps/writing/creation/rootFiles.ts +++ b/src/steps/writing/creation/rootFiles.ts @@ -80,7 +80,7 @@ export async function createRootFiles(options: Options) { releaseName: "v${version}", }, npm: { - publishArgs: ["--provenance"], + publishArgs: [`--access ${options.access}`, "--provenance"], }, plugins: { "@release-it/conventional-changelog": { diff --git a/src/steps/writing/creation/writePackageJson.test.ts b/src/steps/writing/creation/writePackageJson.test.ts index fa9253d5f..90b83eed8 100644 --- a/src/steps/writing/creation/writePackageJson.test.ts +++ b/src/steps/writing/creation/writePackageJson.test.ts @@ -12,6 +12,7 @@ vi.mock("../../../shared/readFileSafeAsJson.js", () => ({ })); const options = { + access: "public", author: "test-author", base: "everything", createRepository: undefined,