diff --git a/.github/DEVELOPMENT.md b/.github/DEVELOPMENT.md
index d403f3860..73b761251 100644
--- a/.github/DEVELOPMENT.md
+++ b/.github/DEVELOPMENT.md
@@ -104,166 +104,3 @@ Add `--watch` to keep the type checker running in a watch mode that updates the
```shell
pnpm tsc --watch
```
-
-## Setup Scripts
-
-As described in the `README.md` file and `docs/`, this template repository comes with three scripts that can set up an existing or new repository.
-
-Each follows roughly the same general flow:
-
-1. `bin/index.ts` uses `bin/mode.ts` to determine which of the three setup scripts to run
-2. `readOptions` parses in options from local files, Git commands, npm APIs, and/or files on disk
-3. `runOrRestore` wraps the setup script's main logic in a friendly prompt wrapper
-4. The setup script wraps each portion of its main logic with `withSpinner`
- - Each step of setup logic is generally imported from within `src/steps`
-5. A call to `outro` summarizes the results for the user
-
-> **Warning**
-> Each setup script overrides many files in the directory they're run in.
-> Make sure to save any changes you want to preserve before running them.
-
-### The Creation Script
-
-> 📝 See [`docs/Creation.md`](../docs/Creation.md) for user documentation on the creation script.
-
-This template's "creation" script is located in `src/create/`.
-You can run it locally with `node bin/index.js --mode create`.
-Note that files need to be built with `pnpm run build` beforehand.
-
-#### Testing the Creation Script
-
-You can run the end-to-end test for creation locally on the command-line.
-Note that the files need to be built with `pnpm run build` beforehand.
-
-```shell
-pnpm run test:create
-```
-
-That end-to-end test executes `script/create-test-e2e.ts`, which:
-
-1. Runs the creation script to create a new `test-repository` child directory and repository, capturing code coverage
-2. Asserts that commands such as `build` and `lint` each pass
-
-The `pnpm run test:create` script is run in CI to ensure that templating changes are in sync with the template's actual files.
-See `.github/workflows/ci.yml`'s `test_creation_script` job.
-
-### The Initialization Script
-
-> 📝 See [`docs/Initialization.md`](../docs/Initialization.md) for user documentation on the initialization script.
-
-This template's "initialization" script is located in `src/initialize/`.
-You can run it locally with `pnpm run initialize`.
-It uses [`tsx`](https://github.com/esbuild-kit/tsx) so you don't need to build files before running.
-
-```shell
-pnpm run initialize
-```
-
-#### Testing the Initialization Script
-
-You can run the end-to-end test for initializing locally on the command-line.
-Note that files need to be built with `pnpm run build` beforehand.
-
-```shell
-pnpm run test:initialize
-```
-
-That end-to-end test executes `script/initialize-test-e2e.ts`, which:
-
-1. Runs the initialization script using `--skip-github-api` and other skip flags
-2. Checks that the local repository's files were changed correctly (e.g. removed initialization-only files)
-3. Runs `pnpm run lint:knip` to make sure no excess dependencies or files were left over
-4. Resets everything
-5. Runs initialization a second time, capturing test coverage
-
-The `pnpm run test:initialize` script is run in CI to ensure that templating changes are in sync with the template's actual files.
-See `.github/workflows/ci.yml`'s `test_initialization_script` job.
-
-### The Migration Script
-
-> 📝 See [`docs/Migration.md`](../docs/Migration.md) for user documentation on the migration script.
-
-This template's "migration" script is located in `src/migrate/`.
-Note that files need to be built with `pnpm run build` beforehand.
-
-To test out the script locally, run it from a different repository's directory:
-
-```shell
-cd ../other-repo
-node ../create-typescript-app/bin/migrate.js
-```
-
-The migration script will work on any directory.
-You can try it out in a blank directory with scripts like:
-
-```shell
-cd ..
-mkdir temp
-cd temp
-node ../create-typescript-app/bin/migrate.js
-```
-
-#### Testing the Migration Script
-
-> 💡 Seeing `Oh no! Running the migrate script unexpectedly modified:` errors?
-> _[Unexpected File Modifications](#unexpected-file-modifications)_ covers that below.
-
-You can run the end-to-end test for migrating locally on the command-line:
-
-```shell
-pnpm run test:migrate
-```
-
-That end-to-end test executes `script/migrate-test-e2e.ts`, which:
-
-1. Runs the migration script using `--skip-github-api` and other skip flags, capturing code coverage
-2. Checks that only a small list of allowed files were changed
-3. Checks that the local repository's files were changed correctly (e.g. removed initialization-only files)
-
-The `pnpm run test:migrate` script is run in CI to ensure that templating changes are in sync with the template's actual files.
-See `.github/workflows/ci.yml`'s `test_migration_script` job.
-
-> Tip: if the migration test is failing in CI and you don't see any errors, try [downloading the full logs](https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/using-workflow-run-logs#downloading-logs).
-
-##### Migration Snapshot Failures
-
-The migration test uses the [Vitest file snapshot](https://vitest.dev/guide/snapshot#file-snapshots) in `script/__snapshots__/migrate-test-e2e.ts.snap` to store expected differences to this repository after running the migration script.
-The end-to-end migration test will fail any changes that don't keep the same differences in that snapshot.
-
-You can update the snapshot file by:
-
-1. Committing any changes to your local repository
-2. Running `pnpm i` and `pnpm build` if any updates have been made to the `package.json` or `src/` files, respectively
-3. Running `pnpm run test:migrate -u` to update the snapshot
-
-At this point there will be some files changed:
-
-- `script/__snapshots__/migrate-test-e2e.ts.snap` will have updates if any files mismatched templates
-- The actual updated files on disk will be there too
-
-If the snapshot file changes are what you expected, then you can commit them.
-The rest of the file changes can be reverted.
-
-> [🚀 Feature: Add a way to apply known file changes after migration #1184](https://github.com/JoshuaKGoldberg/create-typescript-app/issues/1184) tracks turning the test snapshot into a feature.
-
-##### Unexpected File Modifications
-
-The migration test also asserts that no files were unexpectedly changed.
-If you see a failure like:
-
-```plaintext
-Oh no! Running the migrate script unexpectedly modified:
- - ...
-```
-
-...then that means the file generated from templates differs from what's checked into the repository.
-This is most often caused by changes to templates not being applied to checked-in files too.
-
-Templates for files are generally stored in [`src/steps/writing/creation`] under a path roughly corresponding to the file they describe.
-For example, the template for `tsup.config.ts` is stored in [`src/steps/writing/creation/createTsupConfig.ts`](../src/steps/writing/creation/createTsupConfig.ts).
-If the `createTsupConfig` function were to be modified without an equivalent change to `tsup.config.ts` -or vice-versa- then the migration test would report:
-
-```plaintext
-Oh no! Running the migrate script unexpectedly modified:
- - tsup.config.ts
-```
diff --git a/.github/codecov.yml b/.github/codecov.yml
deleted file mode 100644
index 70976385a..000000000
--- a/.github/codecov.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-codecov:
- notify:
- after_n_builds: 4
-comment:
- after_n_builds: 4
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 475d7007c..0dccc0e35 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -69,53 +69,6 @@ jobs:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
if: always()
uses: codecov/codecov-action@v3
- with:
- flags: unit
- test_creation_script:
- name: Test Creation Script
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/prepare
- - run: pnpm run build
- - run: pnpm run test:create
- - env:
- CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- if: always()
- uses: codecov/codecov-action@v3
- with:
- files: coverage-create/lcov.info
- flags: create
- test_initialization_script:
- name: Test Initialization Script
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/prepare
- - run: pnpm run build
- - run: pnpm run test:initialize
- - env:
- CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- if: always()
- uses: codecov/codecov-action@v3
- with:
- files: coverage-initialize/lcov.info
- flags: initialize
- test_migration_script:
- name: Test Migration Script
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/prepare
- - run: pnpm run build
- - run: pnpm run test:migrate
- - env:
- CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- if: always()
- uses: codecov/codecov-action@v3
- with:
- files: coverage-migrate/lcov.info
- flags: migrate
type_check:
name: Type Check
runs-on: ubuntu-latest
diff --git a/.gitignore b/.gitignore
index cd60c28d4..67a4fbfa1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,3 @@
-/coverage*
+/coverage
/lib
/node_modules
diff --git a/.prettierignore b/.prettierignore
index 24fb38510..2663f9c39 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,4 +1,4 @@
/.husky
-/coverage*
+/coverage
/lib
/pnpm-lock.yaml
diff --git a/README.md b/README.md
index 969fac579..cb7690d91 100644
--- a/README.md
+++ b/README.md
@@ -34,10 +34,11 @@ First make sure you have the following installed:
Then in an existing repository or in your directory where you'd like to make a new repository:
```shell
-npx create-typescript-app
+npx create typescript-app
```
-That setup script will walk you through using the template.
+That will launch `create-typescript-app` using the [`create` runner](https://create.bingo).
+
You can read more about the supported setup modes in their docs pages:
- [**Creating from the terminal**](./docs/Creation.md): creating a new repository locally on the command-line _(recommended)_
@@ -48,7 +49,7 @@ You can read more about the supported setup modes in their docs pages:
You can read more about `create-typescript-app` and the tooling it supports:
-1. [**Tooling**](./docs/Tooling.md): a breakdown of all the pieces this template can set up.
+1. [**Blocks**](./docs/Blocks.md): a breakdown of all the pieces this template can set up.
2. [**Options**](./docs/Options.md): granular options to customize how the template is run.
3. [**FAQs**](./docs/FAQs.md): frequently asked questions
diff --git a/bin/index.js b/bin/index.js
index 1b7a28434..a2fcfd5e6 100755
--- a/bin/index.js
+++ b/bin/index.js
@@ -1,4 +1,16 @@
#!/usr/bin/env node
-import { bin } from "../lib/bin/index.js";
+import chalk from "chalk";
-process.exitCode = await bin(process.argv.slice(2));
+console.log(
+ [
+ "create-typescript-app is now run using ",
+ chalk.bold("create"),
+ ".\n\nRun:\n ",
+ chalk.bold("npx create", process.argv.slice(2).join(" ")),
+ "\n\nYou can read more on:\n https://",
+ chalk.bold("create.bingo"),
+ "\n\nThanks for using create-typescript-app! 🎁",
+ ].join(""),
+);
+
+process.exitCode = 1;
diff --git a/cspell.json b/cspell.json
index 0a9089663..924e84d96 100644
--- a/cspell.json
+++ b/cspell.json
@@ -4,21 +4,21 @@
".all-contributorsrc",
".github",
"CHANGELOG.md",
- "coverage*",
+ "coverage",
"lib",
"node_modules",
- "pnpm-lock.yaml",
- "script/__snapshots__"
+ "pnpm-lock.yaml"
],
"words": [
"Anson",
"apexskier",
+ "automerge",
"dbaeumer",
"infile",
"joshuakgoldberg",
"markdownlintignore",
"mtfoley",
- "ruleset",
- "rulesets"
+ "npmjs",
+ "tseslint"
]
}
diff --git a/docs/Tooling.md b/docs/Blocks.md
similarity index 65%
rename from docs/Tooling.md
rename to docs/Blocks.md
index 983f8063b..2b828d9a7 100644
--- a/docs/Tooling.md
+++ b/docs/Blocks.md
@@ -1,48 +1,55 @@
-# Tooling
-
-`create-typescript-app` provides over two dozen pieces of tooling, ranging from code building and formatting to various forms of GitHub repository management.
-Most can be individually turned off or on.
-
-The `create-typescript-app` setup scripts -[creation](./Creation.md), [initialization](./Initialization.md), and [migration](./Migration.md)- will prompt you to choose a "base" template level to initialize from.
-Those template levels provide common presets of which tooling pieces to enable.
-
-```plaintext
-◆ How much tooling would you like the template to set up for you?
-│ ○ minimal Just the bare starter tooling most repositories should ideally include.
-│ ○ common Important additions to the minimal starters such as releases and tests.
-│ ○ everything The most thorough tooling imaginable: sorting, spellchecking, and more!
-│ ○ prompt (allow me to customize)
-└
-```
-
-This table summarizes each tooling piece and which base levels they're included in:
-
-| Tooling Piece | Exclusion Flag | Minimal | Common | Everything |
-| --------------------------------------------- | ------------------------------ | ------- | ------ | ---------- |
-| [Building](#building) | | ✔️ | ✅ | 💯 |
-| [Compliance](#compliance) | `--exclude-compliance` | | | 💯 |
-| [Contributors](#contributors) | `--exclude-contributors` | | ✅ | 💯 |
-| [Formatting](#formatting) | | ✔️ | ✅ | 💯 |
-| [Lint ESLint](#lint-eslint) | `--exclude-lint-eslint` | | | 💯 |
-| [Lint JSDoc](#lint-jsdoc) | `--exclude-lint-jsdoc` | | | 💯 |
-| [Lint JSON](#lint-json) | `--exclude-lint-json` | | | 💯 |
-| [Lint Knip](#lint-knip) | `--exclude-lint-knip` | | ✅ | 💯 |
-| [Lint MD](#lint-md) | `--exclude-lint-md` | | | 💯 |
-| [Lint Package JSON](#lint-package-json) | `--exclude-lint-package-json` | | | 💯 |
-| [Lint Packages](#lint-packages) | `--exclude-lint-packages` | | | 💯 |
-| [Lint Perfectionist](#lint-perfectionist) | `--exclude-lint-perfectionist` | | | 💯 |
-| [Lint Regexp](#lint-regexp) | `--exclude-lint-regexp` | | | 💯 |
-| [Lint Spelling](#lint-spelling) | `--exclude-lint-spelling` | | | 💯 |
-| [Lint Strict](#lint-strict) | `--exclude-lint-strict` | | | 💯 |
-| [Lint Stylistic](#lint-stylistic) | `--exclude-lint-stylistic` | | | 💯 |
-| [Lint YML](#lint-yml) | `--exclude-lint-yml` | | | 💯 |
-| [Linting](#linting) | | ✔️ | ✅ | 💯 |
-| [Package Management](#package-management) | | ✔️ | ✅ | 💯 |
-| [Releases](#releases) | `--exclude-releases` | | ✅ | 💯 |
-| [Renovate](#renovate) | `--exclude-renovate` | | ✅ | 💯 |
-| [Repository Templates](#repository-templates) | | ✔️ | ✅ | 💯 |
-| [Testing](#testing) | `--exclude-tests` | | ✅ | 💯 |
-| [Type Checking](#type-checking) | | ✔️ | ✅ | 💯 |
+# Blocks
+
+`create-typescript-app` provides several dozen pieces of tooling, ranging from code building and formatting to various forms of GitHub repository management.
+Each can be individually turned off or on.
+
+This table summarizes each block and which base levels they're included in:
+
+| Block | Exclusion Flag | Minimal | Common | Everything |
+| ---------------------------- | ---------------------------------------- | ------- | ------ | ---------- |
+| AllContributors | `--exclude-allcontributors` | | ✅ | 💯 |
+| Are The Types Wrong | `--exclude-are-the-types-wrong` | | | |
+| Contributing Docs | `--exclude-contributing-docs` | ✔️ | ✅ | 💯 |
+| Contributor Covenant | `--exclude-contributor-covenant` | ✔️ | ✅ | 💯 |
+| CSpell | `--exclude-cspell` | | | 💯 |
+| Codecov | `--exclude-codecov` | | ✅ | 💯 |
+| Development Docs | `--exclude-development-docs` | ✔️ | ✅ | 💯 |
+| ESLint | `--exclude-eslint` | ✔️ | ✅ | 💯 |
+| ESLint Comments Plugin | `--exclude-eslint-comments-plugin` | | | 💯 |
+| ESLint JSDoc Plugin | `--exclude-eslint-jsdoc-plugin` | | | 💯 |
+| ESLint JSONC Plugin | `--exclude-eslint-jsonc-plugin` | | | 💯 |
+| ESLint Markdown Plugin | `--exclude-eslint-markdown-plugin` | | | 💯 |
+| ESLint More Styling | `--exclude-eslint-more-styling` | | | 💯 |
+| ESLint Node Plugin | `--exclude-eslint-node-plugin` | | | 💯 |
+| ESLint package.json Plugin | `--exclude-eslint-package-json-plugin` | | | 💯 |
+| ESLint Perfectionist Plugin | `--exclude-eslint-perfectionist-plugin` | | | 💯 |
+| ESLint Regexp Plugin | `--exclude-eslint-regexp-plugin` | | | 💯 |
+| ESLint YML Plugin | `--exclude-eslint-yml-plugin` | | | 💯 |
+| Funding | `--exclude-funding` | | ✅ | 💯 |
+| GitHub Actions CI | `--exclude-github-actions-ci` | ✔️ | ✅ | 💯 |
+| GitHub Issue Templates | `--exclude-github-issue-templates` | ✔️ | ✅ | 💯 |
+| GitHub PR Template | `--exclude-github-pr-template` | ✔️ | ✅ | 💯 |
+| Gitignore | `--exclude-gitignore` | ✔️ | ✅ | 💯 |
+| Knip | `--exclude-knip` | | | 💯 |
+| Markdownlint | `--exclude-markdownlint` | | | 💯 |
+| MIT License | `--exclude-mit-license` | ✔️ | ✅ | 💯 |
+| nvmrc | `--exclude-nvmrc` | | | 💯 |
+| Package JSON | `--exclude-package-json` | ✔️ | ✅ | 💯 |
+| pnpm Dedupe | `--exclude-pnpm-dedupe` | | | 💯 |
+| PR Compliance | `--exclude-pr-compliance` | | | 💯 |
+| Prettier | `--exclude-prettier` | ✔️ | ✅ | 💯 |
+| Prettier Plugin Curly | `--exclude-prettier-plugin-curly` | | | 💯 |
+| Prettier Plugin Package JSON | `--exclude-prettier-plugin-package-json` | | | 💯 |
+| Prettier Plugin Sh | `--exclude-prettier-plugin-sh` | | | 💯 |
+| README.md | `--exclude-readme-md` | ✔️ | ✅ | 💯 |
+| release-it | `--exclude-release-it` | | ✅ | 💯 |
+| Renovate | `--exclude-renovate` | | | 💯 |
+| Security Docs | `--exclude-security-docs` | ✔️ | ✅ | 💯 |
+| Templated By Notice | `--exclude-templated-by-notice` | ✔️ | ✅ | 💯 |
+| TSup | `--exclude-tsup` | ✔️ | ✅ | 💯 |
+| TypeScript | `--exclude-typescript` | ✔️ | ✅ | 💯 |
+| Vitest | `--exclude-vitest` | | ✅ | 💯 |
+| VS Code | `--exclude-vs-code` | | | 💯 |
See also [Options](./Options.md) for how to customize the way template is run.
diff --git a/docs/Creation.md b/docs/Creation.md
index 5572d9d15..1fa7bfd06 100644
--- a/docs/Creation.md
+++ b/docs/Creation.md
@@ -1,15 +1,15 @@
# Creating from the Terminal
-You can run `npx create-typescript-app` in your terminal to interactively create a new repository in a child directory:
+You can run `npx create typescript-app` in your terminal to interactively create a new repository:
```shell
-npx create-typescript-app
+npx create typescript-app
```
The creation script will by default:
-1. Create a new directory with the given repository name
-2. Initialize that new directory as a local Git repository
+1. Prompt you for a directory, which template preset to run with, and some starting information
+2. Initialize new directory as a local Git repository
3. Copy the template's files to that directory
4. Create a new repository on GitHub and set it as the local repository's upstream
5. Configure relevant settings on the GitHub repository
@@ -28,13 +28,13 @@ Hooray! 🥳
## Options
-You can explicitly provide some or all of the options the script would prompt for as command-line flags.
+You can customize which pieces of tooling are provided and the options they're created with.
See [Options.md](./Options.md).
-For example, running the creation script and skipping all GitHub-related APIs:
+For example, skipping the _"This package was templated with..."_ block:
```shell
-npx create-typescript-app --mode create --skip-all-contributors-api --skip-github-api
+npx create typescript-app --mode create --exclude-templated-with
```
-See [Tooling.md](./Tooling.md) for details on the tooling pieces and which bases they're included in.
+See [Blocks.md](./Blocks.md) for details on the tooling pieces and which presets they're included in.
diff --git a/docs/FAQs.md b/docs/FAQs.md
index 22014acc3..7c65bb0e2 100644
--- a/docs/FAQs.md
+++ b/docs/FAQs.md
@@ -147,43 +147,24 @@ That's reasonable.
Unless you know a package needs to support a CJS consumer, please strongly consider keeping it ESM-only (the `create-typescript-app` default).
ESM-only packages have a smaller footprint by virtue of including fewer files.
-## Is there a way to pull in template updates to previously created repositories?
-
-Not directly.
-You can always copy & paste them in manually, and/or re-run `npx create-typescript-app --mode migrate`.
-
-See [🚀 Feature: Add a script to sync the tooling updates from forked template repo #498](https://github.com/JoshuaKGoldberg/create-typescript-app/issues/498): it will likely eventually be possible.
-
## What about `eslint-config-prettier`?
[`eslint-config-prettier`](https://github.com/prettier/eslint-config-prettier) is an ESLint plugin that serves only to turn off all rules that are unnecessary or might conflict with formatters such as Prettier.
None of the ESLint configs enabled by this repository's tooling leave any rules enabled that would need to be disabled.
Using `eslint-config-prettier` would be redundant.
-## What determines which "base" a tool goes into?
+## What determines which preset a tool goes into?
-The four bases correspond to what have seemed to be the most common user needs of template consumers:
+The four presets correspond to what have seemed to be the most common user needs of template consumers:
1. **Minimal**: Developers who just want the barest of starting templates.
- They may be very new to TypeScript tooling, or they may have made an informed decision that the additional tooling isn't worth the complexity and/or time investment.
- - Tooling in this base is only what would be essential for a small TypeScript package that can be built, formatted, linted, and released.
+ - Tooling in this preset is only what would be essential for a small TypeScript package that can be built, formatted, linted, and released.
2. **Common**: The common case of users who want the minimal tooling along with common repository management.
- - Tooling added in this base should be essential for a TypeScript repository that additionally automates useful GitHub tasks: contributor recognition, release management, and testing.
+ - Tooling added in this preset should be essential for a TypeScript repository that additionally automates useful GitHub tasks: contributor recognition, release management, and testing.
3. **Everything**: Power users (including this repository) who want as much of the latest and greatest safety checks and standardization as possible.
-Note that users can always customize exactly with portions are kept in with `--base` **`prompt`**.
-
-## Which tools can't I remove?
-
-The following pieces of this template's tooling don't have options to be removed:
-
-- Linting with ESLint and `pnpm run lint`
-- GitHub repository metadata such as the code of conduct and issue templates
-- Prettier and `pnpm run format`
-- tsup and `pnpm run build`
-- TypeScript and `pnpm run tsc`
-
-If you have a strong desire to add an `--exclude-*` flag for any of them, please do [file a feature request](https://github.com/JoshuaKGoldberg/create-typescript-app/issues/new?assignees=&labels=type%3A+feature&projects=&template=03-feature.yml&title=%F0%9F%9A%80+Feature%3A+%3Cshort+description+of+the+feature%3E).
+Note that you can always customize exactly which preset you use per [Options](./Options.md).
## Why does this package include so many tools?
diff --git a/docs/Initialization.md b/docs/Initialization.md
index f2f17d3f7..2164c75bb 100644
--- a/docs/Initialization.md
+++ b/docs/Initialization.md
@@ -1,21 +1,12 @@
# Initializing from the Template
-As an alternative to [creating with `npx create-typescript-app`](./Creation.md), the [_Use this template_](https://github.com/JoshuaKGoldberg/create-typescript-app/generate) button on GitHub can be used to quickly create a new repository from the template.
+As an alternative to [creating with `npx create typescript-app`](./Creation.md), the [_Use this template_](https://github.com/JoshuaKGoldberg/create-typescript-app/generate) button on GitHub can be used to quickly create a new repository from the template.
You can set up the new repository locally by cloning it and installing packages:
```shell
git clone https://github.com/YourUsername/YourRepositoryName
cd YourRepositoryName
-pnpm i
-```
-
-> 💡 If you don't want to clone it locally, you can always [develop in a codespace](https://docs.github.com/en/codespaces/developing-in-codespaces/developing-in-a-codespace) instead.
-
-Once the repository's packages are installed, you can run `pnpm run initialize` to fill out your repository's details and install necessary packages.
-It will then remove itself and uninstall dependencies only used for initialization.
-
-```shell
-pnpm run initialize
+npx create typescript-app
```
You'll then need to manually go through the following two steps to set up tooling on GitHub:
@@ -32,15 +23,13 @@ Hooray! 🥳
## Options
-You can explicitly provide some or all of the options the script would prompt for as command-line flags.
+You can customize which pieces of tooling are provided and the options they're created with.
See [Options.md](./Options.md).
-`pnpm run initialize` will set `--mode` to `initialize`.
-
-For example, running the initialization script and skipping all GitHub-related APIs:
+For example, skipping the _"This package was templated with..."_ block:
```shell
-pnpm run initialize --skip-all-contributors-api --skip-github-api
+npx create typescript-app --exclude-templated-with
```
-See [Tooling.md](./Tooling.md) for details on the tooling pieces and which bases they're included in.
+See [Blocks.md](./Blocks.md) for details on the tooling pieces and which presets they're included in.
diff --git a/docs/Migration.md b/docs/Migration.md
index ef03d0276..0fa226b46 100644
--- a/docs/Migration.md
+++ b/docs/Migration.md
@@ -1,9 +1,9 @@
# Migrating an Existing Repository
-If you have an existing repository that you'd like to give the files from this repository, you can run `npx create-typescript-app` in it to "migrate" its tooling to this template's.
+If you have an existing repository that you'd like to give the files from this repository, you can run `npx create typescript-app` in it to "migrate" its tooling to this template's.
```shell
-npx create-typescript-app
+npx create typescript-app
```
The migration script will:
@@ -40,20 +40,13 @@ Hooray! 🥳
## Options
-`create-typescript-app` will detect whether it's being run in an existing repository.
-It also allows specifying `--mode migrate` if that detection misinterprets the current directory:
-
-```shell
-npx create-typescript-app --mode migrate
-```
-
-You can explicitly provide some or all of the options the script would prompt for as command-line flags.
+You can customize which pieces of tooling are provided and the options they're created with.
See [Options.md](./Options.md).
-For example, running the migration script and skipping all GitHub-related APIs:
+For example, skipping the _"This package was templated with..."_ block:
```shell
-npx create-typescript-app --skip-all-contributors-api --skip-github-api
+npx create typescript-app --exclude-templated-with
```
-See [Tooling.md](./Tooling.md) for details on the tooling pieces and which bases they're included in.
+See [Blocks.md](./Blocks.md) for details on the tooling pieces and which presets they're included in.
diff --git a/docs/Options.md b/docs/Options.md
index 79fd90faa..803c85147 100644
--- a/docs/Options.md
+++ b/docs/Options.md
@@ -1,176 +1,71 @@
# Options
-All three of `create-typescript-app`'s setup scripts -[creation](./Creation.md), [initialization](./Initialization.md), and [migration](./Migration.md)- support a shared set of input options.
+`create-typescript-app` is built on top of [`create`](https://create.bingo).
+`npx create typescript-app` supports all the flags defined by the [`create` CLI](https://www.create.bingo/cli).
+It provides three Presets:
-> This page uses `npx create-typescript-app` in its code examples, but initialization's `pnpm run initialize` works the same.
+1. **Minimal**: Just bare starter tooling: building, formatting, linting, and type checking.
+2. **Common**: Bare starters plus testing and automation for all-contributors and releases.
+3. **Everything**: The most comprehensive tooling imaginable: sorting, spellchecking, and more!
-## Required Options
+For example, to create a new repository on the _everything_ preset:
-The following required options will be prompted for interactively if not provided as CLI flags.
-
-### Base and Mode
-
-These required options determine how the creation script will set up and scaffold the repository:
+```shell
+npx create typescript-app --preset everything
+```
-- `--base`: Whether to scaffold the repository with:
- - `minimal`: Just the bare starter tooling most repositories should ideally include
- - `common`: Important additions to the minimal starters such as releases and tests
- - `everything`: The most thorough tooling imaginable: sorting, spellchecking, and more!
- - `prompt`: Fine-grained control over which tooling pieces to use
-- `--mode`: Whether to:
- - `create` a new repository in a child directory
- - `initialize` a newly created repository in the current directory
- - `migrate` an existing repository in the current directory
+`create-typescript-app` itself adds in two sections of flags:
-For example, scaffolding a full new repository under the current directory and also linking it to a new repository on github.com:
+- [Base Options](#base-options)
+- [Block Exclusions](#block-exclusions)
-```shell
-npx create-typescript-app --base everything --mode create
-```
+## Base Options
-See [Tooling.md](./Tooling.md) for details on the tooling pieces and which bases they're included in.
+Per [`create` > CLI > Template Options](https://www.create.bingo/cli#template-options), options defined by `create-typescript-app` may be provided on the CLI.
-### Core Options
+### Required Base Options
-These required options determine the options that will be substituted into the template's files:
+These options can only be inferred when running on an existing repository.
+Each will be prompted for when creating a new repository if not explicitly provided:
-- `--description` _(`string`)_: Sentence case description of the repository (e.g. `Quickstart-friendly TypeScript package with lots of great repository tooling. ✨`)
-- `--owner` _(`string`)_: GitHub organization or user the repository is underneath (e.g. `JoshuaKGoldberg`)
-- `--repository` _(`string`)_: The kebab-case name of the repository (e.g. `create-typescript-app`)
-- `--title` _(`string`)_: Title Case title for the repository (e.g. `Create TypeScript App`)
+- `--description` _(`string`)_: 'Sentence case.' description of the repository
+- `--title` _(`string`)_: 'Title Case' title for the repository
-For example, pre-populating all core required options and also creating a new repository:
+For example, pre-populating both required base options:
```shell
-npx create-typescript-app --base everything --mode create --repository testing-repository --title "Testing Title" --owner TestingOwner --description "Test Description"
+npx create typescript-app --description "My awesome TypeScript app! 💖" --title "My TypeScript App"
```
That script will run completely autonomously, no prompted inputs required. ✨
-## Optional Options
+### Optional Base Options
-The setup scripts also allow for optional overrides of the following inputs whose defaults are based on other options:
+These optional options do not need to be provided explicitly.
+They will be inferred from the running user, and if migrating an existing repository, its files on disk.
- `--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()`)
- `--bin` _(`string`)_: Value to set in `package.json`'s `"bin"` property, per [FAQs > How can I use `bin`?](./FAQs.md#how-can-i-use-bin)
- `--directory` _(`string`)_: Directory to create the repository in (by default, the same name as the repository)
- `--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
- `--funding` _(`string`)_: GitHub organization or username to mention in `funding.yml` (by default, `owner`)
-- `--guide` _(`string`)_: Link to a contribution guide to place at the top of development docs
- - `--guide-title` _(`string`)_: If `--guide` is provided or detected from an existing DEVELOPMENT.md, the text title to place in the guide link
- `--keywords` _(`string[]`)_: Any number of keywords to include in `package.json` (by default, none)
- This can be specified any number of times, like `--keywords apple --keywords "banana cherry"`
-- `--logo` _(`string`)_: Local image file in the repository to display near the top of the README.md
- - `--logo-alt` _(`string`)_: If `--logo` is provided or detected from an existing README.md, alt text that describes the image (will be prompted for if not provided)
- - `--logo-height` _(`number`)_: If `--logo` is provided or detected from an existing README.md, an explicit height style (by default, read from the image, capped to `128`)
- - `--logo-width` _(`number`)_: If `--logo` is provided or detected from an existing README.md, an explicit width style (by default, read from the image, capped to `128`)
-- `--preserve-generated-from` _(`boolean`)_: Whether to keep the GitHub repository _generated from_ notice (by default, `false`)
-
-For example, customizing the ownership and users associated with a new repository:
-
-```shell
-npx create-typescript-app --author my-npm-username --email example@joshuakgoldberg.com --funding MyGitHubOrganization
-```
-
-> 💡 You can always manually edit files such as `package.json` after running a setup script.
-
-## Opt-Outs
-
-The setup scripts can be directed with CLI flags to opt out tooling portions and/or using API calls.
-
-### Excluding Tooling Portions
-
-The setup scripts normally will prompt you to select how much of the tooling you'd like to enable in a new repository.
-Alternately, you can bypass that prompt by providing any number of the following CLI flags:
-
-- `--exclude-all-contributors`: Don't add all-contributors to track contributions and display them in a README.md table.
-- `--exclude-build`: Don't add a build task to generate built `.js`, `.d.ts`, and related output.
-- `--exclude-compliance`: Don't add a GitHub Actions workflow to verify that PRs match an expected format.
-- `--exclude-lint-json`: Don't apply linting and sorting to `*.json` and `*.jsonc` files.
-- `--exclude-lint-knip`: Don't add Knip to detect unused files, dependencies, and code exports.
-- `--exclude-lint-md`: Don't apply linting to `*.md` files.
-- `--exclude-lint-package-json`: Don't add eslint-plugin-package-json to lint for package.json correctness.
-- `--exclude-lint-eslint`: Don't use eslint-plugin-eslint-comment to enforce good practices around ESLint comment directives.
-- `--exclude-lint-jsdoc`: Don't use eslint-plugin-jsdoc to enforce good practices around JSDoc comments.
-- `--exclude-lint-packages`: Don't add a pnpm dedupe workflow to ensure packages aren't duplicated unnecessarily.
-- `--exclude-lint-perfectionist`: Don't apply eslint-plugin-perfectionist to ensure imports, keys, and so on are in sorted order.
-- `--exclude-lint-regexp`: Don't add eslint-plugin-regexp to enforce good practices around regular expressions.
-- `--exclude-lint-strict`: Don't augment the recommended logical lint rules with typescript-eslint's strict config.
-- `--exclude-lint-stylistic`: Don't add stylistic rules such as typescript-eslint's stylistic config.
-- `--exclude-lint-spelling`: Don't add cspell to spell check against dictionaries of known words.
-- `--exclude-lint-yml`: Don't apply linting and sorting to `*.yaml` and `*.yml` files.
-- `--exclude-releases`: Don't add release-it to generate changelogs, package bumps, and publishes based on conventional commits.
-- `--exclude-renovate`: Don't add a Renovate config to dependencies up-to-date with PRs.
-- `--exclude-templated-by`: Don't add a _"This package was templated with create-typescript-app"_ notice at the end of the README.md.
-- `--exclude-tests`: Don't add Vitest tooling for fast unit tests, configured with coverage tracking.
-
-For example, initializing with all tooling except for `package.json` checks and Renovate:
-
-```shell
-npx create-typescript-app --exclude-lint-package-json --exclude-lint-packages --exclude-renovate
-```
-> **Warning**
-> Specifying any `--exclude-*` flag on the command-line will cause the setup script to skip prompting for more excludes.
-
-See [Tooling.md](./Tooling.md) for details on the tooling pieces and which bases they're included in.
-
-### Skipping API Calls
-
-> Alternately, see [Offline Mode](#offline-mode) to skip API calls without disabling features
-
-You can prevent the migration script from making some network-based changes using any or all of the following CLI flags:
-
-- `--skip-all-contributors-api` _(`boolean`)_: Skips network calls that fetch all-contributors data from GitHub
- - This flag does nothing if `--exclude-all-contributors` was specified.
-- `--skip-github-api` _(`boolean`)_: Skips calling to GitHub APIs.
-- `--skip-install` _(`boolean`)_: Skips installing all the new template packages with `pnpm`.
-
-For example, providing all three flags will completely skip all network requests:
-
-```shell
-npx create-typescript-app --skip-all-contributors-api --skip-github-api --skip-install
-```
-
-> 💡 Tip: To temporarily preview what the script would apply without making changes on GitHub, you can run with all `--skip-*-api` flags, then `git add -A; git reset --hard HEAD` to completely reset all changes.
-
-### Skipping Local Changes
-
-You can prevent the migration script from making some changes on disk using any or all of the following CLI flags:
-
-- `--skip-removal` _(`boolean`)_: Skips removing setup docs and scripts, including this `docs/` directory
-- `--skip-restore` _(`boolean`)_: Skips the prompt offering to restore the repository if an error occurs during setup
-- `--skip-uninstall` _(`boolean`)_: Skips uninstalling packages only used for setup scripts
-
-For example, providing all local change skip flags:
+For example, customizing the npm author and funding source:
```shell
-npx create-typescript-app --skip-removal --skip-restore --skip-uninstall
+npx create typescript-app --author my-npm-username --funding MyGitHubOrganization
```
-## Automatic Mode
-
-You can run `create-typescript-app` in an "automatic" manner with `--auto` and `--mode migrate`.
-Doing so will:
+## Block Exclusions
-- Use the default inference for all options
-- Bail out if any required [core options](#core-options) are missing
+Per [`create` > CLI > Template Options > Block Exclusions](https://www.create.bingo/cli#block-exclusions), individual Blocks may be excluded from running.
+For example, initializing with all tooling except for Renovate:
```shell
-npx create-typescript-app --auto --mode migrate
+npx create typescript-app --exclude-renovate
```
-## Offline Mode
-
-You can run `create-typescript-app` in an "offline" manner with `--offline`.
-Doing so will:
-
-- Enable `--exclude-all-contributors-api` and `--skip-github-api`
-- Skip network calls when setting up contributors
-- Run pnpm commands with pnpm's `--offline` mode
-
-```shell
-npx create-typescript-app --offline
-```
+See [Blocks.md](./Blocks.md) for the list of blocks and their corresponding presets.
diff --git a/eslint.config.js b/eslint.config.js
index 648fac3ac..758d20cbb 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -23,13 +23,7 @@ import tseslint from "typescript-eslint";
export default tseslint.config(
{
- ignores: [
- "**/*.snap",
- "coverage*",
- "lib",
- "node_modules",
- "pnpm-lock.yaml",
- ],
+ ignores: ["**/*.snap", "coverage", "lib", "node_modules", "pnpm-lock.yaml"],
},
{ linterOptions: { reportUnusedDisableDirectives: "error" } },
eslint.configs.recommended,
@@ -59,12 +53,6 @@ export default tseslint.config(
},
rules: {
// These on-by-default rules work well for this repo if configured
- "@typescript-eslint/no-unnecessary-condition": [
- "error",
- {
- allowConstantLoopConditions: true,
- },
- ],
"@typescript-eslint/prefer-nullish-coalescing": [
"error",
{ ignorePrimitives: true },
@@ -73,10 +61,6 @@ export default tseslint.config(
"error",
{ allowBoolean: true, allowNullish: true, allowNumber: true },
],
- "n/no-unsupported-features/node-builtins": [
- "error",
- { allowExperimental: true },
- ],
// Stylistic concerns that don't interfere with Prettier
"logical-assignment-operators": [
@@ -90,10 +74,7 @@ export default tseslint.config(
},
settings: { perfectionist: { partitionByComment: true, type: "natural" } },
},
- {
- extends: [tseslint.configs.disableTypeChecked],
- files: ["**/*.md/*.ts"],
- },
+ { extends: [tseslint.configs.disableTypeChecked], files: ["**/*.md/*.ts"] },
{
extends: [vitest.configs.recommended],
files: ["**/*.test.*"],
diff --git a/knip.json b/knip.json
index 57c4f152a..55408fe8e 100644
--- a/knip.json
+++ b/knip.json
@@ -1,7 +1,11 @@
{
"$schema": "https://unpkg.com/knip@5.41.1/schema.json",
- "entry": ["script/*e2e.js", "src/index.ts", "src/**/*.test.*"],
- "ignoreDependencies": ["all-contributors-cli", "cspell-populate-words"],
+ "entry": ["src/index.ts", "src/**/*.test.*"],
+ "ignoreDependencies": [
+ "all-contributors-cli",
+ "cspell-populate-words",
+ "remove-dependencies"
+ ],
"ignoreExportsUsedInFile": { "interface": true, "type": true },
- "project": ["src/**/*.ts", "script/**/*.js"]
+ "project": ["src/**/*.ts"]
}
diff --git a/package.json b/package.json
index 5214fc2f0..2c7e5fd48 100644
--- a/package.json
+++ b/package.json
@@ -24,7 +24,6 @@
"scripts": {
"build": "tsup",
"format": "prettier .",
- "initialize": "pnpm build --no-dts && tsx bin/index.js --mode initialize",
"lint": "eslint . --max-warnings 0",
"lint:knip": "knip",
"lint:md": "markdownlint \"**/*.md\" \".github/**/*.md\" --rules sentences-per-line",
@@ -32,19 +31,15 @@
"lint:spelling": "cspell \"**\" \".github/**/*\"",
"prepare": "husky",
"test": "vitest",
- "test:create": "npx tsx script/create-test-e2e.ts",
- "test:initialize": "npx tsx script/initialize-test-e2e.ts",
- "test:migrate": "vitest run -r script/",
"tsc": "tsc"
},
"lint-staged": {
"*": "prettier --ignore-unknown --write"
},
"dependencies": {
- "@clack/prompts": "^0.9.0",
- "@prettier/sync": "^0.5.2",
"chalk": "^5.4.1",
- "create": "0.1.0-alpha.11",
+ "create": "0.1.0-alpha.15",
+ "create-fs": "^0.1.1",
"cspell-populate-words": "^0.3.0",
"execa": "^9.5.2",
"git-remote-origin-url": "^4.0.0",
@@ -59,25 +54,19 @@
"lodash": "^4.17.21",
"npm-user": "^6.1.1",
"object-strings-deep": "^0.1.1",
- "octokit": "^4.0.2",
- "octokit-from-auth": "^0.3.0",
"parse-author": "^2.0.0",
"parse-package-name": "^1.0.0",
- "populate-all-contributors-for-repository": "^0.1.2",
- "prettier": "^3.4.2",
+ "remove-dependencies": "^0.1.0",
"remove-undefined-objects": "^5.0.0",
- "replace-in-file": "^8.3.0",
- "rimraf": "^6.0.1",
"set-github-repository-labels": "^0.1.0",
"sort-package-json": "^2.12.0",
"title-case": "^4.3.2",
- "zod": "^3.24.1",
- "zod-validation-error": "^3.4.0"
+ "zod": "^3.24.1"
},
"devDependencies": {
"@eslint-community/eslint-plugin-eslint-comments": "4.4.1",
"@eslint/js": "9.17.0",
- "@octokit/request-error": "6.1.5",
+ "@prettier/sync": "^0.5.2",
"@release-it/conventional-changelog": "9.0.3",
"@types/eslint-plugin-markdown": "2.0.2",
"@types/git-url-parse": "9.0.3",
@@ -89,10 +78,9 @@
"@vitest/coverage-v8": "2.1.8",
"@vitest/eslint-plugin": "1.1.20",
"all-contributors-cli": "6.26.1",
- "c8": "10.1.3",
"console-fail-test": "0.5.0",
- "create-testers": "0.1.0-alpha.11",
- "cspell": "8.17.1",
+ "create-testers": "0.1.0-alpha.14",
+ "cspell": "^8.17.2",
"eslint": "9.17.0",
"eslint-plugin-jsdoc": "50.6.1",
"eslint-plugin-jsonc": "2.18.2",
@@ -102,19 +90,19 @@
"eslint-plugin-perfectionist": "4.4.0",
"eslint-plugin-regexp": "2.7.0",
"eslint-plugin-yml": "1.16.0",
- "globby": "14.0.2",
"husky": "9.1.7",
"knip": "5.41.1",
"lint-staged": "15.3.0",
+ "lodash": "^4.17.21",
"markdownlint": "0.37.2",
"markdownlint-cli": "0.43.0",
+ "prettier": "^3.4.2",
"prettier-plugin-curly": "0.3.1",
"prettier-plugin-packagejson": "2.5.6",
"prettier-plugin-sh": "0.14.0",
"release-it": "17.10.0",
"sentences-per-line": "0.3.0",
"tsup": "8.3.5",
- "tsx": "4.19.2",
"typescript": "5.7.2",
"typescript-eslint": "8.19.0",
"vitest": "2.1.8"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e6b822633..9152cbd51 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -8,18 +8,15 @@ importers:
.:
dependencies:
- '@clack/prompts':
- specifier: ^0.9.0
- version: 0.9.0
- '@prettier/sync':
- specifier: ^0.5.2
- version: 0.5.2(prettier@3.4.2)
chalk:
specifier: ^5.4.1
version: 5.4.1
create:
- specifier: 0.1.0-alpha.11
- version: 0.1.0-alpha.11(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(typescript@5.7.2)
+ specifier: 0.1.0-alpha.15
+ version: 0.1.0-alpha.15
+ create-fs:
+ specifier: ^0.1.1
+ version: 0.1.1
cspell-populate-words:
specifier: ^0.3.0
version: 0.3.0
@@ -40,13 +37,13 @@ importers:
version: 1.2.0
input-from-file:
specifier: 0.1.0-alpha.4
- version: 0.1.0-alpha.4(create@0.1.0-alpha.11(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(typescript@5.7.2))
+ version: 0.1.0-alpha.4(create@0.1.0-alpha.15)
input-from-file-json:
specifier: 0.1.0-alpha.4
- version: 0.1.0-alpha.4(create@0.1.0-alpha.11(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(typescript@5.7.2))
+ version: 0.1.0-alpha.4(create@0.1.0-alpha.15)
input-from-script:
specifier: 0.1.0-alpha.4
- version: 0.1.0-alpha.4(create@0.1.0-alpha.11(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(typescript@5.7.2))
+ version: 0.1.0-alpha.4(create@0.1.0-alpha.15)
js-yaml:
specifier: ^4.1.0
version: 4.1.0
@@ -62,33 +59,18 @@ importers:
object-strings-deep:
specifier: ^0.1.1
version: 0.1.1
- octokit:
- specifier: ^4.0.2
- version: 4.0.2
- octokit-from-auth:
- specifier: ^0.3.0
- version: 0.3.0
parse-author:
specifier: ^2.0.0
version: 2.0.0
parse-package-name:
specifier: ^1.0.0
version: 1.0.0
- populate-all-contributors-for-repository:
- specifier: ^0.1.2
- version: 0.1.2
- prettier:
- specifier: ^3.4.2
- version: 3.4.2
+ remove-dependencies:
+ specifier: ^0.1.0
+ version: 0.1.0
remove-undefined-objects:
specifier: ^5.0.0
version: 5.0.0
- replace-in-file:
- specifier: ^8.3.0
- version: 8.3.0
- rimraf:
- specifier: ^6.0.1
- version: 6.0.1
set-github-repository-labels:
specifier: ^0.1.0
version: 0.1.0
@@ -101,9 +83,6 @@ importers:
zod:
specifier: ^3.24.1
version: 3.24.1
- zod-validation-error:
- specifier: ^3.4.0
- version: 3.4.0(zod@3.24.1)
devDependencies:
'@eslint-community/eslint-plugin-eslint-comments':
specifier: 4.4.1
@@ -111,9 +90,9 @@ importers:
'@eslint/js':
specifier: 9.17.0
version: 9.17.0
- '@octokit/request-error':
- specifier: 6.1.5
- version: 6.1.5
+ '@prettier/sync':
+ specifier: ^0.5.2
+ version: 0.5.2(prettier@3.4.2)
'@release-it/conventional-changelog':
specifier: 9.0.3
version: 9.0.3(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(release-it@17.10.0(typescript@5.7.2))
@@ -147,18 +126,15 @@ importers:
all-contributors-cli:
specifier: 6.26.1
version: 6.26.1
- c8:
- specifier: 10.1.3
- version: 10.1.3
console-fail-test:
specifier: 0.5.0
version: 0.5.0
create-testers:
- specifier: 0.1.0-alpha.11
- version: 0.1.0-alpha.11(create@0.1.0-alpha.11(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(typescript@5.7.2))
+ specifier: 0.1.0-alpha.14
+ version: 0.1.0-alpha.14(create-fs@0.1.1)(create@0.1.0-alpha.15)
cspell:
- specifier: 8.17.1
- version: 8.17.1
+ specifier: ^8.17.2
+ version: 8.17.2
eslint:
specifier: 9.17.0
version: 9.17.0(jiti@2.4.0)
@@ -186,9 +162,6 @@ importers:
eslint-plugin-yml:
specifier: 1.16.0
version: 1.16.0(eslint@9.17.0(jiti@2.4.0))
- globby:
- specifier: 14.0.2
- version: 14.0.2
husky:
specifier: 9.1.7
version: 9.1.7
@@ -204,6 +177,9 @@ importers:
markdownlint-cli:
specifier: 0.43.0
version: 0.43.0
+ prettier:
+ specifier: ^3.4.2
+ version: 3.4.2
prettier-plugin-curly:
specifier: 0.3.1
version: 0.3.1(prettier@3.4.2)
@@ -221,10 +197,7 @@ importers:
version: 0.3.0
tsup:
specifier: 8.3.5
- version: 8.3.5(jiti@2.4.0)(postcss@8.4.36)(tsx@4.19.2)(typescript@5.7.2)(yaml@2.6.1)
- tsx:
- specifier: 4.19.2
- version: 4.19.2
+ version: 8.3.5(jiti@2.4.0)(postcss@8.4.36)(tsx@4.19.2)(typescript@5.7.2)(yaml@2.7.0)
typescript:
specifier: 5.7.2
version: 5.7.2
@@ -292,15 +265,11 @@ packages:
'@bcoe/v8-coverage@0.2.3':
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
- '@bcoe/v8-coverage@1.0.1':
- resolution: {integrity: sha512-W+a0/JpU28AqH4IKtwUPcEUnUyXMDLALcn5/JLczGGT9fHE2sIby/xP/oQnx3nxkForzgzPy201RAKcB4xPAFQ==}
- engines: {node: '>=18'}
+ '@clack/core@0.4.1':
+ resolution: {integrity: sha512-Pxhij4UXg8KSr7rPek6Zowm+5M22rbd2g1nfojHJkxp5YkFqiZ2+YLEM/XGVIzvGOcM0nqjIFxrpDwWRZYWYjA==}
- '@clack/core@0.4.0':
- resolution: {integrity: sha512-YJCYBsyJfNDaTbvDUVSJ3SgSuPrcujarRgkJ5NLjexDZKvaOiVVJvAQYx8lIgG0qRT8ff0fPgqyBCVivanIZ+A==}
-
- '@clack/prompts@0.9.0':
- resolution: {integrity: sha512-nGsytiExgUr4FL0pR/LeqxA28nz3E0cW7eLTSh3Iod9TGrbBt8Y7BHbV3mmkNC4G0evdYyQ3ZsbiBkk7ektArA==}
+ '@clack/prompts@0.9.1':
+ resolution: {integrity: sha512-JIpyaboYZeWYlyP0H+OoPPxd6nqueG/CmN6ixBiNFsIDHREevjIf0n0Ohh5gr5C8pEDknzgvz+pIJ8dMhzWIeg==}
'@conventional-changelog/git-client@1.0.1':
resolution: {integrity: sha512-PJEqBwAleffCMETaVm/fUgHldzBE35JFk3/9LL6NUA5EXa3qednu+UT6M7E5iBu3zIQZCULYIiZ90fBYHt6xUw==}
@@ -314,217 +283,223 @@ packages:
conventional-commits-parser:
optional: true
- '@cspell/cspell-bundled-dicts@8.17.1':
- resolution: {integrity: sha512-HmkXS5uX4bk/XxsRS4Q+zRvhgRa81ddGiR2/Xfag9MIi5L5UnEJ4g21EpmIlXkMxYrTu2fp69SZFss5NfcFF9Q==}
+ '@cspell/cspell-bundled-dicts@8.17.2':
+ resolution: {integrity: sha512-t+DQtruJF2cYfXF5GC4F0O/PQR04hL5WH55R9oOaor5i7K8ejbw6+jex2LB0XbZFf3qBhXNSnMPuM3b/113LnA==}
engines: {node: '>=18'}
- '@cspell/cspell-json-reporter@8.17.1':
- resolution: {integrity: sha512-EV9Xkh42Xw3aORvDZfxusICX91DDbqQpYdGKBdPGuhgxWOUYYZKpLXsHCmDkhruMPo2m5gDh++/OqjLRPZofKQ==}
+ '@cspell/cspell-json-reporter@8.17.2':
+ resolution: {integrity: sha512-9QFzuSApaK7SYB50iCTRIUDjFZf6DXTFj8+qTR2cky+/YmEcHDpJieJVCd3STONO4m2JyqIsV7faEuA6M0YcHg==}
engines: {node: '>=18'}
- '@cspell/cspell-pipe@8.17.1':
- resolution: {integrity: sha512-uhC99Ox+OH3COSgShv4fpVHiotR70dNvAOSkzRvKVRzV6IGyFnxHjmyVVPEV0dsqzVLxltwYTqFhwI+UOwm45A==}
+ '@cspell/cspell-pipe@8.17.2':
+ resolution: {integrity: sha512-LOTKK+hZSUc7vaN8SBEOcv+9dMYbo84awbsjjdI+HkKVBfTt3Lzlu6IJImw39L6pTDAJ1ZxOUdWO89jcxpyihg==}
engines: {node: '>=18'}
- '@cspell/cspell-resolver@8.17.1':
- resolution: {integrity: sha512-XEK2ymTdQNgsV3ny60VkKzWskbICl4zNXh/DbxsoRXHqIRg43MXFpTNkEJ7j873EqdX7BU4opQQ+5D4stWWuhQ==}
+ '@cspell/cspell-resolver@8.17.2':
+ resolution: {integrity: sha512-Z2ndlzVIiXOCBnQby9q+OXcxeddiuCi//pnhO9Jf6Ixgthn+Yg7bwzAnHu+CM1SJaQnZCntGyimdxfojm+WDdA==}
engines: {node: '>=18'}
- '@cspell/cspell-service-bus@8.17.1':
- resolution: {integrity: sha512-2sFWQtMEWZ4tdz7bw0bAx4NaV1t0ynGfjpuKWdQppsJFKNb+ZPZZ6Ah1dC13AdRRMZaG194kDRFwzNvRaCgWkQ==}
+ '@cspell/cspell-service-bus@8.17.2':
+ resolution: {integrity: sha512-Cp4kVxJRyyDRd5RVTASlu+ygWG+dgy6GyH7lzb6P8SOXt1mxzCBK6Q5Dc1XHAsvhRaLrnMziCO/5Pj9/0DKs6w==}
engines: {node: '>=18'}
- '@cspell/cspell-types@8.17.1':
- resolution: {integrity: sha512-NJbov7Jp57fh8addoxesjb8atg/APQfssCH5Q9uZuHBN06wEJDgs7fhfE48bU+RBViC9gltblsYZzZZQKzHYKg==}
+ '@cspell/cspell-types@8.17.2':
+ resolution: {integrity: sha512-4kMBhX92p0pchEzYTpyLCoe/bUJ29YYvMINTeHTd//hLQh0ZAyMGY1opDm1tqaXX0qpYmWG60KcvN4fCR0i6lw==}
engines: {node: '>=18'}
- '@cspell/dict-ada@4.0.5':
- resolution: {integrity: sha512-6/RtZ/a+lhFVmrx/B7bfP7rzC4yjEYe8o74EybXcvu4Oue6J4Ey2WSYj96iuodloj1LWrkNCQyX5h4Pmcj0Iag==}
+ '@cspell/dict-ada@4.1.0':
+ resolution: {integrity: sha512-7SvmhmX170gyPd+uHXrfmqJBY5qLcCX8kTGURPVeGxmt8XNXT75uu9rnZO+jwrfuU2EimNoArdVy5GZRGljGNg==}
- '@cspell/dict-al@1.0.3':
- resolution: {integrity: sha512-V1HClwlfU/qwSq2Kt+MkqRAsonNu3mxjSCDyGRecdLGIHmh7yeEeaxqRiO/VZ4KP+eVSiSIlbwrb5YNFfxYZbw==}
+ '@cspell/dict-al@1.1.0':
+ resolution: {integrity: sha512-PtNI1KLmYkELYltbzuoztBxfi11jcE9HXBHCpID2lou/J4VMYKJPNqe4ZjVzSI9NYbMnMnyG3gkbhIdx66VSXg==}
- '@cspell/dict-aws@4.0.7':
- resolution: {integrity: sha512-PoaPpa2NXtSkhGIMIKhsJUXB6UbtTt6Ao3x9JdU9kn7fRZkwD4RjHDGqulucIOz7KeEX/dNRafap6oK9xHe4RA==}
+ '@cspell/dict-aws@4.0.9':
+ resolution: {integrity: sha512-bDYdnnJGwSkIZ4gzrauu7qzOs/ZAY/FnU4k11LgdMI8BhwMfsbsy2EI1iS+sD/BI5ZnNT9kU5YR3WADeNOmhRg==}
- '@cspell/dict-bash@4.1.8':
- resolution: {integrity: sha512-I2CM2pTNthQwW069lKcrVxchJGMVQBzru2ygsHCwgidXRnJL/NTjAPOFTxN58Jc1bf7THWghfEDyKX/oyfc0yg==}
+ '@cspell/dict-bash@4.2.0':
+ resolution: {integrity: sha512-HOyOS+4AbCArZHs/wMxX/apRkjxg6NDWdt0jF9i9XkvJQUltMwEhyA2TWYjQ0kssBsnof+9amax2lhiZnh3kCg==}
- '@cspell/dict-companies@3.1.9':
- resolution: {integrity: sha512-w7XEJ2B6x2jq9ws5XNyYgpYj2MxdZ3jW3PETLxjK7nc8pulCFmaGVgZ0JTnDWfJ3QMOczoagn5f9LM2PZ/CuJg==}
+ '@cspell/dict-companies@3.1.12':
+ resolution: {integrity: sha512-99FxBNdLOQc3nVQ663Xh7JqDLbIy/AdqOecQ5bk3HpmXpSkoDvTT7XCUU5nQZvmFBrrQlXFKlRRYjLfTEOUDdA==}
- '@cspell/dict-cpp@6.0.2':
- resolution: {integrity: sha512-yw5eejWvY4bAnc6LUA44m4WsFwlmgPt2uMSnO7QViGMBDuoeopMma4z9XYvs4lSjTi8fIJs/A1YDfM9AVzb8eg==}
+ '@cspell/dict-cpp@6.0.3':
+ resolution: {integrity: sha512-OFrVXdxCeGKnon36Pe3yFjBuY4kzzEwWFf3vDz+cJTodZDkjFkBifQeTtt5YfimgF8cfAJZXkBCsxjipAgmAiw==}
- '@cspell/dict-cryptocurrencies@5.0.3':
- resolution: {integrity: sha512-bl5q+Mk+T3xOZ12+FG37dB30GDxStza49Rmoax95n37MTLksk9wBo1ICOlPJ6PnDUSyeuv4SIVKgRKMKkJJglA==}
+ '@cspell/dict-cryptocurrencies@5.0.4':
+ resolution: {integrity: sha512-6iFu7Abu+4Mgqq08YhTKHfH59mpMpGTwdzDB2Y8bbgiwnGFCeoiSkVkgLn1Kel2++hYcZ8vsAW/MJS9oXxuMag==}
- '@cspell/dict-csharp@4.0.5':
- resolution: {integrity: sha512-c/sFnNgtRwRJxtC3JHKkyOm+U3/sUrltFeNwml9VsxKBHVmvlg4tk4ar58PdpW9/zTlGUkWi2i85//DN1EsUCA==}
+ '@cspell/dict-csharp@4.0.6':
+ resolution: {integrity: sha512-w/+YsqOknjQXmIlWDRmkW+BHBPJZ/XDrfJhZRQnp0wzpPOGml7W0q1iae65P2AFRtTdPKYmvSz7AL5ZRkCnSIw==}
- '@cspell/dict-css@4.0.16':
- resolution: {integrity: sha512-70qu7L9z/JR6QLyJPk38fNTKitlIHnfunx0wjpWQUQ8/jGADIhMCrz6hInBjqPNdtGpYm8d1dNFyF8taEkOgrQ==}
+ '@cspell/dict-css@4.0.17':
+ resolution: {integrity: sha512-2EisRLHk6X/PdicybwlajLGKF5aJf4xnX2uuG5lexuYKt05xV/J/OiBADmi8q9obhxf1nesrMQbqAt+6CsHo/w==}
- '@cspell/dict-dart@2.2.4':
- resolution: {integrity: sha512-of/cVuUIZZK/+iqefGln8G3bVpfyN6ZtH+LyLkHMoR5tEj+2vtilGNk9ngwyR8L4lEqbKuzSkOxgfVjsXf5PsQ==}
+ '@cspell/dict-dart@2.3.0':
+ resolution: {integrity: sha512-1aY90lAicek8vYczGPDKr70pQSTQHwMFLbmWKTAI6iavmb1fisJBS1oTmMOKE4ximDf86MvVN6Ucwx3u/8HqLg==}
- '@cspell/dict-data-science@2.0.5':
- resolution: {integrity: sha512-nNSILXmhSJox9/QoXICPQgm8q5PbiSQP4afpbkBqPi/u/b3K9MbNH5HvOOa6230gxcGdbZ9Argl2hY/U8siBlg==}
+ '@cspell/dict-data-science@2.0.6':
+ resolution: {integrity: sha512-gOYKZOg358yhnnQfr1/f232REmjeIymXUHJdrLEMPirluv2rzMWvEBBazqRVQ++jMUNg9IduVI0v096ZWMDekA==}
- '@cspell/dict-django@4.1.3':
- resolution: {integrity: sha512-yBspeL3roJlO0a1vKKNaWABURuHdHZ9b1L8d3AukX0AsBy9snSggc8xCavPmSzNfeMDXbH+1lgQiYBd3IW03fg==}
+ '@cspell/dict-django@4.1.4':
+ resolution: {integrity: sha512-fX38eUoPvytZ/2GA+g4bbdUtCMGNFSLbdJJPKX2vbewIQGfgSFJKY56vvcHJKAvw7FopjvgyS/98Ta9WN1gckg==}
- '@cspell/dict-docker@1.1.11':
- resolution: {integrity: sha512-s0Yhb16/R+UT1y727ekbR/itWQF3Qz275DR1ahOa66wYtPjHUXmhM3B/LT3aPaX+hD6AWmK23v57SuyfYHUjsw==}
+ '@cspell/dict-docker@1.1.12':
+ resolution: {integrity: sha512-6d25ZPBnYZaT9D9An/x6g/4mk542R8bR3ipnby3QFCxnfdd6xaWiTcwDPsCgwN2aQZIQ1jX/fil9KmBEqIK/qA==}
- '@cspell/dict-dotnet@5.0.8':
- resolution: {integrity: sha512-MD8CmMgMEdJAIPl2Py3iqrx3B708MbCIXAuOeZ0Mzzb8YmLmiisY7QEYSZPg08D7xuwARycP0Ki+bb0GAkFSqg==}
+ '@cspell/dict-dotnet@5.0.9':
+ resolution: {integrity: sha512-JGD6RJW5sHtO5lfiJl11a5DpPN6eKSz5M1YBa1I76j4dDOIqgZB6rQexlDlK1DH9B06X4GdDQwdBfnpAB0r2uQ==}
- '@cspell/dict-elixir@4.0.6':
- resolution: {integrity: sha512-TfqSTxMHZ2jhiqnXlVKM0bUADtCvwKQv2XZL/DI0rx3doG8mEMS8SGPOmiyyGkHpR/pGOq18AFH3BEm4lViHIw==}
+ '@cspell/dict-elixir@4.0.7':
+ resolution: {integrity: sha512-MAUqlMw73mgtSdxvbAvyRlvc3bYnrDqXQrx5K9SwW8F7fRYf9V4vWYFULh+UWwwkqkhX9w03ZqFYRTdkFku6uA==}
- '@cspell/dict-en-common-misspellings@2.0.7':
- resolution: {integrity: sha512-qNFo3G4wyabcwnM+hDrMYKN9vNVg/k9QkhqSlSst6pULjdvPyPs1mqz1689xO/v9t8e6sR4IKc3CgUXDMTYOpA==}
+ '@cspell/dict-en-common-misspellings@2.0.8':
+ resolution: {integrity: sha512-l1u/pDjwrPyWwBd1hCkZhdsK8yLbLFPD2xWz+1tFFI7WaV9ckDZoF3woRc/0wFGRy53yrfSAVuwhoYOQnHe/fA==}
'@cspell/dict-en-gb@1.1.33':
resolution: {integrity: sha512-tKSSUf9BJEV+GJQAYGw5e+ouhEe2ZXE620S7BLKe3ZmpnjlNG9JqlnaBhkIMxKnNFkLY2BP/EARzw31AZnOv4g==}
- '@cspell/dict-en_us@4.3.28':
- resolution: {integrity: sha512-BN1PME7cOl7DXRQJ92pEd1f0Xk5sqjcDfThDGkKcsgwbSOY7KnTc/czBW6Pr3WXIchIm6cT12KEfjNqx7U7Rrw==}
+ '@cspell/dict-en_us@4.3.29':
+ resolution: {integrity: sha512-7kHP0sJ271oS5RqakxvhWvHFoCUFCBDV6+cgIRIpKwW0aYVB4F2AwElGsdeE/XEmihhYUje7e/e6X3IEWHrcrQ==}
- '@cspell/dict-filetypes@3.0.9':
- resolution: {integrity: sha512-U7ycC1cE32A5aEgwzp/iE0TVabonUFnVt+Ygbf6NsIWqEuFWZgZChC7gfztA4T1fpuj602nFdp7eOnTWKORsnQ==}
+ '@cspell/dict-filetypes@3.0.10':
+ resolution: {integrity: sha512-JEN3627joBVtpa1yfkdN9vz1Z129PoKGHBKjXCEziJvf2Zt1LeULWYYYg/O6pzRR4yzRa5YbXDTuyrN7vX7DFg==}
- '@cspell/dict-flutter@1.0.3':
- resolution: {integrity: sha512-52C9aUEU22ptpgYh6gQyIdA4MP6NPwzbEqndfgPh3Sra191/kgs7CVqXiO1qbtZa9gnYHUoVApkoxRE7mrXHfg==}
+ '@cspell/dict-flutter@1.1.0':
+ resolution: {integrity: sha512-3zDeS7zc2p8tr9YH9tfbOEYfopKY/srNsAa+kE3rfBTtQERAZeOhe5yxrnTPoufctXLyuUtcGMUTpxr3dO0iaA==}
- '@cspell/dict-fonts@4.0.3':
- resolution: {integrity: sha512-sPd17kV5qgYXLteuHFPn5mbp/oCHKgitNfsZLFC3W2fWEgZlhg4hK+UGig3KzrYhhvQ8wBnmZrAQm0TFKCKzsA==}
+ '@cspell/dict-fonts@4.0.4':
+ resolution: {integrity: sha512-cHFho4hjojBcHl6qxidl9CvUb492IuSk7xIf2G2wJzcHwGaCFa2o3gRcxmIg1j62guetAeDDFELizDaJlVRIOg==}
- '@cspell/dict-fsharp@1.0.4':
- resolution: {integrity: sha512-G5wk0o1qyHUNi9nVgdE1h5wl5ylq7pcBjX8vhjHcO4XBq20D5eMoXjwqMo/+szKAqzJ+WV3BgAL50akLKrT9Rw==}
+ '@cspell/dict-fsharp@1.1.0':
+ resolution: {integrity: sha512-oguWmHhGzgbgbEIBKtgKPrFSVAFtvGHaQS0oj+vacZqMObwkapcTGu7iwf4V3Bc2T3caf0QE6f6rQfIJFIAVsw==}
'@cspell/dict-fullstack@3.2.3':
resolution: {integrity: sha512-62PbndIyQPH11mAv0PyiyT0vbwD0AXEocPpHlCHzfb5v9SspzCCbzQ/LIBiFmyRa+q5LMW35CnSVu6OXdT+LKg==}
- '@cspell/dict-gaming-terms@1.0.9':
- resolution: {integrity: sha512-AVIrZt3YiUnxsUzzGYTZ1XqgtkgwGEO0LWIlEf+SiDUEVLtv4CYmmyXFQ+WXDN0pyJ0wOwDazWrP0Cu7avYQmQ==}
+ '@cspell/dict-gaming-terms@1.1.0':
+ resolution: {integrity: sha512-46AnDs9XkgJ2f1Sqol1WgfJ8gOqp60fojpc9Wxch7x+BA63g4JfMV5/M5x0sI0TLlLY8EBSglcr8wQF/7C80AQ==}
- '@cspell/dict-git@3.0.3':
- resolution: {integrity: sha512-LSxB+psZ0qoj83GkyjeEH/ZViyVsGEF/A6BAo8Nqc0w0HjD2qX/QR4sfA6JHUgQ3Yi/ccxdK7xNIo67L2ScW5A==}
+ '@cspell/dict-git@3.0.4':
+ resolution: {integrity: sha512-C44M+m56rYn6QCsLbiKiedyPTMZxlDdEYAsPwwlL5bhMDDzXZ3Ic8OCQIhMbiunhCOJJT+er4URmOmM+sllnjg==}
- '@cspell/dict-golang@6.0.17':
- resolution: {integrity: sha512-uDDLEJ/cHdLiqPw4+5BnmIo2i/TSR+uDvYd6JlBjTmjBKpOCyvUgYRztH7nv5e7virsN5WDiUWah4/ATQGz4Pw==}
+ '@cspell/dict-golang@6.0.18':
+ resolution: {integrity: sha512-Mt+7NwfodDwUk7423DdaQa0YaA+4UoV3XSxQwZioqjpFBCuxfvvv4l80MxCTAAbK6duGj0uHbGTwpv8fyKYPKg==}
- '@cspell/dict-google@1.0.4':
- resolution: {integrity: sha512-JThUT9eiguCja1mHHLwYESgxkhk17Gv7P3b1S7ZJzXw86QyVHPrbpVoMpozHk0C9o+Ym764B7gZGKmw9uMGduQ==}
+ '@cspell/dict-google@1.0.5':
+ resolution: {integrity: sha512-KNrzfUsoFat94slWzo36g601sIGz6KtE4kBMM0gpqwFLK/MXRyaW65IL4SwysY0PEhuRzg9spLLMnUXuVcY2hQ==}
- '@cspell/dict-haskell@4.0.4':
- resolution: {integrity: sha512-EwQsedEEnND/vY6tqRfg9y7tsnZdxNqOxLXSXTsFA6JRhUlr8Qs88iUUAfsUzWc4nNmmzQH2UbtT25ooG9x4nA==}
+ '@cspell/dict-haskell@4.0.5':
+ resolution: {integrity: sha512-s4BG/4tlj2pPM9Ha7IZYMhUujXDnI0Eq1+38UTTCpatYLbQqDwRFf2KNPLRqkroU+a44yTUAe0rkkKbwy4yRtQ==}
'@cspell/dict-html-symbol-entities@4.0.3':
resolution: {integrity: sha512-aABXX7dMLNFdSE8aY844X4+hvfK7977sOWgZXo4MTGAmOzR8524fjbJPswIBK7GaD3+SgFZ2yP2o0CFvXDGF+A==}
- '@cspell/dict-html@4.0.10':
- resolution: {integrity: sha512-I9uRAcdtHbh0wEtYZlgF0TTcgH0xaw1B54G2CW+tx4vHUwlde/+JBOfIzird4+WcMv4smZOfw+qHf7puFUbI5g==}
+ '@cspell/dict-html@4.0.11':
+ resolution: {integrity: sha512-QR3b/PB972SRQ2xICR1Nw/M44IJ6rjypwzA4jn+GH8ydjAX9acFNfc+hLZVyNe0FqsE90Gw3evLCOIF0vy1vQw==}
+
+ '@cspell/dict-java@5.0.11':
+ resolution: {integrity: sha512-T4t/1JqeH33Raa/QK/eQe26FE17eUCtWu+JsYcTLkQTci2dk1DfcIKo8YVHvZXBnuM43ATns9Xs0s+AlqDeH7w==}
- '@cspell/dict-java@5.0.10':
- resolution: {integrity: sha512-pVNcOnmoGiNL8GSVq4WbX/Vs2FGS0Nej+1aEeGuUY9CU14X8yAVCG+oih5ZoLt1jaR8YfR8byUF8wdp4qG4XIw==}
+ '@cspell/dict-julia@1.1.0':
+ resolution: {integrity: sha512-CPUiesiXwy3HRoBR3joUseTZ9giFPCydSKu2rkh6I2nVjXnl5vFHzOMLXpbF4HQ1tH2CNfnDbUndxD+I+7eL9w==}
- '@cspell/dict-julia@1.0.4':
- resolution: {integrity: sha512-bFVgNX35MD3kZRbXbJVzdnN7OuEqmQXGpdOi9jzB40TSgBTlJWA4nxeAKV4CPCZxNRUGnLH0p05T/AD7Aom9/w==}
+ '@cspell/dict-k8s@1.0.10':
+ resolution: {integrity: sha512-313haTrX9prep1yWO7N6Xw4D6tvUJ0Xsx+YhCP+5YrrcIKoEw5Rtlg8R4PPzLqe6zibw6aJ+Eqq+y76Vx5BZkw==}
- '@cspell/dict-k8s@1.0.9':
- resolution: {integrity: sha512-Q7GELSQIzo+BERl2ya/nBEnZeQC+zJP19SN1pI6gqDYraM51uYJacbbcWLYYO2Y+5joDjNt/sd/lJtLaQwoSlA==}
+ '@cspell/dict-kotlin@1.1.0':
+ resolution: {integrity: sha512-vySaVw6atY7LdwvstQowSbdxjXG6jDhjkWVWSjg1XsUckyzH1JRHXe9VahZz1i7dpoFEUOWQrhIe5B9482UyJQ==}
'@cspell/dict-latex@4.0.3':
resolution: {integrity: sha512-2KXBt9fSpymYHxHfvhUpjUFyzrmN4c4P8mwIzweLyvqntBT3k0YGZJSriOdjfUjwSygrfEwiuPI1EMrvgrOMJw==}
- '@cspell/dict-lorem-ipsum@4.0.3':
- resolution: {integrity: sha512-WFpDi/PDYHXft6p0eCXuYnn7mzMEQLVeqpO+wHSUd+kz5ADusZ4cpslAA4wUZJstF1/1kMCQCZM6HLZic9bT8A==}
+ '@cspell/dict-lorem-ipsum@4.0.4':
+ resolution: {integrity: sha512-+4f7vtY4dp2b9N5fn0za/UR0kwFq2zDtA62JCbWHbpjvO9wukkbl4rZg4YudHbBgkl73HRnXFgCiwNhdIA1JPw==}
- '@cspell/dict-lua@4.0.6':
- resolution: {integrity: sha512-Jwvh1jmAd9b+SP9e1GkS2ACbqKKRo9E1f9GdjF/ijmooZuHU0hPyqvnhZzUAxO1egbnNjxS/J2T6iUtjAUK2KQ==}
+ '@cspell/dict-lua@4.0.7':
+ resolution: {integrity: sha512-Wbr7YSQw+cLHhTYTKV6cAljgMgcY+EUAxVIZW3ljKswEe4OLxnVJ7lPqZF5JKjlXdgCjbPSimsHqyAbC5pQN/Q==}
- '@cspell/dict-makefile@1.0.3':
- resolution: {integrity: sha512-R3U0DSpvTs6qdqfyBATnePj9Q/pypkje0Nj26mQJ8TOBQutCRAJbr2ZFAeDjgRx5EAJU/+8txiyVF97fbVRViw==}
+ '@cspell/dict-makefile@1.0.4':
+ resolution: {integrity: sha512-E4hG/c0ekPqUBvlkrVvzSoAA+SsDA9bLi4xSV3AXHTVru7Y2bVVGMPtpfF+fI3zTkww/jwinprcU1LSohI3ylw==}
- '@cspell/dict-markdown@2.0.7':
- resolution: {integrity: sha512-F9SGsSOokFn976DV4u/1eL4FtKQDSgJHSZ3+haPRU5ki6OEqojxKa8hhj4AUrtNFpmBaJx/WJ4YaEzWqG7hgqg==}
+ '@cspell/dict-markdown@2.0.9':
+ resolution: {integrity: sha512-j2e6Eg18BlTb1mMP1DkyRFMM/FLS7qiZjltpURzDckB57zDZbUyskOFdl4VX7jItZZEeY0fe22bSPOycgS1Z5A==}
peerDependencies:
- '@cspell/dict-css': ^4.0.16
- '@cspell/dict-html': ^4.0.10
+ '@cspell/dict-css': ^4.0.17
+ '@cspell/dict-html': ^4.0.11
'@cspell/dict-html-symbol-entities': ^4.0.3
- '@cspell/dict-typescript': ^3.1.11
+ '@cspell/dict-typescript': ^3.2.0
- '@cspell/dict-monkeyc@1.0.9':
- resolution: {integrity: sha512-Jvf6g5xlB4+za3ThvenYKREXTEgzx5gMUSzrAxIiPleVG4hmRb/GBSoSjtkGaibN3XxGx5x809gSTYCA/IHCpA==}
+ '@cspell/dict-monkeyc@1.0.10':
+ resolution: {integrity: sha512-7RTGyKsTIIVqzbvOtAu6Z/lwwxjGRtY5RkKPlXKHEoEAgIXwfDxb5EkVwzGQwQr8hF/D3HrdYbRT8MFBfsueZw==}
- '@cspell/dict-node@5.0.5':
- resolution: {integrity: sha512-7NbCS2E8ZZRZwlLrh2sA0vAk9n1kcTUiRp/Nia8YvKaItGXLfxYqD2rMQ3HpB1kEutal6hQLVic3N2Yi1X7AaA==}
+ '@cspell/dict-node@5.0.6':
+ resolution: {integrity: sha512-CEbhPCpxGvRNByGolSBTrXXW2rJA4bGqZuTx1KKO85mwR6aadeOmUE7xf/8jiCkXSy+qvr9aJeh+jlfXcsrziQ==}
- '@cspell/dict-npm@5.1.18':
- resolution: {integrity: sha512-/Nukl+DSxtEWSlb8svWFSpJVctAsM9SP+f5Q1n+qdDcXNKMb1bUCo/d3QZPwyOhuMjDawnsGBUAfp+iq7Mw83Q==}
+ '@cspell/dict-npm@5.1.22':
+ resolution: {integrity: sha512-fZBTn8QHr8pAv1/I14CmdDWpVkovCfYpSYiGfV1SZkOjrsKLzPxsP84eaP3RijbFtYj3GMplVN27FR3H5oHfiw==}
- '@cspell/dict-php@4.0.13':
- resolution: {integrity: sha512-P6sREMZkhElzz/HhXAjahnICYIqB/HSGp1EhZh+Y6IhvC15AzgtDP8B8VYCIsQof6rPF1SQrFwunxOv8H1e2eg==}
+ '@cspell/dict-php@4.0.14':
+ resolution: {integrity: sha512-7zur8pyncYZglxNmqsRycOZ6inpDoVd4yFfz1pQRe5xaRWMiK3Km4n0/X/1YMWhh3e3Sl/fQg5Axb2hlN68t1g==}
- '@cspell/dict-powershell@5.0.13':
- resolution: {integrity: sha512-0qdj0XZIPmb77nRTynKidRJKTU0Fl+10jyLbAhFTuBWKMypVY06EaYFnwhsgsws/7nNX8MTEQuewbl9bWFAbsg==}
+ '@cspell/dict-powershell@5.0.14':
+ resolution: {integrity: sha512-ktjjvtkIUIYmj/SoGBYbr3/+CsRGNXGpvVANrY0wlm/IoGlGywhoTUDYN0IsGwI2b8Vktx3DZmQkfb3Wo38jBA==}
- '@cspell/dict-public-licenses@2.0.11':
- resolution: {integrity: sha512-rR5KjRUSnVKdfs5G+gJ4oIvQvm8+NJ6cHWY2N+GE69/FSGWDOPHxulCzeGnQU/c6WWZMSimG9o49i9r//lUQyA==}
+ '@cspell/dict-public-licenses@2.0.12':
+ resolution: {integrity: sha512-obreJMVbz8ZrXyc60PcS/B2FwXaO3AWPO2x50zrI/n4UDuBr/UdPb6M1q++6c08n+151I35GEx52xRFiToSg4g==}
- '@cspell/dict-python@4.2.13':
- resolution: {integrity: sha512-mZIcmo9qif8LkJ6N/lqTZawcOk2kVTcuWIUOSbMcjyomO0XZ7iWz15TfONyr03Ea/l7o5ULV+MZ4vx76bAUb7w==}
+ '@cspell/dict-python@4.2.14':
+ resolution: {integrity: sha512-NZ/rsTH5gqTlEwbSg0vn5b1TsyzrUvA6ykwCVCwsVDdlQAS82cyDsF9JqHp8S4d6PFykmkfSxtAXYyOUr0KCbg==}
- '@cspell/dict-r@2.0.4':
- resolution: {integrity: sha512-cBpRsE/U0d9BRhiNRMLMH1PpWgw+N+1A2jumgt1if9nBGmQw4MUpg2u9I0xlFVhstTIdzXiLXMxP45cABuiUeQ==}
+ '@cspell/dict-r@2.1.0':
+ resolution: {integrity: sha512-k2512wgGG0lTpTYH9w5Wwco+lAMf3Vz7mhqV8+OnalIE7muA0RSuD9tWBjiqLcX8zPvEJr4LdgxVju8Gk3OKyA==}
'@cspell/dict-ruby@5.0.7':
resolution: {integrity: sha512-4/d0hcoPzi5Alk0FmcyqlzFW9lQnZh9j07MJzPcyVO62nYJJAGKaPZL2o4qHeCS/od/ctJC5AHRdoUm0ktsw6Q==}
- '@cspell/dict-rust@4.0.10':
- resolution: {integrity: sha512-6o5C8566VGTTctgcwfF3Iy7314W0oMlFFSQOadQ0OEdJ9Z9ERX/PDimrzP3LGuOrvhtEFoK8pj+BLnunNwRNrw==}
+ '@cspell/dict-rust@4.0.11':
+ resolution: {integrity: sha512-OGWDEEzm8HlkSmtD8fV3pEcO2XBpzG2XYjgMCJCRwb2gRKvR+XIm6Dlhs04N/K2kU+iH8bvrqNpM8fS/BFl0uw==}
+
+ '@cspell/dict-scala@5.0.7':
+ resolution: {integrity: sha512-yatpSDW/GwulzO3t7hB5peoWwzo+Y3qTc0pO24Jf6f88jsEeKmDeKkfgPbYuCgbE4jisGR4vs4+jfQZDIYmXPA==}
- '@cspell/dict-scala@5.0.6':
- resolution: {integrity: sha512-tl0YWAfjUVb4LyyE4JIMVE8DlLzb1ecHRmIWc4eT6nkyDqQgHKzdHsnusxFEFMVLIQomgSg0Zz6hJ5S1E4W4ww==}
+ '@cspell/dict-shell@1.1.0':
+ resolution: {integrity: sha512-D/xHXX7T37BJxNRf5JJHsvziFDvh23IF/KvkZXNSh8VqcRdod3BAz9VGHZf6VDqcZXr1VRqIYR3mQ8DSvs3AVQ==}
- '@cspell/dict-software-terms@4.1.20':
- resolution: {integrity: sha512-ma51njqbk9ZKzZF9NpCZpZ+c50EwR5JTJ2LEXlX0tX+ExVbKpthhlDLhT2+mkUh5Zvj+CLf5F9z0qB4+X3re/w==}
+ '@cspell/dict-software-terms@4.2.2':
+ resolution: {integrity: sha512-cgteXRzx2W/Ug7QSdFJrVxLES7krrZEjZ9J6sXRWOsVYFpgu2Gup8NKmjKOZ8NTnCjHQFrMnbmKdv56q9Kwixw==}
- '@cspell/dict-sql@2.1.8':
- resolution: {integrity: sha512-dJRE4JV1qmXTbbGm6WIcg1knmR6K5RXnQxF4XHs5HA3LAjc/zf77F95i5LC+guOGppVF6Hdl66S2UyxT+SAF3A==}
+ '@cspell/dict-sql@2.2.0':
+ resolution: {integrity: sha512-MUop+d1AHSzXpBvQgQkCiok8Ejzb+nrzyG16E8TvKL2MQeDwnIvMe3bv90eukP6E1HWb+V/MA/4pnq0pcJWKqQ==}
- '@cspell/dict-svelte@1.0.5':
- resolution: {integrity: sha512-sseHlcXOqWE4Ner9sg8KsjxwSJ2yssoJNqFHR9liWVbDV+m7kBiUtn2EB690TihzVsEmDr/0Yxrbb5Bniz70mA==}
+ '@cspell/dict-svelte@1.0.6':
+ resolution: {integrity: sha512-8LAJHSBdwHCoKCSy72PXXzz7ulGROD0rP1CQ0StOqXOOlTUeSFaJJlxNYjlONgd2c62XBQiN2wgLhtPN+1Zv7Q==}
- '@cspell/dict-swift@2.0.4':
- resolution: {integrity: sha512-CsFF0IFAbRtYNg0yZcdaYbADF5F3DsM8C4wHnZefQy8YcHP/qjAF/GdGfBFBLx+XSthYuBlo2b2XQVdz3cJZBw==}
+ '@cspell/dict-swift@2.0.5':
+ resolution: {integrity: sha512-3lGzDCwUmnrfckv3Q4eVSW3sK3cHqqHlPprFJZD4nAqt23ot7fic5ALR7J4joHpvDz36nHX34TgcbZNNZOC/JA==}
- '@cspell/dict-terraform@1.0.6':
- resolution: {integrity: sha512-Sqm5vGbXuI9hCFcr4w6xWf4Y25J9SdleE/IqfM6RySPnk8lISEmVdax4k6+Kinv9qaxyvnIbUUN4WFLWcBPQAg==}
+ '@cspell/dict-terraform@1.1.0':
+ resolution: {integrity: sha512-G55pcUUxeXAhejstmD35B47SkFd4uqCQimc+CMgq8Nx0dr03guL2iMsz8faRWQGkCnGimX8S91rbOhDv9p/heg==}
- '@cspell/dict-typescript@3.1.11':
- resolution: {integrity: sha512-FwvK5sKbwrVpdw0e9+1lVTl8FPoHYvfHRuQRQz2Ql5XkC0gwPPkpoyD1zYImjIyZRoYXk3yp9j8ss4iz7A7zoQ==}
+ '@cspell/dict-typescript@3.2.0':
+ resolution: {integrity: sha512-Pk3zNePLT8qg51l0M4g1ISowYAEGxTuNfZlgkU5SvHa9Cu7x/BWoyYq9Fvc3kAyoisCjRPyvWF4uRYrPitPDFw==}
- '@cspell/dict-vue@3.0.3':
- resolution: {integrity: sha512-akmYbrgAGumqk1xXALtDJcEcOMYBYMnkjpmGzH13Ozhq1mkPF4VgllFQlm1xYde+BUKNnzMgPEzxrL2qZllgYA==}
+ '@cspell/dict-vue@3.0.4':
+ resolution: {integrity: sha512-0dPtI0lwHcAgSiQFx8CzvqjdoXROcH+1LyqgROCpBgppommWpVhbQ0eubnKotFEXgpUCONVkeZJ6Ql8NbTEu+w==}
- '@cspell/dynamic-import@8.17.1':
- resolution: {integrity: sha512-XQtr2olYOtqbg49E+8SISd6I5DzfxmsKINDn0ZgaTFeLalnNdF3ewDU4gOEbApIzGffRa1mW9t19MsiVrznSDw==}
+ '@cspell/dynamic-import@8.17.2':
+ resolution: {integrity: sha512-n3AVbyBlTn/pLtYK62mqgDfJIuQHUTY/k8SMUCjyjfgoqd3LcKhS1PmbLfDWPMTODK30cSMMTLejjy2bL6ksEw==}
engines: {node: '>=18.0'}
- '@cspell/filetypes@8.17.1':
- resolution: {integrity: sha512-AxYw6j7EPYtDFAFjwybjFpMc9waXQzurfBXmEVfQ5RQRlbylujLZWwR6GnMqofeNg4oGDUpEjcAZFrgdkvMQlA==}
+ '@cspell/filetypes@8.17.2':
+ resolution: {integrity: sha512-2B+dB4Ls2xiOjg+vEEbAuJTHtMfXSihVzfLGnj9+qUfq47iqrz4ZBvCOfZhYdiVaaZJoZUgIw8ljrUfqFzYDAg==}
engines: {node: '>=18'}
- '@cspell/strong-weak-map@8.17.1':
- resolution: {integrity: sha512-8cY3vLAKdt5gQEMM3Gr57BuQ8sun2NjYNh9qTdrctC1S9gNC7XzFghTYAfHSWR4VrOUcMFLO/izMdsc1KFvFOA==}
+ '@cspell/strong-weak-map@8.17.2':
+ resolution: {integrity: sha512-LbbhdVwtqyJ71X+O7e2PqpDp7zLiY8jmW2CJFLjZYWTUawgav2bpwECGq6O9Gnwqe+fj7yWxGJFDSpXQcCJQAw==}
engines: {node: '>=18'}
- '@cspell/url@8.17.1':
- resolution: {integrity: sha512-LMvReIndW1ckvemElfDgTt282fb2C3C/ZXfsm0pJsTV5ZmtdelCHwzmgSBmY5fDr7D66XDp8EurotSE0K6BTvw==}
+ '@cspell/url@8.17.2':
+ resolution: {integrity: sha512-yy4eYWNX2iutXmy4Igbn/hL/NYaNt94DylohPtgVr0Zxnn/AAArt9Bv1KXPpjB8VFy2wzzPzWmZ+MWDUVpHCbg==}
engines: {node: '>=18.0'}
'@es-joy/jsdoccomment@0.49.0':
@@ -537,8 +512,8 @@ packages:
cpu: [ppc64]
os: [aix]
- '@esbuild/aix-ppc64@0.23.0':
- resolution: {integrity: sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==}
+ '@esbuild/aix-ppc64@0.23.1':
+ resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
@@ -555,8 +530,8 @@ packages:
cpu: [arm64]
os: [android]
- '@esbuild/android-arm64@0.23.0':
- resolution: {integrity: sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==}
+ '@esbuild/android-arm64@0.23.1':
+ resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
@@ -573,8 +548,8 @@ packages:
cpu: [arm]
os: [android]
- '@esbuild/android-arm@0.23.0':
- resolution: {integrity: sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==}
+ '@esbuild/android-arm@0.23.1':
+ resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==}
engines: {node: '>=18'}
cpu: [arm]
os: [android]
@@ -591,8 +566,8 @@ packages:
cpu: [x64]
os: [android]
- '@esbuild/android-x64@0.23.0':
- resolution: {integrity: sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==}
+ '@esbuild/android-x64@0.23.1':
+ resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==}
engines: {node: '>=18'}
cpu: [x64]
os: [android]
@@ -609,8 +584,8 @@ packages:
cpu: [arm64]
os: [darwin]
- '@esbuild/darwin-arm64@0.23.0':
- resolution: {integrity: sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==}
+ '@esbuild/darwin-arm64@0.23.1':
+ resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==}
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
@@ -627,8 +602,8 @@ packages:
cpu: [x64]
os: [darwin]
- '@esbuild/darwin-x64@0.23.0':
- resolution: {integrity: sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==}
+ '@esbuild/darwin-x64@0.23.1':
+ resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==}
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
@@ -645,8 +620,8 @@ packages:
cpu: [arm64]
os: [freebsd]
- '@esbuild/freebsd-arm64@0.23.0':
- resolution: {integrity: sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==}
+ '@esbuild/freebsd-arm64@0.23.1':
+ resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
@@ -663,8 +638,8 @@ packages:
cpu: [x64]
os: [freebsd]
- '@esbuild/freebsd-x64@0.23.0':
- resolution: {integrity: sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==}
+ '@esbuild/freebsd-x64@0.23.1':
+ resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==}
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
@@ -681,8 +656,8 @@ packages:
cpu: [arm64]
os: [linux]
- '@esbuild/linux-arm64@0.23.0':
- resolution: {integrity: sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==}
+ '@esbuild/linux-arm64@0.23.1':
+ resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==}
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
@@ -699,8 +674,8 @@ packages:
cpu: [arm]
os: [linux]
- '@esbuild/linux-arm@0.23.0':
- resolution: {integrity: sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==}
+ '@esbuild/linux-arm@0.23.1':
+ resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==}
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
@@ -717,8 +692,8 @@ packages:
cpu: [ia32]
os: [linux]
- '@esbuild/linux-ia32@0.23.0':
- resolution: {integrity: sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==}
+ '@esbuild/linux-ia32@0.23.1':
+ resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==}
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
@@ -735,8 +710,8 @@ packages:
cpu: [loong64]
os: [linux]
- '@esbuild/linux-loong64@0.23.0':
- resolution: {integrity: sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==}
+ '@esbuild/linux-loong64@0.23.1':
+ resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==}
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
@@ -753,8 +728,8 @@ packages:
cpu: [mips64el]
os: [linux]
- '@esbuild/linux-mips64el@0.23.0':
- resolution: {integrity: sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==}
+ '@esbuild/linux-mips64el@0.23.1':
+ resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==}
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
@@ -771,8 +746,8 @@ packages:
cpu: [ppc64]
os: [linux]
- '@esbuild/linux-ppc64@0.23.0':
- resolution: {integrity: sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==}
+ '@esbuild/linux-ppc64@0.23.1':
+ resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
@@ -789,8 +764,8 @@ packages:
cpu: [riscv64]
os: [linux]
- '@esbuild/linux-riscv64@0.23.0':
- resolution: {integrity: sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==}
+ '@esbuild/linux-riscv64@0.23.1':
+ resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==}
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
@@ -807,8 +782,8 @@ packages:
cpu: [s390x]
os: [linux]
- '@esbuild/linux-s390x@0.23.0':
- resolution: {integrity: sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==}
+ '@esbuild/linux-s390x@0.23.1':
+ resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==}
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
@@ -825,8 +800,8 @@ packages:
cpu: [x64]
os: [linux]
- '@esbuild/linux-x64@0.23.0':
- resolution: {integrity: sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==}
+ '@esbuild/linux-x64@0.23.1':
+ resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
@@ -843,8 +818,8 @@ packages:
cpu: [x64]
os: [netbsd]
- '@esbuild/netbsd-x64@0.23.0':
- resolution: {integrity: sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==}
+ '@esbuild/netbsd-x64@0.23.1':
+ resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==}
engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
@@ -855,8 +830,8 @@ packages:
cpu: [x64]
os: [netbsd]
- '@esbuild/openbsd-arm64@0.23.0':
- resolution: {integrity: sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==}
+ '@esbuild/openbsd-arm64@0.23.1':
+ resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openbsd]
@@ -873,8 +848,8 @@ packages:
cpu: [x64]
os: [openbsd]
- '@esbuild/openbsd-x64@0.23.0':
- resolution: {integrity: sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==}
+ '@esbuild/openbsd-x64@0.23.1':
+ resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==}
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
@@ -891,8 +866,8 @@ packages:
cpu: [x64]
os: [sunos]
- '@esbuild/sunos-x64@0.23.0':
- resolution: {integrity: sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==}
+ '@esbuild/sunos-x64@0.23.1':
+ resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==}
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
@@ -909,8 +884,8 @@ packages:
cpu: [arm64]
os: [win32]
- '@esbuild/win32-arm64@0.23.0':
- resolution: {integrity: sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==}
+ '@esbuild/win32-arm64@0.23.1':
+ resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==}
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
@@ -927,8 +902,8 @@ packages:
cpu: [ia32]
os: [win32]
- '@esbuild/win32-ia32@0.23.0':
- resolution: {integrity: sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==}
+ '@esbuild/win32-ia32@0.23.1':
+ resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==}
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
@@ -945,8 +920,8 @@ packages:
cpu: [x64]
os: [win32]
- '@esbuild/win32-x64@0.23.0':
- resolution: {integrity: sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==}
+ '@esbuild/win32-x64@0.23.1':
+ resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==}
engines: {node: '>=18'}
cpu: [x64]
os: [win32]
@@ -1066,24 +1041,24 @@ packages:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
- '@octokit/app@15.0.1':
- resolution: {integrity: sha512-nwSjC349E6/wruMCo944y1dBC7uKzUYrBMoC4Qx/xfLLBmD+R66oMKB1jXS2HYRF9Hqh/Alq3UNRggVWZxjvUg==}
+ '@octokit/app@15.1.2':
+ resolution: {integrity: sha512-6aKmKvqnJKoVK+kx0mLlBMKmQYoziPw4Rd/PWr0j65QVQlrDXlu6hGU8fmTXt7tNkf/DsubdIaTT4fkoWzCh5g==}
engines: {node: '>= 18'}
- '@octokit/auth-app@7.1.0':
- resolution: {integrity: sha512-cazGaJPSgeZ8NkVYeM/C5l/6IQ5vZnsI8p1aMucadCkt/bndI+q+VqwrlnWbASRmenjOkf1t1RpCKrif53U8gw==}
+ '@octokit/auth-app@7.1.4':
+ resolution: {integrity: sha512-5F+3l/maq9JfWQ4bV28jT2G/K8eu9OJ317yzXPTGe4Kw+lKDhFaS4dQ3Ltmb6xImKxfCQdqDqMXODhc9YLipLw==}
engines: {node: '>= 18'}
- '@octokit/auth-oauth-app@8.1.1':
- resolution: {integrity: sha512-5UtmxXAvU2wfcHIPPDWzVSAWXVJzG3NWsxb7zCFplCWEmMCArSZV0UQu5jw5goLQXbFyOr5onzEH37UJB3zQQg==}
+ '@octokit/auth-oauth-app@8.1.2':
+ resolution: {integrity: sha512-3woNZgq5/S6RS+9ZTq+JdymxVr7E0s4EYxF20ugQvgX3pomdPUL5r/XdTY9wALoBM2eHVy4ettr5fKpatyTyHw==}
engines: {node: '>= 18'}
- '@octokit/auth-oauth-device@7.1.1':
- resolution: {integrity: sha512-HWl8lYueHonuyjrKKIup/1tiy0xcmQCdq5ikvMO1YwkNNkxb6DXfrPjrMYItNLyCP/o2H87WuijuE+SlBTT8eg==}
+ '@octokit/auth-oauth-device@7.1.2':
+ resolution: {integrity: sha512-gTOIzDeV36OhVfxCl69FmvJix7tJIiU6dlxuzLVAzle7fYfO8UDyddr9B+o4CFQVaMBLMGZ9ak2CWMYcGeZnPw==}
engines: {node: '>= 18'}
- '@octokit/auth-oauth-user@5.1.1':
- resolution: {integrity: sha512-rRkMz0ErOppdvEfnemHJXgZ9vTPhBuC6yASeFaB7I2yLMd7QpjfrL1mnvRPlyKo+M6eeLxrKanXJ9Qte29SRsw==}
+ '@octokit/auth-oauth-user@5.1.2':
+ resolution: {integrity: sha512-PgVDDPJgZYb3qSEXK4moksA23tfn68zwSAsQKZ1uH6IV9IaNEYx35OXXI80STQaLYnmEE86AgU0tC1YkM4WjsA==}
engines: {node: '>= 18'}
'@octokit/auth-token@4.0.0':
@@ -1094,16 +1069,16 @@ packages:
resolution: {integrity: sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==}
engines: {node: '>= 18'}
- '@octokit/auth-unauthenticated@6.1.0':
- resolution: {integrity: sha512-zPSmfrUAcspZH/lOFQnVnvjQZsIvmfApQH6GzJrkIunDooU1Su2qt2FfMTSVPRp7WLTQyC20Kd55lF+mIYaohQ==}
+ '@octokit/auth-unauthenticated@6.1.1':
+ resolution: {integrity: sha512-bGXqdN6RhSFHvpPq46SL8sN+F3odQ6oMNLWc875IgoqcC3qus+fOL2th6Tkl94wvdSTy8/OeHzWy/lZebmnhog==}
engines: {node: '>= 18'}
'@octokit/core@5.2.0':
resolution: {integrity: sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==}
engines: {node: '>= 18'}
- '@octokit/core@6.1.2':
- resolution: {integrity: sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==}
+ '@octokit/core@6.1.3':
+ resolution: {integrity: sha512-z+j7DixNnfpdToYsOutStDgeRzJSMnbj8T1C/oQjB6Aa+kRfNjs/Fn7W6c8bmlt6mfy3FkgeKBRnDjxQow5dow==}
engines: {node: '>= 18'}
'@octokit/endpoint@10.1.1':
@@ -1118,30 +1093,30 @@ packages:
resolution: {integrity: sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==}
engines: {node: '>= 18'}
- '@octokit/graphql@8.1.1':
- resolution: {integrity: sha512-ukiRmuHTi6ebQx/HFRCXKbDlOh/7xEV6QUXaE7MJEKGNAncGI/STSbOkl12qVXZrfZdpXctx5O9X1AIaebiDBg==}
+ '@octokit/graphql@8.1.2':
+ resolution: {integrity: sha512-bdlj/CJVjpaz06NBpfHhp4kGJaRZfz7AzC+6EwUImRtrwIw8dIgJ63Xg0OzV9pRn3rIzrt5c2sa++BL0JJ8GLw==}
engines: {node: '>= 18'}
- '@octokit/oauth-app@7.1.2':
- resolution: {integrity: sha512-4ntCOZIiTozKwuYQroX/ZD722tzMH8Eicv/cgDM/3F3lyrlwENHDv4flTCBpSJbfK546B2SrkKMWB+/HbS84zQ==}
+ '@octokit/oauth-app@7.1.5':
+ resolution: {integrity: sha512-/Y2MiwWDlGUK4blKKfjJiwjzu/FzwKTTTfTZAAQ0QbdBIDEGJPWhOFH6muSN86zaa4tNheB4YS3oWIR2e4ydzA==}
engines: {node: '>= 18'}
'@octokit/oauth-authorization-url@7.1.1':
resolution: {integrity: sha512-ooXV8GBSabSWyhLUowlMIVd9l1s2nsOGQdlP2SQ4LnkEsGXzeCvbSbCPdZThXhEFzleGPwbapT0Sb+YhXRyjCA==}
engines: {node: '>= 18'}
- '@octokit/oauth-methods@5.1.2':
- resolution: {integrity: sha512-C5lglRD+sBlbrhCUTxgJAFjWgJlmTx5bQ7Ch0+2uqRjYv7Cfb5xpX4WuSC9UgQna3sqRGBL9EImX9PvTpMaQ7g==}
+ '@octokit/oauth-methods@5.1.3':
+ resolution: {integrity: sha512-M+bDBi5H8FnH0xhCTg0m9hvcnppdDnxUqbZyOkxlLblKpLAR+eT2nbDPvJDp0eLrvJWA1I8OX0KHf/sBMQARRA==}
engines: {node: '>= 18'}
- '@octokit/openapi-types@22.2.0':
- resolution: {integrity: sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==}
+ '@octokit/openapi-types@23.0.1':
+ resolution: {integrity: sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==}
- '@octokit/openapi-webhooks-types@8.2.1':
- resolution: {integrity: sha512-msAU1oTSm0ZmvAE0xDemuF4tVs5i0xNnNGtNmr4EuATi+1Rn8cZDetj6NXioSf5LwnxEc209COa/WOSbjuhLUA==}
+ '@octokit/openapi-webhooks-types@8.5.1':
+ resolution: {integrity: sha512-i3h1b5zpGSB39ffBbYdSGuAd0NhBAwPyA3QV3LYi/lx4lsbZiu7u2UHgXVUR6EpvOI8REOuVh1DZTRfHoJDvuQ==}
- '@octokit/plugin-paginate-graphql@5.2.2':
- resolution: {integrity: sha512-7znSVvlNAOJisCqAnjN1FtEziweOHSjPGAuc5W58NeGNAr/ZB57yCsjQbXDlWsVryA7hHQaEQPcBbJYFawlkyg==}
+ '@octokit/plugin-paginate-graphql@5.2.4':
+ resolution: {integrity: sha512-pLZES1jWaOynXKHOqdnwZ5ULeVR6tVVCMm+AUbp0htdcyXDU95WbkYdU4R2ej1wKj5Tu94Mee2Ne0PjPO9cCyA==}
engines: {node: '>= 18'}
peerDependencies:
'@octokit/core': '>=6'
@@ -1152,6 +1127,12 @@ packages:
peerDependencies:
'@octokit/core': '5'
+ '@octokit/plugin-paginate-rest@11.4.0':
+ resolution: {integrity: sha512-ttpGck5AYWkwMkMazNCZMqxKqIq1fJBNxBfsFwwfyYKTf914jKkLF0POMS3YkPBwp5g1c2Y4L79gDz01GhSr1g==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ '@octokit/core': '>=6'
+
'@octokit/plugin-request-log@4.0.0':
resolution: {integrity: sha512-2uJI1COtYCq8Z4yNSnM231TgH50bRkheQ9+aH8TnZanB6QilOnx8RMD2qsnamSOXtDj0ilxvevf5fGsBhBBzKA==}
engines: {node: '>= 18'}
@@ -1164,47 +1145,53 @@ packages:
peerDependencies:
'@octokit/core': ^5
- '@octokit/plugin-retry@7.1.1':
- resolution: {integrity: sha512-G9Ue+x2odcb8E1XIPhaFBnTTIrrUDfXN05iFXiqhR+SeeeDMMILcAnysOsxUpEWcQp2e5Ft397FCXTcPkiPkLw==}
+ '@octokit/plugin-rest-endpoint-methods@13.3.0':
+ resolution: {integrity: sha512-LUm44shlmkp/6VC+qQgHl3W5vzUP99ZM54zH6BuqkJK4DqfFLhegANd+fM4YRLapTvPm4049iG7F3haANKMYvQ==}
engines: {node: '>= 18'}
peerDependencies:
'@octokit/core': '>=6'
- '@octokit/plugin-throttling@9.3.0':
- resolution: {integrity: sha512-B5YTToSRTzNSeEyssnrT7WwGhpIdbpV9NKIs3KyTWHX6PhpYn7gqF/+lL3BvsASBM3Sg5BAUYk7KZx5p/Ec77w==}
+ '@octokit/plugin-retry@7.1.3':
+ resolution: {integrity: sha512-8nKOXvYWnzv89gSyIvgFHmCBAxfQAOPRlkacUHL9r5oWtp5Whxl8Skb2n3ACZd+X6cYijD6uvmrQuPH/UCL5zQ==}
engines: {node: '>= 18'}
peerDependencies:
- '@octokit/core': ^6.0.0
+ '@octokit/core': '>=6'
+
+ '@octokit/plugin-throttling@9.4.0':
+ resolution: {integrity: sha512-IOlXxXhZA4Z3m0EEYtrrACkuHiArHLZ3CvqWwOez/pURNqRuwfoFlTPbN5Muf28pzFuztxPyiUiNwz8KctdZaQ==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ '@octokit/core': ^6.1.3
'@octokit/request-error@5.1.0':
resolution: {integrity: sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==}
engines: {node: '>= 18'}
- '@octokit/request-error@6.1.5':
- resolution: {integrity: sha512-IlBTfGX8Yn/oFPMwSfvugfncK2EwRLjzbrpifNaMY8o/HTEAFqCA1FZxjD9cWvSKBHgrIhc4CSBIzMxiLsbzFQ==}
+ '@octokit/request-error@6.1.6':
+ resolution: {integrity: sha512-pqnVKYo/at0NuOjinrgcQYpEbv4snvP3bKMRqHaD9kIsk9u1LCpb2smHZi8/qJfgeNqLo5hNW4Z7FezNdEo0xg==}
engines: {node: '>= 18'}
'@octokit/request@8.4.0':
resolution: {integrity: sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==}
engines: {node: '>= 18'}
- '@octokit/request@9.1.1':
- resolution: {integrity: sha512-pyAguc0p+f+GbQho0uNetNQMmLG1e80WjkIaqqgUkihqUp0boRU6nKItXO4VWnr+nbZiLGEyy4TeKRwqaLvYgw==}
+ '@octokit/request@9.1.4':
+ resolution: {integrity: sha512-tMbOwGm6wDII6vygP3wUVqFTw3Aoo0FnVQyhihh8vVq12uO3P+vQZeo2CKMpWtPSogpACD0yyZAlVlQnjW71DA==}
engines: {node: '>= 18'}
'@octokit/rest@20.1.1':
resolution: {integrity: sha512-MB4AYDsM5jhIHro/dq4ix1iWTLGToIGk6cWF5L6vanFaMble5jTX/UBQyiv05HsWnwUtY8JrfHy2LWfKwihqMw==}
engines: {node: '>= 18'}
- '@octokit/types@13.5.0':
- resolution: {integrity: sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==}
+ '@octokit/types@13.7.0':
+ resolution: {integrity: sha512-BXfRP+3P3IN6fd4uF3SniaHKOO4UXWBfkdR3vA8mIvaoO/wLjGN5qivUtW0QRitBHHMcfC41SLhNVYIZZE+wkA==}
'@octokit/webhooks-methods@5.1.0':
resolution: {integrity: sha512-yFZa3UH11VIxYnnoOYCVoJ3q4ChuSOk2IVBBQ0O3xtKX4x9bmKb/1t+Mxixv2iUhzMdOl1qeWJqEhouXXzB3rQ==}
engines: {node: '>= 18'}
- '@octokit/webhooks@13.2.7':
- resolution: {integrity: sha512-sPHCyi9uZuCs1gg0yF53FFocM+GsiiBEhQQV/itGzzQ8gjyv2GMJ1YvgdDY4lC0ePZeiV3juEw4GbS6w1VHhRw==}
+ '@octokit/webhooks@13.4.2':
+ resolution: {integrity: sha512-fakbgkCScapQXPxyqx2jZs/Y3jGlyezwUp7ATL7oLAGJ0+SqBKWKstoKZpiQ+REeHutKpYjY9UtxdLSurwl2Tg==}
engines: {node: '>= 18'}
'@pkgjs/parseargs@0.11.0':
@@ -1371,9 +1358,6 @@ packages:
'@types/html-to-text@9.0.4':
resolution: {integrity: sha512-pUY3cKH/Nm2yYrEmDlPR1mR7yszjGx4DrwPjQ702C4/D5CwHuZTgZdIdwPkRbcuhs7BAh2L5rg3CL5cbRiGTCQ==}
- '@types/istanbul-lib-coverage@2.0.4':
- resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==}
-
'@types/js-yaml@4.0.9':
resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==}
@@ -1529,10 +1513,6 @@ packages:
resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
engines: {node: '>=8'}
- aggregate-error@5.0.0:
- resolution: {integrity: sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==}
- engines: {node: '>=18'}
-
ajv@6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
@@ -1541,10 +1521,6 @@ packages:
engines: {node: '>=4'}
hasBin: true
- all-contributors-for-repository@0.4.0:
- resolution: {integrity: sha512-qGJHdVaRnoKMEZ6IcDvrFQJIDA9KPSsCVAMk+mjqVkHMYrgvp05TU94I8x4SjwWIfYBLp9heC9Onh55BIrOA4A==}
- engines: {node: '>=18'}
-
ansi-align@3.0.1:
resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==}
@@ -1671,24 +1647,10 @@ packages:
peerDependencies:
esbuild: '>=0.18'
- c8@10.1.3:
- resolution: {integrity: sha512-LvcyrOAaOnrrlMpW22n690PUvxiq4Uf9WMhQwNJ9vgagkL/ph1+D4uvjvDA5XCbykrc0sx+ay6pVi9YZ1GnhyA==}
- engines: {node: '>=18'}
- hasBin: true
- peerDependencies:
- monocart-coverage-reports: ^2
- peerDependenciesMeta:
- monocart-coverage-reports:
- optional: true
-
cac@6.7.14:
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
engines: {node: '>=8'}
- cached-factory@0.0.2:
- resolution: {integrity: sha512-4mhebGQ8YyvlDAX+zOHso5MezPi2pP11ZFE7vYhDIOJifsxEi7R5geB/nrLBYzQH5nwZ9kNsLAjM+WBj6osLDg==}
- engines: {node: '>=18'}
-
cached-factory@0.1.0:
resolution: {integrity: sha512-IGOSWu+NuED5UzCRmBeqQPZ8z7SkgrD/nN67W2iY1Qv83CVhevyMexkGclJ86saXisIqxoOnbeiTWvsCHRqJBw==}
engines: {node: '>=18'}
@@ -1773,10 +1735,6 @@ packages:
resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
engines: {node: '>=6'}
- clean-stack@5.2.0:
- resolution: {integrity: sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==}
- engines: {node: '>=14.16'}
-
clear-module@4.1.2:
resolution: {integrity: sha512-LWAxzHqdHsAZlPlEyJ2Poz6AIs384mPeqLVCru2p0BrP9G/kVGuhNyZYClLO6cXlnuJjzC8xtsJIuMjKqLXoAw==}
engines: {node: '>=8'}
@@ -1820,10 +1778,6 @@ packages:
resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
engines: {node: '>=0.8'}
- co-author-to-username@0.1.1:
- resolution: {integrity: sha512-KtQvKq2m52MncBa9hmYSiUae/hRRjLIOpXY29Ll43mSK/KreIRcoNy+K5/U5UHyVMNNjux1Xi4Ya744BO4G+RA==}
- engines: {node: '>=18'}
-
color-convert@1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
@@ -1844,6 +1798,10 @@ packages:
resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
engines: {node: '>=18'}
+ commander@13.0.0:
+ resolution: {integrity: sha512-oPYleIY8wmTVzkvQq10AEok6YcTC4sRUBl8F9gVuwchGVUCTbl/vhLTaQqutuuySYOsu8YTgV+OxKc/8Yvx+mQ==}
+ engines: {node: '>=18'}
+
commander@4.1.1:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
@@ -1952,9 +1910,6 @@ packages:
engines: {node: '>=18'}
hasBin: true
- convert-source-map@2.0.0:
- resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
-
core-util-is@1.0.3:
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
@@ -1967,14 +1922,19 @@ packages:
typescript:
optional: true
- create-testers@0.1.0-alpha.11:
- resolution: {integrity: sha512-rYayi3nSVRExogBreXSR4xL5ZoeGuEoaq/NJOEJVCC1NsIR1XrkoWNsrmLUEqbYHTZ4KZWhUbXLR+pX2JEdd0w==}
+ create-fs@0.1.1:
+ resolution: {integrity: sha512-tZqeDZ7yLLje2meTDL1pR3oBAnSlDd8fNyRUHtPxhGIGUGEoY8A/DHIpfxHE9eEoamA2snDJlVP9HyItfb18gQ==}
+ engines: {node: '>=18'}
+
+ create-testers@0.1.0-alpha.14:
+ resolution: {integrity: sha512-IWK69nhyVEhMTDfmOwAr3Hlj3jtQ8P3mz4ezo77BI0er82KpPaNGuSePbj5N9NWfP5TuJeeFJ+uEDcHb2x7fzA==}
engines: {node: '>=18'}
peerDependencies:
- create: ^0.1.0-alpha.11
+ create: ^0.1.0-alpha.14
+ create-fs: ^0.1.0
- create@0.1.0-alpha.11:
- resolution: {integrity: sha512-F+FTEm++rsimmCNq4zwq7dXfxAl8UA06XcfR/zS81Q9CZGYSREWEhq1HSCaHseJkAEW0uB8i3cSO/3vhlUsvOQ==}
+ create@0.1.0-alpha.15:
+ resolution: {integrity: sha512-iTBTuTIv+f+nD9mr7hyKrKuPyw46UDDBVz0iU7mCnq5MW/0OUqwm7oTFrQ6GTggDiYiS+7Yz3/AZ92EKKZVadA==}
engines: {node: '>=18'}
hasBin: true
@@ -1982,34 +1942,34 @@ packages:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
- cspell-config-lib@8.17.1:
- resolution: {integrity: sha512-x1S7QWprgUcwuwiJB1Ng0ZTBC4G50qP9qQyg/aroMkcdMsHfk26E8jUGRPNt4ftHFzS4YMhwtXuJQ9IgRUuNPA==}
+ cspell-config-lib@8.17.2:
+ resolution: {integrity: sha512-g08lRd/smLk2je0j7HlCjdDa0dSTyI2oRP3gScWlsyXjb4NSr9qO0Wzyn5BfPgrqFdS/z4dXbHe+tnLQZCt9iQ==}
engines: {node: '>=18'}
- cspell-dictionary@8.17.1:
- resolution: {integrity: sha512-zSl9l3wii+x16yc2NVZl/+CMLeLBAiuEd5YoFkOYPcbTJnfPwdjMNcj71u7wBvNJ+qwbF+kGbutEt15yHW3NBw==}
+ cspell-dictionary@8.17.2:
+ resolution: {integrity: sha512-2JC9RRsZruCs3AHId/8X63fSxDoF94dleRp8y/dXS9LIX7NruofohUJwzc/3tlgzCWWdaek1RXhO5xaYX74QtA==}
engines: {node: '>=18'}
- cspell-gitignore@8.17.1:
- resolution: {integrity: sha512-bk727Zf4FBCjm9Mwvyreyhgjwe+YhPQEW7PldkHiinKd+Irfez4s8GXLQb1EgV0UpvViqaqBqLmngjZdS30BTA==}
+ cspell-gitignore@8.17.2:
+ resolution: {integrity: sha512-zCTTN30zV96LkZmUDrLamEHpLLUGohKglKJ4iXoHQC8pDU3xTsV2qzeCQjM9SEmU3VbE1TzWq+vj0fslasv6pA==}
engines: {node: '>=18'}
hasBin: true
- cspell-glob@8.17.1:
- resolution: {integrity: sha512-cUwM5auSt0RvLX7UkP2GEArJRWc85l51B1voArl+3ZIKeMZwcJpJgN3qvImtF8yRTZwYeYCs1sgsihb179q+mg==}
+ cspell-glob@8.17.2:
+ resolution: {integrity: sha512-MTgrWX12oY8Pq/M3PEYCTHwD6w6l+DPtBWm958nhR4dboUbwi/3KfqCtdorkhnuClqLDQuuZHp0uGBXB4cdQrw==}
engines: {node: '>=18'}
- cspell-grammar@8.17.1:
- resolution: {integrity: sha512-H5tLcBuW7aUj9L0rR+FSbnWPEsWb8lWppHVidtqw9Ll1CUHWOZC9HTB2RdrhJZrsz/8DJbM2yNbok0Xt0VAfdw==}
+ cspell-grammar@8.17.2:
+ resolution: {integrity: sha512-Asg5XRvrg2yHCvBwzARBPSwI4P5/unN+bKBlxqFazHgR72WJE+ASeobfUNfGi/RxJA2+m0hO91oYtvq6LfK52w==}
engines: {node: '>=18'}
hasBin: true
- cspell-io@8.17.1:
- resolution: {integrity: sha512-liIOsblt7oVItifzRAbuxiYrwlgw1VOqKppMxVKtYoAn2VUuuEpjCj6jLWpoTqSszR/38o7ChsHY1LHakhJZmw==}
+ cspell-io@8.17.2:
+ resolution: {integrity: sha512-IUdhbO6gsWYiM2dgudFJQTfnFCDYjLOqal3SxH5o8oOWeu5iIZ+s3N8E1odz0L5zF2Go7zDQSKvPr7Y9OOoRfw==}
engines: {node: '>=18'}
- cspell-lib@8.17.1:
- resolution: {integrity: sha512-66n83Q7bK5tnvkDH7869/pBY/65AKmZVfCOAlsbhJn3YMDbNHFCHR0d1oNMlqG+n65Aco89VGwYfXxImZY+/mA==}
+ cspell-lib@8.17.2:
+ resolution: {integrity: sha512-ZgkTvGh9FO+R3v5TaTqlrJEylWyZhNOzbtrQ5W35Hb3tZ9IJJklxjlcGe+gbFsjGi56kLj6c5L2NR7YX/Fdu5Q==}
engines: {node: '>=18'}
cspell-populate-words@0.3.0:
@@ -2017,12 +1977,12 @@ packages:
engines: {node: '>=18.3.0'}
hasBin: true
- cspell-trie-lib@8.17.1:
- resolution: {integrity: sha512-13WNa5s75VwOjlGzWprmfNbBFIfXyA7tYYrbV+LugKkznyNZJeJPojHouEudcLq3SYb2Q6tJ7qyWcuT5bR9qPA==}
+ cspell-trie-lib@8.17.2:
+ resolution: {integrity: sha512-Bw9q8EWFihkQGo8fNdfkUqYOTsC161+wrQxR7m74K4bKEmQgm0mS0sLHKUwxEOZVGGLmIw9dMQl+8WnTgqOaMQ==}
engines: {node: '>=18'}
- cspell@8.17.1:
- resolution: {integrity: sha512-D0lw8XTXrTycNzOn5DkfPJNUT00X53OgvFDm+0SzhBr1r+na8LEh3CnQ6zKYVU0fL0x8vU82vs4jmGjDho9mPg==}
+ cspell@8.17.2:
+ resolution: {integrity: sha512-y+INkxDa+M9f+gsyyMLjKh1tF20r2g5Gn22peSRJglrNLQtmDuRtDT9vyDHANXZcH5g6pHDnENQu/+P2Tiyu8Q==}
engines: {node: '>=18'}
hasBin: true
@@ -2098,10 +2058,6 @@ packages:
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
engines: {node: '>=6'}
- description-to-co-authors@0.3.0:
- resolution: {integrity: sha512-GaMDuvOCmtkQ3tjjawAEl3YhxNEIsR9tmlXV4xeypGyiO75YLXRm3iHKltqrmxNgtNlppVzT2pdsPM2Yzm67CA==}
- engines: {node: '>=18.3.0'}
-
detect-indent@6.1.0:
resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==}
engines: {node: '>=8'}
@@ -2124,6 +2080,10 @@ packages:
didyoumean@1.2.2:
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
+ diff@7.0.0:
+ resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==}
+ engines: {node: '>=0.3.1'}
+
dom-serializer@2.0.0:
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
@@ -2191,8 +2151,8 @@ packages:
engines: {node: '>=12'}
hasBin: true
- esbuild@0.23.0:
- resolution: {integrity: sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==}
+ esbuild@0.23.1:
+ resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==}
engines: {node: '>=18'}
hasBin: true
@@ -2217,10 +2177,6 @@ packages:
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
engines: {node: '>=10'}
- escape-string-regexp@5.0.0:
- resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
- engines: {node: '>=12'}
-
escodegen@2.1.0:
resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==}
engines: {node: '>=6.0'}
@@ -2389,11 +2345,14 @@ packages:
resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==}
engines: {node: '>=4'}
+ fast-content-type-parse@2.0.1:
+ resolution: {integrity: sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==}
+
fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
- fast-equals@5.0.1:
- resolution: {integrity: sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==}
+ fast-equals@5.2.2:
+ resolution: {integrity: sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==}
engines: {node: '>=6.0.0'}
fast-glob@3.3.2:
@@ -2491,8 +2450,8 @@ packages:
resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==}
engines: {node: '>=18'}
- get-github-auth-token@0.1.0:
- resolution: {integrity: sha512-ENm+A39AV0X4+Ls1jiCvmqx+C8hSYTv4d5hV9Ks+EL+gx9a0P9pYYpRE1k2ExwRT3EFQabGXF1Rkdp5FIsLkiw==}
+ get-github-auth-token@0.1.1:
+ resolution: {integrity: sha512-SifKYtFehQUVgeEBiTeQMGWeNfNx59gZ7GzYzD6vKCIGDh5YT+Axm5i0VgP0XaD8TeN8ABtp593eX+wSFk8IpQ==}
engines: {node: '>=18'}
get-stdin@9.0.0:
@@ -2696,8 +2655,8 @@ packages:
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
engines: {node: '>=6'}
- import-local-or-npx@0.1.0:
- resolution: {integrity: sha512-AIeX2teTRbL4eIGffiqOwFlG/MVZlep49MVEtyls9J0SvHVDzqsuVEHjO29ucaj2LGPcT5Rg/wCTgTFJcWAkVQ==}
+ import-local-or-npx@0.2.0:
+ resolution: {integrity: sha512-K0rFCUuIBX7lmzwp95F4Owg+bRZAUMoiC79fYSRHPG/pi3IFKyMYrc+RE00mC9AWU6J/YZKT8xept5VyLvkvUw==}
engines: {node: '>=18.3.0'}
import-meta-resolve@4.1.0:
@@ -2711,10 +2670,6 @@ packages:
resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
engines: {node: '>=8'}
- indent-string@5.0.0:
- resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==}
- engines: {node: '>=12'}
-
index-to-position@0.1.2:
resolution: {integrity: sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==}
engines: {node: '>=18'}
@@ -3373,12 +3328,8 @@ packages:
resolution: {integrity: sha512-UMo+WQkWi1PS/HZ15SMM1sgPhhXykqPJKCCAi6R0+JAhTbLBcfeKCJ3AwUVdJBJQKSQ37BUqPpME4iGAjZQtkw==}
engines: {node: '>=18.3.0'}
- octokit-from-auth@0.3.0:
- resolution: {integrity: sha512-HeS+YVPExV5nkdRZyQQRepZVV+pL4ahVmh9KfKXLAbNc3D82G2xeuSWfKzHSIlqB1taQnZYPJWdpfcIe45d1lw==}
- engines: {node: '>=18.3.0'}
-
- octokit@4.0.2:
- resolution: {integrity: sha512-wbqF4uc1YbcldtiBFfkSnquHtECEIpYD78YUXI6ri1Im5OO2NLo6ZVpRdbJpdnpZ05zMrVPssNiEo6JQtea+Qg==}
+ octokit@4.1.0:
+ resolution: {integrity: sha512-/UrQAOSvkc+lUUWKNzy4ByAgYU9KpFzZQt8DnC962YmQuDiZb1SNJ90YukCCK5aMzKqqCA+z1kkAlmzYvdYKag==}
engines: {node: '>= 18'}
once@1.4.0:
@@ -3589,11 +3540,6 @@ packages:
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
engines: {node: '>= 6'}
- populate-all-contributors-for-repository@0.1.2:
- resolution: {integrity: sha512-PQ93fI7OpetHtW0c+iu6Dx2aaiRurj07LTu51pAw/qkky0eb1CdcZ+4Y+DYbzZXId4UhHGH/ednm46Pwf1P8FA==}
- engines: {node: '>=18.3.0'}
- hasBin: true
-
postcss-load-config@6.0.1:
resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==}
engines: {node: '>= 18'}
@@ -3733,6 +3679,11 @@ packages:
engines: {node: ^18.18.0 || ^20.9.0 || ^22.0.0}
hasBin: true
+ remove-dependencies@0.1.0:
+ resolution: {integrity: sha512-K9PXkqGYkuQbRVf57SI/t3xBhw87pLbvd94zir6v4+ptJQ0TSjLWtd0ZlebtQEOfnxSchz+wgzTvG7KNpLMAbg==}
+ engines: {node: '>=18.3.0'}
+ hasBin: true
+
remove-undefined-objects@5.0.0:
resolution: {integrity: sha512-DE8C17uIWeHaY4SqIkpQpHXm0MIdYHtIqjieWuh0I2PG8YcZRxFE6pqeEhnRetsrQ7Lu9uvSNQkDbg95NLpvnQ==}
engines: {node: '>=18'}
@@ -3741,11 +3692,6 @@ packages:
resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==}
engines: {node: '>=0.10'}
- replace-in-file@8.3.0:
- resolution: {integrity: sha512-4VhddQiMCPIuypiwHDTM+XHjZoVu9h7ngBbSCnwGRcwdHwxltjt/m//Ep3GDwqaOx1fDSrKFQ+n7uo4uVcEz9Q==}
- engines: {node: '>=18'}
- hasBin: true
-
require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
@@ -3787,11 +3733,6 @@ packages:
rfdc@1.4.1:
resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
- rimraf@6.0.1:
- resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==}
- engines: {node: 20 || >=22}
- hasBin: true
-
rollup@4.28.0:
resolution: {integrity: sha512-G9GOrmgWHBma4YfCcX8PjH0qhXSdH8B4HDE2o4/jaxj93S4DPCIDoLcXz99eWMji4hB29UFCEd7B2gwGJDR9cQ==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
@@ -4105,6 +4046,10 @@ packages:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
+ toad-cache@3.7.0:
+ resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==}
+ engines: {node: '>=12'}
+
tr46@0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
@@ -4234,10 +4179,6 @@ packages:
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
- v8-to-istanbul@9.2.0:
- resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==}
- engines: {node: '>=10.12.0'}
-
validate-npm-package-license@3.0.4:
resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
@@ -4401,6 +4342,11 @@ packages:
engines: {node: '>= 14'}
hasBin: true
+ yaml@2.7.0:
+ resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==}
+ engines: {node: '>= 14'}
+ hasBin: true
+
yargs-parser@18.1.3:
resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
engines: {node: '>=6'}
@@ -4506,16 +4452,14 @@ snapshots:
'@bcoe/v8-coverage@0.2.3': {}
- '@bcoe/v8-coverage@1.0.1': {}
-
- '@clack/core@0.4.0':
+ '@clack/core@0.4.1':
dependencies:
picocolors: 1.1.1
sisteransi: 1.0.5
- '@clack/prompts@0.9.0':
+ '@clack/prompts@0.9.1':
dependencies:
- '@clack/core': 0.4.0
+ '@clack/core': 0.4.1
picocolors: 1.1.1
sisteransi: 1.0.5
@@ -4527,207 +4471,216 @@ snapshots:
conventional-commits-filter: 5.0.0
conventional-commits-parser: 6.0.0
- '@cspell/cspell-bundled-dicts@8.17.1':
- dependencies:
- '@cspell/dict-ada': 4.0.5
- '@cspell/dict-al': 1.0.3
- '@cspell/dict-aws': 4.0.7
- '@cspell/dict-bash': 4.1.8
- '@cspell/dict-companies': 3.1.9
- '@cspell/dict-cpp': 6.0.2
- '@cspell/dict-cryptocurrencies': 5.0.3
- '@cspell/dict-csharp': 4.0.5
- '@cspell/dict-css': 4.0.16
- '@cspell/dict-dart': 2.2.4
- '@cspell/dict-django': 4.1.3
- '@cspell/dict-docker': 1.1.11
- '@cspell/dict-dotnet': 5.0.8
- '@cspell/dict-elixir': 4.0.6
- '@cspell/dict-en-common-misspellings': 2.0.7
+ '@cspell/cspell-bundled-dicts@8.17.2':
+ dependencies:
+ '@cspell/dict-ada': 4.1.0
+ '@cspell/dict-al': 1.1.0
+ '@cspell/dict-aws': 4.0.9
+ '@cspell/dict-bash': 4.2.0
+ '@cspell/dict-companies': 3.1.12
+ '@cspell/dict-cpp': 6.0.3
+ '@cspell/dict-cryptocurrencies': 5.0.4
+ '@cspell/dict-csharp': 4.0.6
+ '@cspell/dict-css': 4.0.17
+ '@cspell/dict-dart': 2.3.0
+ '@cspell/dict-data-science': 2.0.6
+ '@cspell/dict-django': 4.1.4
+ '@cspell/dict-docker': 1.1.12
+ '@cspell/dict-dotnet': 5.0.9
+ '@cspell/dict-elixir': 4.0.7
+ '@cspell/dict-en-common-misspellings': 2.0.8
'@cspell/dict-en-gb': 1.1.33
- '@cspell/dict-en_us': 4.3.28
- '@cspell/dict-filetypes': 3.0.9
- '@cspell/dict-flutter': 1.0.3
- '@cspell/dict-fonts': 4.0.3
- '@cspell/dict-fsharp': 1.0.4
+ '@cspell/dict-en_us': 4.3.29
+ '@cspell/dict-filetypes': 3.0.10
+ '@cspell/dict-flutter': 1.1.0
+ '@cspell/dict-fonts': 4.0.4
+ '@cspell/dict-fsharp': 1.1.0
'@cspell/dict-fullstack': 3.2.3
- '@cspell/dict-gaming-terms': 1.0.9
- '@cspell/dict-git': 3.0.3
- '@cspell/dict-golang': 6.0.17
- '@cspell/dict-google': 1.0.4
- '@cspell/dict-haskell': 4.0.4
- '@cspell/dict-html': 4.0.10
+ '@cspell/dict-gaming-terms': 1.1.0
+ '@cspell/dict-git': 3.0.4
+ '@cspell/dict-golang': 6.0.18
+ '@cspell/dict-google': 1.0.5
+ '@cspell/dict-haskell': 4.0.5
+ '@cspell/dict-html': 4.0.11
'@cspell/dict-html-symbol-entities': 4.0.3
- '@cspell/dict-java': 5.0.10
- '@cspell/dict-julia': 1.0.4
- '@cspell/dict-k8s': 1.0.9
+ '@cspell/dict-java': 5.0.11
+ '@cspell/dict-julia': 1.1.0
+ '@cspell/dict-k8s': 1.0.10
+ '@cspell/dict-kotlin': 1.1.0
'@cspell/dict-latex': 4.0.3
- '@cspell/dict-lorem-ipsum': 4.0.3
- '@cspell/dict-lua': 4.0.6
- '@cspell/dict-makefile': 1.0.3
- '@cspell/dict-markdown': 2.0.7(@cspell/dict-css@4.0.16)(@cspell/dict-html-symbol-entities@4.0.3)(@cspell/dict-html@4.0.10)(@cspell/dict-typescript@3.1.11)
- '@cspell/dict-monkeyc': 1.0.9
- '@cspell/dict-node': 5.0.5
- '@cspell/dict-npm': 5.1.18
- '@cspell/dict-php': 4.0.13
- '@cspell/dict-powershell': 5.0.13
- '@cspell/dict-public-licenses': 2.0.11
- '@cspell/dict-python': 4.2.13
- '@cspell/dict-r': 2.0.4
+ '@cspell/dict-lorem-ipsum': 4.0.4
+ '@cspell/dict-lua': 4.0.7
+ '@cspell/dict-makefile': 1.0.4
+ '@cspell/dict-markdown': 2.0.9(@cspell/dict-css@4.0.17)(@cspell/dict-html-symbol-entities@4.0.3)(@cspell/dict-html@4.0.11)(@cspell/dict-typescript@3.2.0)
+ '@cspell/dict-monkeyc': 1.0.10
+ '@cspell/dict-node': 5.0.6
+ '@cspell/dict-npm': 5.1.22
+ '@cspell/dict-php': 4.0.14
+ '@cspell/dict-powershell': 5.0.14
+ '@cspell/dict-public-licenses': 2.0.12
+ '@cspell/dict-python': 4.2.14
+ '@cspell/dict-r': 2.1.0
'@cspell/dict-ruby': 5.0.7
- '@cspell/dict-rust': 4.0.10
- '@cspell/dict-scala': 5.0.6
- '@cspell/dict-software-terms': 4.1.20
- '@cspell/dict-sql': 2.1.8
- '@cspell/dict-svelte': 1.0.5
- '@cspell/dict-swift': 2.0.4
- '@cspell/dict-terraform': 1.0.6
- '@cspell/dict-typescript': 3.1.11
- '@cspell/dict-vue': 3.0.3
+ '@cspell/dict-rust': 4.0.11
+ '@cspell/dict-scala': 5.0.7
+ '@cspell/dict-shell': 1.1.0
+ '@cspell/dict-software-terms': 4.2.2
+ '@cspell/dict-sql': 2.2.0
+ '@cspell/dict-svelte': 1.0.6
+ '@cspell/dict-swift': 2.0.5
+ '@cspell/dict-terraform': 1.1.0
+ '@cspell/dict-typescript': 3.2.0
+ '@cspell/dict-vue': 3.0.4
- '@cspell/cspell-json-reporter@8.17.1':
+ '@cspell/cspell-json-reporter@8.17.2':
dependencies:
- '@cspell/cspell-types': 8.17.1
+ '@cspell/cspell-types': 8.17.2
- '@cspell/cspell-pipe@8.17.1': {}
+ '@cspell/cspell-pipe@8.17.2': {}
- '@cspell/cspell-resolver@8.17.1':
+ '@cspell/cspell-resolver@8.17.2':
dependencies:
global-directory: 4.0.1
- '@cspell/cspell-service-bus@8.17.1': {}
+ '@cspell/cspell-service-bus@8.17.2': {}
- '@cspell/cspell-types@8.17.1': {}
+ '@cspell/cspell-types@8.17.2': {}
- '@cspell/dict-ada@4.0.5': {}
+ '@cspell/dict-ada@4.1.0': {}
- '@cspell/dict-al@1.0.3': {}
+ '@cspell/dict-al@1.1.0': {}
- '@cspell/dict-aws@4.0.7': {}
+ '@cspell/dict-aws@4.0.9': {}
- '@cspell/dict-bash@4.1.8': {}
+ '@cspell/dict-bash@4.2.0':
+ dependencies:
+ '@cspell/dict-shell': 1.1.0
- '@cspell/dict-companies@3.1.9': {}
+ '@cspell/dict-companies@3.1.12': {}
- '@cspell/dict-cpp@6.0.2': {}
+ '@cspell/dict-cpp@6.0.3': {}
- '@cspell/dict-cryptocurrencies@5.0.3': {}
+ '@cspell/dict-cryptocurrencies@5.0.4': {}
- '@cspell/dict-csharp@4.0.5': {}
+ '@cspell/dict-csharp@4.0.6': {}
- '@cspell/dict-css@4.0.16': {}
+ '@cspell/dict-css@4.0.17': {}
- '@cspell/dict-dart@2.2.4': {}
+ '@cspell/dict-dart@2.3.0': {}
- '@cspell/dict-data-science@2.0.5': {}
+ '@cspell/dict-data-science@2.0.6': {}
- '@cspell/dict-django@4.1.3': {}
+ '@cspell/dict-django@4.1.4': {}
- '@cspell/dict-docker@1.1.11': {}
+ '@cspell/dict-docker@1.1.12': {}
- '@cspell/dict-dotnet@5.0.8': {}
+ '@cspell/dict-dotnet@5.0.9': {}
- '@cspell/dict-elixir@4.0.6': {}
+ '@cspell/dict-elixir@4.0.7': {}
- '@cspell/dict-en-common-misspellings@2.0.7': {}
+ '@cspell/dict-en-common-misspellings@2.0.8': {}
'@cspell/dict-en-gb@1.1.33': {}
- '@cspell/dict-en_us@4.3.28': {}
+ '@cspell/dict-en_us@4.3.29': {}
- '@cspell/dict-filetypes@3.0.9': {}
+ '@cspell/dict-filetypes@3.0.10': {}
- '@cspell/dict-flutter@1.0.3': {}
+ '@cspell/dict-flutter@1.1.0': {}
- '@cspell/dict-fonts@4.0.3': {}
+ '@cspell/dict-fonts@4.0.4': {}
- '@cspell/dict-fsharp@1.0.4': {}
+ '@cspell/dict-fsharp@1.1.0': {}
'@cspell/dict-fullstack@3.2.3': {}
- '@cspell/dict-gaming-terms@1.0.9': {}
+ '@cspell/dict-gaming-terms@1.1.0': {}
- '@cspell/dict-git@3.0.3': {}
+ '@cspell/dict-git@3.0.4': {}
- '@cspell/dict-golang@6.0.17': {}
+ '@cspell/dict-golang@6.0.18': {}
- '@cspell/dict-google@1.0.4': {}
+ '@cspell/dict-google@1.0.5': {}
- '@cspell/dict-haskell@4.0.4': {}
+ '@cspell/dict-haskell@4.0.5': {}
'@cspell/dict-html-symbol-entities@4.0.3': {}
- '@cspell/dict-html@4.0.10': {}
+ '@cspell/dict-html@4.0.11': {}
- '@cspell/dict-java@5.0.10': {}
+ '@cspell/dict-java@5.0.11': {}
- '@cspell/dict-julia@1.0.4': {}
+ '@cspell/dict-julia@1.1.0': {}
- '@cspell/dict-k8s@1.0.9': {}
+ '@cspell/dict-k8s@1.0.10': {}
+
+ '@cspell/dict-kotlin@1.1.0': {}
'@cspell/dict-latex@4.0.3': {}
- '@cspell/dict-lorem-ipsum@4.0.3': {}
+ '@cspell/dict-lorem-ipsum@4.0.4': {}
- '@cspell/dict-lua@4.0.6': {}
+ '@cspell/dict-lua@4.0.7': {}
- '@cspell/dict-makefile@1.0.3': {}
+ '@cspell/dict-makefile@1.0.4': {}
- '@cspell/dict-markdown@2.0.7(@cspell/dict-css@4.0.16)(@cspell/dict-html-symbol-entities@4.0.3)(@cspell/dict-html@4.0.10)(@cspell/dict-typescript@3.1.11)':
+ '@cspell/dict-markdown@2.0.9(@cspell/dict-css@4.0.17)(@cspell/dict-html-symbol-entities@4.0.3)(@cspell/dict-html@4.0.11)(@cspell/dict-typescript@3.2.0)':
dependencies:
- '@cspell/dict-css': 4.0.16
- '@cspell/dict-html': 4.0.10
+ '@cspell/dict-css': 4.0.17
+ '@cspell/dict-html': 4.0.11
'@cspell/dict-html-symbol-entities': 4.0.3
- '@cspell/dict-typescript': 3.1.11
+ '@cspell/dict-typescript': 3.2.0
- '@cspell/dict-monkeyc@1.0.9': {}
+ '@cspell/dict-monkeyc@1.0.10': {}
- '@cspell/dict-node@5.0.5': {}
+ '@cspell/dict-node@5.0.6': {}
- '@cspell/dict-npm@5.1.18': {}
+ '@cspell/dict-npm@5.1.22': {}
- '@cspell/dict-php@4.0.13': {}
+ '@cspell/dict-php@4.0.14': {}
- '@cspell/dict-powershell@5.0.13': {}
+ '@cspell/dict-powershell@5.0.14': {}
- '@cspell/dict-public-licenses@2.0.11': {}
+ '@cspell/dict-public-licenses@2.0.12': {}
- '@cspell/dict-python@4.2.13':
+ '@cspell/dict-python@4.2.14':
dependencies:
- '@cspell/dict-data-science': 2.0.5
+ '@cspell/dict-data-science': 2.0.6
- '@cspell/dict-r@2.0.4': {}
+ '@cspell/dict-r@2.1.0': {}
'@cspell/dict-ruby@5.0.7': {}
- '@cspell/dict-rust@4.0.10': {}
+ '@cspell/dict-rust@4.0.11': {}
+
+ '@cspell/dict-scala@5.0.7': {}
- '@cspell/dict-scala@5.0.6': {}
+ '@cspell/dict-shell@1.1.0': {}
- '@cspell/dict-software-terms@4.1.20': {}
+ '@cspell/dict-software-terms@4.2.2': {}
- '@cspell/dict-sql@2.1.8': {}
+ '@cspell/dict-sql@2.2.0': {}
- '@cspell/dict-svelte@1.0.5': {}
+ '@cspell/dict-svelte@1.0.6': {}
- '@cspell/dict-swift@2.0.4': {}
+ '@cspell/dict-swift@2.0.5': {}
- '@cspell/dict-terraform@1.0.6': {}
+ '@cspell/dict-terraform@1.1.0': {}
- '@cspell/dict-typescript@3.1.11': {}
+ '@cspell/dict-typescript@3.2.0': {}
- '@cspell/dict-vue@3.0.3': {}
+ '@cspell/dict-vue@3.0.4': {}
- '@cspell/dynamic-import@8.17.1':
+ '@cspell/dynamic-import@8.17.2':
dependencies:
- '@cspell/url': 8.17.1
+ '@cspell/url': 8.17.2
import-meta-resolve: 4.1.0
- '@cspell/filetypes@8.17.1': {}
+ '@cspell/filetypes@8.17.2': {}
- '@cspell/strong-weak-map@8.17.1': {}
+ '@cspell/strong-weak-map@8.17.2': {}
- '@cspell/url@8.17.1': {}
+ '@cspell/url@8.17.2': {}
'@es-joy/jsdoccomment@0.49.0':
dependencies:
@@ -4738,7 +4691,7 @@ snapshots:
'@esbuild/aix-ppc64@0.19.12':
optional: true
- '@esbuild/aix-ppc64@0.23.0':
+ '@esbuild/aix-ppc64@0.23.1':
optional: true
'@esbuild/aix-ppc64@0.24.0':
@@ -4747,7 +4700,7 @@ snapshots:
'@esbuild/android-arm64@0.19.12':
optional: true
- '@esbuild/android-arm64@0.23.0':
+ '@esbuild/android-arm64@0.23.1':
optional: true
'@esbuild/android-arm64@0.24.0':
@@ -4756,7 +4709,7 @@ snapshots:
'@esbuild/android-arm@0.19.12':
optional: true
- '@esbuild/android-arm@0.23.0':
+ '@esbuild/android-arm@0.23.1':
optional: true
'@esbuild/android-arm@0.24.0':
@@ -4765,7 +4718,7 @@ snapshots:
'@esbuild/android-x64@0.19.12':
optional: true
- '@esbuild/android-x64@0.23.0':
+ '@esbuild/android-x64@0.23.1':
optional: true
'@esbuild/android-x64@0.24.0':
@@ -4774,7 +4727,7 @@ snapshots:
'@esbuild/darwin-arm64@0.19.12':
optional: true
- '@esbuild/darwin-arm64@0.23.0':
+ '@esbuild/darwin-arm64@0.23.1':
optional: true
'@esbuild/darwin-arm64@0.24.0':
@@ -4783,7 +4736,7 @@ snapshots:
'@esbuild/darwin-x64@0.19.12':
optional: true
- '@esbuild/darwin-x64@0.23.0':
+ '@esbuild/darwin-x64@0.23.1':
optional: true
'@esbuild/darwin-x64@0.24.0':
@@ -4792,7 +4745,7 @@ snapshots:
'@esbuild/freebsd-arm64@0.19.12':
optional: true
- '@esbuild/freebsd-arm64@0.23.0':
+ '@esbuild/freebsd-arm64@0.23.1':
optional: true
'@esbuild/freebsd-arm64@0.24.0':
@@ -4801,7 +4754,7 @@ snapshots:
'@esbuild/freebsd-x64@0.19.12':
optional: true
- '@esbuild/freebsd-x64@0.23.0':
+ '@esbuild/freebsd-x64@0.23.1':
optional: true
'@esbuild/freebsd-x64@0.24.0':
@@ -4810,7 +4763,7 @@ snapshots:
'@esbuild/linux-arm64@0.19.12':
optional: true
- '@esbuild/linux-arm64@0.23.0':
+ '@esbuild/linux-arm64@0.23.1':
optional: true
'@esbuild/linux-arm64@0.24.0':
@@ -4819,7 +4772,7 @@ snapshots:
'@esbuild/linux-arm@0.19.12':
optional: true
- '@esbuild/linux-arm@0.23.0':
+ '@esbuild/linux-arm@0.23.1':
optional: true
'@esbuild/linux-arm@0.24.0':
@@ -4828,7 +4781,7 @@ snapshots:
'@esbuild/linux-ia32@0.19.12':
optional: true
- '@esbuild/linux-ia32@0.23.0':
+ '@esbuild/linux-ia32@0.23.1':
optional: true
'@esbuild/linux-ia32@0.24.0':
@@ -4837,7 +4790,7 @@ snapshots:
'@esbuild/linux-loong64@0.19.12':
optional: true
- '@esbuild/linux-loong64@0.23.0':
+ '@esbuild/linux-loong64@0.23.1':
optional: true
'@esbuild/linux-loong64@0.24.0':
@@ -4846,7 +4799,7 @@ snapshots:
'@esbuild/linux-mips64el@0.19.12':
optional: true
- '@esbuild/linux-mips64el@0.23.0':
+ '@esbuild/linux-mips64el@0.23.1':
optional: true
'@esbuild/linux-mips64el@0.24.0':
@@ -4855,7 +4808,7 @@ snapshots:
'@esbuild/linux-ppc64@0.19.12':
optional: true
- '@esbuild/linux-ppc64@0.23.0':
+ '@esbuild/linux-ppc64@0.23.1':
optional: true
'@esbuild/linux-ppc64@0.24.0':
@@ -4864,7 +4817,7 @@ snapshots:
'@esbuild/linux-riscv64@0.19.12':
optional: true
- '@esbuild/linux-riscv64@0.23.0':
+ '@esbuild/linux-riscv64@0.23.1':
optional: true
'@esbuild/linux-riscv64@0.24.0':
@@ -4873,7 +4826,7 @@ snapshots:
'@esbuild/linux-s390x@0.19.12':
optional: true
- '@esbuild/linux-s390x@0.23.0':
+ '@esbuild/linux-s390x@0.23.1':
optional: true
'@esbuild/linux-s390x@0.24.0':
@@ -4882,7 +4835,7 @@ snapshots:
'@esbuild/linux-x64@0.19.12':
optional: true
- '@esbuild/linux-x64@0.23.0':
+ '@esbuild/linux-x64@0.23.1':
optional: true
'@esbuild/linux-x64@0.24.0':
@@ -4891,13 +4844,13 @@ snapshots:
'@esbuild/netbsd-x64@0.19.12':
optional: true
- '@esbuild/netbsd-x64@0.23.0':
+ '@esbuild/netbsd-x64@0.23.1':
optional: true
'@esbuild/netbsd-x64@0.24.0':
optional: true
- '@esbuild/openbsd-arm64@0.23.0':
+ '@esbuild/openbsd-arm64@0.23.1':
optional: true
'@esbuild/openbsd-arm64@0.24.0':
@@ -4906,7 +4859,7 @@ snapshots:
'@esbuild/openbsd-x64@0.19.12':
optional: true
- '@esbuild/openbsd-x64@0.23.0':
+ '@esbuild/openbsd-x64@0.23.1':
optional: true
'@esbuild/openbsd-x64@0.24.0':
@@ -4915,7 +4868,7 @@ snapshots:
'@esbuild/sunos-x64@0.19.12':
optional: true
- '@esbuild/sunos-x64@0.23.0':
+ '@esbuild/sunos-x64@0.23.1':
optional: true
'@esbuild/sunos-x64@0.24.0':
@@ -4924,7 +4877,7 @@ snapshots:
'@esbuild/win32-arm64@0.19.12':
optional: true
- '@esbuild/win32-arm64@0.23.0':
+ '@esbuild/win32-arm64@0.23.1':
optional: true
'@esbuild/win32-arm64@0.24.0':
@@ -4933,7 +4886,7 @@ snapshots:
'@esbuild/win32-ia32@0.19.12':
optional: true
- '@esbuild/win32-ia32@0.23.0':
+ '@esbuild/win32-ia32@0.23.1':
optional: true
'@esbuild/win32-ia32@0.24.0':
@@ -4942,7 +4895,7 @@ snapshots:
'@esbuild/win32-x64@0.19.12':
optional: true
- '@esbuild/win32-x64@0.23.0':
+ '@esbuild/win32-x64@0.23.1':
optional: true
'@esbuild/win32-x64@0.24.0':
@@ -5052,58 +5005,58 @@ snapshots:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.15.0
- '@octokit/app@15.0.1':
+ '@octokit/app@15.1.2':
dependencies:
- '@octokit/auth-app': 7.1.0
- '@octokit/auth-unauthenticated': 6.1.0
- '@octokit/core': 6.1.2
- '@octokit/oauth-app': 7.1.2
- '@octokit/plugin-paginate-rest': 11.3.1(@octokit/core@6.1.2)
- '@octokit/types': 13.5.0
- '@octokit/webhooks': 13.2.7
+ '@octokit/auth-app': 7.1.4
+ '@octokit/auth-unauthenticated': 6.1.1
+ '@octokit/core': 6.1.3
+ '@octokit/oauth-app': 7.1.5
+ '@octokit/plugin-paginate-rest': 11.4.0(@octokit/core@6.1.3)
+ '@octokit/types': 13.7.0
+ '@octokit/webhooks': 13.4.2
- '@octokit/auth-app@7.1.0':
+ '@octokit/auth-app@7.1.4':
dependencies:
- '@octokit/auth-oauth-app': 8.1.1
- '@octokit/auth-oauth-user': 5.1.1
- '@octokit/request': 9.1.1
- '@octokit/request-error': 6.1.5
- '@octokit/types': 13.5.0
- lru-cache: 10.4.3
+ '@octokit/auth-oauth-app': 8.1.2
+ '@octokit/auth-oauth-user': 5.1.2
+ '@octokit/request': 9.1.4
+ '@octokit/request-error': 6.1.6
+ '@octokit/types': 13.7.0
+ toad-cache: 3.7.0
universal-github-app-jwt: 2.2.0
universal-user-agent: 7.0.2
- '@octokit/auth-oauth-app@8.1.1':
+ '@octokit/auth-oauth-app@8.1.2':
dependencies:
- '@octokit/auth-oauth-device': 7.1.1
- '@octokit/auth-oauth-user': 5.1.1
- '@octokit/request': 9.1.1
- '@octokit/types': 13.5.0
+ '@octokit/auth-oauth-device': 7.1.2
+ '@octokit/auth-oauth-user': 5.1.2
+ '@octokit/request': 9.1.4
+ '@octokit/types': 13.7.0
universal-user-agent: 7.0.2
- '@octokit/auth-oauth-device@7.1.1':
+ '@octokit/auth-oauth-device@7.1.2':
dependencies:
- '@octokit/oauth-methods': 5.1.2
- '@octokit/request': 9.1.1
- '@octokit/types': 13.5.0
+ '@octokit/oauth-methods': 5.1.3
+ '@octokit/request': 9.1.4
+ '@octokit/types': 13.7.0
universal-user-agent: 7.0.2
- '@octokit/auth-oauth-user@5.1.1':
+ '@octokit/auth-oauth-user@5.1.2':
dependencies:
- '@octokit/auth-oauth-device': 7.1.1
- '@octokit/oauth-methods': 5.1.2
- '@octokit/request': 9.1.1
- '@octokit/types': 13.5.0
+ '@octokit/auth-oauth-device': 7.1.2
+ '@octokit/oauth-methods': 5.1.3
+ '@octokit/request': 9.1.4
+ '@octokit/types': 13.7.0
universal-user-agent: 7.0.2
'@octokit/auth-token@4.0.0': {}
'@octokit/auth-token@5.1.1': {}
- '@octokit/auth-unauthenticated@6.1.0':
+ '@octokit/auth-unauthenticated@6.1.1':
dependencies:
- '@octokit/request-error': 6.1.5
- '@octokit/types': 13.5.0
+ '@octokit/request-error': 6.1.6
+ '@octokit/types': 13.7.0
'@octokit/core@5.2.0':
dependencies:
@@ -5111,79 +5064,79 @@ snapshots:
'@octokit/graphql': 7.1.0
'@octokit/request': 8.4.0
'@octokit/request-error': 5.1.0
- '@octokit/types': 13.5.0
+ '@octokit/types': 13.7.0
before-after-hook: 2.2.3
universal-user-agent: 6.0.1
- '@octokit/core@6.1.2':
+ '@octokit/core@6.1.3':
dependencies:
'@octokit/auth-token': 5.1.1
- '@octokit/graphql': 8.1.1
- '@octokit/request': 9.1.1
- '@octokit/request-error': 6.1.5
- '@octokit/types': 13.5.0
+ '@octokit/graphql': 8.1.2
+ '@octokit/request': 9.1.4
+ '@octokit/request-error': 6.1.6
+ '@octokit/types': 13.7.0
before-after-hook: 3.0.2
universal-user-agent: 7.0.2
'@octokit/endpoint@10.1.1':
dependencies:
- '@octokit/types': 13.5.0
+ '@octokit/types': 13.7.0
universal-user-agent: 7.0.2
'@octokit/endpoint@9.0.5':
dependencies:
- '@octokit/types': 13.5.0
+ '@octokit/types': 13.7.0
universal-user-agent: 6.0.1
'@octokit/graphql@7.1.0':
dependencies:
'@octokit/request': 8.4.0
- '@octokit/types': 13.5.0
+ '@octokit/types': 13.7.0
universal-user-agent: 6.0.1
- '@octokit/graphql@8.1.1':
+ '@octokit/graphql@8.1.2':
dependencies:
- '@octokit/request': 9.1.1
- '@octokit/types': 13.5.0
+ '@octokit/request': 9.1.4
+ '@octokit/types': 13.7.0
universal-user-agent: 7.0.2
- '@octokit/oauth-app@7.1.2':
+ '@octokit/oauth-app@7.1.5':
dependencies:
- '@octokit/auth-oauth-app': 8.1.1
- '@octokit/auth-oauth-user': 5.1.1
- '@octokit/auth-unauthenticated': 6.1.0
- '@octokit/core': 6.1.2
+ '@octokit/auth-oauth-app': 8.1.2
+ '@octokit/auth-oauth-user': 5.1.2
+ '@octokit/auth-unauthenticated': 6.1.1
+ '@octokit/core': 6.1.3
'@octokit/oauth-authorization-url': 7.1.1
- '@octokit/oauth-methods': 5.1.2
+ '@octokit/oauth-methods': 5.1.3
'@types/aws-lambda': 8.10.137
universal-user-agent: 7.0.2
'@octokit/oauth-authorization-url@7.1.1': {}
- '@octokit/oauth-methods@5.1.2':
+ '@octokit/oauth-methods@5.1.3':
dependencies:
'@octokit/oauth-authorization-url': 7.1.1
- '@octokit/request': 9.1.1
- '@octokit/request-error': 6.1.5
- '@octokit/types': 13.5.0
+ '@octokit/request': 9.1.4
+ '@octokit/request-error': 6.1.6
+ '@octokit/types': 13.7.0
- '@octokit/openapi-types@22.2.0': {}
+ '@octokit/openapi-types@23.0.1': {}
- '@octokit/openapi-webhooks-types@8.2.1': {}
+ '@octokit/openapi-webhooks-types@8.5.1': {}
- '@octokit/plugin-paginate-graphql@5.2.2(@octokit/core@6.1.2)':
+ '@octokit/plugin-paginate-graphql@5.2.4(@octokit/core@6.1.3)':
dependencies:
- '@octokit/core': 6.1.2
+ '@octokit/core': 6.1.3
'@octokit/plugin-paginate-rest@11.3.1(@octokit/core@5.2.0)':
dependencies:
'@octokit/core': 5.2.0
- '@octokit/types': 13.5.0
+ '@octokit/types': 13.7.0
- '@octokit/plugin-paginate-rest@11.3.1(@octokit/core@6.1.2)':
+ '@octokit/plugin-paginate-rest@11.4.0(@octokit/core@6.1.3)':
dependencies:
- '@octokit/core': 6.1.2
- '@octokit/types': 13.5.0
+ '@octokit/core': 6.1.3
+ '@octokit/types': 13.7.0
'@octokit/plugin-request-log@4.0.0(@octokit/core@5.2.0)':
dependencies:
@@ -5192,48 +5145,49 @@ snapshots:
'@octokit/plugin-rest-endpoint-methods@13.2.2(@octokit/core@5.2.0)':
dependencies:
'@octokit/core': 5.2.0
- '@octokit/types': 13.5.0
+ '@octokit/types': 13.7.0
- '@octokit/plugin-rest-endpoint-methods@13.2.2(@octokit/core@6.1.2)':
+ '@octokit/plugin-rest-endpoint-methods@13.3.0(@octokit/core@6.1.3)':
dependencies:
- '@octokit/core': 6.1.2
- '@octokit/types': 13.5.0
+ '@octokit/core': 6.1.3
+ '@octokit/types': 13.7.0
- '@octokit/plugin-retry@7.1.1(@octokit/core@6.1.2)':
+ '@octokit/plugin-retry@7.1.3(@octokit/core@6.1.3)':
dependencies:
- '@octokit/core': 6.1.2
- '@octokit/request-error': 6.1.5
- '@octokit/types': 13.5.0
+ '@octokit/core': 6.1.3
+ '@octokit/request-error': 6.1.6
+ '@octokit/types': 13.7.0
bottleneck: 2.19.5
- '@octokit/plugin-throttling@9.3.0(@octokit/core@6.1.2)':
+ '@octokit/plugin-throttling@9.4.0(@octokit/core@6.1.3)':
dependencies:
- '@octokit/core': 6.1.2
- '@octokit/types': 13.5.0
+ '@octokit/core': 6.1.3
+ '@octokit/types': 13.7.0
bottleneck: 2.19.5
'@octokit/request-error@5.1.0':
dependencies:
- '@octokit/types': 13.5.0
+ '@octokit/types': 13.7.0
deprecation: 2.3.1
once: 1.4.0
- '@octokit/request-error@6.1.5':
+ '@octokit/request-error@6.1.6':
dependencies:
- '@octokit/types': 13.5.0
+ '@octokit/types': 13.7.0
'@octokit/request@8.4.0':
dependencies:
'@octokit/endpoint': 9.0.5
'@octokit/request-error': 5.1.0
- '@octokit/types': 13.5.0
+ '@octokit/types': 13.7.0
universal-user-agent: 6.0.1
- '@octokit/request@9.1.1':
+ '@octokit/request@9.1.4':
dependencies:
'@octokit/endpoint': 10.1.1
- '@octokit/request-error': 6.1.5
- '@octokit/types': 13.5.0
+ '@octokit/request-error': 6.1.6
+ '@octokit/types': 13.7.0
+ fast-content-type-parse: 2.0.1
universal-user-agent: 7.0.2
'@octokit/rest@20.1.1':
@@ -5243,18 +5197,17 @@ snapshots:
'@octokit/plugin-request-log': 4.0.0(@octokit/core@5.2.0)
'@octokit/plugin-rest-endpoint-methods': 13.2.2(@octokit/core@5.2.0)
- '@octokit/types@13.5.0':
+ '@octokit/types@13.7.0':
dependencies:
- '@octokit/openapi-types': 22.2.0
+ '@octokit/openapi-types': 23.0.1
'@octokit/webhooks-methods@5.1.0': {}
- '@octokit/webhooks@13.2.7':
+ '@octokit/webhooks@13.4.2':
dependencies:
- '@octokit/openapi-webhooks-types': 8.2.1
- '@octokit/request-error': 6.1.5
+ '@octokit/openapi-webhooks-types': 8.5.1
+ '@octokit/request-error': 6.1.6
'@octokit/webhooks-methods': 5.1.0
- aggregate-error: 5.0.0
'@pkgjs/parseargs@0.11.0':
optional: true
@@ -5385,8 +5338,6 @@ snapshots:
'@types/html-to-text@9.0.4': {}
- '@types/istanbul-lib-coverage@2.0.4': {}
-
'@types/js-yaml@4.0.9': {}
'@types/json-schema@7.0.15': {}
@@ -5577,11 +5528,6 @@ snapshots:
clean-stack: 2.2.0
indent-string: 4.0.0
- aggregate-error@5.0.0:
- dependencies:
- clean-stack: 5.2.0
- indent-string: 5.0.0
-
ajv@6.12.6:
dependencies:
fast-deep-equal: 3.1.3
@@ -5606,14 +5552,6 @@ snapshots:
transitivePeerDependencies:
- encoding
- all-contributors-for-repository@0.4.0:
- dependencies:
- co-author-to-username: 0.1.1
- conventional-commits-parser: 6.0.0
- description-to-co-authors: 0.3.0
- octokit: 4.0.2
- octokit-from-auth: 0.3.0
-
ansi-align@3.0.1:
dependencies:
string-width: 4.2.3
@@ -5733,24 +5671,8 @@ snapshots:
esbuild: 0.24.0
load-tsconfig: 0.2.5
- c8@10.1.3:
- dependencies:
- '@bcoe/v8-coverage': 1.0.1
- '@istanbuljs/schema': 0.1.3
- find-up: 5.0.0
- foreground-child: 3.3.0
- istanbul-lib-coverage: 3.2.2
- istanbul-lib-report: 3.0.1
- istanbul-reports: 3.1.7
- test-exclude: 7.0.1
- v8-to-istanbul: 9.2.0
- yargs: 17.7.2
- yargs-parser: 21.1.1
-
cac@6.7.14: {}
- cached-factory@0.0.2: {}
-
cached-factory@0.1.0: {}
callsites@3.1.0: {}
@@ -5829,10 +5751,6 @@ snapshots:
clean-stack@2.2.0: {}
- clean-stack@5.2.0:
- dependencies:
- escape-string-regexp: 5.0.0
-
clear-module@4.1.2:
dependencies:
parent-module: 2.0.0
@@ -5873,11 +5791,6 @@ snapshots:
clone@1.0.4: {}
- co-author-to-username@0.1.1:
- dependencies:
- cached-factory: 0.0.2
- octokit: 4.0.2
-
color-convert@1.9.3:
dependencies:
color-name: 1.1.3
@@ -5894,6 +5807,8 @@ snapshots:
commander@12.1.0: {}
+ commander@13.0.0: {}
+
commander@4.1.1: {}
commander@8.3.0: {}
@@ -6017,8 +5932,6 @@ snapshots:
conventional-commits-parser: 6.0.0
meow: 13.2.0
- convert-source-map@2.0.0: {}
-
core-util-is@1.0.3: {}
cosmiconfig@9.0.0(typescript@5.7.2):
@@ -6030,31 +5943,32 @@ snapshots:
optionalDependencies:
typescript: 5.7.2
- create-testers@0.1.0-alpha.11(create@0.1.0-alpha.11(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(typescript@5.7.2)):
+ create-fs@0.1.1: {}
+
+ create-testers@0.1.0-alpha.14(create-fs@0.1.1)(create@0.1.0-alpha.15):
dependencies:
- create: 0.1.0-alpha.11(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(typescript@5.7.2)
- octokit: 4.0.2
+ create: 0.1.0-alpha.15
+ create-fs: 0.1.1
+ diff: 7.0.0
+ octokit: 4.1.0
+ without-undefined-properties: 0.1.1
- create@0.1.0-alpha.11(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(typescript@5.7.2):
+ create@0.1.0-alpha.15:
dependencies:
- '@clack/prompts': 0.9.0
+ '@clack/prompts': 0.9.1
cached-factory: 0.1.0
chalk: 5.4.1
+ create-fs: 0.1.1
execa: 9.5.2
- get-github-auth-token: 0.1.0
+ get-github-auth-token: 0.1.1
hash-object: 5.0.1
hosted-git-info: 8.0.2
- import-local-or-npx: 0.1.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(typescript@5.7.2)
- octokit: 4.0.2
+ import-local-or-npx: 0.2.0
+ octokit: 4.1.0
prettier: 3.4.2
read-pkg: 9.0.1
without-undefined-properties: 0.1.1
zod: 3.24.1
- transitivePeerDependencies:
- - conventional-commits-filter
- - conventional-commits-parser
- - supports-color
- - typescript
cross-spawn@7.0.6:
dependencies:
@@ -6062,61 +5976,61 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
- cspell-config-lib@8.17.1:
+ cspell-config-lib@8.17.2:
dependencies:
- '@cspell/cspell-types': 8.17.1
+ '@cspell/cspell-types': 8.17.2
comment-json: 4.2.5
- yaml: 2.6.1
+ yaml: 2.7.0
- cspell-dictionary@8.17.1:
+ cspell-dictionary@8.17.2:
dependencies:
- '@cspell/cspell-pipe': 8.17.1
- '@cspell/cspell-types': 8.17.1
- cspell-trie-lib: 8.17.1
- fast-equals: 5.0.1
+ '@cspell/cspell-pipe': 8.17.2
+ '@cspell/cspell-types': 8.17.2
+ cspell-trie-lib: 8.17.2
+ fast-equals: 5.2.2
- cspell-gitignore@8.17.1:
+ cspell-gitignore@8.17.2:
dependencies:
- '@cspell/url': 8.17.1
- cspell-glob: 8.17.1
- cspell-io: 8.17.1
+ '@cspell/url': 8.17.2
+ cspell-glob: 8.17.2
+ cspell-io: 8.17.2
find-up-simple: 1.0.0
- cspell-glob@8.17.1:
+ cspell-glob@8.17.2:
dependencies:
- '@cspell/url': 8.17.1
+ '@cspell/url': 8.17.2
micromatch: 4.0.8
- cspell-grammar@8.17.1:
+ cspell-grammar@8.17.2:
dependencies:
- '@cspell/cspell-pipe': 8.17.1
- '@cspell/cspell-types': 8.17.1
+ '@cspell/cspell-pipe': 8.17.2
+ '@cspell/cspell-types': 8.17.2
- cspell-io@8.17.1:
+ cspell-io@8.17.2:
dependencies:
- '@cspell/cspell-service-bus': 8.17.1
- '@cspell/url': 8.17.1
+ '@cspell/cspell-service-bus': 8.17.2
+ '@cspell/url': 8.17.2
- cspell-lib@8.17.1:
+ cspell-lib@8.17.2:
dependencies:
- '@cspell/cspell-bundled-dicts': 8.17.1
- '@cspell/cspell-pipe': 8.17.1
- '@cspell/cspell-resolver': 8.17.1
- '@cspell/cspell-types': 8.17.1
- '@cspell/dynamic-import': 8.17.1
- '@cspell/filetypes': 8.17.1
- '@cspell/strong-weak-map': 8.17.1
- '@cspell/url': 8.17.1
+ '@cspell/cspell-bundled-dicts': 8.17.2
+ '@cspell/cspell-pipe': 8.17.2
+ '@cspell/cspell-resolver': 8.17.2
+ '@cspell/cspell-types': 8.17.2
+ '@cspell/dynamic-import': 8.17.2
+ '@cspell/filetypes': 8.17.2
+ '@cspell/strong-weak-map': 8.17.2
+ '@cspell/url': 8.17.2
clear-module: 4.1.2
comment-json: 4.2.5
- cspell-config-lib: 8.17.1
- cspell-dictionary: 8.17.1
- cspell-glob: 8.17.1
- cspell-grammar: 8.17.1
- cspell-io: 8.17.1
- cspell-trie-lib: 8.17.1
+ cspell-config-lib: 8.17.2
+ cspell-dictionary: 8.17.2
+ cspell-glob: 8.17.2
+ cspell-grammar: 8.17.2
+ cspell-io: 8.17.2
+ cspell-trie-lib: 8.17.2
env-paths: 3.0.0
- fast-equals: 5.0.1
+ fast-equals: 5.2.2
gensequence: 7.0.0
import-fresh: 3.3.0
resolve-from: 5.0.0
@@ -6126,29 +6040,29 @@ snapshots:
cspell-populate-words@0.3.0:
dependencies:
- cspell: 8.17.1
+ cspell: 8.17.2
- cspell-trie-lib@8.17.1:
+ cspell-trie-lib@8.17.2:
dependencies:
- '@cspell/cspell-pipe': 8.17.1
- '@cspell/cspell-types': 8.17.1
+ '@cspell/cspell-pipe': 8.17.2
+ '@cspell/cspell-types': 8.17.2
gensequence: 7.0.0
- cspell@8.17.1:
+ cspell@8.17.2:
dependencies:
- '@cspell/cspell-json-reporter': 8.17.1
- '@cspell/cspell-pipe': 8.17.1
- '@cspell/cspell-types': 8.17.1
- '@cspell/dynamic-import': 8.17.1
- '@cspell/url': 8.17.1
+ '@cspell/cspell-json-reporter': 8.17.2
+ '@cspell/cspell-pipe': 8.17.2
+ '@cspell/cspell-types': 8.17.2
+ '@cspell/dynamic-import': 8.17.2
+ '@cspell/url': 8.17.2
chalk: 5.4.1
chalk-template: 1.1.0
- commander: 12.1.0
- cspell-dictionary: 8.17.1
- cspell-gitignore: 8.17.1
- cspell-glob: 8.17.1
- cspell-io: 8.17.1
- cspell-lib: 8.17.1
+ commander: 13.0.0
+ cspell-dictionary: 8.17.2
+ cspell-gitignore: 8.17.2
+ cspell-glob: 8.17.2
+ cspell-io: 8.17.2
+ cspell-lib: 8.17.2
fast-json-stable-stringify: 2.1.0
file-entry-cache: 9.1.0
get-stdin: 9.0.0
@@ -6210,8 +6124,6 @@ snapshots:
dequal@2.0.3: {}
- description-to-co-authors@0.3.0: {}
-
detect-indent@6.1.0: {}
detect-indent@7.0.1: {}
@@ -6226,6 +6138,8 @@ snapshots:
didyoumean@1.2.2: {}
+ diff@7.0.0: {}
+
dom-serializer@2.0.0:
dependencies:
domelementtype: 2.3.0
@@ -6311,32 +6225,33 @@ snapshots:
'@esbuild/win32-ia32': 0.19.12
'@esbuild/win32-x64': 0.19.12
- esbuild@0.23.0:
+ esbuild@0.23.1:
optionalDependencies:
- '@esbuild/aix-ppc64': 0.23.0
- '@esbuild/android-arm': 0.23.0
- '@esbuild/android-arm64': 0.23.0
- '@esbuild/android-x64': 0.23.0
- '@esbuild/darwin-arm64': 0.23.0
- '@esbuild/darwin-x64': 0.23.0
- '@esbuild/freebsd-arm64': 0.23.0
- '@esbuild/freebsd-x64': 0.23.0
- '@esbuild/linux-arm': 0.23.0
- '@esbuild/linux-arm64': 0.23.0
- '@esbuild/linux-ia32': 0.23.0
- '@esbuild/linux-loong64': 0.23.0
- '@esbuild/linux-mips64el': 0.23.0
- '@esbuild/linux-ppc64': 0.23.0
- '@esbuild/linux-riscv64': 0.23.0
- '@esbuild/linux-s390x': 0.23.0
- '@esbuild/linux-x64': 0.23.0
- '@esbuild/netbsd-x64': 0.23.0
- '@esbuild/openbsd-arm64': 0.23.0
- '@esbuild/openbsd-x64': 0.23.0
- '@esbuild/sunos-x64': 0.23.0
- '@esbuild/win32-arm64': 0.23.0
- '@esbuild/win32-ia32': 0.23.0
- '@esbuild/win32-x64': 0.23.0
+ '@esbuild/aix-ppc64': 0.23.1
+ '@esbuild/android-arm': 0.23.1
+ '@esbuild/android-arm64': 0.23.1
+ '@esbuild/android-x64': 0.23.1
+ '@esbuild/darwin-arm64': 0.23.1
+ '@esbuild/darwin-x64': 0.23.1
+ '@esbuild/freebsd-arm64': 0.23.1
+ '@esbuild/freebsd-x64': 0.23.1
+ '@esbuild/linux-arm': 0.23.1
+ '@esbuild/linux-arm64': 0.23.1
+ '@esbuild/linux-ia32': 0.23.1
+ '@esbuild/linux-loong64': 0.23.1
+ '@esbuild/linux-mips64el': 0.23.1
+ '@esbuild/linux-ppc64': 0.23.1
+ '@esbuild/linux-riscv64': 0.23.1
+ '@esbuild/linux-s390x': 0.23.1
+ '@esbuild/linux-x64': 0.23.1
+ '@esbuild/netbsd-x64': 0.23.1
+ '@esbuild/openbsd-arm64': 0.23.1
+ '@esbuild/openbsd-x64': 0.23.1
+ '@esbuild/sunos-x64': 0.23.1
+ '@esbuild/win32-arm64': 0.23.1
+ '@esbuild/win32-ia32': 0.23.1
+ '@esbuild/win32-x64': 0.23.1
+ optional: true
esbuild@0.24.0:
optionalDependencies:
@@ -6373,8 +6288,6 @@ snapshots:
escape-string-regexp@4.0.0: {}
- escape-string-regexp@5.0.0: {}
-
escodegen@2.1.0:
dependencies:
esprima: 4.0.1
@@ -6654,9 +6567,11 @@ snapshots:
iconv-lite: 0.4.24
tmp: 0.0.33
+ fast-content-type-parse@2.0.1: {}
+
fast-deep-equal@3.1.3: {}
- fast-equals@5.0.1: {}
+ fast-equals@5.2.2: {}
fast-glob@3.3.2:
dependencies:
@@ -6746,7 +6661,7 @@ snapshots:
get-east-asian-width@1.2.0: {}
- get-github-auth-token@0.1.0: {}
+ get-github-auth-token@0.1.1: {}
get-stdin@9.0.0: {}
@@ -6970,17 +6885,10 @@ snapshots:
parent-module: 1.0.1
resolve-from: 4.0.0
- import-local-or-npx@0.1.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(typescript@5.7.2):
+ import-local-or-npx@0.2.0:
dependencies:
- '@release-it/conventional-changelog': 9.0.3(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(release-it@17.10.0(typescript@5.7.2))
enhanced-resolve: 5.18.0
npx-import: 1.1.4
- release-it: 17.10.0(typescript@5.7.2)
- transitivePeerDependencies:
- - conventional-commits-filter
- - conventional-commits-parser
- - supports-color
- - typescript
import-meta-resolve@4.1.0: {}
@@ -6988,8 +6896,6 @@ snapshots:
indent-string@4.0.0: {}
- indent-string@5.0.0: {}
-
index-to-position@0.1.2: {}
inflight@1.0.6:
@@ -7003,20 +6909,20 @@ snapshots:
ini@4.1.1: {}
- input-from-file-json@0.1.0-alpha.4(create@0.1.0-alpha.11(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(typescript@5.7.2)):
+ input-from-file-json@0.1.0-alpha.4(create@0.1.0-alpha.15):
dependencies:
- create: 0.1.0-alpha.11(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(typescript@5.7.2)
- input-from-file: 0.1.0-alpha.4(create@0.1.0-alpha.11(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(typescript@5.7.2))
+ create: 0.1.0-alpha.15
+ input-from-file: 0.1.0-alpha.4(create@0.1.0-alpha.15)
zod: 3.24.1
- input-from-file@0.1.0-alpha.4(create@0.1.0-alpha.11(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(typescript@5.7.2)):
+ input-from-file@0.1.0-alpha.4(create@0.1.0-alpha.15):
dependencies:
- create: 0.1.0-alpha.11(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(typescript@5.7.2)
+ create: 0.1.0-alpha.15
zod: 3.24.1
- input-from-script@0.1.0-alpha.4(create@0.1.0-alpha.11(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(typescript@5.7.2)):
+ input-from-script@0.1.0-alpha.4(create@0.1.0-alpha.15):
dependencies:
- create: 0.1.0-alpha.11(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)(typescript@5.7.2)
+ create: 0.1.0-alpha.15
zod: 3.24.1
inquirer@7.3.3:
@@ -7739,26 +7645,21 @@ snapshots:
octokit-from-auth@0.2.0:
dependencies:
- get-github-auth-token: 0.1.0
- octokit: 4.0.2
-
- octokit-from-auth@0.3.0:
- dependencies:
- get-github-auth-token: 0.1.0
- octokit: 4.0.2
+ get-github-auth-token: 0.1.1
+ octokit: 4.1.0
- octokit@4.0.2:
+ octokit@4.1.0:
dependencies:
- '@octokit/app': 15.0.1
- '@octokit/core': 6.1.2
- '@octokit/oauth-app': 7.1.2
- '@octokit/plugin-paginate-graphql': 5.2.2(@octokit/core@6.1.2)
- '@octokit/plugin-paginate-rest': 11.3.1(@octokit/core@6.1.2)
- '@octokit/plugin-rest-endpoint-methods': 13.2.2(@octokit/core@6.1.2)
- '@octokit/plugin-retry': 7.1.1(@octokit/core@6.1.2)
- '@octokit/plugin-throttling': 9.3.0(@octokit/core@6.1.2)
- '@octokit/request-error': 6.1.5
- '@octokit/types': 13.5.0
+ '@octokit/app': 15.1.2
+ '@octokit/core': 6.1.3
+ '@octokit/oauth-app': 7.1.5
+ '@octokit/plugin-paginate-graphql': 5.2.4(@octokit/core@6.1.3)
+ '@octokit/plugin-paginate-rest': 11.4.0(@octokit/core@6.1.3)
+ '@octokit/plugin-rest-endpoint-methods': 13.3.0(@octokit/core@6.1.3)
+ '@octokit/plugin-retry': 7.1.3(@octokit/core@6.1.3)
+ '@octokit/plugin-throttling': 9.4.0(@octokit/core@6.1.3)
+ '@octokit/request-error': 6.1.6
+ '@octokit/types': 13.7.0
once@1.4.0:
dependencies:
@@ -7998,22 +7899,14 @@ snapshots:
pirates@4.0.6: {}
- populate-all-contributors-for-repository@0.1.2:
- dependencies:
- all-contributors-cli: 6.26.1
- all-contributors-for-repository: 0.4.0
- execa: 9.5.2
- transitivePeerDependencies:
- - encoding
-
- postcss-load-config@6.0.1(jiti@2.4.0)(postcss@8.4.36)(tsx@4.19.2)(yaml@2.6.1):
+ postcss-load-config@6.0.1(jiti@2.4.0)(postcss@8.4.36)(tsx@4.19.2)(yaml@2.7.0):
dependencies:
lilconfig: 3.1.3
optionalDependencies:
jiti: 2.4.0
postcss: 8.4.36
tsx: 4.19.2
- yaml: 2.6.1
+ yaml: 2.7.0
postcss@8.4.36:
dependencies:
@@ -8169,16 +8062,12 @@ snapshots:
- supports-color
- typescript
+ remove-dependencies@0.1.0: {}
+
remove-undefined-objects@5.0.0: {}
repeat-string@1.6.1: {}
- replace-in-file@8.3.0:
- dependencies:
- chalk: 5.4.1
- glob: 10.4.5
- yargs: 17.7.2
-
require-directory@2.1.1: {}
require-main-filename@2.0.0: {}
@@ -8211,11 +8100,6 @@ snapshots:
rfdc@1.4.1: {}
- rimraf@6.0.1:
- dependencies:
- glob: 11.0.0
- package-json-from-dist: 1.0.1
-
rollup@4.28.0:
dependencies:
'@types/estree': 1.0.6
@@ -8524,6 +8408,8 @@ snapshots:
dependencies:
is-number: 7.0.0
+ toad-cache@3.7.0: {}
+
tr46@0.0.3: {}
tr46@1.0.1:
@@ -8542,7 +8428,7 @@ snapshots:
tslib@2.6.2: {}
- tsup@8.3.5(jiti@2.4.0)(postcss@8.4.36)(tsx@4.19.2)(typescript@5.7.2)(yaml@2.6.1):
+ tsup@8.3.5(jiti@2.4.0)(postcss@8.4.36)(tsx@4.19.2)(typescript@5.7.2)(yaml@2.7.0):
dependencies:
bundle-require: 5.0.0(esbuild@0.24.0)
cac: 6.7.14
@@ -8552,7 +8438,7 @@ snapshots:
esbuild: 0.24.0
joycon: 3.1.1
picocolors: 1.1.1
- postcss-load-config: 6.0.1(jiti@2.4.0)(postcss@8.4.36)(tsx@4.19.2)(yaml@2.6.1)
+ postcss-load-config: 6.0.1(jiti@2.4.0)(postcss@8.4.36)(tsx@4.19.2)(yaml@2.7.0)
resolve-from: 5.0.0
rollup: 4.28.0
source-map: 0.8.0-beta.0
@@ -8571,10 +8457,11 @@ snapshots:
tsx@4.19.2:
dependencies:
- esbuild: 0.23.0
+ esbuild: 0.23.1
get-tsconfig: 4.8.1
optionalDependencies:
fsevents: 2.3.3
+ optional: true
type-check@0.4.0:
dependencies:
@@ -8644,12 +8531,6 @@ snapshots:
util-deprecate@1.0.2: {}
- v8-to-istanbul@9.2.0:
- dependencies:
- '@jridgewell/trace-mapping': 0.3.25
- '@types/istanbul-lib-coverage': 2.0.4
- convert-source-map: 2.0.0
-
validate-npm-package-license@3.0.4:
dependencies:
spdx-correct: 3.1.1
@@ -8807,10 +8688,12 @@ snapshots:
dependencies:
eslint-visitor-keys: 3.4.3
lodash: 4.17.21
- yaml: 2.6.1
+ yaml: 2.7.0
yaml@2.6.1: {}
+ yaml@2.7.0: {}
+
yargs-parser@18.1.3:
dependencies:
camelcase: 5.3.1
diff --git a/script/__snapshots__/migrate-test-e2e.ts.snap b/script/__snapshots__/migrate-test-e2e.ts.snap
deleted file mode 100644
index 82f836f99..000000000
--- a/script/__snapshots__/migrate-test-e2e.ts.snap
+++ /dev/null
@@ -1,247 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`expected file changes > .github/workflows/ci.yml 1`] = `
-"--- a/.github/workflows/ci.yml
-+++ b/.github/workflows/ci.yml
-@@ ... @@
- jobs:
-- are_the_types_wrong:
-- name: Are The Types Wrong?
-- runs-on: ubuntu-latest
-- steps:
-- - uses: actions/checkout@v4
-- - uses: ./.github/actions/prepare
-- - run: pnpm build
-- - run: npx --yes @arethetypeswrong/cli --pack . --ignore-rules cjs-resolves-to-esm
- build:
- name: Build
- runs-on: ubuntu-latest
-@@ ... @@ jobs:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/prepare
- - run: pnpm build
-- - run: node lib/index.js --version
-+ - run: node lib/index.js
- lint:
- name: Lint
- runs-on: ubuntu-latest
-@@ ... @@ jobs:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/prepare
- - run: pnpm run test --coverage
-- - env:
-- CODECOV_TOKEN: \${{ secrets.CODECOV_TOKEN }}
-- if: always()
-- uses: codecov/codecov-action@v3
-- with:
-- flags: unit
-- test_creation_script:
-- name: Test Creation Script
-- runs-on: ubuntu-latest
-- steps:
-- - uses: actions/checkout@v4
-- - uses: ./.github/actions/prepare
-- - run: pnpm run build
-- - run: pnpm run test:create
-- - env:
-- CODECOV_TOKEN: \${{ secrets.CODECOV_TOKEN }}
-- if: always()
-- uses: codecov/codecov-action@v3
-- with:
-- files: coverage-create/lcov.info
-- flags: create
-- test_initialization_script:
-- name: Test Initialization Script
-- runs-on: ubuntu-latest
-- steps:
-- - uses: actions/checkout@v4
-- - uses: ./.github/actions/prepare
-- - run: pnpm run build
-- - run: pnpm run test:initialize
-- - env:
-- CODECOV_TOKEN: \${{ secrets.CODECOV_TOKEN }}
-- if: always()
-- uses: codecov/codecov-action@v3
-- with:
-- files: coverage-initialize/lcov.info
-- flags: initialize
-- test_migration_script:
-- name: Test Migration Script
-- runs-on: ubuntu-latest
-- steps:
-- - uses: actions/checkout@v4
-- - uses: ./.github/actions/prepare
-- - run: pnpm run build
-- - run: pnpm run test:migrate
-- - env:
-- CODECOV_TOKEN: \${{ secrets.CODECOV_TOKEN }}
-- if: always()
-+ - if: always()
- uses: codecov/codecov-action@v3
-- with:
-- files: coverage-migrate/lcov.info
-- flags: migrate
- type_check:
- name: Type Check
- runs-on: ubuntu-latest"
-`;
-
-exports[`expected file changes > .gitignore 1`] = `
-"--- a/.gitignore
-+++ b/.gitignore
-@@ ... @@
--/coverage*
-+/coverage
- /lib
- /node_modules"
-`;
-
-exports[`expected file changes > .prettierignore 1`] = `
-"--- a/.prettierignore
-+++ b/.prettierignore
-@@ ... @@
- /.husky
--/coverage*
-+/coverage
- /lib
- /pnpm-lock.yaml"
-`;
-
-exports[`expected file changes > README.md 1`] = `
-"--- a/README.md
-+++ b/README.md
-@@ ... @@
-
Create TypeScript App
-
--Quickstart-friendly TypeScript template with comprehensive, configurable, opinionated tooling. 🎁
-+A very lovely package. Hooray!
-
-
-
-@@ ... @@ Thanks! 💖
-
-
-
-+
-+
-+
-+> 💙 This package was templated with [\`create-typescript-app\`](https://github.com/JoshuaKGoldberg/create-typescript-app)."
-`;
-
-exports[`expected file changes > eslint.config.js 1`] = `
-"--- a/eslint.config.js
-+++ b/eslint.config.js
-@@ ... @@
--/*
--👋 Hi! This ESLint configuration contains a lot more stuff than many repos'!
--You can read from it to see all sorts of linting goodness, but don't worry -
--it's not something you need to exhaustively understand immediately. 💙
--
--If you're interested in learning more, see the 'getting started' docs on:
--- ESLint: https://eslint.org
--- typescript-eslint: https://typescript-eslint.io
--*/
--
- import comments from "@eslint-community/eslint-plugin-eslint-comments/configs";
- import eslint from "@eslint/js";
- import vitest from "@vitest/eslint-plugin";
-@@ ... @@ import tseslint from "typescript-eslint";
-
- export default tseslint.config(
- {
-- ignores: [
-- "**/*.snap",
-- "coverage*",
-- "lib",
-- "node_modules",
-- "pnpm-lock.yaml",
-- ],
-+ ignores: ["**/*.snap", "coverage", "lib", "node_modules", "pnpm-lock.yaml"],
- },
- { linterOptions: { reportUnusedDisableDirectives: "error" } },
- eslint.configs.recommended,
-@@ ... @@ export default tseslint.config(
- files: ["**/*.js", "**/*.ts"],
- languageOptions: {
- parserOptions: {
-- projectService: {
-- allowDefaultProject: ["*.config.*s", "bin/index.js"],
-- },
-+ projectService: { allowDefaultProject: ["*.config.*s"] },
- tsconfigRootDir: import.meta.dirname,
- },
- },
- rules: {
-- // These on-by-default rules work well for this repo if configured
-- "@typescript-eslint/no-unnecessary-condition": [
-- "error",
-- {
-- allowConstantLoopConditions: true,
-- },
-- ],
-- "@typescript-eslint/prefer-nullish-coalescing": [
-- "error",
-- { ignorePrimitives: true },
-- ],
-- "@typescript-eslint/restrict-template-expressions": [
-- "error",
-- { allowBoolean: true, allowNullish: true, allowNumber: true },
-- ],
-- "n/no-unsupported-features/node-builtins": [
-- "error",
-- { allowExperimental: true },
-- ],
--
- // Stylistic concerns that don't interfere with Prettier
- "logical-assignment-operators": [
- "error",
-`;
-
-exports[`expected file changes > knip.json 1`] = `
-"--- a/knip.json
-+++ b/knip.json
-@@ ... @@
- {
- "$schema": "https://unpkg.com/knip@5.41.1/schema.json",
-- "entry": ["script/*e2e.js", "src/index.ts", "src/**/*.test.*"],
-- "ignoreDependencies": ["all-contributors-cli", "cspell-populate-words"],
-+ "entry": ["src/index.ts"],
- "ignoreExportsUsedInFile": { "interface": true, "type": true },
-- "project": ["src/**/*.ts", "script/**/*.js"]
-+ "project": ["src/**/*.ts"]
- }"
-`;
-
-exports[`expected file changes > package.json 1`] = `
-"--- a/package.json
-+++ b/package.json
-@@ ... @@
- {
- "name": "create-typescript-app",
- "version": "1.79.0",
-- "description": "Quickstart-friendly TypeScript template with comprehensive, configurable, opinionated tooling. 🎁",
-+ "description": "A very lovely package. Hooray! 💖",
- "repository": {
- "type": "git",
- "url": "https://github.com/JoshuaKGoldberg/create-typescript-app"
-@@ ... @@
- "lint-staged": "15.2.11",
- "markdownlint": "0.37.2",
- "markdownlint-cli": "0.43.0",
-+ "prettier": "^3.4.2",
- "prettier-plugin-curly": "0.3.1",
- "prettier-plugin-packagejson": "2.5.6",
- "prettier-plugin-sh": "0.14.0","
-`;
-
-exports[`expected file changes > tsconfig.json 1`] = `
-"--- a/tsconfig.json
-+++ b/tsconfig.json
-@@ ... @@
- "strict": true,
- "target": "ES2022"
- },
-- "include": ["src", "script"]
-+ "include": ["src"]
- }"
-`;
diff --git a/script/create-test-e2e.ts b/script/create-test-e2e.ts
deleted file mode 100644
index 28548f2fc..000000000
--- a/script/create-test-e2e.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { $, execaCommand } from "execa";
-import { strict as assert } from "node:assert";
-import { rimraf } from "rimraf";
-
-const author = "Test Author";
-const description = "Test description.";
-const email = "test@email.com";
-const repository = "testing-repository";
-const owner = "TestOwner";
-const title = "Test Title";
-
-await rimraf(["coverage*", repository]);
-
-// Fist we run with --mode create to create a new new local repository,
-// asserting that pnpm i passes in that repository's directory.
-await $({
- stdio: "inherit",
-})`c8 -o ./coverage-create -r html -r lcov --src src node bin/index.js --base everything --mode create --author ${author} --email ${email} --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-all-contributors-api --skip-github-api`;
-
-process.chdir(repository);
-
-const failures = [];
-
-// Then we run each of the CI commands to assert that they pass too.
-for (const command of [
- `pnpm i`,
- `pnpm run build`,
- `pnpm run format --list-different`,
- `pnpm run lint`,
- `pnpm run lint:md`,
- `pnpm run lint:packages`,
- `pnpm run lint:spelling`,
- `pnpm run lint:knip`,
- `pnpm run test run`,
- `pnpm run tsc`,
-]) {
- const result = await execaCommand(command, { stdio: "inherit" });
-
- if (result.exitCode) {
- failures.push({ command, result });
- }
-}
-
-assert.deepEqual(failures, []);
diff --git a/script/initialize-test-e2e.ts b/script/initialize-test-e2e.ts
deleted file mode 100644
index 441e5f60a..000000000
--- a/script/initialize-test-e2e.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import { $ } from "execa";
-import { globby } from "globby";
-import { strict as assert } from "node:assert";
-import * as fs from "node:fs/promises";
-import { rimraf } from "rimraf";
-
-const description = "New Description Test";
-const owner = "RNR1";
-const title = "New Title Test";
-const repository = "new-repository-test";
-
-await rimraf("coverage*");
-
-// Fist we run with --mode initialize to modify the local repository files,
-// asserting that the created package.json keeps the general description.
-await $({
- stdio: "inherit",
-})`pnpm run initialize --base everything --mode initialize --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-all-contributors-api --skip-github-api --skip-restore`;
-
-const newPackageJson = JSON.parse(
- (await fs.readFile("./package.json")).toString(),
-) as Record;
-console.log("New package JSON:", newPackageJson);
-
-assert.equal(newPackageJson.description, description);
-assert.equal(newPackageJson.name, repository);
-
-// Assert that the initialize script used the provided values in files,
-// except for the 'This package was templated with ...' attribution notice.
-const files = await globby(["*.*", "**/*.*"], {
- gitignore: true,
- ignoreFiles: ["script/initialize-test-e2e.js"],
-});
-
-for (const search of [`/JoshuaKGoldberg/`, "create-typescript-app"]) {
- const { stdout } = await $`grep -i ${search} ${files}`;
- assert.equal(
- stdout,
- `README.md:> 💙 This package was templated with [\`create-typescript-app\`](https://github.com/JoshuaKGoldberg/create-typescript-app).`,
- );
-}
-
-// Use Knip to assert that none of the template-only dependencies remain.
-// They should have been removed as part of initialization.
-try {
- await $`pnpm run lint:knip`;
-} catch (error) {
- throw new Error(
- `Error running lint:knip: ${(error as Error).stack ?? (error as string)}`,
- );
-}
-
-// Now that initialize has passed normal steps, we reset everything,
-// then run again without removing files - so we can capture test coverage
-await $`git add -A`;
-await $`git reset --hard HEAD`;
-await $`pnpm i`;
-await $`pnpm run build`;
-await $({
- stdio: "inherit",
-})`c8 -o ./coverage -r html -r lcov --src src node bin/index.js --base everything --mode initialize --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-all-contributors-api --skip-github-api --skip-removal --skip-restore`;
diff --git a/script/migrate-test-e2e.ts b/script/migrate-test-e2e.ts
deleted file mode 100644
index 0b0b66fc1..000000000
--- a/script/migrate-test-e2e.ts
+++ /dev/null
@@ -1,150 +0,0 @@
-import chalk from "chalk";
-import { $, execaCommand } from "execa";
-import * as fs from "node:fs/promises";
-import { rimraf } from "rimraf";
-import { assert, describe, expect, test } from "vitest";
-
-const filesExpectedToBeChanged = [
- "README.md",
- "knip.json",
- ".github/workflows/ci.yml",
- ".gitignore",
- ".prettierignore",
- "eslint.config.js",
- "package.json",
- "tsconfig.json",
-];
-
-const filesThatMightBeChanged = new Set([
- // For now, ignore typos cspell is picking up from migration snapshots.
- "cspell.json",
-
- "script/__snapshots__/migrate-test-e2e.ts.snap",
- ...filesExpectedToBeChanged,
-]);
-
-await rimraf("coverage*");
-
-const originalReadme = (await fs.readFile("README.md")).toString();
-
-const originalSnapshots = (
- await fs.readFile("script/__snapshots__/migrate-test-e2e.ts.snap")
-).toString();
-
-await $({
- stdio: "inherit",
-})`c8 -o ./coverage -r html -r lcov --src src node bin/index.js --auto --mode migrate --skip-all-contributors-api --skip-github-api --skip-install`;
-
-// All Contributors seems to not be using Prettier to format files...
-await fs.writeFile(
- ".all-contributorsrc",
- JSON.stringify(
- JSON.parse((await fs.readFile(".all-contributorsrc")).toString()),
- null,
- 2,
- ) + "\n",
-);
-
-// Ignore changes to the README.md all-contributor count and contributors table...
-const updatedReadme = (await fs.readFile("README.md")).toString();
-await fs.writeFile(
- "README.md",
- [
- updatedReadme.slice(0, updatedReadme.indexOf("## Contributors")) +
- originalReadme.slice(
- originalReadme.indexOf("## Contributors"),
- originalReadme.indexOf(""),
- ),
- updatedReadme.slice(updatedReadme.indexOf("")),
- ]
- .join("")
- .replace(
- /All Contributors: \d+/g,
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- /All Contributors: \d+/.exec(originalReadme)![0],
- )
- .replace(
- /all_contributors-\d+/g,
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- /all_contributors-\d+/.exec(originalReadme)![0],
- ),
-);
-
-// ...and even to the snapshot file, so diffs don't mind it.
-await fs.writeFile(
- "script/__snapshots__/migrate-test-e2e.ts.snap",
- originalSnapshots
- .replace(
- /All Contributors: \d+/g,
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- /All Contributors: \d+/.exec(originalReadme)![0],
- )
- .replace(
- /all_contributors-\d+/g,
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- /all_contributors-\d+/.exec(originalReadme)![0],
- ),
-);
-
-describe("expected file changes", () => {
- test.each(filesExpectedToBeChanged)("%s", async (file) => {
- const { stdout } = await execaCommand(`git diff HEAD -- ${file}`);
- const contentsAfterGitMarkers = stdout
- .split("\n")
- .slice(2)
- .join("\n")
- .replace(/@@ -\d+,\d+ \+\d+,\d+ @@/g, "@@ ... @@");
-
- assert(
- stdout,
- `Looks like there were no changes to ${file} from migration?`,
- );
-
- // If this fails, see .github/DEVELOPMENT.md > Setup Scripts for context.
- // Then see .github/DEVELOPMENT.md > Migration Snapshot Failures.
- expect(contentsAfterGitMarkers).toMatchSnapshot();
- });
-});
-
-test("unexpected file changes", async () => {
- const { stdout: gitStatus } = await $`git status`;
- console.log(`Stdout from running \`git status\`:\n${gitStatus}`);
-
- const indexOfUnstagedFilesMessage = gitStatus.indexOf(
- "Changes not staged for commit:",
- );
- assert(
- indexOfUnstagedFilesMessage !== -1,
- `Looks like migrate didn't cause any file changes? That's ...probably incorrect? 😬`,
- );
-
- const unstagedModifiedFiles = gitStatus
- .slice(indexOfUnstagedFilesMessage)
- .match(/modified: {3}\S+\n/g)
- ?.map((match) => match.split(/\s+/)[1])
- .filter((filePath) => !filesThatMightBeChanged.has(filePath));
-
- console.log("Unexpected modified files are:", unstagedModifiedFiles);
-
- if (unstagedModifiedFiles?.length) {
- const gitDiffCommand = `git diff HEAD -- ${unstagedModifiedFiles.join(
- " ",
- )}`;
- const { stdout } = await execaCommand(gitDiffCommand);
-
- console.log(`Stdout from running \`${gitDiffCommand}\`:\n${stdout}`);
-
- throw new Error(
- [
- "",
- "Oh no! Running the migrate script unexpectedly modified:",
- ...unstagedModifiedFiles.map((filePath) => ` - ${filePath}`),
- "",
- "See .github/DEVELOPMENT.md > Setup Scripts for context.",
- "Then see .github/DEVELOPMENT.md > Unexpected File Modifications.",
- ]
- .map((line) => chalk.red(line))
- .join("\n"),
- );
- }
-});
diff --git a/script/vitest.config.ts b/script/vitest.config.ts
deleted file mode 100644
index 663590231..000000000
--- a/script/vitest.config.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import { defineConfig } from "vitest/config";
-
-export default defineConfig({ test: { include: ["./migrate-test-e2e.ts"] } });
diff --git a/src/base.test.ts b/src/base.test.ts
new file mode 100644
index 000000000..9734102e7
--- /dev/null
+++ b/src/base.test.ts
@@ -0,0 +1,56 @@
+import { produceBase } from "create";
+import { readFile } from "fs/promises";
+import { describe, expect, test } from "vitest";
+
+import { base } from "./base.js";
+import { AllContributorsData } from "./types.js";
+
+describe("base", () => {
+ test("production from create-typescript-app", async () => {
+ const options = await produceBase(base);
+
+ expect(options).toEqual({
+ access: "public",
+ author: "Josh Goldberg ✨",
+ bin: "bin/index.js",
+ contributors: (
+ JSON.parse(
+ (await readFile(".all-contributorsrc")).toString(),
+ ) as AllContributorsData
+ ).contributors,
+ description:
+ "Quickstart-friendly TypeScript template with comprehensive, configurable, opinionated tooling. 🎁",
+ documentation: "",
+ email: {
+ github: "github@joshuakgoldberg.com",
+ npm: "npm@joshuakgoldberg.com",
+ },
+ explainer: [
+ `\`create-typescript-app\` is a one-stop-shop solution to set up a new or existing repository with the latest and greatest TypeScript tooling.`,
+ `It includes options not just for building and testing but also automated release management, contributor recognition, GitHub repository settings, and more.`,
+ ],
+ funding: "JoshuaKGoldberg",
+ guide: {
+ href: "https://www.joshuakgoldberg.com/blog/contributing-to-a-create-typescript-app-repository",
+ title: "Contributing to a create-typescript-app Repository",
+ },
+ login: "Josh Goldberg ✨",
+ logo: {
+ alt: "Project logo: the TypeScript blue square with rounded corners, but a plus sign instead of 'TS'",
+ height: 128,
+ src: "./docs/create-typescript-app.png",
+ width: 128,
+ },
+ node: {
+ minimum: expect.any(String),
+ pinned: expect.any(String),
+ },
+ owner: "JoshuaKGoldberg",
+ packageData: expect.any(Object),
+ repository: "create-typescript-app",
+ title: "Create TypeScript App",
+ usage: expect.any(String),
+ version: expect.any(String),
+ });
+ });
+});
diff --git a/src/next/base.ts b/src/base.ts
similarity index 86%
rename from src/next/base.ts
rename to src/base.ts
index 11e592f6d..7185d8427 100644
--- a/src/next/base.ts
+++ b/src/base.ts
@@ -9,18 +9,18 @@ import lazyValue from "lazy-value";
import npmUser from "npm-user";
import { z } from "zod";
-import { parsePackageAuthor } from "../shared/options/createOptionDefaults/parsePackageAuthor.js";
-import { readDefaultsFromReadme } from "../shared/options/createOptionDefaults/readDefaultsFromReadme.js";
-import { readEmails } from "../shared/options/createOptionDefaults/readEmails.js";
-import { readFunding } from "../shared/options/createOptionDefaults/readFunding.js";
-import { readGuide } from "../shared/options/createOptionDefaults/readGuide.js";
-import { readPackageData } from "../shared/packages.js";
-import { readFileSafe } from "../shared/readFileSafe.js";
-import { tryCatchLazyValueAsync } from "../shared/tryCatchLazyValueAsync.js";
-import { AllContributorsData } from "../shared/types.js";
-import { readDescription } from "./readDescription.js";
-import { readDocumentation } from "./readDocumentation.js";
+import { parsePackageAuthor } from "./options/parsePackageAuthor.js";
+import { readDefaultsFromReadme } from "./options/readDefaultsFromReadme.js";
+import { readDescription } from "./options/readDescription.js";
+import { readDocumentation } from "./options/readDocumentation.js";
+import { readEmails } from "./options/readEmails.js";
+import { readFileSafe } from "./options/readFileSafe.js";
+import { readFunding } from "./options/readFunding.js";
+import { readGuide } from "./options/readGuide.js";
+import { readPackageData } from "./options/readPackageData.js";
+import { AllContributorsData } from "./types.js";
import { swallowError } from "./utils/swallowError.js";
+import { tryCatchLazyValueAsync } from "./utils/tryCatchLazyValueAsync.js";
const zContributor = z.object({
avatar_url: z.string(),
@@ -89,12 +89,6 @@ export const base = createBase({
.describe(
"link to a contribution guide to place at the top of development docs",
),
- hideTemplatedBy: z
- .boolean()
- .optional()
- .describe(
- "whether to hide the 'created by ...' notice at the bottom of the README.md",
- ),
keywords: z
.array(z.string())
.optional()
diff --git a/src/bin/help.test.ts b/src/bin/help.test.ts
deleted file mode 100644
index 42f0965f2..000000000
--- a/src/bin/help.test.ts
+++ /dev/null
@@ -1,354 +0,0 @@
-import chalk from "chalk";
-import { beforeEach, describe, expect, it, MockInstance, vi } from "vitest";
-
-import { logHelpText } from "./help.js";
-
-function makeProxy(receiver: T): T {
- return new Proxy(receiver, {
- get: () => makeProxy((input: string) => input),
- });
-}
-
-vi.mock("chalk", () => ({
- default: makeProxy({}),
-}));
-
-let mockConsoleLog: MockInstance;
-
-describe("logHelpText", () => {
- beforeEach(() => {
- mockConsoleLog = vi
- .spyOn(console, "log")
- .mockImplementation(() => undefined);
- });
-
- it("logs help text when called", () => {
- logHelpText([
- chalk.yellow(
- "⚠️ This template is early stage, opinionated, and not endorsed by the TypeScript team. ⚠️",
- ),
- chalk.yellow(
- "⚠️ If any tooling it sets displeases you, you can always remove that portion manually. ⚠️",
- ),
- ]);
-
- expect(mockConsoleLog.mock.calls).toMatchInlineSnapshot(`
- [
- [
- "⚠️ This template is early stage, opinionated, and not endorsed by the TypeScript team. ⚠️",
- ],
- [
- " ",
- ],
- [
- "⚠️ If any tooling it sets displeases you, you can always remove that portion manually. ⚠️",
- ],
- [
- " ",
- ],
- [
- "
- A quickstart-friendly TypeScript template with comprehensive formatting,
- linting, releases, testing, and other great tooling built-in.
- ",
- ],
- [
- " ",
- ],
- [
- "Core options:",
- ],
- [
- "
- --base (string): Whether to scaffold the repository with:
- • everything: that comes with the template (recommended)
- • common: additions to the minimal starters such as releases and tests
- • minimal: amounts of tooling, essentially opting out of everything
- • prompt: for which portions to exclude",
- ],
- [
- "
- --create-repository: Whether to create a corresponding repository on github.com
- (if it doesn't yet exist)",
- ],
- [
- "
- --description (string): Sentence case description of the repository
- (e.g. A quickstart-friendly TypeScript package with lots of great
- repository tooling. ✨)",
- ],
- [
- "
- --mode (string): Whether to:
- • create: a new repository in a child directory
- • initialize: a freshly repository in the current directory
- • migrate: an existing repository in the current directory",
- ],
- [
- "
- --owner (string): GitHub organization or user the repository is underneath
- (e.g. JoshuaKGoldberg)",
- ],
- [
- "
- --repository (string): The kebab-case name of the repository
- (e.g. create-typescript-app)",
- ],
- [
- "
- --title (string): Title Case title for the repository to be used in
- documentation (e.g. Create TypeScript App)",
- ],
- [],
- [
- " ",
- ],
- [
- "Optional options:",
- ],
- [
- "
- --access (string): ("public" | "restricted"): Which 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())",
- ],
- [
- "
- --auto: Whether to infer all options from files on disk.",
- ],
- [
- "
- --bin (string): package.json bin value to include for npx-style running.",
- ],
- [
- "
- --directory (string): Directory to create the repository in (by default, the same
- name as the repository)",
- ],
- [
- "
- --email (string): Email address to be listed as the point of contact in docs
- and packages (e.g. example@joshuakgoldberg.com)",
- ],
- [
- "
- --email-github (string): Optionally, may be provided to use different emails in .md
- files",
- ],
- [
- "
- --email-npm (string): Optionally, may be provided to use different emails in
- package.json",
- ],
- [
- "
- --funding (string): GitHub organization or username to mention in funding.yml
- (by default, owner)",
- ],
- [
- "
- --guide (string): Link to a contribution guide to place at the top of the
- development docs",
- ],
- [
- "
- --guide-title (string): If --guide is provided or detected from an existing
- DEVELOPMENT.md, the text title to place in the guide link",
- ],
- [
- "
- --keywords (string): Any number of keywords to include in package.json (by default,
- none). This can be specified any number of times, like
- --keywords apple --keywords "banana cherry"",
- ],
- [
- "
- --logo (string): Local image file in the repository to display near the top of
- the README.md as a logo",
- ],
- [
- "
- --logo-alt (string): If --logo is provided or detected from an existing README.md,
- alt text that describes the image will be prompted for if not provided",
- ],
- [
- "
- --logo-height (string): If --logo is provided or detected from an existing README.md,
- an explicit height style",
- ],
- [
- "
- --logo-width (string): If --logo is provided or detected from an existing README.md,
- an explicit width style",
- ],
- [
- "
- --preserve-generated-from: Whether to keep the GitHub repository generated from
- notice (by default, false)",
- ],
- [],
- [
- " ",
- ],
- [
- "Opt-outs:",
- ],
- [
- "
- ⚠️ Warning: Specifying any --exclude-* flag on the command-line will
- cause the setup script to skip prompting for more excludes. ⚠️",
- ],
- [
- "
- --exclude-all-contributors: Don't add all-contributors to track contributions
- and display them in a README.md table.",
- ],
- [
- "
- --exclude-compliance: Don't add a GitHub Actions workflow to verify that PRs match
- an expected format.",
- ],
- [
- "
- --exclude-lint-jsdoc: Don't use eslint-plugin-jsdoc to enforce good practices around
- JSDoc comments.",
- ],
- [
- "
- --exclude-lint-json: Don't apply linting and sorting to *.json, and
- *.jsonc files.",
- ],
- [
- "
- --exclude-lint-knip: Don't add Knip to detect unused files, dependencies, and code
- exports.",
- ],
- [
- "
- --exclude-lint-md: Don't apply linting to *.md files.",
- ],
- [
- "
- --exclude-lint-package-json: Don't add eslint-plugin-package-json to lint for
- package.json correctness.",
- ],
- [
- "
- --exclude-lint-packages: Don't add a pnpm dedupe workflow to ensure packages
- aren't duplicated unnecessarily.",
- ],
- [
- "
- --exclude-lint-perfectionist: Don't apply eslint-plugin-perfectionist to ensure
- imports, keys, and so on are in sorted order.",
- ],
- [
- "
- --exclude-lint-regexp: Don't add eslint-plugin-regexp to enforce good practices around
- regular expressions.",
- ],
- [
- "
- --exclude-lint-spelling: Don't add cspell to spell check against dictionaries
- of known words.",
- ],
- [
- "
- --exclude-lint-strict: Don't augment the recommended logical lint rules with
- typescript-eslint's strict config.",
- ],
- [
- "
- --exclude-lint-stylistic: Don't add stylistic rules such as typescript-eslint's
- stylistic config.",
- ],
- [
- "
- --exclude-lint-yml: Don't apply linting and sorting to *.yaml and *.yml files.",
- ],
- [
- "
- --exclude-releases: Don't add release-it to generate changelogs, package bumps,
- and publishes based on conventional commits.",
- ],
- [
- "
- --exclude-renovate: Don't add a Renovate config to dependencies up-to-date with
- PRs.",
- ],
- [
- "
- --exclude-templated-by: Don't add a _"This package was templated with create-typescript-app"_ notice at the end of the README.md.",
- ],
- [
- "
- --exclude-tests: Don't add Vitest tooling for fast unit tests, configured
- with coverage tracking.",
- ],
- [
- "
- You can prevent the migration script from making some network-based
- changes using any or all of the following CLI flags:",
- ],
- [
- "
- --exclude-contributors: Skips network calls that fetch all-contributors
- data from GitHub",
- ],
- [
- "
- --skip-all-contributors-api: Skips network calls that fetch all-contributors data from
- GitHub. This flag does nothing if --exclude-all-contributors was specified.",
- ],
- [
- "
- --skip-github-api: Skips calling to GitHub APIs.",
- ],
- [
- "
- --skip-install: Skips installing all the new template packages with pnpm.",
- ],
- [
- "
- You can prevent the migration script from making some changes on disk
- using any or all of the following CLI flags:",
- ],
- [
- "
- --skip-removal: Skips removing setup docs and scripts, including this docs/
- directory",
- ],
- [
- "
- --skip-restore: Skips the prompt offering to restore the repository if an
- error occurs during setup",
- ],
- [
- "
- --skip-uninstall: Skips uninstalling packages only used for setup scripts",
- ],
- [],
- [
- " ",
- ],
- [
- "Offline Mode:",
- ],
- [
- "
- --offline: You can run create-typescript-app in an "offline" mode.
- Doing so will:
- • Enable --exclude-all-contributors-api and --skip-github-api
- • Skip network calls when setting up contributors
- • Run pnpm commands with pnpm's --offline mode",
- ],
- [],
- ]
- `);
- });
-});
diff --git a/src/bin/help.ts b/src/bin/help.ts
deleted file mode 100644
index a36b8737a..000000000
--- a/src/bin/help.ts
+++ /dev/null
@@ -1,148 +0,0 @@
-import chalk from "chalk";
-
-import { allArgOptions } from "../shared/options/args.js";
-
-interface HelpTextSection {
- sectionHeading: string;
- subsections: {
- flags: SubsectionFlag[];
- subheading?: string;
- warning?: string;
- }[];
-}
-
-interface SubsectionFlag {
- description: string;
- flag: string;
- type: string;
-}
-
-export function logHelpText(introLogs: string[]): void {
- const helpTextSections = createHelpTextSections();
-
- for (const log of introLogs) {
- console.log(log);
- console.log(" ");
- }
-
- console.log(
- chalk.cyan(
- `
-A quickstart-friendly TypeScript template with comprehensive formatting,
-linting, releases, testing, and other great tooling built-in.
- `,
- ),
- );
-
- for (const section of helpTextSections) {
- logHelpTextSection(section);
-
- console.log();
- }
-}
-
-function createHelpTextSections(): HelpTextSection[] {
- const core: HelpTextSection = {
- sectionHeading: "Core options:",
- subsections: [
- {
- flags: [],
- },
- ],
- };
-
- const optional: HelpTextSection = {
- sectionHeading: "Optional options:",
- subsections: [
- {
- flags: [],
- },
- ],
- };
-
- const optOut: HelpTextSection = {
- sectionHeading: "Opt-outs:",
- subsections: [
- {
- flags: [],
- warning: `
- ⚠️ Warning: Specifying any --exclude-* flag on the command-line will
- cause the setup script to skip prompting for more excludes. ⚠️`,
- },
- {
- flags: [
- {
- description: `Skips network calls that fetch all-contributors
- data from GitHub`,
- flag: "exclude-contributors",
- type: "boolean",
- },
- ],
- subheading: `
-You can prevent the migration script from making some network-based
-changes using any or all of the following CLI flags:`,
- },
- {
- flags: [],
- subheading: `
-You can prevent the migration script from making some changes on disk
-using any or all of the following CLI flags:`,
- },
- ],
- };
-
- const offline: HelpTextSection = {
- sectionHeading: "Offline Mode:",
- subsections: [
- {
- flags: [],
- },
- ],
- };
-
- const subsections = {
- core: core.subsections[0],
- offline: offline.subsections[0],
- "opt-out": optOut.subsections[0],
- optional: optional.subsections[0],
- "skip-disk": optOut.subsections[2],
- "skip-net": optOut.subsections[1],
- };
-
- for (const [option, data] of Object.entries(allArgOptions)) {
- subsections[data.docsSection].flags.push({
- description: data.description,
- flag: option,
- type: data.type,
- });
- }
-
- return [core, optional, optOut, offline];
-}
-
-function logHelpTextSection(section: HelpTextSection): void {
- console.log(" ");
-
- console.log(chalk.black.bgGreenBright(section.sectionHeading));
-
- for (const subsection of section.subsections) {
- if (subsection.warning) {
- console.log(chalk.yellow(subsection.warning));
- }
-
- if (subsection.subheading) {
- console.log(chalk.green(subsection.subheading));
- }
-
- for (const { description, flag, type } of subsection.flags) {
- console.log(
- chalk.cyan(
- `
- --${flag}${
- type !== "boolean" ? ` (${chalk.cyanBright(type)})` : ""
- }: ${description}`,
- ),
- );
- }
- }
-}
diff --git a/src/bin/index.test.ts b/src/bin/index.test.ts
deleted file mode 100644
index 8ed7fa0a9..000000000
--- a/src/bin/index.test.ts
+++ /dev/null
@@ -1,205 +0,0 @@
-import chalk from "chalk";
-import { beforeEach, describe, expect, it, vi } from "vitest";
-import z from "zod";
-
-import { bin } from "./index.js";
-import { getVersionFromPackageJson } from "./packageJson.js";
-
-const mockCancel = vi.fn();
-const mockOutro = vi.fn();
-
-vi.mock("@clack/prompts", () => ({
- get cancel() {
- return mockCancel;
- },
- intro: vi.fn(),
- log: {
- info: vi.fn(),
- },
- get outro() {
- return mockOutro;
- },
-}));
-
-const mockLogLine = vi.fn();
-
-vi.mock("../shared/cli/lines.js", () => ({
- get logLine() {
- return mockLogLine;
- },
-}));
-
-const mockCreate = vi.fn();
-
-vi.mock("../create/index.js", () => ({
- get create() {
- return mockCreate;
- },
-}));
-
-const mockInitialize = vi.fn();
-
-vi.mock("../initialize/index.js", () => ({
- get initialize() {
- return mockInitialize;
- },
-}));
-
-const mockMigrate = vi.fn();
-
-vi.mock("../migrate/index.js", () => ({
- get migrate() {
- return mockMigrate;
- },
-}));
-
-const mockPromptForMode = vi.fn();
-
-vi.mock("./promptForMode.js", () => ({
- get promptForMode() {
- return mockPromptForMode;
- },
-}));
-
-describe("bin", () => {
- beforeEach(() => {
- vi.spyOn(console, "clear").mockImplementation(() => undefined);
- vi.spyOn(console, "log").mockImplementation(() => undefined);
- });
-
- it("returns 1 when promptForMode returns an undefined mode", async () => {
- mockPromptForMode.mockResolvedValue({});
-
- const result = await bin([]);
-
- expect(mockOutro).toHaveBeenCalledWith(
- chalk.red("Operation cancelled. Exiting - maybe another time? 👋"),
- );
- expect(result).toBe(1);
- });
-
- it("returns 1 when promptForMode returns an error mode", async () => {
- const error = new Error("Oh no!");
- mockPromptForMode.mockResolvedValue({ mode: error });
-
- const result = await bin([]);
-
- expect(mockOutro).toHaveBeenCalledWith(chalk.red(error.message));
- expect(result).toBe(1);
- });
-
- it("returns the success result of the corresponding runner without cancel logging when promptForMode returns a mode that succeeds", async () => {
- const mode = "create";
- const args = ["--owner", "abc123"];
- const code = 0;
- const promptedOptions = { directory: "." };
-
- mockPromptForMode.mockResolvedValue({ mode, options: promptedOptions });
- mockCreate.mockResolvedValue({ code, options: {} });
-
- const result = await bin(args);
-
- expect(mockCreate).toHaveBeenCalledWith(args, promptedOptions);
- expect(mockCancel).not.toHaveBeenCalled();
- expect(mockInitialize).not.toHaveBeenCalled();
- expect(mockMigrate).not.toHaveBeenCalled();
- expect(result).toEqual(code);
- });
-
- it("returns the cancel result of the corresponding runner and cancel logs when promptForMode returns a mode that cancels", async () => {
- const mode = "create";
- const args = ["--owner", "abc123"];
- const code = 2;
- const promptedOptions = { directory: "." };
-
- mockPromptForMode.mockResolvedValue({ mode, options: promptedOptions });
- mockCreate.mockResolvedValue({ code, options: {} });
-
- const result = await bin(args);
-
- expect(mockCreate).toHaveBeenCalledWith(args, promptedOptions);
- expect(mockCancel).toHaveBeenCalledWith(
- `Operation cancelled. Exiting - maybe another time? 👋`,
- );
- expect(result).toEqual(code);
- });
-
- it("returns the cancel result containing a zod error of the corresponding runner and output plus cancel logs when promptForMode returns a mode that cancels with a string error", async () => {
- const mode = "initialize";
- const args = ["--email", "abc123"];
- const code = 2;
- const error = "Oh no!";
-
- mockPromptForMode.mockResolvedValue({ mode });
- mockInitialize.mockResolvedValue({
- code: 2,
- error,
- options: {},
- });
-
- const result = await bin(args);
-
- expect(mockInitialize).toHaveBeenCalledWith(args, undefined);
- expect(mockLogLine).toHaveBeenCalledWith(chalk.red(error));
- expect(mockCancel).toHaveBeenCalledWith(
- `Operation cancelled. Exiting - maybe another time? 👋`,
- );
- expect(result).toEqual(code);
- });
-
- it("returns the cancel result containing a zod error of the corresponding runner and output plus cancel logs when promptForMode returns a mode that cancels with a zod error", async () => {
- const mode = "initialize";
- const args = ["--email", "abc123"];
- const code = 2;
-
- const validationResult = z
- .object({ email: z.string().email() })
- .safeParse({ email: "abc123" });
-
- mockPromptForMode.mockResolvedValue({ mode });
- mockInitialize.mockResolvedValue({
- code: 2,
- error: (validationResult as z.SafeParseError<{ email: string }>).error,
- options: {},
- });
-
- const result = await bin(args);
-
- expect(mockInitialize).toHaveBeenCalledWith(args, undefined);
- expect(mockLogLine).toHaveBeenCalledWith(
- chalk.red('Validation error: Invalid email at "email"'),
- );
- expect(mockCancel).toHaveBeenCalledWith(
- `Operation cancelled. Exiting - maybe another time? 👋`,
- );
- expect(result).toEqual(code);
- });
-
- it("returns the cancel result of the corresponding runner and cancel logs when promptForMode returns a mode that fails", async () => {
- const mode = "create";
- const args = ["--owner", "abc123"];
- const code = 1;
- const promptedOptions = { directory: "." };
-
- mockPromptForMode.mockResolvedValue({ mode, options: promptedOptions });
- mockCreate.mockResolvedValue({ code, options: {} });
-
- const result = await bin(args);
-
- expect(mockCreate).toHaveBeenCalledWith(args, promptedOptions);
- expect(mockCancel).toHaveBeenCalledWith(
- `Operation failed. Exiting - maybe another time? 👋`,
- );
- expect(result).toEqual(code);
- });
-
- it("prints the version when the --version flag is passed", async () => {
- const args = ["--version"];
- const version = await getVersionFromPackageJson();
-
- const result = await bin(args);
-
- expect(console.log).toHaveBeenCalledWith(version);
- expect(result).toBe(0);
- });
-});
diff --git a/src/bin/index.ts b/src/bin/index.ts
deleted file mode 100644
index 923727759..000000000
--- a/src/bin/index.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-import * as prompts from "@clack/prompts";
-import chalk from "chalk";
-import { parseArgs } from "node:util";
-import { fromZodError } from "zod-validation-error";
-
-import { createRerunSuggestion } from "../create/createRerunSuggestion.js";
-import { create } from "../create/index.js";
-import { initialize } from "../initialize/index.js";
-import { migrate } from "../migrate/index.js";
-import { logLine } from "../shared/cli/lines.js";
-import { StatusCodes } from "../shared/codes.js";
-import { logHelpText } from "./help.js";
-import { getVersionFromPackageJson } from "./packageJson.js";
-import { promptForMode } from "./promptForMode.js";
-
-const operationMessage = (verb: string) =>
- `Operation ${verb}. Exiting - maybe another time? 👋`;
-
-export async function bin(args: string[]) {
- console.clear();
-
- const version = await getVersionFromPackageJson();
-
- const introPrompts = [
- chalk.greenBright(`✨ Welcome to`),
- chalk.bgGreenBright.black(`create-typescript-app`),
- chalk.greenBright(`${version}! ✨`),
- ].join(" ");
-
- const introWarnings = [
- chalk.yellow(
- "⚠️ This template is early stage, opinionated, and not endorsed by the TypeScript team. ⚠️",
- ),
- chalk.yellow(
- "⚠️ If any tooling it sets displeases you, you can always remove that portion manually. ⚠️",
- ),
- ];
-
- const { values } = parseArgs({
- args,
- options: {
- help: {
- short: "h",
- type: "boolean",
- },
- mode: { type: "string" },
- version: {
- short: "v",
- type: "boolean",
- },
- },
- strict: false,
- });
-
- if (values.help) {
- logHelpText([introPrompts, ...introWarnings]);
- return 0;
- }
-
- if (values.version) {
- console.log(version);
- return 0;
- }
-
- prompts.intro(introPrompts);
-
- logLine();
- logLine(introWarnings[0]);
- logLine(introWarnings[1]);
-
- const { mode, options: promptedOptions } = await promptForMode(
- !!values.auto,
- values.mode,
- );
- if (typeof mode !== "string") {
- prompts.outro(chalk.red(mode?.message ?? operationMessage("cancelled")));
- return 1;
- }
-
- const runners = { create, initialize, migrate };
- const { code, error, options } = await runners[mode](args, promptedOptions);
-
- prompts.log.info(
- [
- chalk.italic(`Tip: to run again with the same input values, use:`),
- chalk.blue(createRerunSuggestion(options)),
- ].join(" "),
- );
-
- if (code) {
- logLine();
-
- if (error) {
- logLine(
- chalk.red(typeof error === "string" ? error : fromZodError(error)),
- );
- logLine();
- }
-
- prompts.cancel(
- code === StatusCodes.Cancelled
- ? operationMessage("cancelled")
- : operationMessage("failed"),
- );
- }
-
- return code;
-}
diff --git a/src/bin/packageJson.test.ts b/src/bin/packageJson.test.ts
deleted file mode 100644
index 7e1be8dee..000000000
--- a/src/bin/packageJson.test.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { describe, expect, it, vi } from "vitest";
-
-import { getVersionFromPackageJson } from "./packageJson.js";
-
-const mockReadFileSafeAsJson = vi.fn();
-
-vi.mock("../shared/readFileSafeAsJson.js", () => ({
- get readFileSafeAsJson() {
- return mockReadFileSafeAsJson;
- },
-}));
-
-describe("getVersionFromPackageJson", () => {
- it("returns the current version number from the package.json", async () => {
- mockReadFileSafeAsJson.mockResolvedValue({
- version: "1.40.0",
- });
-
- const version = await getVersionFromPackageJson();
-
- expect(version).toBe("1.40.0");
- });
-
- it("throws an error when there is no version number", async () => {
- mockReadFileSafeAsJson.mockResolvedValue({});
-
- await expect(() => getVersionFromPackageJson()).rejects.toEqual(
- new Error("Cannot find version number"),
- );
- });
-});
diff --git a/src/bin/packageJson.ts b/src/bin/packageJson.ts
deleted file mode 100644
index 18d7004e2..000000000
--- a/src/bin/packageJson.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { readFileSafeAsJson } from "../shared/readFileSafeAsJson.js";
-
-interface PackageWithVersion {
- version?: string;
-}
-
-export async function getVersionFromPackageJson(): Promise {
- const path = new URL("../../package.json", import.meta.url);
- const data = (await readFileSafeAsJson(path)) as PackageWithVersion;
-
- if (typeof data === "object" && typeof data.version === "string") {
- return data.version;
- }
-
- throw new Error("Cannot find version number");
-}
diff --git a/src/bin/promptForMode.test.ts b/src/bin/promptForMode.test.ts
deleted file mode 100644
index f508c6d14..000000000
--- a/src/bin/promptForMode.test.ts
+++ /dev/null
@@ -1,129 +0,0 @@
-import chalk from "chalk";
-import { describe, expect, it, vi } from "vitest";
-
-import { promptForMode } from "./promptForMode.js";
-
-const mockSelect = vi.fn();
-
-vi.mock("@clack/prompts", () => ({
- isCancel: () => false,
- get select() {
- return mockSelect;
- },
-}));
-
-const mockReaddir = vi.fn();
-
-vi.mock("node:fs/promises", () => ({
- get readdir() {
- return mockReaddir;
- },
-}));
-
-const mockCwd = vi.fn();
-
-vi.mock("node:process", () => ({
- get cwd() {
- return mockCwd;
- },
-}));
-
-const mockLogLine = vi.fn();
-
-vi.mock("../shared/cli/lines.js", () => ({
- get logLine() {
- return mockLogLine;
- },
-}));
-describe("promptForMode", () => {
- it("returns an error when auto exists and input is not migrate", async () => {
- const mode = await promptForMode(true, "create");
-
- expect(mode).toMatchInlineSnapshot(
- `
- {
- "mode": [Error: --auto can only be used with --mode migrate.],
- }
- `,
- );
- });
-
- it("returns an error when the input exists and is not a mode", async () => {
- const mode = await promptForMode(false, "other");
-
- expect(mode).toMatchInlineSnapshot(
- `
- {
- "mode": [Error: Unknown --mode: other. Allowed modes are: create, initialize, migrate.],
- }
- `,
- );
- });
-
- it("returns the input when it is a mode", async () => {
- const input = "create";
-
- const mode = await promptForMode(false, input);
-
- expect(mode).toEqual({ mode: input });
- });
-
- it("returns creating in the current directory when the current directory is empty and the user selects create-current", async () => {
- mockSelect.mockResolvedValueOnce("create-current");
- const directory = "test-directory";
-
- mockReaddir.mockResolvedValueOnce([]);
- mockCwd.mockReturnValueOnce(`/path/to/${directory}`);
-
- const actual = await promptForMode(false, undefined);
-
- expect(actual).toEqual({
- mode: "create",
- options: { directory: ".", repository: directory },
- });
- expect(mockLogLine).not.toHaveBeenCalled();
- });
-
- it("returns creating in a child directory when the current directory is empty and the user selects create-child", async () => {
- mockSelect.mockResolvedValueOnce("create-child");
- const directory = "test-directory";
-
- mockReaddir.mockResolvedValueOnce([]);
- mockCwd.mockReturnValueOnce(`/path/to/${directory}`);
-
- const actual = await promptForMode(false, undefined);
-
- expect(actual).toEqual({
- mode: "create",
- });
- expect(mockLogLine).not.toHaveBeenCalled();
- });
-
- it("returns the user selection when the current directory is a Git directory", async () => {
- const mode = "initialize";
- mockSelect.mockResolvedValueOnce(mode);
-
- mockReaddir.mockResolvedValueOnce([".git"]);
-
- const actual = await promptForMode(false, undefined);
-
- expect(actual).toEqual({ mode });
- expect(mockLogLine).not.toHaveBeenCalled();
- });
-
- it("returns create without prompting when the current directory contains children but is not a Git directory", async () => {
- const mode = "create";
-
- mockReaddir.mockResolvedValueOnce(["file"]);
-
- const actual = await promptForMode(false, undefined);
-
- expect(actual).toEqual({ mode });
- expect(mockSelect).not.toHaveBeenCalled();
- expect(mockLogLine).toHaveBeenCalledWith(
- chalk.gray(
- "Defaulting to --mode create because the directory contains children and isn't a Git repository.",
- ),
- );
- });
-});
diff --git a/src/bin/promptForMode.ts b/src/bin/promptForMode.ts
deleted file mode 100644
index 8bb6ab43c..000000000
--- a/src/bin/promptForMode.ts
+++ /dev/null
@@ -1,127 +0,0 @@
-import * as prompts from "@clack/prompts";
-import chalk from "chalk";
-import * as fs from "fs/promises";
-import path from "node:path";
-import * as process from "node:process";
-
-import { logLine } from "../shared/cli/lines.js";
-import { isUsingCreateEngine } from "../shared/isUsingCreateEngine.js";
-import { filterPromptCancel } from "../shared/prompts.js";
-import { Mode, PromptedOptions } from "../shared/types.js";
-
-const allowedModes = ["create", "initialize", "migrate"] satisfies Mode[];
-
-export interface PromptedMode {
- mode: Error | Mode | undefined;
- options?: PromptedOptions;
-}
-
-export async function promptForMode(
- auto: boolean,
- input: boolean | string | undefined,
-): Promise {
- if (auto && input !== "migrate") {
- return {
- mode: new Error("--auto can only be used with --mode migrate."),
- };
- }
-
- if (input) {
- if (!isMode(input)) {
- return {
- mode: new Error(
- `Unknown --mode: ${input}. Allowed modes are: ${allowedModes.join(
- ", ",
- )}.`,
- ),
- };
- }
-
- return { mode: input };
- }
-
- const dir = await fs.readdir(".");
-
- if (dir.length === 0 && !isUsingCreateEngine()) {
- const mode = filterPromptCancel(
- (await prompts.select({
- message: chalk.blue("How would you like to use the template?"),
- options: [
- {
- label: label(
- "create",
- "a new repository in the current empty directory",
- ),
- value: "create-current",
- },
- {
- label: label("create", "a new repository in a new child directory"),
- value: "create-child",
- },
- ],
- })) as string,
- );
-
- const directory = path.basename(process.cwd());
-
- return {
- mode: "create",
- ...(mode === "create-current" && {
- options: {
- directory: ".",
- repository: directory,
- },
- }),
- };
- }
-
- if (dir.includes(".git")) {
- return {
- mode: filterPromptCancel(
- (await prompts.select({
- initialValue: "migrate" as Mode,
- message: chalk.blue("How would you like to use the template?"),
- options: [
- {
- label: label("create", "a new repository in a child directory"),
- value: "create",
- },
- {
- label: label(
- "initialize",
- "a freshly cloned repository in the current directory",
- ),
- value: "initialize",
- },
- {
- label: label(
- "migrate",
- "the existing repository in the current directory",
- ),
- value: "migrate",
- },
- ],
- })) as Mode | symbol,
- ),
- };
- }
-
- logLine();
- logLine(
- chalk.gray(
- "Defaulting to --mode create because the directory contains children and isn't a Git repository.",
- ),
- );
-
- return {
- mode: "create",
- };
-}
-
-function isMode(input: boolean | string): input is Mode {
- return allowedModes.includes(input as Mode);
-}
-
-function label(base: string, text: string) {
- return `${chalk.bold(base)} ${text}`;
-}
diff --git a/src/next/blocks/blockAllContributors.test.ts b/src/blocks/blockAllContributors.test.ts
similarity index 100%
rename from src/next/blocks/blockAllContributors.test.ts
rename to src/blocks/blockAllContributors.test.ts
diff --git a/src/next/blocks/blockAllContributors.ts b/src/blocks/blockAllContributors.ts
similarity index 97%
rename from src/next/blocks/blockAllContributors.ts
rename to src/blocks/blockAllContributors.ts
index 89ec1aac4..6a996940a 100644
--- a/src/next/blocks/blockAllContributors.ts
+++ b/src/blocks/blockAllContributors.ts
@@ -1,9 +1,9 @@
import _ from "lodash";
-import { createSoloWorkflowFile } from "../../steps/writing/creation/dotGitHub/createSoloWorkflowFile.js";
import { base, Contributor } from "../base.js";
import { blockREADME } from "./blockREADME.js";
import { blockRepositorySecrets } from "./blockRepositorySecrets.js";
+import { createSoloWorkflowFile } from "./files/createSoloWorkflowFile.js";
import { CommandPhase } from "./phases.js";
export const blockAllContributors = base.createBlock({
diff --git a/src/next/blocks/blockAreTheTypesWrong.test.ts b/src/blocks/blockAreTheTypesWrong.test.ts
similarity index 100%
rename from src/next/blocks/blockAreTheTypesWrong.test.ts
rename to src/blocks/blockAreTheTypesWrong.test.ts
diff --git a/src/next/blocks/blockAreTheTypesWrong.ts b/src/blocks/blockAreTheTypesWrong.ts
similarity index 100%
rename from src/next/blocks/blockAreTheTypesWrong.ts
rename to src/blocks/blockAreTheTypesWrong.ts
diff --git a/src/next/blocks/blockCSpell.test.ts b/src/blocks/blockCSpell.test.ts
similarity index 97%
rename from src/next/blocks/blockCSpell.test.ts
rename to src/blocks/blockCSpell.test.ts
index 6431025e6..9b64b5053 100644
--- a/src/next/blocks/blockCSpell.test.ts
+++ b/src/blocks/blockCSpell.test.ts
@@ -58,7 +58,7 @@ describe("blockCSpell", () => {
"addons": {
"properties": {
"devDependencies": {
- "cspell": "8.17.1",
+ "cspell": "^8.17.2",
},
"scripts": {
"lint:spelling": "cspell "**" ".github/**/*"",
@@ -128,7 +128,7 @@ describe("blockCSpell", () => {
"addons": {
"properties": {
"devDependencies": {
- "cspell": "8.17.1",
+ "cspell": "^8.17.2",
},
"scripts": {
"lint:spelling": "cspell "**" ".github/**/*"",
diff --git a/src/next/blocks/blockCSpell.ts b/src/blocks/blockCSpell.ts
similarity index 97%
rename from src/next/blocks/blockCSpell.ts
rename to src/blocks/blockCSpell.ts
index 130991124..5a3cebb14 100644
--- a/src/next/blocks/blockCSpell.ts
+++ b/src/blocks/blockCSpell.ts
@@ -2,12 +2,12 @@ import { getObjectStringsDeep } from "object-strings-deep";
import { z } from "zod";
import { base } from "../base.js";
+import { getPackageDependencies } from "../data/packageData.js";
import { resolveBin } from "../utils/resolveBin.js";
import { blockDevelopmentDocs } from "./blockDevelopmentDocs.js";
import { blockGitHubActionsCI } from "./blockGitHubActionsCI.js";
import { blockPackageJson } from "./blockPackageJson.js";
import { blockVSCode } from "./blockVSCode.js";
-import { getPackageDependencies } from "./packageData.js";
import { CommandPhase } from "./phases.js";
const filesGlob = `"**" ".github/**/*"`;
diff --git a/src/next/blocks/blockCodecov.test.ts b/src/blocks/blockCodecov.test.ts
similarity index 99%
rename from src/next/blocks/blockCodecov.test.ts
rename to src/blocks/blockCodecov.test.ts
index 878e424c3..185f91f67 100644
--- a/src/next/blocks/blockCodecov.test.ts
+++ b/src/blocks/blockCodecov.test.ts
@@ -78,6 +78,7 @@ describe("blockCodecov", () => {
"rm .github/codecov.yml codecov.yml",
],
"phase": 0,
+ "silent": true,
},
],
}
diff --git a/src/next/blocks/blockCodecov.ts b/src/blocks/blockCodecov.ts
similarity index 97%
rename from src/next/blocks/blockCodecov.ts
rename to src/blocks/blockCodecov.ts
index 36203aa96..2233296a2 100644
--- a/src/next/blocks/blockCodecov.ts
+++ b/src/blocks/blockCodecov.ts
@@ -16,6 +16,7 @@ export const blockCodecov = base.createBlock({
{
commands: ["rm .github/codecov.yml codecov.yml"],
phase: CommandPhase.Migrations,
+ silent: true,
},
],
};
diff --git a/src/next/blocks/blockContributingDocs.test.ts b/src/blocks/blockContributingDocs.test.ts
similarity index 99%
rename from src/next/blocks/blockContributingDocs.test.ts
rename to src/blocks/blockContributingDocs.test.ts
index 115ab626e..869d7472d 100644
--- a/src/next/blocks/blockContributingDocs.test.ts
+++ b/src/blocks/blockContributingDocs.test.ts
@@ -234,6 +234,7 @@ describe("blockContributingDocs", () => {
"rm CONTRIBUTING.md",
],
"phase": 0,
+ "silent": true,
},
],
}
diff --git a/src/next/blocks/blockContributingDocs.ts b/src/blocks/blockContributingDocs.ts
similarity index 99%
rename from src/next/blocks/blockContributingDocs.ts
rename to src/blocks/blockContributingDocs.ts
index 99e30a767..0e68dc515 100644
--- a/src/next/blocks/blockContributingDocs.ts
+++ b/src/blocks/blockContributingDocs.ts
@@ -11,6 +11,7 @@ export const blockContributingDocs = base.createBlock({
{
commands: ["rm CONTRIBUTING.md"],
phase: CommandPhase.Migrations,
+ silent: true,
},
],
};
diff --git a/src/next/blocks/blockContributorCovenant.test.ts b/src/blocks/blockContributorCovenant.test.ts
similarity index 99%
rename from src/next/blocks/blockContributorCovenant.test.ts
rename to src/blocks/blockContributorCovenant.test.ts
index e04d232c0..0904a8921 100644
--- a/src/next/blocks/blockContributorCovenant.test.ts
+++ b/src/blocks/blockContributorCovenant.test.ts
@@ -304,6 +304,7 @@ describe("blockContributorCovenant", () => {
"rm CODE_OF_CONDUCT.md",
],
"phase": 0,
+ "silent": true,
},
],
}
diff --git a/src/next/blocks/blockContributorCovenant.ts b/src/blocks/blockContributorCovenant.ts
similarity index 99%
rename from src/next/blocks/blockContributorCovenant.ts
rename to src/blocks/blockContributorCovenant.ts
index 5254b5026..996ec8833 100644
--- a/src/next/blocks/blockContributorCovenant.ts
+++ b/src/blocks/blockContributorCovenant.ts
@@ -11,6 +11,7 @@ export const blockContributorCovenant = base.createBlock({
{
commands: ["rm CODE_OF_CONDUCT.md"],
phase: CommandPhase.Migrations,
+ silent: true,
},
],
};
diff --git a/src/next/blocks/blockDevelopmentDocs.test.ts b/src/blocks/blockDevelopmentDocs.test.ts
similarity index 99%
rename from src/next/blocks/blockDevelopmentDocs.test.ts
rename to src/blocks/blockDevelopmentDocs.test.ts
index e07c4c126..659faecea 100644
--- a/src/next/blocks/blockDevelopmentDocs.test.ts
+++ b/src/blocks/blockDevelopmentDocs.test.ts
@@ -58,6 +58,7 @@ describe("blockDevelopmentDocs", () => {
"rm DEVELOPMENT.md",
],
"phase": 0,
+ "silent": true,
},
],
}
diff --git a/src/next/blocks/blockDevelopmentDocs.ts b/src/blocks/blockDevelopmentDocs.ts
similarity index 99%
rename from src/next/blocks/blockDevelopmentDocs.ts
rename to src/blocks/blockDevelopmentDocs.ts
index fa3e40756..13dcc8986 100644
--- a/src/next/blocks/blockDevelopmentDocs.ts
+++ b/src/blocks/blockDevelopmentDocs.ts
@@ -70,6 +70,7 @@ export const blockDevelopmentDocs = base.createBlock({
{
commands: ["rm DEVELOPMENT.md"],
phase: CommandPhase.Migrations,
+ silent: true,
},
],
};
diff --git a/src/next/blocks/blockESLint.test.ts b/src/blocks/blockESLint.test.ts
similarity index 99%
rename from src/next/blocks/blockESLint.test.ts
rename to src/blocks/blockESLint.test.ts
index 1f93d2c89..bc6cbf551 100644
--- a/src/next/blocks/blockESLint.test.ts
+++ b/src/blocks/blockESLint.test.ts
@@ -262,6 +262,7 @@ describe("blockESLint", () => {
"rm .eslintrc* .eslintignore eslint.config.*",
],
"phase": 0,
+ "silent": true,
},
],
}
diff --git a/src/next/blocks/blockESLint.ts b/src/blocks/blockESLint.ts
similarity index 98%
rename from src/next/blocks/blockESLint.ts
rename to src/blocks/blockESLint.ts
index e8061ca05..663934fd1 100644
--- a/src/next/blocks/blockESLint.ts
+++ b/src/blocks/blockESLint.ts
@@ -3,12 +3,12 @@ import { parse as parsePackageName } from "parse-package-name";
import { z } from "zod";
import { base } from "../base.js";
+import { getPackageDependencies } from "../data/packageData.js";
import { blockCSpell } from "./blockCSpell.js";
import { blockDevelopmentDocs } from "./blockDevelopmentDocs.js";
import { blockGitHubActionsCI } from "./blockGitHubActionsCI.js";
import { blockPackageJson } from "./blockPackageJson.js";
import { blockVSCode } from "./blockVSCode.js";
-import { getPackageDependencies } from "./packageData.js";
import { CommandPhase } from "./phases.js";
const zRuleOptions = z.union([
@@ -70,6 +70,7 @@ export const blockESLint = base.createBlock({
{
commands: ["rm .eslintrc* .eslintignore eslint.config.*"],
phase: CommandPhase.Migrations,
+ silent: true,
},
],
};
diff --git a/src/next/blocks/blockESLintComments.ts b/src/blocks/blockESLintComments.ts
similarity index 100%
rename from src/next/blocks/blockESLintComments.ts
rename to src/blocks/blockESLintComments.ts
diff --git a/src/next/blocks/blockESLintJSDoc.ts b/src/blocks/blockESLintJSDoc.ts
similarity index 100%
rename from src/next/blocks/blockESLintJSDoc.ts
rename to src/blocks/blockESLintJSDoc.ts
diff --git a/src/next/blocks/blockESLintJSONC.ts b/src/blocks/blockESLintJSONC.ts
similarity index 100%
rename from src/next/blocks/blockESLintJSONC.ts
rename to src/blocks/blockESLintJSONC.ts
diff --git a/src/next/blocks/blockESLintMarkdown.ts b/src/blocks/blockESLintMarkdown.ts
similarity index 100%
rename from src/next/blocks/blockESLintMarkdown.ts
rename to src/blocks/blockESLintMarkdown.ts
diff --git a/src/next/blocks/blockESLintMoreStyling.ts b/src/blocks/blockESLintMoreStyling.ts
similarity index 100%
rename from src/next/blocks/blockESLintMoreStyling.ts
rename to src/blocks/blockESLintMoreStyling.ts
diff --git a/src/next/blocks/blockESLintNode.test.ts b/src/blocks/blockESLintNode.test.ts
similarity index 100%
rename from src/next/blocks/blockESLintNode.test.ts
rename to src/blocks/blockESLintNode.test.ts
diff --git a/src/next/blocks/blockESLintNode.ts b/src/blocks/blockESLintNode.ts
similarity index 100%
rename from src/next/blocks/blockESLintNode.ts
rename to src/blocks/blockESLintNode.ts
diff --git a/src/next/blocks/blockESLintPackageJson.ts b/src/blocks/blockESLintPackageJson.ts
similarity index 100%
rename from src/next/blocks/blockESLintPackageJson.ts
rename to src/blocks/blockESLintPackageJson.ts
diff --git a/src/next/blocks/blockESLintPerfectionist.ts b/src/blocks/blockESLintPerfectionist.ts
similarity index 100%
rename from src/next/blocks/blockESLintPerfectionist.ts
rename to src/blocks/blockESLintPerfectionist.ts
diff --git a/src/next/blocks/blockESLintRegexp.ts b/src/blocks/blockESLintRegexp.ts
similarity index 100%
rename from src/next/blocks/blockESLintRegexp.ts
rename to src/blocks/blockESLintRegexp.ts
diff --git a/src/next/blocks/blockESLintYML.ts b/src/blocks/blockESLintYML.ts
similarity index 100%
rename from src/next/blocks/blockESLintYML.ts
rename to src/blocks/blockESLintYML.ts
diff --git a/src/next/blocks/blockExampleFiles.test.ts b/src/blocks/blockExampleFiles.test.ts
similarity index 100%
rename from src/next/blocks/blockExampleFiles.test.ts
rename to src/blocks/blockExampleFiles.test.ts
diff --git a/src/next/blocks/blockExampleFiles.ts b/src/blocks/blockExampleFiles.ts
similarity index 100%
rename from src/next/blocks/blockExampleFiles.ts
rename to src/blocks/blockExampleFiles.ts
diff --git a/src/next/blocks/blockFunding.ts b/src/blocks/blockFunding.ts
similarity index 77%
rename from src/next/blocks/blockFunding.ts
rename to src/blocks/blockFunding.ts
index 934d3ed19..64cff2929 100644
--- a/src/next/blocks/blockFunding.ts
+++ b/src/blocks/blockFunding.ts
@@ -1,5 +1,5 @@
-import { formatYaml } from "../../steps/writing/creation/formatters/formatYaml.js";
import { base } from "../base.js";
+import { formatYaml } from "./files/formatYaml.js";
export const blockFunding = base.createBlock({
about: {
diff --git a/src/next/blocks/blockGitHubActionsCI.test.ts b/src/blocks/blockGitHubActionsCI.test.ts
similarity index 90%
rename from src/next/blocks/blockGitHubActionsCI.test.ts
rename to src/blocks/blockGitHubActionsCI.test.ts
index af9efb099..cbf7801f5 100644
--- a/src/next/blocks/blockGitHubActionsCI.test.ts
+++ b/src/blocks/blockGitHubActionsCI.test.ts
@@ -12,6 +12,14 @@ describe("blockGitHubActionsCI", () => {
expect(creation).toMatchInlineSnapshot(`
{
+ "addons": [
+ {
+ "addons": {
+ "requiredStatusChecks": undefined,
+ },
+ "block": [Function],
+ },
+ ],
"files": {
".github": {
"actions": {
@@ -70,7 +78,7 @@ describe("blockGitHubActionsCI", () => {
steps:
- uses: actions-ecosystem/action-remove-labels@v1
with:
- labels: "status: waiting for author"
+ labels: 'status: waiting for author'
- if: failure()
run: |
echo "Don't worry if the previous step failed."
@@ -101,6 +109,14 @@ describe("blockGitHubActionsCI", () => {
expect(creation).toMatchInlineSnapshot(`
{
+ "addons": [
+ {
+ "addons": {
+ "requiredStatusChecks": undefined,
+ },
+ "block": [Function],
+ },
+ ],
"files": {
".github": {
"actions": {
@@ -159,7 +175,7 @@ describe("blockGitHubActionsCI", () => {
steps:
- uses: actions-ecosystem/action-remove-labels@v1
with:
- labels: "status: waiting for author"
+ labels: 'status: waiting for author'
- if: failure()
run: |
echo "Don't worry if the previous step failed."
@@ -184,6 +200,7 @@ describe("blockGitHubActionsCI", () => {
"rm -rf .circleci travis.yml",
],
"phase": 0,
+ "silent": true,
},
],
}
@@ -212,6 +229,16 @@ describe("blockGitHubActionsCI", () => {
expect(creation).toMatchInlineSnapshot(`
{
+ "addons": [
+ {
+ "addons": {
+ "requiredStatusChecks": [
+ "Validate",
+ ],
+ },
+ "block": [Function],
+ },
+ ],
"files": {
".github": {
"actions": {
@@ -271,11 +298,11 @@ describe("blockGitHubActionsCI", () => {
- uses: actions/checkout@v4
- uses: ./.github/actions/prepare
- env:
- VAR_ENV: "true"
+ VAR_ENV: 'true'
if: always()
run: pnpm validate
with:
- VAR_WITH: "true"
+ VAR_WITH: 'true'
name: CI
@@ -291,7 +318,7 @@ describe("blockGitHubActionsCI", () => {
steps:
- uses: actions-ecosystem/action-remove-labels@v1
with:
- labels: "status: waiting for author"
+ labels: 'status: waiting for author'
- if: failure()
run: |
echo "Don't worry if the previous step failed."
diff --git a/src/next/blocks/blockGitHubActionsCI.ts b/src/blocks/blockGitHubActionsCI.ts
similarity index 88%
rename from src/next/blocks/blockGitHubActionsCI.ts
rename to src/blocks/blockGitHubActionsCI.ts
index f9e995aa7..1da0d2289 100644
--- a/src/next/blocks/blockGitHubActionsCI.ts
+++ b/src/blocks/blockGitHubActionsCI.ts
@@ -1,9 +1,10 @@
import jsYaml from "js-yaml";
import { z } from "zod";
-import { createMultiWorkflowFile } from "../../steps/writing/creation/dotGitHub/createMultiWorkflowFile.js";
-import { createSoloWorkflowFile } from "../../steps/writing/creation/dotGitHub/createSoloWorkflowFile.js";
import { base } from "../base.js";
+import { blockRepositoryBranchRuleset } from "./blockRepositoryBranchRuleset.js";
+import { createMultiWorkflowFile } from "./files/createMultiWorkflowFile.js";
+import { createSoloWorkflowFile } from "./files/createSoloWorkflowFile.js";
import { CommandPhase } from "./phases.js";
export const zActionStep = z.intersection(
@@ -35,6 +36,7 @@ export const blockGitHubActionsCI = base.createBlock({
{
commands: ["rm -rf .circleci travis.yml"],
phase: CommandPhase.Migrations,
+ silent: true,
},
],
};
@@ -43,6 +45,11 @@ export const blockGitHubActionsCI = base.createBlock({
const { jobs } = addons;
return {
+ addons: [
+ blockRepositoryBranchRuleset({
+ requiredStatusChecks: jobs?.map((job) => job.name),
+ }),
+ ],
files: {
".github": {
actions: {
diff --git a/src/next/blocks/blockGitHubApps.ts b/src/blocks/blockGitHubApps.ts
similarity index 100%
rename from src/next/blocks/blockGitHubApps.ts
rename to src/blocks/blockGitHubApps.ts
diff --git a/src/next/blocks/blockGitHubIssueTemplates.ts b/src/blocks/blockGitHubIssueTemplates.ts
similarity index 98%
rename from src/next/blocks/blockGitHubIssueTemplates.ts
rename to src/blocks/blockGitHubIssueTemplates.ts
index 23bd3e977..6d3ef2bb3 100644
--- a/src/next/blocks/blockGitHubIssueTemplates.ts
+++ b/src/blocks/blockGitHubIssueTemplates.ts
@@ -1,5 +1,5 @@
-import { formatYaml } from "../../steps/writing/creation/formatters/formatYaml.js";
import { base } from "../base.js";
+import { formatYaml } from "./files/formatYaml.js";
export const blockGitHubIssueTemplates = base.createBlock({
about: {
diff --git a/src/next/blocks/blockGitHubPRTemplate.ts b/src/blocks/blockGitHubPRTemplate.ts
similarity index 100%
rename from src/next/blocks/blockGitHubPRTemplate.ts
rename to src/blocks/blockGitHubPRTemplate.ts
diff --git a/src/next/blocks/blockGitignore.test.ts b/src/blocks/blockGitignore.test.ts
similarity index 100%
rename from src/next/blocks/blockGitignore.test.ts
rename to src/blocks/blockGitignore.test.ts
diff --git a/src/next/blocks/blockGitignore.ts b/src/blocks/blockGitignore.ts
similarity index 79%
rename from src/next/blocks/blockGitignore.ts
rename to src/blocks/blockGitignore.ts
index b10e4bf6c..fe607e3ef 100644
--- a/src/next/blocks/blockGitignore.ts
+++ b/src/blocks/blockGitignore.ts
@@ -1,7 +1,7 @@
import { z } from "zod";
-import { formatIgnoreFile } from "../../steps/writing/creation/formatters/formatIgnoreFile.js";
import { base } from "../base.js";
+import { formatIgnoreFile } from "./files/formatIgnoreFile.js";
export const blockGitignore = base.createBlock({
about: {
diff --git a/src/next/blocks/blockKnip.test.ts b/src/blocks/blockKnip.test.ts
similarity index 100%
rename from src/next/blocks/blockKnip.test.ts
rename to src/blocks/blockKnip.test.ts
diff --git a/src/next/blocks/blockKnip.ts b/src/blocks/blockKnip.ts
similarity index 93%
rename from src/next/blocks/blockKnip.ts
rename to src/blocks/blockKnip.ts
index 03efbe269..82585d554 100644
--- a/src/next/blocks/blockKnip.ts
+++ b/src/blocks/blockKnip.ts
@@ -1,10 +1,13 @@
import { z } from "zod";
import { base } from "../base.js";
+import {
+ getPackageDependencies,
+ getPackageDependency,
+} from "../data/packageData.js";
import { blockDevelopmentDocs } from "./blockDevelopmentDocs.js";
import { blockGitHubActionsCI } from "./blockGitHubActionsCI.js";
import { blockPackageJson } from "./blockPackageJson.js";
-import { getPackageDependencies, getPackageDependency } from "./packageData.js";
import { CommandPhase } from "./phases.js";
export const blockKnip = base.createBlock({
@@ -20,6 +23,7 @@ export const blockKnip = base.createBlock({
{
commands: ["rm .knip* knip.*"],
phase: CommandPhase.Migrations,
+ silent: true,
},
],
};
diff --git a/src/next/blocks/blockMITLicense.ts b/src/blocks/blockMITLicense.ts
similarity index 100%
rename from src/next/blocks/blockMITLicense.ts
rename to src/blocks/blockMITLicense.ts
diff --git a/src/next/blocks/blockMarkdownlint.test.ts b/src/blocks/blockMarkdownlint.test.ts
similarity index 100%
rename from src/next/blocks/blockMarkdownlint.test.ts
rename to src/blocks/blockMarkdownlint.test.ts
diff --git a/src/next/blocks/blockMarkdownlint.ts b/src/blocks/blockMarkdownlint.ts
similarity index 92%
rename from src/next/blocks/blockMarkdownlint.ts
rename to src/blocks/blockMarkdownlint.ts
index c3e9a75f7..314cad795 100644
--- a/src/next/blocks/blockMarkdownlint.ts
+++ b/src/blocks/blockMarkdownlint.ts
@@ -1,13 +1,13 @@
import { z } from "zod";
-import { formatIgnoreFile } from "../../steps/writing/creation/formatters/formatIgnoreFile.js";
import { base } from "../base.js";
+import { getPackageDependencies } from "../data/packageData.js";
import { blockCSpell } from "./blockCSpell.js";
import { blockDevelopmentDocs } from "./blockDevelopmentDocs.js";
import { blockGitHubActionsCI } from "./blockGitHubActionsCI.js";
import { blockPackageJson } from "./blockPackageJson.js";
import { blockVSCode } from "./blockVSCode.js";
-import { getPackageDependencies } from "./packageData.js";
+import { formatIgnoreFile } from "./files/formatIgnoreFile.js";
import { CommandPhase } from "./phases.js";
export const blockMarkdownlint = base.createBlock({
diff --git a/src/next/blocks/blockNvmrc.test.ts b/src/blocks/blockNvmrc.test.ts
similarity index 100%
rename from src/next/blocks/blockNvmrc.test.ts
rename to src/blocks/blockNvmrc.test.ts
diff --git a/src/next/blocks/blockNvmrc.ts b/src/blocks/blockNvmrc.ts
similarity index 100%
rename from src/next/blocks/blockNvmrc.ts
rename to src/blocks/blockNvmrc.ts
diff --git a/src/next/blocks/blockPRCompliance.ts b/src/blocks/blockPRCompliance.ts
similarity index 89%
rename from src/next/blocks/blockPRCompliance.ts
rename to src/blocks/blockPRCompliance.ts
index eac9a64cd..a671555ca 100644
--- a/src/next/blocks/blockPRCompliance.ts
+++ b/src/blocks/blockPRCompliance.ts
@@ -1,5 +1,5 @@
-import { createSoloWorkflowFile } from "../../steps/writing/creation/dotGitHub/createSoloWorkflowFile.js";
import { base } from "../base.js";
+import { createSoloWorkflowFile } from "./files/createSoloWorkflowFile.js";
export const blockPRCompliance = base.createBlock({
about: {
diff --git a/src/next/blocks/blockPackageJson.test.ts b/src/blocks/blockPackageJson.test.ts
similarity index 96%
rename from src/next/blocks/blockPackageJson.test.ts
rename to src/blocks/blockPackageJson.test.ts
index 7e9bf3b24..56801d9f2 100644
--- a/src/next/blocks/blockPackageJson.test.ts
+++ b/src/blocks/blockPackageJson.test.ts
@@ -21,7 +21,7 @@ describe("blockPackageJson", () => {
"scripts": [
{
"commands": [
- "pnpm install --offline",
+ "pnpm install",
],
"phase": 1,
},
@@ -44,7 +44,7 @@ describe("blockPackageJson", () => {
"scripts": [
{
"commands": [
- "pnpm install --offline",
+ "pnpm install",
],
"phase": 1,
},
@@ -53,6 +53,7 @@ describe("blockPackageJson", () => {
"rm package-lock.json yarn.lock",
],
"phase": 0,
+ "silent": true,
},
],
}
@@ -81,7 +82,7 @@ describe("blockPackageJson", () => {
"scripts": [
{
"commands": [
- "pnpm install --offline",
+ "pnpm install",
"pnpm dedupe",
],
"phase": 1,
@@ -116,7 +117,7 @@ describe("blockPackageJson", () => {
"scripts": [
{
"commands": [
- "pnpm install --offline",
+ "pnpm install",
"pnpm dedupe",
],
"phase": 1,
diff --git a/src/next/blocks/blockPackageJson.ts b/src/blocks/blockPackageJson.ts
similarity index 97%
rename from src/next/blocks/blockPackageJson.ts
rename to src/blocks/blockPackageJson.ts
index 3629977c7..6ae6bc46b 100644
--- a/src/next/blocks/blockPackageJson.ts
+++ b/src/blocks/blockPackageJson.ts
@@ -32,6 +32,7 @@ export const blockPackageJson = base.createBlock({
{
commands: ["rm package-lock.json yarn.lock"],
phase: CommandPhase.Migrations,
+ silent: true,
},
],
};
@@ -100,7 +101,7 @@ export const blockPackageJson = base.createBlock({
scripts: [
{
commands: [
- offline ? "pnpm install" : "pnpm install --offline",
+ offline ? "pnpm install --offline" : "pnpm install",
...addons.cleanupCommands,
],
phase: CommandPhase.Install,
diff --git a/src/next/blocks/blockPnpmDedupe.ts b/src/blocks/blockPnpmDedupe.ts
similarity index 100%
rename from src/next/blocks/blockPnpmDedupe.ts
rename to src/blocks/blockPnpmDedupe.ts
diff --git a/src/next/blocks/blockPrettier.test.ts b/src/blocks/blockPrettier.test.ts
similarity index 98%
rename from src/next/blocks/blockPrettier.test.ts
rename to src/blocks/blockPrettier.test.ts
index 3bdad764b..ea0fb6474 100644
--- a/src/next/blocks/blockPrettier.test.ts
+++ b/src/blocks/blockPrettier.test.ts
@@ -94,7 +94,7 @@ describe("blockPrettier", () => {
"npx lint-staged
",
{
- "mode": 33279,
+ "executable": true,
},
],
},
@@ -206,7 +206,7 @@ describe("blockPrettier", () => {
"npx lint-staged
",
{
- "mode": 33279,
+ "executable": true,
},
],
},
@@ -228,6 +228,7 @@ describe("blockPrettier", () => {
"rm .prettierrc* prettier.config*",
],
"phase": 0,
+ "silent": true,
},
],
}
@@ -335,7 +336,7 @@ describe("blockPrettier", () => {
"npx lint-staged
",
{
- "mode": 33279,
+ "executable": true,
},
],
},
diff --git a/src/next/blocks/blockPrettier.ts b/src/blocks/blockPrettier.ts
similarity index 92%
rename from src/next/blocks/blockPrettier.ts
rename to src/blocks/blockPrettier.ts
index f08bf42e6..e385cd658 100644
--- a/src/next/blocks/blockPrettier.ts
+++ b/src/blocks/blockPrettier.ts
@@ -1,13 +1,13 @@
import { z } from "zod";
-import { formatIgnoreFile } from "../../steps/writing/creation/formatters/formatIgnoreFile.js";
import { base } from "../base.js";
+import { getPackageDependencies } from "../data/packageData.js";
import { blockCSpell } from "./blockCSpell.js";
import { blockDevelopmentDocs } from "./blockDevelopmentDocs.js";
import { blockGitHubActionsCI } from "./blockGitHubActionsCI.js";
import { blockPackageJson } from "./blockPackageJson.js";
import { blockVSCode } from "./blockVSCode.js";
-import { getPackageDependencies } from "./packageData.js";
+import { formatIgnoreFile } from "./files/formatIgnoreFile.js";
import { CommandPhase } from "./phases.js";
export const blockPrettier = base.createBlock({
@@ -34,6 +34,7 @@ export const blockPrettier = base.createBlock({
{
commands: ["rm .prettierrc* prettier.config*"],
phase: CommandPhase.Migrations,
+ silent: true,
},
],
};
@@ -95,7 +96,7 @@ pnpm format --write
files: {
".husky": {
".gitignore": "_\n",
- "pre-commit": ["npx lint-staged\n", { mode: 33279 }],
+ "pre-commit": ["npx lint-staged\n", { executable: true }],
},
".prettierignore": formatIgnoreFile(
["/.husky", "/lib", "/pnpm-lock.yaml", ...ignores].sort(),
diff --git a/src/next/blocks/blockPrettierPluginCurly.ts b/src/blocks/blockPrettierPluginCurly.ts
similarity index 100%
rename from src/next/blocks/blockPrettierPluginCurly.ts
rename to src/blocks/blockPrettierPluginCurly.ts
diff --git a/src/next/blocks/blockPrettierPluginPackageJson.ts b/src/blocks/blockPrettierPluginPackageJson.ts
similarity index 100%
rename from src/next/blocks/blockPrettierPluginPackageJson.ts
rename to src/blocks/blockPrettierPluginPackageJson.ts
diff --git a/src/next/blocks/blockPrettierPluginSh.ts b/src/blocks/blockPrettierPluginSh.ts
similarity index 100%
rename from src/next/blocks/blockPrettierPluginSh.ts
rename to src/blocks/blockPrettierPluginSh.ts
diff --git a/src/next/blocks/blockREADME.test.ts b/src/blocks/blockREADME.test.ts
similarity index 100%
rename from src/next/blocks/blockREADME.test.ts
rename to src/blocks/blockREADME.test.ts
diff --git a/src/next/blocks/blockREADME.ts b/src/blocks/blockREADME.ts
similarity index 100%
rename from src/next/blocks/blockREADME.ts
rename to src/blocks/blockREADME.ts
diff --git a/src/next/blocks/blockReleaseIt.ts b/src/blocks/blockReleaseIt.ts
similarity index 95%
rename from src/next/blocks/blockReleaseIt.ts
rename to src/blocks/blockReleaseIt.ts
index 5f79022c3..66ccd3e48 100644
--- a/src/next/blocks/blockReleaseIt.ts
+++ b/src/blocks/blockReleaseIt.ts
@@ -1,9 +1,9 @@
-import { createSoloWorkflowFile } from "../../steps/writing/creation/dotGitHub/createSoloWorkflowFile.js";
import { base } from "../base.js";
+import { getPackageDependencies } from "../data/packageData.js";
import { blockCSpell } from "./blockCSpell.js";
import { blockPackageJson } from "./blockPackageJson.js";
import { blockRepositorySecrets } from "./blockRepositorySecrets.js";
-import { getPackageDependencies } from "./packageData.js";
+import { createSoloWorkflowFile } from "./files/createSoloWorkflowFile.js";
export const blockReleaseIt = base.createBlock({
about: {
diff --git a/src/next/blocks/blockRenovate.ts b/src/blocks/blockRenovate.ts
similarity index 100%
rename from src/next/blocks/blockRenovate.ts
rename to src/blocks/blockRenovate.ts
diff --git a/src/next/blocks/blockRepositoryBranchRuleset.test.ts b/src/blocks/blockRepositoryBranchRuleset.test.ts
similarity index 100%
rename from src/next/blocks/blockRepositoryBranchRuleset.test.ts
rename to src/blocks/blockRepositoryBranchRuleset.test.ts
diff --git a/src/next/blocks/blockRepositoryBranchRuleset.ts b/src/blocks/blockRepositoryBranchRuleset.ts
similarity index 94%
rename from src/next/blocks/blockRepositoryBranchRuleset.ts
rename to src/blocks/blockRepositoryBranchRuleset.ts
index 0c26e380b..652b73931 100644
--- a/src/next/blocks/blockRepositoryBranchRuleset.ts
+++ b/src/blocks/blockRepositoryBranchRuleset.ts
@@ -39,7 +39,6 @@ export const blockRepositoryBranchRuleset = base.createBlock({
{ type: "deletion" },
{
parameters: {
- // @ts-expect-error -- https://github.com/github/rest-api-description/issues/4405
allowed_merge_methods: ["squash"],
dismiss_stale_reviews_on_push: false,
require_code_owner_review: false,
diff --git a/src/next/blocks/blockRepositoryLabels.ts b/src/blocks/blockRepositoryLabels.ts
similarity index 84%
rename from src/next/blocks/blockRepositoryLabels.ts
rename to src/blocks/blockRepositoryLabels.ts
index b8980788b..4b00f32dc 100644
--- a/src/next/blocks/blockRepositoryLabels.ts
+++ b/src/blocks/blockRepositoryLabels.ts
@@ -1,7 +1,7 @@
import { setGitHubRepositoryLabels } from "set-github-repository-labels";
-import { outcomeLabels } from "../../steps/initializeGitHubRepository/outcomeLabels.js";
import { base } from "../base.js";
+import { outcomeLabels } from "./outcomeLabels.js";
export const blockRepositoryLabels = base.createBlock({
about: {
diff --git a/src/next/blocks/blockRepositorySecrets.ts b/src/blocks/blockRepositorySecrets.ts
similarity index 100%
rename from src/next/blocks/blockRepositorySecrets.ts
rename to src/blocks/blockRepositorySecrets.ts
diff --git a/src/next/blocks/blockRepositorySettings.ts b/src/blocks/blockRepositorySettings.ts
similarity index 100%
rename from src/next/blocks/blockRepositorySettings.ts
rename to src/blocks/blockRepositorySettings.ts
diff --git a/src/next/blocks/blockSecurityDocs.ts b/src/blocks/blockSecurityDocs.ts
similarity index 100%
rename from src/next/blocks/blockSecurityDocs.ts
rename to src/blocks/blockSecurityDocs.ts
diff --git a/src/next/blocks/blockTSup.test.ts b/src/blocks/blockTSup.test.ts
similarity index 99%
rename from src/next/blocks/blockTSup.test.ts
rename to src/blocks/blockTSup.test.ts
index 1cfbe508b..fd7a10225 100644
--- a/src/next/blocks/blockTSup.test.ts
+++ b/src/blocks/blockTSup.test.ts
@@ -181,6 +181,7 @@ describe("blockTSup", () => {
"rm -rf .babelrc* babel.config.* dist lib",
],
"phase": 0,
+ "silent": true,
},
],
}
diff --git a/src/next/blocks/blockTSup.ts b/src/blocks/blockTSup.ts
similarity index 96%
rename from src/next/blocks/blockTSup.ts
rename to src/blocks/blockTSup.ts
index 7d6d8a381..171bc2e29 100644
--- a/src/next/blocks/blockTSup.ts
+++ b/src/blocks/blockTSup.ts
@@ -1,11 +1,11 @@
import { z } from "zod";
import { base } from "../base.js";
+import { getPackageDependencies } from "../data/packageData.js";
import { blockDevelopmentDocs } from "./blockDevelopmentDocs.js";
import { blockESLint } from "./blockESLint.js";
import { blockGitHubActionsCI } from "./blockGitHubActionsCI.js";
import { blockPackageJson } from "./blockPackageJson.js";
-import { getPackageDependencies } from "./packageData.js";
import { CommandPhase } from "./phases.js";
export const blockTSup = base.createBlock({
@@ -22,6 +22,7 @@ export const blockTSup = base.createBlock({
{
commands: ["rm -rf .babelrc* babel.config.* dist lib"],
phase: CommandPhase.Migrations,
+ silent: true,
},
],
};
diff --git a/src/next/blocks/blockTemplatedBy.ts b/src/blocks/blockTemplatedWith.ts
similarity index 91%
rename from src/next/blocks/blockTemplatedBy.ts
rename to src/blocks/blockTemplatedWith.ts
index ab85c72cb..9d9d2c38f 100644
--- a/src/next/blocks/blockTemplatedBy.ts
+++ b/src/blocks/blockTemplatedWith.ts
@@ -2,7 +2,7 @@ import { base } from "../base.js";
import { blockCSpell } from "./blockCSpell.js";
import { blockREADME } from "./blockREADME.js";
-export const blockTemplatedBy = base.createBlock({
+export const blockTemplatedWith = base.createBlock({
about: {
name: "Templated By Notice",
},
diff --git a/src/next/blocks/blockTypeScript.test.ts b/src/blocks/blockTypeScript.test.ts
similarity index 100%
rename from src/next/blocks/blockTypeScript.test.ts
rename to src/blocks/blockTypeScript.test.ts
diff --git a/src/next/blocks/blockTypeScript.ts b/src/blocks/blockTypeScript.ts
similarity index 98%
rename from src/next/blocks/blockTypeScript.ts
rename to src/blocks/blockTypeScript.ts
index f89304170..ee6bffe02 100644
--- a/src/next/blocks/blockTypeScript.ts
+++ b/src/blocks/blockTypeScript.ts
@@ -1,4 +1,5 @@
import { base } from "../base.js";
+import { getPackageDependencies } from "../data/packageData.js";
import { blockDevelopmentDocs } from "./blockDevelopmentDocs.js";
import { blockExampleFiles } from "./blockExampleFiles.js";
import { blockGitHubActionsCI } from "./blockGitHubActionsCI.js";
@@ -7,7 +8,6 @@ import { blockMarkdownlint } from "./blockMarkdownlint.js";
import { blockPackageJson } from "./blockPackageJson.js";
import { blockVitest } from "./blockVitest.js";
import { blockVSCode } from "./blockVSCode.js";
-import { getPackageDependencies } from "./packageData.js";
export const blockTypeScript = base.createBlock({
about: {
diff --git a/src/next/blocks/blockVSCode.test.ts b/src/blocks/blockVSCode.test.ts
similarity index 100%
rename from src/next/blocks/blockVSCode.test.ts
rename to src/blocks/blockVSCode.test.ts
diff --git a/src/next/blocks/blockVSCode.ts b/src/blocks/blockVSCode.ts
similarity index 100%
rename from src/next/blocks/blockVSCode.ts
rename to src/blocks/blockVSCode.ts
diff --git a/src/next/blocks/blockVitest.test.ts b/src/blocks/blockVitest.test.ts
similarity index 97%
rename from src/next/blocks/blockVitest.test.ts
rename to src/blocks/blockVitest.test.ts
index 3ae3e90fc..fdd06f467 100644
--- a/src/next/blocks/blockVitest.test.ts
+++ b/src/blocks/blockVitest.test.ts
@@ -1,9 +1,13 @@
import { testBlock } from "create-testers";
-import { describe, expect, test } from "vitest";
+import { describe, expect, test, vi } from "vitest";
import { blockVitest } from "./blockVitest.js";
import { optionsBase } from "./options.fakes.js";
+vi.mock("../utils/resolveBin.js", () => ({
+ resolveBin: (bin: string) => `path/to/${bin}`,
+}));
+
describe("blockVitest", () => {
test("without addons or mode", () => {
const creation = testBlock(blockVitest, {
@@ -467,11 +471,19 @@ describe("blockVitest", () => {
",
},
"scripts": [
+ {
+ "commands": [
+ "node path/to/remove-dependencies/bin/index.mjs eslint-plugin-jest eslint-plugin-mocha eslint-plugin-vitest jest mocha",
+ ],
+ "phase": 3,
+ "silent": true,
+ },
{
"commands": [
"rm .mocha* jest.config.* vitest.config.*",
],
"phase": 0,
+ "silent": true,
},
],
}
@@ -482,7 +494,6 @@ describe("blockVitest", () => {
const creation = testBlock(blockVitest, {
addons: {
coverage: {
- directory: "coverage*",
exclude: ["other"],
include: ["src/"],
},
@@ -497,7 +508,7 @@ describe("blockVitest", () => {
{
"addons": {
"ignores": [
- "coverage*",
+ "coverage",
],
},
"block": [Function],
@@ -550,7 +561,7 @@ describe("blockVitest", () => {
},
],
"ignores": [
- "coverage*",
+ "coverage",
"**/*.snap",
],
"imports": [
@@ -617,7 +628,7 @@ describe("blockVitest", () => {
{
"addons": {
"ignores": [
- "/coverage*",
+ "/coverage",
],
},
"block": [Function],
@@ -656,7 +667,7 @@ describe("blockVitest", () => {
{
"addons": {
"ignores": [
- "/coverage*",
+ "/coverage",
],
},
"block": [Function],
diff --git a/src/next/blocks/blockVitest.ts b/src/blocks/blockVitest.ts
similarity index 90%
rename from src/next/blocks/blockVitest.ts
rename to src/blocks/blockVitest.ts
index bdf8f6b9b..2ef2097df 100644
--- a/src/next/blocks/blockVitest.ts
+++ b/src/blocks/blockVitest.ts
@@ -1,6 +1,8 @@
import { z } from "zod";
import { base } from "../base.js";
+import { getPackageDependencies } from "../data/packageData.js";
+import { resolveBin } from "../utils/resolveBin.js";
import { blockCSpell } from "./blockCSpell.js";
import { blockDevelopmentDocs } from "./blockDevelopmentDocs.js";
import { blockESLint } from "./blockESLint.js";
@@ -11,7 +13,6 @@ import { blockPackageJson } from "./blockPackageJson.js";
import { blockPrettier } from "./blockPrettier.js";
import { blockTSup } from "./blockTSup.js";
import { blockVSCode } from "./blockVSCode.js";
-import { getPackageDependencies } from "./packageData.js";
import { CommandPhase } from "./phases.js";
export const blockVitest = base.createBlock({
@@ -22,7 +23,7 @@ export const blockVitest = base.createBlock({
actionSteps: z.array(zActionStep).default([]),
coverage: z
.object({
- directory: z.string().optional(),
+ env: z.record(z.string(), z.string()).optional(),
exclude: z.array(z.string()).optional(),
include: z.array(z.string()).optional(),
})
@@ -32,22 +33,29 @@ export const blockVitest = base.createBlock({
migrate() {
return {
scripts: [
+ {
+ commands: [
+ `node ${resolveBin("remove-dependencies/bin/index.js")} eslint-plugin-jest eslint-plugin-mocha eslint-plugin-vitest jest mocha`,
+ ],
+ phase: CommandPhase.Process,
+ silent: true,
+ },
{
commands: ["rm .mocha* jest.config.* vitest.config.*"],
phase: CommandPhase.Migrations,
+ silent: true,
},
],
};
},
produce({ addons }) {
const { actionSteps, coverage, exclude = [] } = addons;
- const coverageDirectory = coverage.directory ?? "coverage";
const excludeText = JSON.stringify(exclude);
return {
addons: [
blockCSpell({
- ignores: [coverageDirectory],
+ ignores: ["coverage"],
}),
blockDevelopmentDocs({
sections: {
@@ -88,7 +96,7 @@ Calls to \`console.log\`, \`console.warn\`, and other console methods will cause
],
},
],
- ignores: [coverageDirectory, "**/*.snap"],
+ ignores: ["coverage", "**/*.snap"],
imports: [{ source: "@vitest/eslint-plugin", specifier: "vitest" }],
}),
blockExampleFiles({
@@ -141,7 +149,7 @@ describe("greet", () => {
},
}),
blockGitignore({
- ignores: [`/${coverageDirectory}`],
+ ignores: ["/coverage"],
}),
blockGitHubActionsCI({
jobs: [
@@ -165,7 +173,7 @@ describe("greet", () => {
},
}),
blockPrettier({
- ignores: [`/${coverageDirectory}`],
+ ignores: ["/coverage"],
}),
blockTSup({
entry: ["!src/**/*.test.*"],
diff --git a/src/steps/writing/creation/dotGitHub/createJobName.ts b/src/blocks/files/createJobName.ts
similarity index 100%
rename from src/steps/writing/creation/dotGitHub/createJobName.ts
rename to src/blocks/files/createJobName.ts
diff --git a/src/steps/writing/creation/dotGitHub/createMultiWorkflowFile.ts b/src/blocks/files/createMultiWorkflowFile.ts
similarity index 100%
rename from src/steps/writing/creation/dotGitHub/createMultiWorkflowFile.ts
rename to src/blocks/files/createMultiWorkflowFile.ts
diff --git a/src/steps/writing/creation/dotGitHub/createSoloWorkflowFile.ts b/src/blocks/files/createSoloWorkflowFile.ts
similarity index 100%
rename from src/steps/writing/creation/dotGitHub/createSoloWorkflowFile.ts
rename to src/blocks/files/createSoloWorkflowFile.ts
diff --git a/src/steps/writing/creation/formatters/formatIgnoreFile.ts b/src/blocks/files/formatIgnoreFile.ts
similarity index 100%
rename from src/steps/writing/creation/formatters/formatIgnoreFile.ts
rename to src/blocks/files/formatIgnoreFile.ts
diff --git a/src/steps/writing/creation/dotGitHub/formatWorkflowYaml.ts b/src/blocks/files/formatWorkflowYaml.ts
similarity index 82%
rename from src/steps/writing/creation/dotGitHub/formatWorkflowYaml.ts
rename to src/blocks/files/formatWorkflowYaml.ts
index b2dbfefe6..c7e088372 100644
--- a/src/steps/writing/creation/dotGitHub/formatWorkflowYaml.ts
+++ b/src/blocks/files/formatWorkflowYaml.ts
@@ -1,4 +1,4 @@
-import { formatYaml } from "../formatters/formatYaml.js";
+import { formatYaml } from "./formatYaml.js";
export function formatWorkflowYaml(value: unknown) {
return (
diff --git a/src/steps/writing/creation/formatters/formatYaml.ts b/src/blocks/files/formatYaml.ts
similarity index 78%
rename from src/steps/writing/creation/formatters/formatYaml.ts
rename to src/blocks/files/formatYaml.ts
index ef7245d44..8ad1ff528 100644
--- a/src/steps/writing/creation/formatters/formatYaml.ts
+++ b/src/blocks/files/formatYaml.ts
@@ -1,4 +1,3 @@
-import prettier from "@prettier/sync";
import jsYaml from "js-yaml";
const options: jsYaml.DumpOptions = {
@@ -22,6 +21,5 @@ const options: jsYaml.DumpOptions = {
};
export function formatYaml(value: unknown) {
- const dumped = jsYaml.dump(value, options);
- return prettier.format(dumped, { parser: "yaml" });
+ return jsYaml.dump(value, options);
}
diff --git a/src/blocks/index.ts b/src/blocks/index.ts
new file mode 100644
index 000000000..300b4cf0a
--- /dev/null
+++ b/src/blocks/index.ts
@@ -0,0 +1,133 @@
+import { blockAllContributors } from "./blockAllContributors.js";
+import { blockAreTheTypesWrong } from "./blockAreTheTypesWrong.js";
+import { blockCodecov } from "./blockCodecov.js";
+import { blockContributingDocs } from "./blockContributingDocs.js";
+import { blockContributorCovenant } from "./blockContributorCovenant.js";
+import { blockCSpell } from "./blockCSpell.js";
+import { blockDevelopmentDocs } from "./blockDevelopmentDocs.js";
+import { blockESLint } from "./blockESLint.js";
+import { blockESLintComments } from "./blockESLintComments.js";
+import { blockESLintJSDoc } from "./blockESLintJSDoc.js";
+import { blockESLintJSONC } from "./blockESLintJSONC.js";
+import { blockESLintMarkdown } from "./blockESLintMarkdown.js";
+import { blockESLintMoreStyling } from "./blockESLintMoreStyling.js";
+import { blockESLintNode } from "./blockESLintNode.js";
+import { blockESLintPackageJson } from "./blockESLintPackageJson.js";
+import { blockESLintPerfectionist } from "./blockESLintPerfectionist.js";
+import { blockESLintRegexp } from "./blockESLintRegexp.js";
+import { blockESLintYML } from "./blockESLintYML.js";
+import { blockFunding } from "./blockFunding.js";
+import { blockGitHubActionsCI } from "./blockGitHubActionsCI.js";
+import { blockGitHubIssueTemplates } from "./blockGitHubIssueTemplates.js";
+import { blockGitHubPRTemplate } from "./blockGitHubPRTemplate.js";
+import { blockGitignore } from "./blockGitignore.js";
+import { blockKnip } from "./blockKnip.js";
+import { blockMarkdownlint } from "./blockMarkdownlint.js";
+import { blockMITLicense } from "./blockMITLicense.js";
+import { blockNvmrc } from "./blockNvmrc.js";
+import { blockPackageJson } from "./blockPackageJson.js";
+import { blockPnpmDedupe } from "./blockPnpmDedupe.js";
+import { blockPRCompliance } from "./blockPRCompliance.js";
+import { blockPrettier } from "./blockPrettier.js";
+import { blockPrettierPluginCurly } from "./blockPrettierPluginCurly.js";
+import { blockPrettierPluginPackageJson } from "./blockPrettierPluginPackageJson.js";
+import { blockPrettierPluginSh } from "./blockPrettierPluginSh.js";
+import { blockREADME } from "./blockREADME.js";
+import { blockReleaseIt } from "./blockReleaseIt.js";
+import { blockRenovate } from "./blockRenovate.js";
+import { blockSecurityDocs } from "./blockSecurityDocs.js";
+import { blockTemplatedWith } from "./blockTemplatedWith.js";
+import { blockTSup } from "./blockTSup.js";
+import { blockTypeScript } from "./blockTypeScript.js";
+import { blockVitest } from "./blockVitest.js";
+import { blockVSCode } from "./blockVSCode.js";
+
+export const blocks = {
+ blockAllContributors,
+ blockAreTheTypesWrong,
+ blockCodecov,
+ blockContributingDocs,
+ blockContributorCovenant,
+ blockCSpell,
+ blockDevelopmentDocs,
+ blockESLint,
+ blockESLintComments,
+ blockESLintJSDoc,
+ blockESLintJSONC,
+ blockESLintMarkdown,
+ blockESLintMoreStyling,
+ blockESLintNode,
+ blockESLintPackageJson,
+ blockESLintPerfectionist,
+ blockESLintRegexp,
+ blockESLintYML,
+ blockFunding,
+ blockGitHubActionsCI,
+ blockGitHubIssueTemplates,
+ blockGitHubPRTemplate,
+ blockGitignore,
+ blockKnip,
+ blockMarkdownlint,
+ blockMITLicense,
+ blockNvmrc,
+ blockPackageJson,
+ blockPnpmDedupe,
+ blockPRCompliance,
+ blockPrettier,
+ blockPrettierPluginCurly,
+ blockPrettierPluginPackageJson,
+ blockPrettierPluginSh,
+ blockREADME,
+ blockReleaseIt,
+ blockRenovate,
+ blockSecurityDocs,
+ blockTemplatedWith,
+ blockTSup,
+ blockTypeScript,
+ blockVitest,
+ blockVSCode,
+};
+
+export { blockAllContributors } from "./blockAllContributors.js";
+export { blockAreTheTypesWrong } from "./blockAreTheTypesWrong.js";
+export { blockCodecov } from "./blockCodecov.js";
+export { blockContributingDocs } from "./blockContributingDocs.js";
+export { blockContributorCovenant } from "./blockContributorCovenant.js";
+export { blockCSpell } from "./blockCSpell.js";
+export { blockDevelopmentDocs } from "./blockDevelopmentDocs.js";
+export { blockESLint } from "./blockESLint.js";
+export { blockESLintComments } from "./blockESLintComments.js";
+export { blockESLintJSDoc } from "./blockESLintJSDoc.js";
+export { blockESLintJSONC } from "./blockESLintJSONC.js";
+export { blockESLintMarkdown } from "./blockESLintMarkdown.js";
+export { blockESLintMoreStyling } from "./blockESLintMoreStyling.js";
+export { blockESLintNode } from "./blockESLintNode.js";
+export { blockESLintPackageJson } from "./blockESLintPackageJson.js";
+export { blockESLintPerfectionist } from "./blockESLintPerfectionist.js";
+export { blockESLintRegexp } from "./blockESLintRegexp.js";
+export { blockESLintYML } from "./blockESLintYML.js";
+export { blockFunding } from "./blockFunding.js";
+export { blockGitHubActionsCI } from "./blockGitHubActionsCI.js";
+export { blockGitHubIssueTemplates } from "./blockGitHubIssueTemplates.js";
+export { blockGitHubPRTemplate } from "./blockGitHubPRTemplate.js";
+export { blockGitignore } from "./blockGitignore.js";
+export { blockKnip } from "./blockKnip.js";
+export { blockMarkdownlint } from "./blockMarkdownlint.js";
+export { blockMITLicense } from "./blockMITLicense.js";
+export { blockNvmrc } from "./blockNvmrc.js";
+export { blockPackageJson } from "./blockPackageJson.js";
+export { blockPnpmDedupe } from "./blockPnpmDedupe.js";
+export { blockPRCompliance } from "./blockPRCompliance.js";
+export { blockPrettier } from "./blockPrettier.js";
+export { blockPrettierPluginCurly } from "./blockPrettierPluginCurly.js";
+export { blockPrettierPluginPackageJson } from "./blockPrettierPluginPackageJson.js";
+export { blockPrettierPluginSh } from "./blockPrettierPluginSh.js";
+export { blockREADME } from "./blockREADME.js";
+export { blockReleaseIt } from "./blockReleaseIt.js";
+export { blockRenovate } from "./blockRenovate.js";
+export { blockSecurityDocs } from "./blockSecurityDocs.js";
+export { blockTemplatedWith } from "./blockTemplatedWith.js";
+export { blockTSup } from "./blockTSup.js";
+export { blockTypeScript } from "./blockTypeScript.js";
+export { blockVitest } from "./blockVitest.js";
+export { blockVSCode } from "./blockVSCode.js";
diff --git a/src/next/blocks/options.fakes.ts b/src/blocks/options.fakes.ts
similarity index 100%
rename from src/next/blocks/options.fakes.ts
rename to src/blocks/options.fakes.ts
diff --git a/src/steps/initializeGitHubRepository/outcomeLabels.ts b/src/blocks/outcomeLabels.ts
similarity index 98%
rename from src/steps/initializeGitHubRepository/outcomeLabels.ts
rename to src/blocks/outcomeLabels.ts
index 092bfd5bc..e589e97eb 100644
--- a/src/steps/initializeGitHubRepository/outcomeLabels.ts
+++ b/src/blocks/outcomeLabels.ts
@@ -1,4 +1,3 @@
-/* spellchecker: disable */
export const outcomeLabels = [
{
aliases: ["docs"],
@@ -75,6 +74,7 @@ export const outcomeLabels = [
},
{
aliases: ["enhancement"],
+ /* spellchecker: disable-next-line */
color: "a2eeef",
description: "New enhancement or request 🚀",
name: "type: feature",
diff --git a/src/next/blocks/phases.ts b/src/blocks/phases.ts
similarity index 100%
rename from src/next/blocks/phases.ts
rename to src/blocks/phases.ts
diff --git a/src/create/createAndEnterGitDirectory.test.ts b/src/create/createAndEnterGitDirectory.test.ts
deleted file mode 100644
index 85ceb3a02..000000000
--- a/src/create/createAndEnterGitDirectory.test.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-import { describe, expect, it, vi } from "vitest";
-
-import { createAndEnterGitDirectory } from "./createAndEnterGitDirectory.js";
-
-const mockMkdir = vi.fn();
-const mockReaddir = vi.fn();
-
-vi.mock("node:fs/promises", () => ({
- get mkdir() {
- return mockMkdir;
- },
- get readdir() {
- return mockReaddir;
- },
-}));
-
-const mockChdir = vi.fn();
-const mockCwd = "/path/to/cwd";
-
-vi.mock("node:process", () => ({
- get chdir() {
- return mockChdir;
- },
- cwd() {
- return mockCwd;
- },
-}));
-
-const mock$$ = vi.fn();
-
-const mock$ = vi.fn().mockReturnValue(mock$$);
-
-vi.mock("execa", () => ({
- get $() {
- return mock$;
- },
-}));
-
-describe("createAndEnterGitDirectory", () => {
- it("returns false and doesn't run fs.mkdir when the directory is '.' and has children", async () => {
- mockReaddir.mockResolvedValueOnce(["file"]);
-
- const actual = await createAndEnterGitDirectory(".");
-
- expect(actual).toBeUndefined();
- expect(mockMkdir).not.toHaveBeenCalled();
- });
-
- it("returns true and doesn't run fs.mkdir when the directory is '.' and is empty", async () => {
- mockReaddir.mockResolvedValueOnce([]);
-
- const actual = await createAndEnterGitDirectory(".");
-
- expect(actual).toBe(mockCwd);
- expect(mockMkdir).not.toHaveBeenCalled();
- });
-
- it("returns false and doesn't run process.chdir when the directory is a child directory with children", async () => {
- const directory = "dir";
- mockReaddir
- .mockResolvedValueOnce([directory])
- .mockResolvedValueOnce(["file"]);
-
- const actual = await createAndEnterGitDirectory(directory);
-
- expect(actual).toBeUndefined();
- expect(mockChdir).not.toHaveBeenCalled();
- expect(mock$).not.toHaveBeenCalled();
- });
-
- it("returns true and runs process.chdir when the directory is a child directory that doesn't exist", async () => {
- const directory = "dir";
- mockReaddir.mockResolvedValueOnce([directory]).mockResolvedValueOnce([]);
-
- const actual = await createAndEnterGitDirectory(directory);
-
- expect(actual).toBe(mockCwd);
- expect(mockChdir).toHaveBeenCalledWith(directory);
- expect(mock$).toHaveBeenCalledWith({ cwd: mockCwd });
- expect(mock$$).toHaveBeenCalledWith(["git init -b main"]);
- });
-});
diff --git a/src/create/createAndEnterGitDirectory.ts b/src/create/createAndEnterGitDirectory.ts
deleted file mode 100644
index c249d823d..000000000
--- a/src/create/createAndEnterGitDirectory.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { $ } from "execa";
-import * as fs from "node:fs/promises";
-import * as process from "node:process";
-
-export async function createAndEnterGitDirectory(directory: string) {
- if (directory !== "." && !(await fs.readdir(".")).includes(directory)) {
- await fs.mkdir(directory);
- } else if ((await fs.readdir(directory)).length) {
- return undefined;
- }
-
- if (directory !== ".") {
- process.chdir(directory);
- }
-
- // https://github.com/JoshuaKGoldberg/create-typescript-app/pull/1781
- // For some reason, after this function returns, the cwd was resetting back?
- // Also $ commands seem to preserve the cwd from the start of the script?!
- // Maybe some parallelized running of scripts was messing with it?
- // All this code will be gone soon once the create engine takes over anyway.
- const cwd = process.cwd();
-
- await $({ cwd })`git init -b main`;
-
- return cwd;
-}
diff --git a/src/create/createRerunDirectorySuggestion.test.ts b/src/create/createRerunDirectorySuggestion.test.ts
deleted file mode 100644
index 9b4798348..000000000
--- a/src/create/createRerunDirectorySuggestion.test.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { describe, expect, it } from "vitest";
-
-import { createRerunDirectorySuggestion } from "./createRerunDirectorySuggestion.js";
-
-const directory = "test-directory";
-const repository = "test-repository";
-
-describe("createRerunDirectorySuggestion", () => {
- it("returns undefined when mode is create and directory matches repository", () => {
- const suggestion = createRerunDirectorySuggestion({
- directory: repository,
- mode: "create",
- repository,
- });
-
- expect(suggestion).toBe(undefined);
- });
-
- it("returns directory when mode is create and directory doesn't match repository", () => {
- const suggestion = createRerunDirectorySuggestion({
- directory,
- mode: "create",
- repository,
- });
-
- expect(suggestion).toBe(directory);
- });
-
- it("returns undefined when mode is initialize and directory is .", () => {
- const suggestion = createRerunDirectorySuggestion({
- directory: ".",
- mode: "initialize",
- repository,
- });
-
- expect(suggestion).toBe(undefined);
- });
-
- it("returns directory when mode is initialize and directory is not .", () => {
- const suggestion = createRerunDirectorySuggestion({
- directory,
- mode: "initialize",
- repository,
- });
-
- expect(suggestion).toBe(directory);
- });
-});
diff --git a/src/create/createRerunDirectorySuggestion.ts b/src/create/createRerunDirectorySuggestion.ts
deleted file mode 100644
index 307299423..000000000
--- a/src/create/createRerunDirectorySuggestion.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { Options } from "../shared/types.js";
-
-export function createRerunDirectorySuggestion(options: Partial) {
- const defaultValue = options.mode === "create" ? options.repository : ".";
-
- return options.directory === defaultValue ? undefined : options.directory;
-}
diff --git a/src/create/createRerunSuggestion.test.ts b/src/create/createRerunSuggestion.test.ts
deleted file mode 100644
index 856d55c9c..000000000
--- a/src/create/createRerunSuggestion.test.ts
+++ /dev/null
@@ -1,185 +0,0 @@
-import { describe, expect, it } from "vitest";
-
-import { getExclusions } from "../shared/options/exclusionKeys.js";
-import { Options } from "../shared/types.js";
-import { createRerunSuggestion } from "./createRerunSuggestion.js";
-
-const options = {
- access: "public",
- author: "TestAuthor",
- base: "everything",
- description: "Test description.",
- directory: ".",
- email: {
- github: "github@email.com",
- npm: "npm@email.com",
- },
- excludeAllContributors: true,
- excludeCompliance: true,
- excludeLintJSDoc: true,
- excludeLintJson: true,
- excludeLintKnip: true,
- excludeLintMd: false,
- excludeLintPackageJson: true,
- excludeLintPackages: false,
- excludeLintPerfectionist: true,
- excludeLintSpelling: false,
- excludeLintYml: false,
- excludeReleases: false,
- excludeRenovate: undefined,
- excludeTemplatedBy: undefined,
- excludeTests: undefined,
- funding: undefined,
- keywords: ["abc", "def ghi", "jkl mno pqr"],
- mode: "create",
- owner: "TestOwner",
- repository: "test-repository",
- skipGitHubApi: true,
- skipInstall: true,
- skipRemoval: true,
- skipRestore: undefined,
- skipUninstall: undefined,
- title: "Test Title",
-} satisfies Options;
-
-describe("createRerunSuggestion", () => {
- it("prints no options when no options are provided", () => {
- const actual = createRerunSuggestion({});
-
- expect(actual).toMatchInlineSnapshot(`"npx create-typescript-app"`);
- });
-
- it("prints only mode when no other options are provided", () => {
- const actual = createRerunSuggestion({
- mode: "create",
- });
-
- expect(actual).toMatchInlineSnapshot(
- `"npx create-typescript-app --mode create"`,
- );
- });
-
- it("includes key-value pairs with mixed truthy and falsy values", () => {
- const actual = createRerunSuggestion(options);
-
- expect(actual).toMatchInlineSnapshot(
- `"npx create-typescript-app --base everything --author TestAuthor --description "Test description." --directory . --email-github github@email.com --email-npm npm@email.com --exclude-all-contributors --exclude-compliance --exclude-lint-jsdoc --exclude-lint-json --exclude-lint-knip --exclude-lint-package-json --exclude-lint-perfectionist --keywords "abc def ghi jkl mno pqr" --mode create --owner TestOwner --repository test-repository --skip-github-api --skip-install --skip-removal --title "Test Title""`,
- );
- });
-
- it("includes a non-default value when specified", () => {
- const actual = createRerunSuggestion({
- ...options,
- access: "restricted",
- });
-
- expect(actual).toMatchInlineSnapshot(
- `"npx create-typescript-app --base everything --access restricted --author TestAuthor --description "Test description." --directory . --email-github github@email.com --email-npm npm@email.com --exclude-all-contributors --exclude-compliance --exclude-lint-jsdoc --exclude-lint-json --exclude-lint-knip --exclude-lint-package-json --exclude-lint-perfectionist --keywords "abc def ghi jkl mno pqr" --mode create --owner TestOwner --repository test-repository --skip-github-api --skip-install --skip-removal --title "Test Title""`,
- );
- });
-
- it("includes stringified guide when it exists", () => {
- const actual = createRerunSuggestion({
- ...options,
- guide: {
- href: "https://example.com",
- title: "Test Title",
- },
- mode: "initialize",
- });
-
- expect(actual).toMatchInlineSnapshot(
- `"npx create-typescript-app --base everything --author TestAuthor --description "Test description." --email-github github@email.com --email-npm npm@email.com --exclude-all-contributors --exclude-compliance --exclude-lint-jsdoc --exclude-lint-json --exclude-lint-knip --exclude-lint-package-json --exclude-lint-perfectionist --guide https://example.com --guide-title "Test Title" --keywords "abc def ghi jkl mno pqr" --mode initialize --owner TestOwner --repository test-repository --skip-github-api --skip-install --skip-removal --title "Test Title""`,
- );
- });
-
- it("includes stringified logo when it exists", () => {
- const actual = createRerunSuggestion({
- ...options,
- logo: {
- alt: "Test alt.",
- src: "test/src.png",
- },
- mode: "initialize",
- });
-
- expect(actual).toMatchInlineSnapshot(
- `"npx create-typescript-app --base everything --author TestAuthor --description "Test description." --email-github github@email.com --email-npm npm@email.com --exclude-all-contributors --exclude-compliance --exclude-lint-jsdoc --exclude-lint-json --exclude-lint-knip --exclude-lint-package-json --exclude-lint-perfectionist --keywords "abc def ghi jkl mno pqr" --logo test/src.png --logo-alt "Test alt." --mode initialize --owner TestOwner --repository test-repository --skip-github-api --skip-install --skip-removal --title "Test Title""`,
- );
- });
-
- it("does not include directory when it is repository and the mode is create", () => {
- const actual = createRerunSuggestion({
- ...options,
- directory: options.repository,
- mode: "create",
- });
-
- expect(actual).toMatchInlineSnapshot(
- `"npx create-typescript-app --base everything --author TestAuthor --description "Test description." --email-github github@email.com --email-npm npm@email.com --exclude-all-contributors --exclude-compliance --exclude-lint-jsdoc --exclude-lint-json --exclude-lint-knip --exclude-lint-package-json --exclude-lint-perfectionist --keywords "abc def ghi jkl mno pqr" --mode create --owner TestOwner --repository test-repository --skip-github-api --skip-install --skip-removal --title "Test Title""`,
- );
- });
-
- it("includes directory when it is repository and the mode is migrate", () => {
- const actual = createRerunSuggestion({
- ...options,
- directory: options.repository,
- mode: "migrate",
- });
-
- expect(actual).toMatchInlineSnapshot(
- `"npx create-typescript-app --base everything --author TestAuthor --description "Test description." --directory test-repository --email-github github@email.com --email-npm npm@email.com --exclude-all-contributors --exclude-compliance --exclude-lint-jsdoc --exclude-lint-json --exclude-lint-knip --exclude-lint-package-json --exclude-lint-perfectionist --keywords "abc def ghi jkl mno pqr" --mode migrate --owner TestOwner --repository test-repository --skip-github-api --skip-install --skip-removal --title "Test Title""`,
- );
- });
-
- it("includes exclusions when they exist", () => {
- const actual = createRerunSuggestion({
- ...options,
- excludeCompliance: true,
- excludeLintMd: true,
- excludeLintSpelling: true,
- mode: "initialize",
- });
-
- expect(actual).toMatchInlineSnapshot(
- `"npx create-typescript-app --base everything --author TestAuthor --description "Test description." --email-github github@email.com --email-npm npm@email.com --exclude-all-contributors --exclude-compliance --exclude-lint-jsdoc --exclude-lint-json --exclude-lint-knip --exclude-lint-md --exclude-lint-package-json --exclude-lint-perfectionist --exclude-lint-spelling --keywords "abc def ghi jkl mno pqr" --mode initialize --owner TestOwner --repository test-repository --skip-github-api --skip-install --skip-removal --title "Test Title""`,
- );
- });
-
- it("does not list all excludes when using common base", () => {
- const common = createRerunSuggestion({
- base: "common",
- ...getExclusions(options, "common"),
- excludeLintKnip: undefined,
- });
-
- expect(common).toMatchInlineSnapshot(
- `"npx create-typescript-app --base common"`,
- );
- });
-
- it("does not list all excludes when using minimal base", () => {
- const minimal = createRerunSuggestion({
- base: "minimal",
- ...getExclusions(options, "minimal"),
- excludeLintKnip: undefined,
- });
-
- expect(minimal).toMatchInlineSnapshot(
- `"npx create-typescript-app --base minimal"`,
- );
- });
-
- it("does not list API skip flags when --offline is true", () => {
- const actual = createRerunSuggestion({
- ...options,
- offline: true,
- skipAllContributorsApi: true,
- skipGitHubApi: true,
- });
-
- expect(actual).toMatchInlineSnapshot(
- `"npx create-typescript-app --base everything --author TestAuthor --description "Test description." --directory . --email-github github@email.com --email-npm npm@email.com --exclude-all-contributors --exclude-compliance --exclude-lint-jsdoc --exclude-lint-json --exclude-lint-knip --exclude-lint-package-json --exclude-lint-perfectionist --keywords "abc def ghi jkl mno pqr" --mode create --offline --owner TestOwner --repository test-repository --skip-install --skip-removal --title "Test Title""`,
- );
- });
-});
diff --git a/src/create/createRerunSuggestion.ts b/src/create/createRerunSuggestion.ts
deleted file mode 100644
index 0ffb97865..000000000
--- a/src/create/createRerunSuggestion.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-import { allArgOptions } from "../shared/options/args.js";
-import {
- ExclusionKey,
- getExclusions,
-} from "../shared/options/exclusionKeys.js";
-import { Options } from "../shared/types.js";
-import { createRerunDirectorySuggestion } from "./createRerunDirectorySuggestion.js";
-
-function getFirstMatchingArg(key: string) {
- return Object.keys(allArgOptions).find(
- (arg) => arg.replaceAll("-", "") === key.toLowerCase(),
- );
-}
-
-const defaultValues = new Map([["access", "public"]]);
-
-export function createRerunSuggestion(options: Partial): string {
- const optionsNormalized = {
- ...options,
- email: undefined,
- ...(options.email && {
- emailGitHub: options.email.github,
- emailNpm: options.email.npm,
- }),
- ...(options.guide
- ? {
- guide: options.guide.href,
- guideTitle: options.guide.title,
- }
- : { guide: undefined }),
- ...(options.logo
- ? {
- logo: options.logo.src,
- logoAlt: options.logo.alt,
- }
- : { logo: undefined }),
- ...(options.offline && {
- skipAllContributorsApi: undefined,
- skipGitHubApi: undefined,
- }),
- directory: createRerunDirectorySuggestion(options),
- };
-
- const args = Object.entries(optionsNormalized)
- // Sort so the base is first, then the rest are sorted alphabetically
- .sort(([a], [b]) =>
- a === "base" ? -1 : b === "base" ? 1 : a.localeCompare(b),
- )
- // Filter out entries with an excluded key or a default or falsy value
- .filter(
- ([key, value]) =>
- getExclusions(options, optionsNormalized.base)[key as ExclusionKey] ==
- undefined &&
- !!value &&
- value !== defaultValues.get(key),
- )
- .map(([key, value]) => {
- return `--${getFirstMatchingArg(key)}${stringifyValue(value)}`;
- })
- .join(" ");
-
- return ["npx create-typescript-app", args].filter(Boolean).join(" ");
-}
-
-function stringifyValue(
- value: boolean | string | string[] | undefined,
-): string {
- if (Array.isArray(value)) {
- return stringifyValue(value.join(" "));
- }
-
- if (typeof value === "boolean" && value) {
- return "";
- }
-
- const valueStringified = `${value}`;
-
- return valueStringified.includes(" ")
- ? ` "${valueStringified}"`
- : ` ${valueStringified}`;
-}
diff --git a/src/create/createWithOptions.test.ts b/src/create/createWithOptions.test.ts
deleted file mode 100644
index cbb5ce483..000000000
--- a/src/create/createWithOptions.test.ts
+++ /dev/null
@@ -1,195 +0,0 @@
-import { Octokit } from "octokit";
-import { describe, expect, it, vi } from "vitest";
-
-import { SpinnerTask } from "../shared/cli/spinners.js";
-import { doesRepositoryExist } from "../shared/doesRepositoryExist.js";
-import { Options } from "../shared/types.js";
-import { addToolAllContributors } from "../steps/addToolAllContributors.js";
-import { finalizeDependencies } from "../steps/finalizeDependencies.js";
-import { initializeGitHubRepository } from "../steps/initializeGitHubRepository/index.js";
-import { runCleanup } from "../steps/runCleanup.js";
-import { createWithOptions } from "./createWithOptions.js";
-
-const optionsBase: Options = {
- access: "public",
- author: "Test Author",
- base: "common",
- description: "Test Description",
- directory: "test-directory",
- email: { github: "github@example.com", npm: "npm@example.com" },
- funding: "Test Funding",
- keywords: ["test", "keywords"],
- logo: { alt: "Test Alt", src: "test.png" },
- mode: "create",
- owner: "Test Owner",
- repository: "test-repo",
- title: "Test Title",
-};
-
-const mock$$ = vi.fn();
-
-const mock$ = vi.fn().mockReturnValue(mock$$);
-
-vi.mock("execa", () => ({
- get $() {
- return mock$;
- },
-}));
-
-const mockOctokit = new Octokit();
-
-vi.mock("../shared/cli/spinners.js", () => ({
- withSpinner: async (label: string, task: SpinnerTask) => {
- return await task();
- },
- withSpinners: async (
- label: string,
- tasks: [string, SpinnerTask][],
- ) => {
- for (const [, task] of tasks) {
- await task();
- }
- },
-}));
-
-vi.mock("../steps/writing/writeStructure.js");
-
-vi.mock("../steps/writeReadme/index.js");
-
-vi.mock("../steps/finalizeDependencies.js");
-
-vi.mock("../steps/clearLocalGitTags.js");
-
-vi.mock("../steps/runCleanup.js");
-
-vi.mock("../shared/doesRepositoryExist.js", () => ({
- doesRepositoryExist: vi.fn().mockResolvedValue(true),
-}));
-
-vi.mock("../steps/initializeGitHubRepository/index.js", () => ({
- initializeGitHubRepository: vi.fn().mockResolvedValue(true),
-}));
-
-vi.mock("../shared/getGitHubUserAsAllContributor.js", () => ({
- getGitHubUserAsAllContributor: vi.fn().mockResolvedValue({
- contributions: ["code", "doc"],
- name: "Test User",
- }),
-}));
-
-vi.mock("../steps/addToolAllContributors.js");
-
-describe("createWithOptions", () => {
- it("calls addToolAllContributors with options when excludeAllContributors is false", async () => {
- const options = {
- ...optionsBase,
- excludeAllContributors: false,
- skipAllContributorsApi: false,
- };
-
- await createWithOptions({ octokit: mockOctokit, options }, ".");
- expect(addToolAllContributors).toHaveBeenCalledWith(mockOctokit, options);
- });
-
- it("does not call addToolAllContributors when excludeAllContributors is true", async () => {
- const options = {
- ...optionsBase,
- excludeAllContributors: true,
- };
-
- await createWithOptions({ octokit: mockOctokit, options }, ".");
- expect(addToolAllContributors).not.toHaveBeenCalled();
- });
-
- it("does not call addToolAllContributors when skipAllContributorsApi is true", async () => {
- const options = {
- ...optionsBase,
- skipAllContributorsApi: true,
- };
-
- await createWithOptions({ octokit: mockOctokit, options }, ".");
- expect(addToolAllContributors).not.toHaveBeenCalled();
- });
-
- it("does not call finalizeDependencies or runCleanup when skipInstall is true", async () => {
- const options = {
- ...optionsBase,
- skipInstall: true,
- };
-
- await createWithOptions({ octokit: mockOctokit, options }, ".");
- expect(finalizeDependencies).not.toHaveBeenCalled();
- expect(runCleanup).not.toHaveBeenCalled();
- });
-
- it("calls finalizeDependencies and runCleanup when skipInstall is false", async () => {
- const options = {
- ...optionsBase,
- skipInstall: false,
- };
-
- await createWithOptions({ octokit: mockOctokit, options }, ".");
-
- expect(finalizeDependencies).toHaveBeenCalledWith(options);
- expect(runCleanup).toHaveBeenCalled();
- });
-
- it("does not initialize GitHub repository if repository does not exist", async () => {
- const options = optionsBase;
- vi.mocked(doesRepositoryExist).mockResolvedValueOnce(false);
- await createWithOptions({ octokit: mockOctokit, options }, ".");
- expect(initializeGitHubRepository).not.toHaveBeenCalled();
- expect(mock$$).not.toHaveBeenCalled();
- });
-
- it("executes git commands when initializing GitHub repository when doesRepositoryExist is true", async () => {
- const options = optionsBase;
-
- vi.mocked(doesRepositoryExist).mockResolvedValueOnce(true);
- await createWithOptions({ octokit: mockOctokit, options }, ".");
-
- expect(mock$$.mock.calls).toMatchInlineSnapshot(`
- [
- [
- [
- "git remote add origin https://github.com/",
- "/",
- "",
- ],
- "Test Owner",
- "test-repo",
- ],
- [
- [
- "git add -A",
- ],
- ],
- [
- [
- "git commit --message ",
- " --no-gpg-sign",
- ],
- "feat: initialized repo ✨",
- ],
- [
- [
- "git push -u origin main --force",
- ],
- ],
- ]
- `);
- });
-
- it("calls doesRepositoryExist with github and options when doesRepositoryExist is true", async () => {
- const options = optionsBase;
- vi.mocked(doesRepositoryExist).mockResolvedValueOnce(true);
-
- await createWithOptions({ octokit: mockOctokit, options }, ".");
-
- expect(doesRepositoryExist).toHaveBeenCalledWith(mockOctokit, options);
- expect(initializeGitHubRepository).toHaveBeenCalledWith(
- mockOctokit,
- options,
- );
- });
-});
diff --git a/src/create/createWithOptions.ts b/src/create/createWithOptions.ts
deleted file mode 100644
index a87275160..000000000
--- a/src/create/createWithOptions.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-import { $ } from "execa";
-
-import { runCreateEnginePreset } from "../next/runCreateEnginePreset.js";
-import {
- LabeledSpinnerTask,
- withSpinner,
- withSpinners,
-} from "../shared/cli/spinners.js";
-import { createCleanupCommands } from "../shared/createCleanupCommands.js";
-import { doesRepositoryExist } from "../shared/doesRepositoryExist.js";
-import { isUsingCreateEngine } from "../shared/isUsingCreateEngine.js";
-import { OctokitAndOptions } from "../shared/options/readOptions.js";
-import { addToolAllContributors } from "../steps/addToolAllContributors.js";
-import { clearLocalGitTags } from "../steps/clearLocalGitTags.js";
-import { finalizeDependencies } from "../steps/finalizeDependencies.js";
-import { initializeGitHubRepository } from "../steps/initializeGitHubRepository/index.js";
-import { runCleanup } from "../steps/runCleanup.js";
-import { writeReadme } from "../steps/writeReadme/index.js";
-import { writeStructure } from "../steps/writing/writeStructure.js";
-
-export async function createWithOptions(
- { octokit, options }: OctokitAndOptions,
- repositoryDirectory: string,
-) {
- // https://github.com/JoshuaKGoldberg/create-typescript-app/pull/1781
- // I don't know why the chdir wasn't sticking from createAndEnterGitDirectory
- process.chdir(repositoryDirectory);
- const $$ = $({ cwd: repositoryDirectory });
-
- if (isUsingCreateEngine()) {
- await withSpinner("Creating repository", async () => {
- await runCreateEnginePreset(options);
- });
- return { sentToGitHub: false };
- }
-
- await withSpinners("Creating repository structure", [
- [
- "Writing structure",
- async () => {
- await writeStructure(options);
- },
- ],
- [
- "Writing README.md",
- async () => {
- await writeReadme(options);
- },
- ] satisfies LabeledSpinnerTask,
- ]);
-
- if (!options.excludeAllContributors && !options.skipAllContributorsApi) {
- await withSpinner("Adding contributors to table", async () => {
- await addToolAllContributors(octokit, options);
- });
- }
-
- if (!options.skipInstall) {
- await withSpinner("Installing packages", async () =>
- finalizeDependencies(options),
- );
-
- await runCleanup(createCleanupCommands(options.bin), options.mode);
- }
-
- await withSpinner("Clearing any local Git tags", clearLocalGitTags);
-
- const sendToGitHub = octokit && (await doesRepositoryExist(octokit, options));
-
- if (sendToGitHub) {
- await withSpinner("Initializing GitHub repository", async () => {
- await $$`git remote add origin https://github.com/${options.owner}/${options.repository}`;
- await $$`git add -A`;
- await $$`git commit --message ${"feat: initialized repo ✨"} --no-gpg-sign`;
- await $$`git push -u origin main --force`;
- await initializeGitHubRepository(octokit, options);
- });
- }
-
- return { sentToGitHub: sendToGitHub };
-}
diff --git a/src/create/index.test.ts b/src/create/index.test.ts
deleted file mode 100644
index d86ec6b3f..000000000
--- a/src/create/index.test.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-import chalk from "chalk";
-import { describe, expect, it, vi } from "vitest";
-
-import { StatusCodes } from "../shared/codes.js";
-import { create } from "./index.js";
-
-const mockOutro = vi.fn();
-
-vi.mock("@clack/prompts", () => ({
- get outro() {
- return mockOutro;
- },
- spinner: vi.fn(),
-}));
-
-const mockReadOptions = vi.fn();
-
-vi.mock("../shared/options/readOptions.js", () => ({
- get readOptions() {
- return mockReadOptions;
- },
-}));
-
-const mockCreateAndEnterGitDirectory = vi.fn();
-
-vi.mock("./createAndEnterGitDirectory.js", () => ({
- get createAndEnterGitDirectory() {
- return mockCreateAndEnterGitDirectory;
- },
-}));
-
-const optionsBase = {
- directory: "TestDirectory",
- repository: "TestRepository",
-};
-
-describe("create", () => {
- it("returns a cancellation code when readOptions cancels", async () => {
- mockReadOptions.mockResolvedValue({
- cancelled: true,
- options: optionsBase,
- });
-
- const result = await create([]);
-
- expect(result).toEqual({
- code: StatusCodes.Cancelled,
- options: optionsBase,
- });
- });
-
- it("returns a failure code when createAndEnterGitDirectory returns false", async () => {
- mockReadOptions.mockResolvedValue({
- cancelled: false,
- options: optionsBase,
- });
-
- mockCreateAndEnterGitDirectory.mockResolvedValue(false);
-
- const result = await create([]);
-
- expect(result).toEqual({
- code: StatusCodes.Failure,
- options: optionsBase,
- });
- expect(mockOutro).toHaveBeenCalledWith(
- chalk.red(
- "The TestDirectory directory already exists and is not empty. Please clear the directory, run with --mode initialize, or try a different directory.",
- ),
- );
- });
-});
diff --git a/src/create/index.ts b/src/create/index.ts
deleted file mode 100644
index 5d1ce6610..000000000
--- a/src/create/index.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-import * as prompts from "@clack/prompts";
-import chalk from "chalk";
-
-import { outro } from "../shared/cli/outro.js";
-import { StatusCodes } from "../shared/codes.js";
-import { generateNextSteps } from "../shared/generateNextSteps.js";
-import { readOptions } from "../shared/options/readOptions.js";
-import { runOrRestore } from "../shared/runOrRestore.js";
-import { ModeRunner } from "../shared/types.js";
-import { createAndEnterGitDirectory } from "./createAndEnterGitDirectory.js";
-import { createRerunSuggestion } from "./createRerunSuggestion.js";
-import { createWithOptions } from "./createWithOptions.js";
-
-export const create: ModeRunner = async (args, promptedOptions) => {
- const inputs = await readOptions(args, "create", promptedOptions);
- if (inputs.cancelled) {
- return {
- code: StatusCodes.Cancelled,
- error: inputs.error,
- options: inputs.options,
- };
- }
-
- const repositoryDirectory = await createAndEnterGitDirectory(
- inputs.options.directory,
- );
- if (!repositoryDirectory) {
- prompts.outro(
- chalk.red(
- `The ${inputs.options.directory} directory already exists and is not empty. Please clear the directory, run with --mode initialize, or try a different directory.`,
- ),
- );
- return { code: StatusCodes.Failure, options: inputs.options };
- }
-
- return {
- code: await runOrRestore({
- run: async () => {
- const { sentToGitHub } = await createWithOptions(
- inputs,
- repositoryDirectory,
- );
- const nextSteps = generateNextSteps(inputs.options);
-
- outro(
- sentToGitHub
- ? nextSteps
- : [
- {
- label:
- "Consider creating a GitHub repository from the new directory:",
- lines: [
- `cd ${inputs.options.repository}`,
- createRerunSuggestion({
- ...inputs.options,
- mode: "initialize",
- skipGitHubApi: false,
- skipInstall: false,
- }),
- `git add -A`,
- `git commit -m "feat: initial commit ✨"`,
- `git push -u origin main`,
- ],
- variant: "code",
- },
- ...nextSteps,
- ],
- );
- },
- skipRestore: inputs.options.skipRestore,
- }),
- options: inputs.options,
- };
-};
diff --git a/src/next/blocks/packageData.test.ts b/src/data/packageData.test.ts
similarity index 100%
rename from src/next/blocks/packageData.test.ts
rename to src/data/packageData.test.ts
diff --git a/src/next/blocks/packageData.ts b/src/data/packageData.ts
similarity index 68%
rename from src/next/blocks/packageData.ts
rename to src/data/packageData.ts
index a72bf3adc..14d7bc033 100644
--- a/src/next/blocks/packageData.ts
+++ b/src/data/packageData.ts
@@ -1,4 +1,10 @@
-import { sourcePackageJson } from "./sourcePackageJson.js";
+import { createRequire } from "node:module";
+
+const require = createRequire(import.meta.url);
+
+export const packageData =
+ // Importing from above src/ would expand the TS build rootDir
+ require("../../package.json") as typeof import("../../package.json");
export function getPackageDependencies(...names: string[]) {
return Object.fromEntries(
@@ -26,7 +32,7 @@ function getPackageInner(
key: "dependencies" | "devDependencies",
name: string,
) {
- const inner = sourcePackageJson[key];
+ const inner = packageData[key];
return inner[name as keyof typeof inner] as string | undefined;
}
diff --git a/src/docs.test.ts b/src/docs.test.ts
new file mode 100644
index 000000000..4fcc0b160
--- /dev/null
+++ b/src/docs.test.ts
@@ -0,0 +1,90 @@
+import { Block } from "create";
+import * as fs from "node:fs/promises";
+import * as prettier from "prettier";
+import { describe, expect, test } from "vitest";
+
+import { blocks, presets } from "./index.js";
+
+const actualLines = await createActualLines();
+const expectedLines = await createExpectedLines();
+
+// This test ensures ensures docs/Blocks.md has a row for each of CTA's blocks.
+// Each row should include emojis describing which preset(s) include the block.
+//
+// If this fails, it's likely due to adding, removing, or renaming a block.
+// You may need to manually change docs/Blocks.md to match to those changes.
+//
+// For example, if you add a blockExample to the Common and Everything presets,
+// you'll need to add a row like:
+//
+// ```md
+// | Example | `--exclude-example` | | ✅ | 💯 |
+// ```
+//
+// Rows are kept sorted by alphabetical order of name.
+describe("docs/Blocks.md", () => {
+ for (const [i, line] of expectedLines.entries()) {
+ const name = line.split(" | ")[0].replace("| ", "").trim();
+ if (!name) {
+ continue;
+ }
+
+ // TODO: Enable vitest/eslint-plugin type-checking:
+ // https://github.com/vitest-dev/eslint-plugin-vitest?tab=readme-ov-file#enabling-with-type-testing
+ // eslint-disable-next-line vitest/valid-title
+ test(name, () => {
+ const actualLine = actualLines.find((line) => line.includes(`| ${name}`));
+ const expectedLine = expectedLines[i];
+
+ expect(actualLine).toBe(expectedLine);
+ });
+ }
+});
+
+async function createActualLines() {
+ const actualFile = (await fs.readFile("docs/Blocks.md")).toString();
+
+ actualFile
+ .split("\n")
+ .filter((line) => !line.includes("----"))
+ .map((line) => line.toLowerCase());
+
+ return splitTable(actualFile);
+}
+
+async function createExpectedLines() {
+ const lines = [
+ "| Block | Exclusion Flag | Minimal | Common | Everything |",
+ "| ----- | -------------- | ------- | ------ | ---------- |",
+ ];
+
+ for (const block of Object.values(blocks) as Block[]) {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ const name = block.about!.name!;
+
+ lines.push(
+ [
+ name,
+ `\`--exclude-${name.replaceAll(/\W+/g, "-").toLowerCase()}\``,
+ presets.minimal.blocks.includes(block) ? "✔️" : " ",
+ presets.common.blocks.includes(block) ? "✅" : " ",
+ presets.everything.blocks.includes(block) ? "💯" : " ",
+ "",
+ ].join(" | "),
+ );
+ }
+
+ const expectedTable = await prettier.format(lines.join("\n"), {
+ parser: "markdown",
+ useTabs: true,
+ });
+
+ return splitTable(expectedTable);
+}
+
+function splitTable(table: string) {
+ return table
+ .split("\n")
+ .filter((line) => !line.includes("----"))
+ .map((line) => line.toLowerCase());
+}
diff --git a/src/greet.test.ts b/src/greet.test.ts
deleted file mode 100644
index f729115fc..000000000
--- a/src/greet.test.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { describe, expect, it, vi } from "vitest";
-
-import { greet } from "./greet.js";
-
-const message = "Yay, testing!";
-
-describe("greet", () => {
- it("logs to the console once when message is provided as a string", () => {
- const logger = vi.spyOn(console, "log").mockImplementation(() => undefined);
-
- greet(message);
-
- expect(logger).toHaveBeenCalledWith(message);
- expect(logger).toHaveBeenCalledTimes(1);
- });
-
- it("logs to the console once when message is provided as an object", () => {
- const logger = vi.spyOn(console, "log").mockImplementation(() => undefined);
-
- greet({ message });
-
- expect(logger).toHaveBeenCalledWith(message);
- expect(logger).toHaveBeenCalledTimes(1);
- });
-
- it("logs once when times is not provided in an object", () => {
- const logger = vi.fn();
-
- greet({ logger, message });
-
- expect(logger).toHaveBeenCalledWith(message);
- expect(logger).toHaveBeenCalledTimes(1);
- });
-
- it("logs a specified number of times when times is provided", () => {
- const logger = vi.fn();
- const times = 7;
-
- greet({ logger, message, times });
-
- expect(logger).toHaveBeenCalledWith(message);
- expect(logger).toHaveBeenCalledTimes(7);
- });
-});
diff --git a/src/greet.ts b/src/greet.ts
deleted file mode 100644
index a0d3b4c67..000000000
--- a/src/greet.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { GreetOptions } from "./types.js";
-
-export function greet(options: GreetOptions | string) {
- const {
- logger = console.log.bind(console),
- message,
- times = 1,
- } = typeof options === "string" ? { message: options } : options;
-
- for (let i = 0; i < times; i += 1) {
- logger(message);
- }
-}
diff --git a/src/index.ts b/src/index.ts
index 39b62f22e..d2fbcef84 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,9 +1,4 @@
-export * from "./greet.js";
-
-// If you're using create-typescript-app as a template, ignore these.
-// They're plumbing for the create engine. :)
-export * from "./next/blocks/index.js";
-export * from "./next/presets/index.js";
-export { default } from "./next/template.js";
-
-export * from "./types.js";
+export * from "./base.js";
+export * from "./blocks/index.js";
+export * from "./presets/index.js";
+export { default } from "./template.js";
diff --git a/src/initialize/index.test.ts b/src/initialize/index.test.ts
deleted file mode 100644
index 703dcdd83..000000000
--- a/src/initialize/index.test.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-import { describe, expect, it, vi } from "vitest";
-
-import { StatusCodes } from "../shared/codes.js";
-import { RunOrRestoreOptions } from "../shared/runOrRestore.js";
-import { initialize } from "./index.js";
-
-const mockOutro = vi.fn();
-
-vi.mock("../shared/cli/outro.js", () => ({
- get outro() {
- return mockOutro;
- },
-}));
-
-const mockEnsureGitRepository = vi.fn();
-
-vi.mock("../shared/ensureGitRepository.js", () => ({
- get ensureGitRepository() {
- return mockEnsureGitRepository;
- },
-}));
-
-const mockReadOptions = vi.fn();
-
-vi.mock("../shared/options/readOptions.js", () => ({
- get readOptions() {
- return mockReadOptions;
- },
-}));
-
-vi.mock("../shared/runOrRestore.js", () => ({
- async runOrRestore({ run }: RunOrRestoreOptions) {
- await run();
- return StatusCodes.Success;
- },
-}));
-
-const mockInitializeWithOptions = vi.fn();
-
-vi.mock("./initializeWithOptions.js", () => ({
- get initializeWithOptions() {
- return mockInitializeWithOptions;
- },
-}));
-
-const optionsBase = {
- repository: "TestRepository",
-};
-
-describe("initialize", () => {
- it("returns a cancellation code when readOptions cancels", async () => {
- mockReadOptions.mockResolvedValue({
- cancelled: true,
- options: optionsBase,
- });
-
- const result = await initialize([]);
-
- expect(result).toEqual({
- code: StatusCodes.Cancelled,
- options: optionsBase,
- });
- expect(mockEnsureGitRepository).not.toHaveBeenCalled();
- });
-
- it("runs initializeWithOptions when readOptions returns inputs", async () => {
- mockReadOptions.mockResolvedValue({
- cancelled: false,
- options: optionsBase,
- });
-
- const result = await initialize([]);
-
- expect(result).toEqual({
- code: StatusCodes.Success,
- options: optionsBase,
- });
- expect(mockEnsureGitRepository).toHaveBeenCalled();
- expect(mockOutro.mock.calls).toMatchInlineSnapshot(`
- [
- [
- [
- {
- "label": "You may consider committing these changes:",
- "lines": [
- "git add -A",
- "git commit -m "feat: initialized repo ✨",
- "git push",
- ],
- "variant": "code",
- },
- {
- "label": "Be sure to:",
- "lines": [
- "- enable the GitHub apps:
- - Codecov (https://github.com/apps/codecov)
- - Renovate (https://github.com/apps/renovate)",
- "- populate the secrets:
- - ACCESS_TOKEN (a GitHub PAT with repo and workflow permissions)
- - NPM_TOKEN (an npm access token with automation permissions)",
- ],
- },
- ],
- ],
- ]
- `);
- });
-});
diff --git a/src/initialize/index.ts b/src/initialize/index.ts
deleted file mode 100644
index a2b4caa3e..000000000
--- a/src/initialize/index.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { outro } from "../shared/cli/outro.js";
-import { StatusCodes } from "../shared/codes.js";
-import { ensureGitRepository } from "../shared/ensureGitRepository.js";
-import { generateNextSteps } from "../shared/generateNextSteps.js";
-import { readOptions } from "../shared/options/readOptions.js";
-import { runOrRestore } from "../shared/runOrRestore.js";
-import { ModeRunner } from "../shared/types.js";
-import { initializeWithOptions } from "./initializeWithOptions.js";
-
-export const initialize: ModeRunner = async (args) => {
- const inputs = await readOptions(args, "initialize");
- if (inputs.cancelled) {
- return {
- code: StatusCodes.Cancelled,
- error: inputs.error,
- options: inputs.options,
- };
- }
-
- await ensureGitRepository();
-
- return {
- code: await runOrRestore({
- run: async () => {
- await initializeWithOptions(inputs);
-
- outro([
- {
- label: "You may consider committing these changes:",
- lines: [
- `git add -A`,
- `git commit -m "feat: initialized repo ✨`,
- `git push`,
- ],
- variant: "code",
- },
- ...generateNextSteps(inputs.options),
- ]);
- },
- skipRestore: inputs.options.skipRestore,
- }),
- options: inputs.options,
- };
-};
diff --git a/src/initialize/initializeWithOptions.test.ts b/src/initialize/initializeWithOptions.test.ts
deleted file mode 100644
index 3910a7c00..000000000
--- a/src/initialize/initializeWithOptions.test.ts
+++ /dev/null
@@ -1,188 +0,0 @@
-import { Octokit } from "octokit";
-import { describe, expect, it, vi } from "vitest";
-
-import { Options } from "../shared/types.js";
-import { initializeWithOptions } from "./initializeWithOptions.js";
-
-vi.mock("../shared/cli/spinners.js", () => ({
- async withSpinner(_label: string, task: () => Promise) {
- await task();
- },
- withSpinners: vi.fn(),
-}));
-
-const mockAddOwnerAsAllContributor = vi.fn();
-
-vi.mock("../steps/addOwnerAsAllContributor.js", () => ({
- get addOwnerAsAllContributor() {
- return mockAddOwnerAsAllContributor;
- },
-}));
-
-const mockClearChangelog = vi.fn();
-
-vi.mock("../steps/clearChangelog.js", () => ({
- get clearChangelog() {
- return mockClearChangelog;
- },
-}));
-
-const mockInitializeGitHubRepository = vi.fn();
-
-vi.mock("../steps/initializeGitHubRepository/index.js", () => ({
- get initializeGitHubRepository() {
- return mockInitializeGitHubRepository;
- },
-}));
-
-const mockRemoveSetupScripts = vi.fn();
-
-vi.mock("../steps/removeSetupScripts.js", () => ({
- get removeSetupScripts() {
- return mockRemoveSetupScripts;
- },
-}));
-
-const mockResetGitTags = vi.fn();
-
-vi.mock("../steps/resetGitTags.js", () => ({
- get resetGitTags() {
- return mockResetGitTags;
- },
-}));
-
-const mockRunCleanup = vi.fn();
-
-vi.mock("../steps/runCleanup.js", () => ({
- get runCleanup() {
- return mockRunCleanup;
- },
-}));
-
-const mockUninstallPackages = vi.fn();
-
-vi.mock("../steps/uninstallPackages.js", () => ({
- get uninstallPackages() {
- return mockUninstallPackages;
- },
-}));
-
-const optionsBase = {} as Options;
-
-describe("initializeWithOptions", () => {
- it("runs addOwnerAsAllContributor when excludeAllContributors is false", async () => {
- const options = {
- ...optionsBase,
- excludeAllContributors: false,
- };
-
- await initializeWithOptions({
- octokit: undefined,
- options,
- });
-
- expect(mockAddOwnerAsAllContributor).toHaveBeenCalledWith(
- undefined,
- options,
- );
- });
-
- it("does not run addOwnerAsAllContributor when excludeAllContributors is true", async () => {
- const options = {
- ...optionsBase,
- excludeAllContributors: true,
- };
-
- await initializeWithOptions({
- octokit: undefined,
- options,
- });
-
- expect(mockAddOwnerAsAllContributor).not.toHaveBeenCalled();
- });
-
- it("runs initializeGitHubRepository when github is truthy", async () => {
- const octokit = {} as Octokit;
-
- await initializeWithOptions({
- octokit,
- options: optionsBase,
- });
-
- expect(mockInitializeGitHubRepository).toHaveBeenCalledWith(
- octokit,
- optionsBase,
- );
- });
-
- it("does not run initializeGitHubRepository when github is falsy", async () => {
- const options = {
- ...optionsBase,
- excludeAllContributors: true,
- };
-
- await initializeWithOptions({
- octokit: undefined,
- options,
- });
-
- expect(mockInitializeGitHubRepository).not.toHaveBeenCalled();
- });
-
- it("runs removeSetupScripts when skipRemoval is false", async () => {
- const options = {
- ...optionsBase,
- skipRemoval: false,
- };
-
- await initializeWithOptions({
- octokit: undefined,
- options,
- });
-
- expect(mockRemoveSetupScripts).toHaveBeenCalled();
- });
-
- it("does not run removeSetupScripts when skipRemoval is true", async () => {
- const options = {
- ...optionsBase,
- skipRemoval: true,
- };
-
- await initializeWithOptions({
- octokit: undefined,
- options,
- });
-
- expect(mockRemoveSetupScripts).not.toHaveBeenCalled();
- });
-
- it("runs uninstallPackages when skipUninstall is false", async () => {
- const options = {
- ...optionsBase,
- offline: true,
- skipUninstall: false,
- };
-
- await initializeWithOptions({
- octokit: undefined,
- options,
- });
-
- expect(mockUninstallPackages).toHaveBeenCalledWith(options.offline);
- });
-
- it("does not run uninstallPackages when skipUninstall is true", async () => {
- const options = {
- ...optionsBase,
- skipUninstall: true,
- };
-
- await initializeWithOptions({
- octokit: undefined,
- options,
- });
-
- expect(mockUninstallPackages).not.toHaveBeenCalled();
- });
-});
diff --git a/src/initialize/initializeWithOptions.ts b/src/initialize/initializeWithOptions.ts
deleted file mode 100644
index f6e37cbf6..000000000
--- a/src/initialize/initializeWithOptions.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import { withSpinner, withSpinners } from "../shared/cli/spinners.js";
-import { createCleanupCommands } from "../shared/createCleanupCommands.js";
-import { OctokitAndOptions } from "../shared/options/readOptions.js";
-import { addOwnerAsAllContributor } from "../steps/addOwnerAsAllContributor.js";
-import { clearChangelog } from "../steps/clearChangelog.js";
-import { initializeGitHubRepository } from "../steps/initializeGitHubRepository/index.js";
-import { removeSetupScripts } from "../steps/removeSetupScripts.js";
-import { resetGitTags } from "../steps/resetGitTags.js";
-import { runCleanup } from "../steps/runCleanup.js";
-import { uninstallPackages } from "../steps/uninstallPackages.js";
-import { updateAllContributorsTable } from "../steps/updateAllContributorsTable.js";
-import { updateLocalFiles } from "../steps/updateLocalFiles.js";
-import { updateReadme } from "../steps/updateReadme.js";
-
-export async function initializeWithOptions({
- octokit,
- options,
-}: OctokitAndOptions) {
- await withSpinners("Initializing local files", [
- [
- "Updating local files",
- async () => {
- await updateLocalFiles(options);
- },
- ],
- [
- "Updating README.md",
- async () => {
- await updateReadme(options);
- },
- ],
- ["Clearing changelog", clearChangelog],
- [
- "Updating all-contributors table",
- async () => {
- await updateAllContributorsTable(options);
- },
- ],
- ["Resetting Git tags", resetGitTags],
- ]);
-
- if (!options.excludeAllContributors) {
- await withSpinner("Updating existing contributor details", async () => {
- await addOwnerAsAllContributor(octokit, options);
- });
- }
-
- if (octokit) {
- await withSpinner("Initializing GitHub repository", async () => {
- await initializeGitHubRepository(octokit, options);
- });
- }
-
- if (!options.skipRemoval) {
- await withSpinner("Removing setup scripts", removeSetupScripts);
- }
-
- if (!options.skipUninstall) {
- await withSpinner("Uninstalling initialization-only packages", async () =>
- uninstallPackages(options.offline),
- );
- }
-
- await runCleanup(
- createCleanupCommands(options.bin, "pnpm dedupe --offline"),
- options.mode,
- );
-}
diff --git a/src/integration.test.ts b/src/integration.test.ts
new file mode 100644
index 000000000..90992bbf6
--- /dev/null
+++ b/src/integration.test.ts
@@ -0,0 +1,138 @@
+import prettier from "@prettier/sync";
+import { produceBase, producePreset } from "create";
+import { intakeFromDirectory } from "create-fs";
+import { diffCreatedDirectory } from "create-testers";
+import { expect, test } from "vitest";
+
+import {
+ base,
+ BaseOptions,
+ blockAreTheTypesWrong,
+ blockCodecov,
+ blockCSpell,
+ blockESLint,
+ blockKnip,
+ blockTemplatedWith,
+ blockTSup,
+ presets,
+} from "./index.js";
+
+// This test checks the `create` production using options inferred from disk,
+// along with some explicit addons and blocks specified.
+// It ensures that result has no differences from the actual files on disk.
+//
+// If the test fails, it's most likely due to a block being changed without the
+// corresponding file(s) on disk also being changed.
+// You may need to manually update files on disk to match the block's output.
+//
+// The next most likely culprit for failures is changing file contents that are
+// specified by the addons mentioned in the producePreset() call below.
+// For now, if you change the output on disk, you'll need to manually update here too.
+// TODO: Eventually the create engine will be able to infer them:
+// https://github.com/JoshuaKGoldberg/create/issues/128
+//
+// For example, if you change blockTypeScript's target from "ES2022 to "ES2023",
+// you'll also need to update the ./tsconfig.json on disk in the same way.
+test("Producing the everything preset matches the files in this repository", async () => {
+ const actual = await intakeFromDirectory(".", {
+ exclude: /node_modules|^\.git$/,
+ });
+
+ const created = await producePreset(presets.everything, {
+ addons: [
+ blockCodecov({
+ env: {
+ CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}",
+ },
+ }),
+ blockCSpell({
+ words: [
+ "Anson",
+ "apexskier",
+ "dbaeumer",
+ "joshuakgoldberg",
+ "markdownlintignore",
+ "mtfoley",
+ "infile",
+ "npmjs",
+ ],
+ }),
+ blockESLint({
+ explanations: [
+ `👋 Hi! This ESLint configuration contains a lot more stuff than many repos'!
+You can read from it to see all sorts of linting goodness, but don't worry -
+it's not something you need to exhaustively understand immediately. 💙
+
+If you're interested in learning more, see the 'getting started' docs on:
+- ESLint: https://eslint.org
+- typescript-eslint: https://typescript-eslint.io`,
+ ],
+ rules: [
+ {
+ comment:
+ "These on-by-default rules work well for this repo if configured",
+ entries: {
+ "@typescript-eslint/prefer-nullish-coalescing": [
+ "error",
+ { ignorePrimitives: true },
+ ],
+ "@typescript-eslint/restrict-template-expressions": [
+ "error",
+ { allowBoolean: true, allowNullish: true, allowNumber: true },
+ ],
+ },
+ },
+ ],
+ }),
+ blockKnip({
+ ignoreDependencies: [
+ "all-contributors-cli",
+ "cspell-populate-words",
+ "remove-dependencies",
+ ],
+ }),
+ blockTSup({
+ runArgs: ["--version"],
+ }),
+ ],
+ blocks: {
+ add: [blockAreTheTypesWrong],
+ exclude: [blockTemplatedWith],
+ },
+ options: (await produceBase(base)) as BaseOptions,
+ });
+
+ const processText = (text: string, filePath: string) =>
+ /all-contributorsrc|js|md|ts|yml/.test(filePath)
+ ? prettier.format(text, { filepath: filePath, useTabs: true })
+ : text;
+
+ // Right now, there is exactly one change: the altered beta release flow
+ // TODO: That will be removed once releases switch back to stable:
+ // https://github.com/JoshuaKGoldberg/create-typescript-app/issues/1831
+ expect(diffCreatedDirectory(actual, created.files, processText))
+ .toMatchInlineSnapshot(`
+ {
+ ".github": {
+ "workflows": {
+ "release.yml": "@@ -14,13 +14,9 @@
+ - run: pnpm build
+ - env:
+ GITHUB_TOKEN: \${{ secrets.ACCESS_TOKEN }}
+ NPM_TOKEN: \${{ secrets.NPM_TOKEN }}
+ - run: |
+ - git config --global user.email "git@joshuakgoldberg.com"
+ - git config --global user.name "Josh Goldberg"
+ - npm config set //registry.npmjs.org/:_authToken $NPM_TOKEN
+ - - run: npx release-it --preRelease=beta
+ + uses: JoshuaKGoldberg/release-it-action@v0.2.2
+
+ name: Release
+
+ on:
+ ",
+ },
+ },
+ }
+ `);
+});
diff --git a/src/migrate/index.test.ts b/src/migrate/index.test.ts
deleted file mode 100644
index c13782e55..000000000
--- a/src/migrate/index.test.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-import { describe, expect, it, vi } from "vitest";
-
-import { StatusCodes } from "../shared/codes.js";
-import { RunOrRestoreOptions } from "../shared/runOrRestore.js";
-import { migrate } from "./index.js";
-
-const mockOutro = vi.fn();
-
-vi.mock("../shared/cli/outro.js", () => ({
- get outro() {
- return mockOutro;
- },
-}));
-
-const mockEnsureGitRepository = vi.fn();
-
-vi.mock("../shared/ensureGitRepository.js", () => ({
- get ensureGitRepository() {
- return mockEnsureGitRepository;
- },
-}));
-
-const mockReadOptions = vi.fn();
-
-vi.mock("../shared/options/readOptions.js", () => ({
- get readOptions() {
- return mockReadOptions;
- },
-}));
-
-vi.mock("../shared/runOrRestore.js", () => ({
- async runOrRestore({ run }: RunOrRestoreOptions) {
- await run();
- return StatusCodes.Success;
- },
-}));
-
-const mockMigrateWithOptions = vi.fn();
-
-vi.mock("./migrateWithOptions.js", () => ({
- get migrateWithOptions() {
- return mockMigrateWithOptions;
- },
-}));
-
-const optionsBase = {
- repository: "TestRepository",
-};
-
-describe("migrate", () => {
- it("returns a cancellation code when readOptions cancels", async () => {
- mockReadOptions.mockResolvedValue({
- cancelled: true,
- options: optionsBase,
- });
-
- const result = await migrate([]);
-
- expect(result).toEqual({
- code: StatusCodes.Cancelled,
- options: optionsBase,
- });
- });
-
- it("runs migrateWithOptions when readOptions returns inputs", async () => {
- mockReadOptions.mockResolvedValue({
- cancelled: false,
- options: optionsBase,
- });
-
- const result = await migrate([]);
-
- expect(result).toEqual({
- code: StatusCodes.Success,
- options: optionsBase,
- });
- expect(mockEnsureGitRepository).toHaveBeenCalled();
- expect(mockOutro.mock.calls).toMatchInlineSnapshot(`
- [
- [
- [
- {
- "label": "You may consider committing these changes:",
- "lines": [
- "git add -A",
- "git commit -m "migrated repo to create-typescript-app ✨",
- "git push",
- ],
- "variant": "code",
- },
- {
- "label": "Be sure to:",
- "lines": [
- "- enable the GitHub apps:
- - Codecov (https://github.com/apps/codecov)
- - Renovate (https://github.com/apps/renovate)",
- "- populate the secrets:
- - ACCESS_TOKEN (a GitHub PAT with repo and workflow permissions)
- - NPM_TOKEN (an npm access token with automation permissions)",
- ],
- },
- ],
- ],
- ]
- `);
- });
-});
diff --git a/src/migrate/index.ts b/src/migrate/index.ts
deleted file mode 100644
index 7f4fd02ed..000000000
--- a/src/migrate/index.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { outro } from "../shared/cli/outro.js";
-import { StatusCodes } from "../shared/codes.js";
-import { ensureGitRepository } from "../shared/ensureGitRepository.js";
-import { generateNextSteps } from "../shared/generateNextSteps.js";
-import { readOptions } from "../shared/options/readOptions.js";
-import { runOrRestore } from "../shared/runOrRestore.js";
-import { ModeRunner } from "../shared/types.js";
-import { migrateWithOptions } from "./migrateWithOptions.js";
-
-export const migrate: ModeRunner = async (args) => {
- const inputs = await readOptions(args, "migrate");
- if (inputs.cancelled) {
- return {
- code: StatusCodes.Cancelled,
- error: inputs.error,
- options: inputs.options,
- };
- }
-
- await ensureGitRepository();
-
- return {
- code: await runOrRestore({
- run: async () => {
- await migrateWithOptions(inputs);
-
- outro([
- {
- label: "You may consider committing these changes:",
- lines: [
- `git add -A`,
- `git commit -m "migrated repo to create-typescript-app ✨`,
- `git push`,
- ],
- variant: "code",
- },
- ...generateNextSteps(inputs.options),
- ]);
- },
- skipRestore: inputs.options.skipRestore,
- }),
- options: inputs.options,
- };
-};
diff --git a/src/migrate/migrateWithOptions.test.ts b/src/migrate/migrateWithOptions.test.ts
deleted file mode 100644
index 5215b27a9..000000000
--- a/src/migrate/migrateWithOptions.test.ts
+++ /dev/null
@@ -1,199 +0,0 @@
-import { Octokit } from "octokit";
-import { describe, expect, it, vi } from "vitest";
-
-import { Options } from "../shared/types.js";
-import { migrateWithOptions } from "./migrateWithOptions.js";
-
-vi.mock("../shared/cli/spinners.js", () => ({
- async withSpinner(_label: string, task: () => Promise) {
- await task();
- },
- withSpinners: vi.fn(),
-}));
-
-const mockPopulateAllContributorsForRepository = vi.fn();
-
-vi.mock("populate-all-contributors-for-repository", () => ({
- get populateAllContributorsForRepository() {
- return mockPopulateAllContributorsForRepository;
- },
-}));
-
-const mockFinalizeDependencies = vi.fn();
-
-vi.mock("../steps/finalizeDependencies.js", () => ({
- get finalizeDependencies() {
- return mockFinalizeDependencies;
- },
-}));
-
-const mockInitializeGitHubRepository = vi.fn();
-
-vi.mock("../steps/initializeGitHubRepository/index.js", () => ({
- get initializeGitHubRepository() {
- return mockInitializeGitHubRepository;
- },
-}));
-
-const mockPopulateCSpellDictionary = vi.fn();
-
-vi.mock("../steps/populateCSpellDictionary.js", () => ({
- get populateCSpellDictionary() {
- return mockPopulateCSpellDictionary;
- },
-}));
-
-vi.mock("../steps/runCleanup.js", () => ({
- runCleanup: vi.fn(),
-}));
-
-vi.mock("../shared/cli/spinners.js", () => ({
- async withSpinner(_label: string, task: () => Promise) {
- await task();
- },
- withSpinners: vi.fn(),
-}));
-
-const mockGitHubAndOptions = vi.fn();
-
-vi.mock("../shared/options/readOptions.js", () => ({
- get GitHubAndOptions() {
- return mockGitHubAndOptions;
- },
-}));
-
-const optionsBase = {} as Options;
-
-describe("migrateWithOptions", () => {
- it("runs initializeGitHubRepository when octokit is truthy", async () => {
- const octokit = {} as Octokit;
-
- await migrateWithOptions({
- octokit,
- options: optionsBase,
- });
-
- expect(mockInitializeGitHubRepository).toHaveBeenCalledWith(
- octokit,
- optionsBase,
- );
- });
-
- it("does not run initializeGitHubRepository when github is falsy", async () => {
- const options = {
- ...optionsBase,
- excludeAllContributors: true,
- };
-
- await migrateWithOptions({
- octokit: undefined,
- options,
- });
-
- expect(mockInitializeGitHubRepository).not.toHaveBeenCalled();
- });
-
- it("does not run populateAllContributorsForRepository excludeAllContributors is true", async () => {
- const options = {
- ...optionsBase,
- excludeAllContributors: true,
- skipAllContributorsApi: false,
- };
-
- await migrateWithOptions({
- octokit: undefined,
- options,
- });
-
- expect(mockPopulateAllContributorsForRepository).not.toHaveBeenCalled();
- });
-
- it("does not run populateAllContributorsForRepository skipAllContributorsApi is true", async () => {
- const options = {
- ...optionsBase,
- excludeAllContributors: false,
- skipAllContributorsApi: true,
- };
-
- await migrateWithOptions({
- octokit: undefined,
- options,
- });
-
- expect(mockPopulateAllContributorsForRepository).not.toHaveBeenCalled();
- });
-
- it("runs populateAllContributorsForRepository excludeAllContributors and skipAllContributorsApi are false", async () => {
- const options = {
- ...optionsBase,
- excludeAllContributors: false,
- skipAllContributorsApi: false,
- };
-
- await migrateWithOptions({
- octokit: undefined,
- options,
- });
-
- expect(mockPopulateAllContributorsForRepository).toHaveBeenCalledWith({
- owner: options.owner,
- repo: options.repository,
- });
- });
-
- it("runs finalizeDependencies when skipInstall is false", async () => {
- const options = {
- ...optionsBase,
- skipInstall: false,
- };
-
- await migrateWithOptions({
- octokit: undefined,
- options,
- });
-
- expect(mockFinalizeDependencies).toHaveBeenCalledWith(options);
- });
-
- it("does not run finalizeDependencies when skipInstall is true", async () => {
- const options = {
- ...optionsBase,
- skipInstall: true,
- };
-
- await migrateWithOptions({
- octokit: undefined,
- options,
- });
-
- expect(mockFinalizeDependencies).not.toHaveBeenCalled();
- });
-
- it("runs populateCSpellDictionary when excludeLintSpelling is false", async () => {
- const options = {
- ...optionsBase,
- excludeLintSpelling: false,
- };
-
- await migrateWithOptions({
- octokit: undefined,
- options,
- });
-
- expect(mockPopulateCSpellDictionary).toHaveBeenCalled();
- });
-
- it("does not run populateCSpellDictionary when excludeLintSpelling is true", async () => {
- const options = {
- ...optionsBase,
- excludeLintSpelling: true,
- };
-
- await migrateWithOptions({
- octokit: undefined,
- options,
- });
-
- expect(mockPopulateCSpellDictionary).not.toHaveBeenCalled();
- });
-});
diff --git a/src/migrate/migrateWithOptions.ts b/src/migrate/migrateWithOptions.ts
deleted file mode 100644
index 00ea83c6f..000000000
--- a/src/migrate/migrateWithOptions.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-import { populateAllContributorsForRepository } from "populate-all-contributors-for-repository";
-
-import { withSpinner, withSpinners } from "../shared/cli/spinners.js";
-import { createCleanupCommands } from "../shared/createCleanupCommands.js";
-import { OctokitAndOptions } from "../shared/options/readOptions.js";
-import { clearUnnecessaryFiles } from "../steps/clearUnnecessaryFiles.js";
-import { finalizeDependencies } from "../steps/finalizeDependencies.js";
-import { initializeGitHubRepository } from "../steps/initializeGitHubRepository/index.js";
-import { populateCSpellDictionary } from "../steps/populateCSpellDictionary.js";
-import { runCleanup } from "../steps/runCleanup.js";
-import { updateAllContributorsTable } from "../steps/updateAllContributorsTable.js";
-import { updateLocalFiles } from "../steps/updateLocalFiles.js";
-import { writeReadme } from "../steps/writeReadme/index.js";
-import { writeStructure } from "../steps/writing/writeStructure.js";
-
-export async function migrateWithOptions({
- octokit,
- options,
-}: OctokitAndOptions) {
- await withSpinners("Migrating repository structure", [
- ["Clearing unnecessary files", clearUnnecessaryFiles],
- [
- "Writing structure",
- async () => {
- await writeStructure(options);
- },
- ],
- [
- "Writing README.md",
- async () => {
- await writeReadme(options);
- },
- ],
- [
- "Updating local files",
- async () => {
- await updateLocalFiles(options);
- },
- ],
- [
- "Updating all-contributors table",
- async () => {
- await updateAllContributorsTable(options);
- },
- ],
- ]);
-
- if (octokit) {
- await withSpinner("Initializing GitHub repository", async () => {
- await initializeGitHubRepository(octokit, options);
- });
- }
-
- if (!options.excludeAllContributors && !options.skipAllContributorsApi) {
- await withSpinner("Detecting existing contributors", async () =>
- populateAllContributorsForRepository({
- owner: options.owner,
- repo: options.repository,
- }),
- );
- }
-
- if (!options.skipInstall) {
- await withSpinner("Installing packages", async () =>
- finalizeDependencies(options),
- );
- }
-
- if (!options.excludeLintSpelling) {
- await withSpinner("Populating CSpell dictionary", populateCSpellDictionary);
- }
-
- await runCleanup(createCleanupCommands(options.bin), options.mode);
-}
diff --git a/src/next/blocks/index.ts b/src/next/blocks/index.ts
deleted file mode 100644
index 26d79f044..000000000
--- a/src/next/blocks/index.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-export * from "./blockAllContributors.js";
-export * from "./blockAreTheTypesWrong.js";
-export * from "./blockContributingDocs.js";
-export * from "./blockContributorCovenant.js";
-export * from "./blockCSpell.js";
-export * from "./blockDevelopmentDocs.js";
-export * from "./blockESLint.js";
-export * from "./blockESLintComments.js";
-export * from "./blockESLintJSDoc.js";
-export * from "./blockESLintJSONC.js";
-export * from "./blockESLintMarkdown.js";
-export * from "./blockESLintMoreStyling.js";
-export * from "./blockESLintNode.js";
-export * from "./blockESLintPackageJson.js";
-export * from "./blockESLintPerfectionist.js";
-export * from "./blockESLintRegexp.js";
-export * from "./blockESLintYML.js";
-export * from "./blockFunding.js";
-export * from "./blockGitHubActionsCI.js";
-export * from "./blockGitHubIssueTemplates.js";
-export * from "./blockGitHubPRTemplate.js";
-export * from "./blockGitignore.js";
-export * from "./blockKnip.js";
-export * from "./blockMarkdownlint.js";
-export * from "./blockMITLicense.js";
-export * from "./blockNvmrc.js";
-export * from "./blockPackageJson.js";
-export * from "./blockPnpmDedupe.js";
-export * from "./blockPRCompliance.js";
-export * from "./blockPrettier.js";
-export * from "./blockPrettierPluginCurly.js";
-export * from "./blockPrettierPluginPackageJson.js";
-export * from "./blockPrettierPluginSh.js";
-export * from "./blockREADME.js";
-export * from "./blockReleaseIt.js";
-export * from "./blockRenovate.js";
-export * from "./blockSecurityDocs.js";
-export * from "./blockTemplatedBy.js";
-export * from "./blockTSup.js";
-export * from "./blockTypeScript.js";
-export * from "./blockVitest.js";
-export * from "./blockVSCode.js";
diff --git a/src/next/blocks/sourcePackageJson.ts b/src/next/blocks/sourcePackageJson.ts
deleted file mode 100644
index 75867f05d..000000000
--- a/src/next/blocks/sourcePackageJson.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { createRequire } from "node:module";
-
-const require = createRequire(import.meta.url);
-
-export const sourcePackageJson =
- // Importing from above src/ would expand the TS build rootDir
- require("../../../package.json") as typeof import("../../../package.json");
diff --git a/src/next/presets/index.ts b/src/next/presets/index.ts
deleted file mode 100644
index d995968ea..000000000
--- a/src/next/presets/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from "./presetCommon.js";
-export * from "./presetEverything.js";
-export * from "./presetMinimal.js";
diff --git a/src/next/runCreateEnginePreset.ts b/src/next/runCreateEnginePreset.ts
deleted file mode 100644
index 30196a235..000000000
--- a/src/next/runCreateEnginePreset.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { runPreset } from "create";
-
-import { Options } from "../shared/types.js";
-import { presetCommon } from "./presets/presetCommon.js";
-import { presetEverything } from "./presets/presetEverything.js";
-import { presetMinimal } from "./presets/presetMinimal.js";
-
-const presets = {
- common: presetCommon,
- everything: presetEverything,
- minimal: presetMinimal,
-};
-
-export async function runCreateEnginePreset(options: Options) {
- const preset =
- options.base && options.base !== "prompt" && presets[options.base];
-
- if (!preset) {
- throw new Error(`Cannot yet use create engine with base ${options.base}.`);
- }
-
- await runPreset(preset, { mode: "initialize", options });
-}
diff --git a/src/shared/options/createOptionDefaults/getUsageFromReadme.test.ts b/src/options/getUsageFromReadme.test.ts
similarity index 100%
rename from src/shared/options/createOptionDefaults/getUsageFromReadme.test.ts
rename to src/options/getUsageFromReadme.test.ts
diff --git a/src/shared/options/createOptionDefaults/getUsageFromReadme.ts b/src/options/getUsageFromReadme.ts
similarity index 100%
rename from src/shared/options/createOptionDefaults/getUsageFromReadme.ts
rename to src/options/getUsageFromReadme.ts
diff --git a/src/shared/options/createOptionDefaults/parsePackageAuthor.test.ts b/src/options/parsePackageAuthor.test.ts
similarity index 100%
rename from src/shared/options/createOptionDefaults/parsePackageAuthor.test.ts
rename to src/options/parsePackageAuthor.test.ts
diff --git a/src/shared/options/createOptionDefaults/parsePackageAuthor.ts b/src/options/parsePackageAuthor.ts
similarity index 91%
rename from src/shared/options/createOptionDefaults/parsePackageAuthor.ts
rename to src/options/parsePackageAuthor.ts
index 5fa833d19..b7ffd000a 100644
--- a/src/shared/options/createOptionDefaults/parsePackageAuthor.ts
+++ b/src/options/parsePackageAuthor.ts
@@ -1,6 +1,6 @@
import parse from "parse-author";
-import { PartialPackageData } from "../../types.js";
+import { PartialPackageData } from "../types.js";
export function parsePackageAuthor(packageData: PartialPackageData) {
let packageAuthor: string | undefined;
diff --git a/src/shared/options/createOptionDefaults/readDefaultsFromReadme.test.ts b/src/options/readDefaultsFromReadme.test.ts
similarity index 99%
rename from src/shared/options/createOptionDefaults/readDefaultsFromReadme.test.ts
rename to src/options/readDefaultsFromReadme.test.ts
index 5fac317dc..e874fcd82 100644
--- a/src/shared/options/createOptionDefaults/readDefaultsFromReadme.test.ts
+++ b/src/options/readDefaultsFromReadme.test.ts
@@ -4,7 +4,7 @@ import { readDefaultsFromReadme } from "./readDefaultsFromReadme.js";
const mockReadLogoSizing = vi.fn().mockResolvedValue({});
-vi.mock("../readLogoSizing.js", () => ({
+vi.mock("./readLogoSizing.js", () => ({
get readLogoSizing() {
return mockReadLogoSizing;
},
diff --git a/src/shared/options/createOptionDefaults/readDefaultsFromReadme.ts b/src/options/readDefaultsFromReadme.ts
similarity index 97%
rename from src/shared/options/createOptionDefaults/readDefaultsFromReadme.ts
rename to src/options/readDefaultsFromReadme.ts
index b6f6c7d80..350b4b525 100644
--- a/src/shared/options/createOptionDefaults/readDefaultsFromReadme.ts
+++ b/src/options/readDefaultsFromReadme.ts
@@ -1,8 +1,8 @@
import lazyValue from "lazy-value";
import { titleCase } from "title-case";
-import { readLogoSizing } from "../readLogoSizing.js";
import { getUsageFromReadme } from "./getUsageFromReadme.js";
+import { readLogoSizing } from "./readLogoSizing.js";
export function readDefaultsFromReadme(
readme: () => Promise,
diff --git a/src/next/readDescription.test.ts b/src/options/readDescription.test.ts
similarity index 79%
rename from src/next/readDescription.test.ts
rename to src/options/readDescription.test.ts
index 8f44f250a..0fb5da8e5 100644
--- a/src/next/readDescription.test.ts
+++ b/src/options/readDescription.test.ts
@@ -2,12 +2,12 @@ import { describe, expect, it, vi } from "vitest";
import { readDescription } from "./readDescription.js";
-const mockSourcePackageJson = vi.fn<() => string>();
+const mockPackageDataDescription = vi.fn<() => string>();
-vi.mock("./blocks/sourcePackageJson", () => ({
- sourcePackageJson: {
+vi.mock("../data/packageData.js", () => ({
+ packageData: {
get description() {
- return mockSourcePackageJson();
+ return mockPackageDataDescription();
},
},
}));
@@ -16,7 +16,7 @@ describe("readDescription", () => {
it("returns undefined when the description matches the current package.json description", async () => {
const existing = "Same description.";
- mockSourcePackageJson.mockReturnValueOnce(existing);
+ mockPackageDataDescription.mockReturnValueOnce(existing);
const description = await readDescription(
() => Promise.resolve({ description: existing }),
@@ -29,7 +29,7 @@ describe("readDescription", () => {
it("returns the updated description when neither description nor name match the current package.json", async () => {
const updated = "Updated description.";
- mockSourcePackageJson.mockReturnValueOnce("Existing description");
+ mockPackageDataDescription.mockReturnValueOnce("Existing description");
const description = await readDescription(
() => Promise.resolve({ description: updated }),
@@ -43,7 +43,7 @@ describe("readDescription", () => {
const plaintext = "Updated description.";
const encoded = "Updated description
.";
- mockSourcePackageJson.mockReturnValueOnce("Existing description");
+ mockPackageDataDescription.mockReturnValueOnce("Existing description");
const description = await readDescription(
() => Promise.resolve({ description: plaintext }),
@@ -57,7 +57,7 @@ describe("readDescription", () => {
const plaintext = "Updated description.";
const encoded = "Incorrect description
.";
- mockSourcePackageJson.mockReturnValueOnce("Existing description");
+ mockPackageDataDescription.mockReturnValueOnce("Existing description");
const description = await readDescription(
() => Promise.resolve({ description: plaintext }),
diff --git a/src/next/readDescription.ts b/src/options/readDescription.ts
similarity index 74%
rename from src/next/readDescription.ts
rename to src/options/readDescription.ts
index 5caa5c53e..ced7370e6 100644
--- a/src/next/readDescription.ts
+++ b/src/options/readDescription.ts
@@ -1,5 +1,5 @@
-import { PartialPackageData } from "../shared/types.js";
-import { sourcePackageJson } from "./blocks/sourcePackageJson.js";
+import { packageData } from "../data/packageData.js";
+import { PartialPackageData } from "../types.js";
import { readDescriptionFromReadme } from "./readDescriptionFromReadme.js";
export async function readDescription(
@@ -11,7 +11,7 @@ export async function readDescription(
return undefined;
}
- const { description: existing } = sourcePackageJson;
+ const { description: existing } = packageData;
const fromReadme = await readDescriptionFromReadme(getReadme);
if (fromReadme?.replaceAll(/<\s*(?:\/\s*)?\w+\s*>/gu, "") === inferred) {
diff --git a/src/next/readDescriptionFromReadme.test.ts b/src/options/readDescriptionFromReadme.test.ts
similarity index 100%
rename from src/next/readDescriptionFromReadme.test.ts
rename to src/options/readDescriptionFromReadme.test.ts
diff --git a/src/next/readDescriptionFromReadme.ts b/src/options/readDescriptionFromReadme.ts
similarity index 100%
rename from src/next/readDescriptionFromReadme.ts
rename to src/options/readDescriptionFromReadme.ts
diff --git a/src/next/readDocumentation.test.ts b/src/options/readDocumentation.test.ts
similarity index 100%
rename from src/next/readDocumentation.test.ts
rename to src/options/readDocumentation.test.ts
diff --git a/src/next/readDocumentation.ts b/src/options/readDocumentation.ts
similarity index 92%
rename from src/next/readDocumentation.ts
rename to src/options/readDocumentation.ts
index 5fd0d0be9..e2cac2c4d 100644
--- a/src/next/readDocumentation.ts
+++ b/src/options/readDocumentation.ts
@@ -1,7 +1,7 @@
import { TakeInput } from "create";
import { inputFromFile } from "input-from-file";
-import { swallowError } from "./utils/swallowError.js";
+import { swallowError } from "../utils/swallowError.js";
const knownHeadings = new Set([
"building",
diff --git a/src/shared/options/createOptionDefaults/readEmails.ts b/src/options/readEmails.ts
similarity index 91%
rename from src/shared/options/createOptionDefaults/readEmails.ts
rename to src/options/readEmails.ts
index d26579e98..0fa4af380 100644
--- a/src/shared/options/createOptionDefaults/readEmails.ts
+++ b/src/options/readEmails.ts
@@ -1,7 +1,7 @@
import { $ } from "execa";
import { UserInfo } from "npm-user";
-import { tryCatchAsync } from "../../tryCatchAsync.js";
+import { tryCatchAsync } from "../utils/tryCatchAsync.js";
import { readGitHubEmail } from "./readGitHubEmail.js";
export async function readEmails(
diff --git a/src/shared/readFileAsJson.test.ts b/src/options/readFileAsJson.test.ts
similarity index 100%
rename from src/shared/readFileAsJson.test.ts
rename to src/options/readFileAsJson.test.ts
diff --git a/src/shared/readFileAsJson.ts b/src/options/readFileAsJson.ts
similarity index 100%
rename from src/shared/readFileAsJson.ts
rename to src/options/readFileAsJson.ts
diff --git a/src/shared/readFileSafe.test.ts b/src/options/readFileSafe.test.ts
similarity index 100%
rename from src/shared/readFileSafe.test.ts
rename to src/options/readFileSafe.test.ts
diff --git a/src/shared/readFileSafe.ts b/src/options/readFileSafe.ts
similarity index 100%
rename from src/shared/readFileSafe.ts
rename to src/options/readFileSafe.ts
diff --git a/src/shared/options/createOptionDefaults/readFunding.ts b/src/options/readFunding.ts
similarity index 77%
rename from src/shared/options/createOptionDefaults/readFunding.ts
rename to src/options/readFunding.ts
index 7de124697..9d78ab08c 100644
--- a/src/shared/options/createOptionDefaults/readFunding.ts
+++ b/src/options/readFunding.ts
@@ -1,6 +1,6 @@
import fs from "node:fs/promises";
-import { tryCatchAsync } from "../../tryCatchAsync.js";
+import { tryCatchAsync } from "../utils/tryCatchAsync.js";
export async function readFunding() {
return await tryCatchAsync(async () =>
diff --git a/src/shared/options/createOptionDefaults/readGitHubEmail.test.ts b/src/options/readGitHubEmail.test.ts
similarity index 96%
rename from src/shared/options/createOptionDefaults/readGitHubEmail.test.ts
rename to src/options/readGitHubEmail.test.ts
index f472abeb1..a001e7667 100644
--- a/src/shared/options/createOptionDefaults/readGitHubEmail.test.ts
+++ b/src/options/readGitHubEmail.test.ts
@@ -4,7 +4,7 @@ import { readGitHubEmail } from "./readGitHubEmail.js";
const mockReadFileSafe = vi.fn();
-vi.mock("../../readFileSafe.js", () => ({
+vi.mock("./readFileSafe.js", () => ({
get readFileSafe() {
return mockReadFileSafe;
},
diff --git a/src/shared/options/createOptionDefaults/readGitHubEmail.ts b/src/options/readGitHubEmail.ts
similarity index 88%
rename from src/shared/options/createOptionDefaults/readGitHubEmail.ts
rename to src/options/readGitHubEmail.ts
index ea52beacb..884274e4a 100644
--- a/src/shared/options/createOptionDefaults/readGitHubEmail.ts
+++ b/src/options/readGitHubEmail.ts
@@ -1,4 +1,4 @@
-import { readFileSafe } from "../../readFileSafe.js";
+import { readFileSafe } from "./readFileSafe.js";
export async function readGitHubEmail() {
// The create-typescript-app template puts the GitHub email in the CoC.
diff --git a/src/shared/options/createOptionDefaults/readGuide.test.ts b/src/options/readGuide.test.ts
similarity index 96%
rename from src/shared/options/createOptionDefaults/readGuide.test.ts
rename to src/options/readGuide.test.ts
index 9a438babc..d0fcdb761 100644
--- a/src/shared/options/createOptionDefaults/readGuide.test.ts
+++ b/src/options/readGuide.test.ts
@@ -4,7 +4,7 @@ import { readGuide } from "./readGuide.js";
const mockReadFileSafe = vi.fn();
-vi.mock("../../readFileSafe.js", () => ({
+vi.mock("./readFileSafe.js", () => ({
get readFileSafe() {
return mockReadFileSafe;
},
diff --git a/src/shared/options/createOptionDefaults/readGuide.ts b/src/options/readGuide.ts
similarity index 84%
rename from src/shared/options/createOptionDefaults/readGuide.ts
rename to src/options/readGuide.ts
index dbbf6ad03..05c44904f 100644
--- a/src/shared/options/createOptionDefaults/readGuide.ts
+++ b/src/options/readGuide.ts
@@ -1,4 +1,4 @@
-import { readFileSafe } from "../../readFileSafe.js";
+import { readFileSafe } from "./readFileSafe.js";
export async function readGuide() {
const development = await readFileSafe(".github/DEVELOPMENT.md", "");
diff --git a/src/shared/options/readLogoSizing.test.ts b/src/options/readLogoSizing.test.ts
similarity index 100%
rename from src/shared/options/readLogoSizing.test.ts
rename to src/options/readLogoSizing.test.ts
diff --git a/src/shared/options/readLogoSizing.ts b/src/options/readLogoSizing.ts
similarity index 100%
rename from src/shared/options/readLogoSizing.ts
rename to src/options/readLogoSizing.ts
diff --git a/src/options/readPackageData.ts b/src/options/readPackageData.ts
new file mode 100644
index 000000000..359c70a31
--- /dev/null
+++ b/src/options/readPackageData.ts
@@ -0,0 +1,10 @@
+import { PartialPackageData } from "../types.js";
+import { readFileSafe } from "./readFileSafe.js";
+
+export async function readPackageData() {
+ return (
+ (JSON.parse(await readFileSafe("./package.json", "{}")) as
+ | PartialPackageData
+ | undefined) ?? {}
+ );
+}
diff --git a/src/next/presets/presetCommon.ts b/src/presets/common.ts
similarity index 82%
rename from src/next/presets/presetCommon.ts
rename to src/presets/common.ts
index fa0e03ef6..d499d04f5 100644
--- a/src/next/presets/presetCommon.ts
+++ b/src/presets/common.ts
@@ -1,9 +1,10 @@
import { base } from "../base.js";
import { blockAllContributors } from "../blocks/blockAllContributors.js";
import { blockCodecov } from "../blocks/blockCodecov.js";
+import { blockFunding } from "../blocks/blockFunding.js";
import { blockReleaseIt } from "../blocks/blockReleaseIt.js";
import { blockVitest } from "../blocks/blockVitest.js";
-import { presetMinimal } from "./presetMinimal.js";
+import { presetMinimal } from "./minimal.js";
export const presetCommon = base.createPreset({
about: {
@@ -15,6 +16,7 @@ export const presetCommon = base.createPreset({
...presetMinimal.blocks,
blockAllContributors,
blockCodecov,
+ blockFunding,
blockReleaseIt,
blockVitest,
],
diff --git a/src/next/presets/presetEverything.ts b/src/presets/everything.ts
similarity index 93%
rename from src/next/presets/presetEverything.ts
rename to src/presets/everything.ts
index 557dce519..d5317f1fc 100644
--- a/src/next/presets/presetEverything.ts
+++ b/src/presets/everything.ts
@@ -19,9 +19,8 @@ import { blockPrettierPluginCurly } from "../blocks/blockPrettierPluginCurly.js"
import { blockPrettierPluginPackageJson } from "../blocks/blockPrettierPluginPackageJson.js";
import { blockPrettierPluginSh } from "../blocks/blockPrettierPluginSh.js";
import { blockRenovate } from "../blocks/blockRenovate.js";
-import { blockSecurityDocs } from "../blocks/blockSecurityDocs.js";
import { blockVSCode } from "../blocks/blockVSCode.js";
-import { presetCommon } from "../presets/presetCommon.js";
+import { presetCommon } from "./common.js";
export const presetEverything = base.createPreset({
about: {
@@ -51,7 +50,6 @@ export const presetEverything = base.createPreset({
blockPrettierPluginPackageJson,
blockPrettierPluginSh,
blockRenovate,
- blockSecurityDocs,
blockVSCode,
],
});
diff --git a/src/presets/index.ts b/src/presets/index.ts
new file mode 100644
index 000000000..5b140abdb
--- /dev/null
+++ b/src/presets/index.ts
@@ -0,0 +1,13 @@
+import { presetCommon } from "./common.js";
+import { presetEverything } from "./everything.js";
+import { presetMinimal } from "./minimal.js";
+
+export const presets = {
+ common: presetCommon,
+ everything: presetEverything,
+ minimal: presetMinimal,
+};
+
+export { presetCommon } from "./common.js";
+export { presetEverything } from "./everything.js";
+export { presetMinimal } from "./minimal.js";
diff --git a/src/next/presets/presetMinimal.ts b/src/presets/minimal.ts
similarity index 91%
rename from src/next/presets/presetMinimal.ts
rename to src/presets/minimal.ts
index 587f9ea0b..2106bd10a 100644
--- a/src/next/presets/presetMinimal.ts
+++ b/src/presets/minimal.ts
@@ -4,7 +4,6 @@ import { blockContributorCovenant } from "../blocks/blockContributorCovenant.js"
import { blockDevelopmentDocs } from "../blocks/blockDevelopmentDocs.js";
import { blockESLint } from "../blocks/blockESLint.js";
import { blockExampleFiles } from "../blocks/blockExampleFiles.js";
-import { blockFunding } from "../blocks/blockFunding.js";
import { blockGitHubActionsCI } from "../blocks/blockGitHubActionsCI.js";
import { blockGitHubApps } from "../blocks/blockGitHubApps.js";
import { blockGitHubIssueTemplates } from "../blocks/blockGitHubIssueTemplates.js";
@@ -18,7 +17,8 @@ import { blockRepositoryBranchRuleset } from "../blocks/blockRepositoryBranchRul
import { blockRepositoryLabels } from "../blocks/blockRepositoryLabels.js";
import { blockRepositorySecrets } from "../blocks/blockRepositorySecrets.js";
import { blockRepositorySettings } from "../blocks/blockRepositorySettings.js";
-import { blockTemplatedBy } from "../blocks/blockTemplatedBy.js";
+import { blockSecurityDocs } from "../blocks/blockSecurityDocs.js";
+import { blockTemplatedWith } from "../blocks/blockTemplatedWith.js";
import { blockTSup } from "../blocks/blockTSup.js";
import { blockTypeScript } from "../blocks/blockTypeScript.js";
@@ -34,7 +34,6 @@ export const presetMinimal = base.createPreset({
blockDevelopmentDocs,
blockESLint,
blockExampleFiles,
- blockFunding,
blockGitHubActionsCI,
blockGitHubApps,
blockGitHubIssueTemplates,
@@ -48,7 +47,8 @@ export const presetMinimal = base.createPreset({
blockRepositoryLabels,
blockRepositorySecrets,
blockRepositorySettings,
- blockTemplatedBy,
+ blockSecurityDocs,
+ blockTemplatedWith,
blockTSup,
blockTypeScript,
],
diff --git a/src/shared/__snapshots__/generateNextSteps.test.ts.snap b/src/shared/__snapshots__/generateNextSteps.test.ts.snap
deleted file mode 100644
index df9a0ec6e..000000000
--- a/src/shared/__snapshots__/generateNextSteps.test.ts.snap
+++ /dev/null
@@ -1,183 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`generateNextSteps > {"excludeAllContributors":false,"excludeReleases":false,"excludeRenovate":false,"excludeTests":false} 1`] = `
-[
- {
- "label": "Be sure to:",
- "lines": [
- "- enable the GitHub apps:
- - Codecov (https://github.com/apps/codecov)
- - Renovate (https://github.com/apps/renovate)",
- "- populate the secrets:
- - ACCESS_TOKEN (a GitHub PAT with repo and workflow permissions)
- - NPM_TOKEN (an npm access token with automation permissions)",
- ],
- },
-]
-`;
-
-exports[`generateNextSteps > {"excludeAllContributors":false,"excludeReleases":false,"excludeRenovate":false,"excludeTests":true} 1`] = `
-[
- {
- "label": "Be sure to:",
- "lines": [
- "- enable the Renovate GitHub app (https://github.com/apps/renovate).",
- "- populate the secrets:
- - ACCESS_TOKEN (a GitHub PAT with repo and workflow permissions)
- - NPM_TOKEN (an npm access token with automation permissions)",
- ],
- },
-]
-`;
-
-exports[`generateNextSteps > {"excludeAllContributors":false,"excludeReleases":false,"excludeRenovate":true,"excludeTests":false} 1`] = `
-[
- {
- "label": "Be sure to:",
- "lines": [
- "- enable the Codecov GitHub app (https://github.com/apps/codecov).",
- "- populate the secrets:
- - ACCESS_TOKEN (a GitHub PAT with repo and workflow permissions)
- - NPM_TOKEN (an npm access token with automation permissions)",
- ],
- },
-]
-`;
-
-exports[`generateNextSteps > {"excludeAllContributors":false,"excludeReleases":false,"excludeRenovate":true,"excludeTests":true} 1`] = `
-[
- {
- "label": "Be sure to populate the secrets:
- - ACCESS_TOKEN (a GitHub PAT with repo and workflow permissions)
- - NPM_TOKEN (an npm access token with automation permissions)",
- },
-]
-`;
-
-exports[`generateNextSteps > {"excludeAllContributors":false,"excludeReleases":true,"excludeRenovate":false,"excludeTests":false} 1`] = `
-[
- {
- "label": "Be sure to:",
- "lines": [
- "- enable the GitHub apps:
- - Codecov (https://github.com/apps/codecov)
- - Renovate (https://github.com/apps/renovate)",
- "- populate the ACCESS_TOKEN secret (a GitHub PAT with repo and workflow permissions).",
- ],
- },
-]
-`;
-
-exports[`generateNextSteps > {"excludeAllContributors":false,"excludeReleases":true,"excludeRenovate":false,"excludeTests":true} 1`] = `
-[
- {
- "label": "Be sure to:",
- "lines": [
- "- enable the Renovate GitHub app (https://github.com/apps/renovate).",
- "- populate the ACCESS_TOKEN secret (a GitHub PAT with repo and workflow permissions).",
- ],
- },
-]
-`;
-
-exports[`generateNextSteps > {"excludeAllContributors":false,"excludeReleases":true,"excludeRenovate":true,"excludeTests":false} 1`] = `
-[
- {
- "label": "Be sure to:",
- "lines": [
- "- enable the Codecov GitHub app (https://github.com/apps/codecov).",
- "- populate the ACCESS_TOKEN secret (a GitHub PAT with repo and workflow permissions).",
- ],
- },
-]
-`;
-
-exports[`generateNextSteps > {"excludeAllContributors":false,"excludeReleases":true,"excludeRenovate":true,"excludeTests":true} 1`] = `
-[
- {
- "label": "Be sure to populate the ACCESS_TOKEN secret (a GitHub PAT with repo and workflow permissions).",
- },
-]
-`;
-
-exports[`generateNextSteps > {"excludeAllContributors":true,"excludeReleases":false,"excludeRenovate":false,"excludeTests":false} 1`] = `
-[
- {
- "label": "Be sure to:",
- "lines": [
- "- enable the GitHub apps:
- - Codecov (https://github.com/apps/codecov)
- - Renovate (https://github.com/apps/renovate)",
- "- populate the secrets:
- - ACCESS_TOKEN (a GitHub PAT with repo and workflow permissions)
- - NPM_TOKEN (an npm access token with automation permissions)",
- ],
- },
-]
-`;
-
-exports[`generateNextSteps > {"excludeAllContributors":true,"excludeReleases":false,"excludeRenovate":false,"excludeTests":true} 1`] = `
-[
- {
- "label": "Be sure to:",
- "lines": [
- "- enable the Renovate GitHub app (https://github.com/apps/renovate).",
- "- populate the secrets:
- - ACCESS_TOKEN (a GitHub PAT with repo and workflow permissions)
- - NPM_TOKEN (an npm access token with automation permissions)",
- ],
- },
-]
-`;
-
-exports[`generateNextSteps > {"excludeAllContributors":true,"excludeReleases":false,"excludeRenovate":true,"excludeTests":false} 1`] = `
-[
- {
- "label": "Be sure to:",
- "lines": [
- "- enable the Codecov GitHub app (https://github.com/apps/codecov).",
- "- populate the secrets:
- - ACCESS_TOKEN (a GitHub PAT with repo and workflow permissions)
- - NPM_TOKEN (an npm access token with automation permissions)",
- ],
- },
-]
-`;
-
-exports[`generateNextSteps > {"excludeAllContributors":true,"excludeReleases":false,"excludeRenovate":true,"excludeTests":true} 1`] = `
-[
- {
- "label": "Be sure to populate the secrets:
- - ACCESS_TOKEN (a GitHub PAT with repo and workflow permissions)
- - NPM_TOKEN (an npm access token with automation permissions)",
- },
-]
-`;
-
-exports[`generateNextSteps > {"excludeAllContributors":true,"excludeReleases":true,"excludeRenovate":false,"excludeTests":false} 1`] = `
-[
- {
- "label": "Be sure to enable the GitHub apps:
- - Codecov (https://github.com/apps/codecov)
- - Renovate (https://github.com/apps/renovate)",
- },
-]
-`;
-
-exports[`generateNextSteps > {"excludeAllContributors":true,"excludeReleases":true,"excludeRenovate":false,"excludeTests":true} 1`] = `
-[
- {
- "label": "Be sure to enable the Renovate GitHub app (https://github.com/apps/renovate).",
- },
-]
-`;
-
-exports[`generateNextSteps > {"excludeAllContributors":true,"excludeReleases":true,"excludeRenovate":true,"excludeTests":false} 1`] = `
-[
- {
- "label": "Be sure to enable the Codecov GitHub app (https://github.com/apps/codecov).",
- },
-]
-`;
-
-exports[`generateNextSteps > {"excludeAllContributors":true,"excludeReleases":true,"excludeRenovate":true,"excludeTests":true} 1`] = `[]`;
diff --git a/src/shared/cli/lines.ts b/src/shared/cli/lines.ts
deleted file mode 100644
index d1075ad4c..000000000
--- a/src/shared/cli/lines.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import chalk from "chalk";
-
-export function logLine(line?: string) {
- console.log(makeLine(line));
-}
-
-export function logNewSection(line: string) {
- logLine();
- console.log(`◇ ${line}`);
-}
-
-export function makeLine(line: string | undefined) {
- return [chalk.gray("│"), line].filter(Boolean).join(" ");
-}
diff --git a/src/shared/cli/lowerFirst.ts b/src/shared/cli/lowerFirst.ts
deleted file mode 100644
index 3b96e98f2..000000000
--- a/src/shared/cli/lowerFirst.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export function lowerFirst(text: string) {
- return text[0].toLowerCase() + text.slice(1);
-}
diff --git a/src/shared/cli/outro.test.ts b/src/shared/cli/outro.test.ts
deleted file mode 100644
index 9f228a5ab..000000000
--- a/src/shared/cli/outro.test.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import chalk from "chalk";
-import { beforeEach, describe, expect, it, MockInstance, vi } from "vitest";
-
-import { outro } from "./outro.js";
-
-const mockOutro = vi.fn();
-
-vi.mock("@clack/prompts", () => ({
- get outro() {
- return mockOutro;
- },
-}));
-
-let mockConsoleLog: MockInstance;
-
-describe("outro", () => {
- beforeEach(() => {
- mockConsoleLog = vi
- .spyOn(console, "log")
- .mockImplementation(() => undefined);
- });
-
- it("logs only basic statements when no lines are provided", () => {
- outro([{ label: "Abc 123" }]);
-
- expect(mockConsoleLog.mock.calls).toEqual([
- [chalk.blue("Abc 123")],
- [],
- [chalk.greenBright(`See ya! 👋`)],
- [],
- ]);
- });
-
- it("also logs lines when provided", () => {
- outro([{ label: "Abc 123", lines: ["one", "two"] }]);
-
- expect(mockConsoleLog.mock.calls).toEqual([
- [chalk.blue("Abc 123")],
- [],
- ["one"],
- ["two"],
- [],
- [chalk.greenBright(`See ya! 👋`)],
- [],
- ]);
- });
-
- it("logs lines as code when variant is specified", () => {
- outro([{ label: "Abc 123", lines: ["one", "two"], variant: "code" }]);
-
- expect(mockConsoleLog.mock.calls).toEqual([
- [chalk.blue("Abc 123")],
- [],
- [chalk.gray("one")],
- [chalk.gray("two")],
- [],
- [chalk.greenBright(`See ya! 👋`)],
- [],
- ]);
- });
-});
diff --git a/src/shared/cli/outro.ts b/src/shared/cli/outro.ts
deleted file mode 100644
index 444891de1..000000000
--- a/src/shared/cli/outro.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import * as prompts from "@clack/prompts";
-import chalk from "chalk";
-
-export interface OutroGroup {
- label: string;
- lines?: string[];
- variant?: "code";
-}
-
-export function outro(groups: OutroGroup[]) {
- prompts.outro(chalk.blue(`Great, looks like the script finished! 🎉`));
-
- for (const { label, lines, variant } of groups) {
- console.log(chalk.blue(label));
- console.log();
-
- if (lines) {
- for (const line of lines) {
- console.log(variant === "code" ? chalk.gray(line) : line);
- }
-
- console.log();
- }
- }
-
- console.log(chalk.greenBright(`See ya! 👋`));
- console.log();
-}
diff --git a/src/shared/cli/spinners.ts b/src/shared/cli/spinners.ts
deleted file mode 100644
index 00a271f86..000000000
--- a/src/shared/cli/spinners.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-import * as prompts from "@clack/prompts";
-import chalk from "chalk";
-import readline from "readline";
-
-import { logLine, logNewSection, makeLine } from "./lines.js";
-import { lowerFirst } from "./lowerFirst.js";
-import { startLineWithDots } from "./startLineWithDots.js";
-
-const s = prompts.spinner();
-
-export type LabeledSpinnerTask = [string, SpinnerTask];
-
-export type SpinnerTask = () => Promise;
-
-export async function withSpinner(
- label: string,
- task: SpinnerTask,
-) {
- s.start(`${label}...`);
-
- try {
- const result = await task();
-
- s.stop(chalk.green(`✅ Passed ${lowerFirst(label)}.`));
-
- return result;
- } catch (error) {
- s.stop(chalk.red(`❌ Error ${lowerFirst(label)}.`));
-
- throw new Error(`Failed ${lowerFirst(label)}`, { cause: error });
- }
-}
-
-export async function withSpinners(
- label: string,
- tasks: LabeledSpinnerTask[],
-) {
- logNewSection(`${label}...`);
-
- let currentLabel!: string;
- let lastLogged!: string;
-
- for (const [label, run] of tasks) {
- currentLabel = label;
-
- const line = makeLine(chalk.gray(` - ${label}`));
- const stopWriting = startLineWithDots(line);
-
- try {
- await run();
- } catch (error) {
- const descriptor = `${lowerFirst(label)} > ${lowerFirst(currentLabel)}`;
-
- logLine(chalk.red(`❌ Error ${descriptor}.`));
-
- throw new Error(`Failed ${descriptor}`, { cause: error });
- } finally {
- const lineLength = stopWriting();
- readline.clearLine(process.stdout, -1);
- readline.moveCursor(process.stdout, -lineLength, 0);
- }
-
- lastLogged = chalk.gray(`${line} ✔️\n`);
-
- process.stdout.write(lastLogged);
- }
-
- readline.moveCursor(process.stdout, -lastLogged.length, -tasks.length - 2);
- readline.clearScreenDown(process.stdout);
-
- logNewSection(chalk.green(`✅ Passed ${lowerFirst(label)}.`));
-}
diff --git a/src/shared/cli/startLineWithDots.ts b/src/shared/cli/startLineWithDots.ts
deleted file mode 100644
index e80378160..000000000
--- a/src/shared/cli/startLineWithDots.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import readline from "readline";
-
-export function startLineWithDots(line: string) {
- const timer = [setTimeout(tick, 500)];
- let dots = 0;
- let lastLogged!: string;
-
- function clearLine() {
- readline.clearLine(process.stdout, -1);
- readline.moveCursor(process.stdout, -lastLogged.length, 0);
- }
-
- function writeLine() {
- dots = (dots + 1) % 4;
-
- const toLog = `${line}${".".repeat(dots)}`;
-
- process.stdout.write(toLog);
-
- lastLogged = toLog;
-
- return toLog;
- }
-
- function tick() {
- clearLine();
- writeLine();
- timer[0] = setTimeout(tick, 500);
- }
-
- writeLine();
-
- return () => {
- clearLine();
- clearInterval(timer[0]);
- return lastLogged.length;
- };
-}
diff --git a/src/shared/codes.ts b/src/shared/codes.ts
deleted file mode 100644
index 89b39571e..000000000
--- a/src/shared/codes.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-export const StatusCodes = {
- Cancelled: 2,
- Failure: 1,
- Success: 0,
-} as const;
-
-export type StatusCode = (typeof StatusCodes)[keyof typeof StatusCodes];
diff --git a/src/shared/createCleanupCommands.test.ts b/src/shared/createCleanupCommands.test.ts
deleted file mode 100644
index 8c2117f7e..000000000
--- a/src/shared/createCleanupCommands.test.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { describe, expect, it } from "vitest";
-
-import { createCleanupCommands } from "./createCleanupCommands.js";
-
-describe("createCleanupCommands", () => {
- it("only lints and formats when bin is not enabled and there are no prepended commands", () => {
- const actual = createCleanupCommands(undefined);
-
- expect(actual).toEqual(["pnpm lint --fix", "pnpm format --write"]);
- });
-
- it("runs prepended commands before it lints and formats when bin is not enabled", () => {
- const actual = createCleanupCommands(undefined, "prepended");
-
- expect(actual).toEqual([
- "prepended",
- "pnpm lint --fix",
- "pnpm format --write",
- ]);
- });
-
- it("runs prepended commands before it builds, lints, and formats when bin is not enabled", () => {
- const actual = createCleanupCommands("bin/index.js", "prepended");
-
- expect(actual).toEqual([
- "prepended",
- "pnpm build",
- "pnpm lint --fix",
- "pnpm format --write",
- ]);
- });
-});
diff --git a/src/shared/createCleanupCommands.ts b/src/shared/createCleanupCommands.ts
deleted file mode 100644
index d48c6477f..000000000
--- a/src/shared/createCleanupCommands.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-export function createCleanupCommands(
- bin: string | undefined,
- ...prependedCommands: string[]
-) {
- return [
- ...prependedCommands,
- // n/no-missing-import rightfully reports on a missing the bin .js file
- ...(bin ? ["pnpm build"] : []),
- "pnpm lint --fix",
- "pnpm format --write",
- ];
-}
diff --git a/src/shared/doesRepositoryExist.test.ts b/src/shared/doesRepositoryExist.test.ts
deleted file mode 100644
index 5932d647e..000000000
--- a/src/shared/doesRepositoryExist.test.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { Octokit } from "octokit";
-import { describe, expect, it, MockInstance, vi } from "vitest";
-
-import { doesRepositoryExist } from "./doesRepositoryExist.js";
-
-const createMockOctokit = (
- repos: Partial>,
-) =>
- ({
- rest: {
- repos,
- },
- }) as unknown as Octokit;
-
-const owner = "StubOwner";
-const repository = "stub-repository";
-
-describe("doesRepositoryExist", () => {
- it("returns true when the octokit GET resolves", async () => {
- const octokit = createMockOctokit({ get: vi.fn().mockResolvedValue({}) });
-
- const actual = await doesRepositoryExist(octokit, { owner, repository });
-
- expect(actual).toBe(true);
- });
-
- it("returns false when the octokit GET rejects with a 404", async () => {
- const octokit = createMockOctokit({
- get: vi.fn().mockRejectedValue({ status: 404 }),
- });
-
- const actual = await doesRepositoryExist(octokit, { owner, repository });
-
- expect(actual).toBe(false);
- });
-
- it("throws the error when awaiting the octokit GET throws a non-404 error", async () => {
- const error = new Error("Oh no!");
- const octokit = createMockOctokit({
- get: vi.fn().mockRejectedValue(error),
- });
-
- await expect(
- async () => await doesRepositoryExist(octokit, { owner, repository }),
- ).rejects.toEqual(error);
- });
-});
diff --git a/src/shared/doesRepositoryExist.ts b/src/shared/doesRepositoryExist.ts
deleted file mode 100644
index 8868a2f94..000000000
--- a/src/shared/doesRepositoryExist.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Octokit, RequestError } from "octokit";
-
-export interface DoesRepositoryExistOptions {
- owner: string;
- repository: string;
-}
-
-export async function doesRepositoryExist(
- octokit: Octokit,
- options: DoesRepositoryExistOptions,
-) {
- // Because the Octokit SDK throws on 404s (😡),
- // we try/catch to check whether the repo exists.
- try {
- await octokit.rest.repos.get({
- owner: options.owner,
- repo: options.repository,
- });
- return true;
- } catch (error) {
- if ((error as RequestError).status !== 404) {
- throw error;
- }
-
- return false;
- }
-}
diff --git a/src/shared/ensureGitRepository.test.ts b/src/shared/ensureGitRepository.test.ts
deleted file mode 100644
index a9b4b7ec6..000000000
--- a/src/shared/ensureGitRepository.test.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { describe, expect, it, vi } from "vitest";
-
-import { ensureGitRepository } from "./ensureGitRepository.js";
-
-const mock$ = vi.fn();
-
-vi.mock("execa", () => ({
- get $() {
- return mock$;
- },
-}));
-
-describe("ensureGitRepository", () => {
- it("does not run git init when git status succeeds", async () => {
- mock$.mockResolvedValue(0);
-
- await ensureGitRepository();
-
- expect(mock$).toHaveBeenCalledTimes(1);
- });
-
- it("runs git init when git status fails", async () => {
- mock$.mockRejectedValueOnce(1);
-
- await ensureGitRepository();
-
- expect(mock$).toHaveBeenCalledWith(["git init"]);
- });
-});
diff --git a/src/shared/ensureGitRepository.ts b/src/shared/ensureGitRepository.ts
deleted file mode 100644
index 97ad7074d..000000000
--- a/src/shared/ensureGitRepository.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { $ } from "execa";
-
-export async function ensureGitRepository() {
- try {
- await $`git status`;
- } catch {
- await $`git init`;
- }
-}
diff --git a/src/shared/generateNextSteps.test.ts b/src/shared/generateNextSteps.test.ts
deleted file mode 100644
index 88c83812a..000000000
--- a/src/shared/generateNextSteps.test.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { describe, expect, test } from "vitest";
-
-import { generateNextSteps } from "./generateNextSteps.js";
-import { Options } from "./types.js";
-
-const options = {
- access: "public",
- base: "everything",
- description: "Test description.",
- directory: ".",
- email: {
- github: "github@email.com",
- npm: "npm@email.com",
- },
- mode: "create",
- owner: "TestOwner",
- repository: "test-repository",
- title: "Test Title",
-} satisfies Options;
-
-describe("generateNextSteps", () => {
- for (const excludeAllContributors of [false, true]) {
- for (const excludeReleases of [false, true]) {
- for (const excludeRenovate of [false, true]) {
- for (const excludeTests of [false, true]) {
- test(
- // eslint-disable-next-line vitest/valid-title
- JSON.stringify({
- excludeAllContributors,
- excludeReleases,
- excludeRenovate,
- excludeTests,
- }),
- () => {
- expect(
- generateNextSteps({
- ...options,
- excludeAllContributors,
- excludeReleases,
- excludeRenovate,
- excludeTests,
- }),
- ).toMatchSnapshot();
- },
- );
- }
- }
- }
- }
-});
diff --git a/src/shared/generateNextSteps.ts b/src/shared/generateNextSteps.ts
deleted file mode 100644
index c8eb8b998..000000000
--- a/src/shared/generateNextSteps.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import { OutroGroup } from "./cli/outro.js";
-import { Options } from "./types.js";
-
-export function generateNextSteps(options: Options): OutroGroup[] {
- const lines = [
- joinedMessage(
- "enable the",
- [
- options.excludeTests || ["Codecov", "https://github.com/apps/codecov"],
- options.excludeRenovate || [
- "Renovate",
- "https://github.com/apps/renovate",
- ],
- ],
- "GitHub app",
- ),
- joinedMessage(
- "populate the",
- [
- (options.excludeAllContributors && options.excludeReleases) || [
- "ACCESS_TOKEN",
- "a GitHub PAT with repo and workflow permissions",
- ],
- options.excludeReleases || [
- "NPM_TOKEN",
- "an npm access token with automation permissions",
- ],
- ],
- "secret",
- ),
- ].filter((line): line is string => !!line);
-
- switch (lines.length) {
- case 0:
- return [];
- case 1:
- return [{ label: `Be sure to ${lines[0]}` }];
- default:
- return [
- {
- label: "Be sure to:",
- lines: lines.map((line) => `- ${line}`),
- },
- ];
- }
-}
-
-const itemBreak = "\n - ";
-
-function joinedMessage(
- prefix: string,
- entries: ([string, string] | true)[],
- suffix: string,
-) {
- const realEntries = entries.filter(
- (entry): entry is [string, string] => entry !== true,
- );
-
- switch (realEntries.length) {
- case 0:
- return undefined;
- case 1:
- return `${prefix} ${realEntries[0][0]} ${suffix} (${realEntries[0][1]}).`;
- default:
- return `${prefix} ${suffix}s: ${itemBreak}${realEntries
- .map((entry) => `${entry[0]} (${entry[1]})`)
- .join(itemBreak)}`;
- }
-}
diff --git a/src/shared/getGitHubUserAsAllContributor.test.ts b/src/shared/getGitHubUserAsAllContributor.test.ts
deleted file mode 100644
index 25fe80e68..000000000
--- a/src/shared/getGitHubUserAsAllContributor.test.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-import chalk from "chalk";
-import { Octokit } from "octokit";
-import { beforeEach, describe, expect, it, MockInstance, vi } from "vitest";
-
-import { getGitHubUserAsAllContributor } from "./getGitHubUserAsAllContributor.js";
-
-const mock$ = vi.fn();
-
-vi.mock("execa", () => ({
- get $() {
- return mock$;
- },
-}));
-
-let mockConsoleWarn: MockInstance;
-
-const createMockOctokit = (getAuthenticated: MockInstance = vi.fn()) =>
- ({
- rest: { users: { getAuthenticated } },
- }) as unknown as Octokit;
-
-const owner = "TestOwner";
-
-describe("getGitHubUserAsAllContributor", () => {
- beforeEach(() => {
- mockConsoleWarn = vi
- .spyOn(console, "warn")
- .mockImplementation(() => undefined);
- });
-
- it("defaults to owner with a log when options.offline is true", async () => {
- const octokit = createMockOctokit();
- const actual = await getGitHubUserAsAllContributor(octokit, {
- offline: true,
- owner,
- });
-
- expect(actual).toEqual(owner);
- expect(mockConsoleWarn).toHaveBeenCalledWith(
- chalk.gray(
- `Skipping populating all-contributors contributions for TestOwner because in --offline mode.`,
- ),
- );
- });
-
- it("defaults to owner without a log when octokit is undefined", async () => {
- const actual = await getGitHubUserAsAllContributor(undefined, { owner });
-
- expect(actual).toEqual(owner);
- expect(mockConsoleWarn).not.toHaveBeenCalled();
- });
-
- it("uses the user from gh api user when it succeeds", async () => {
- const login = "gh-api-user";
- const octokit = createMockOctokit(
- vi.fn().mockResolvedValue({ data: { login } }),
- );
-
- await getGitHubUserAsAllContributor(octokit, { owner });
-
- expect(mockConsoleWarn).not.toHaveBeenCalled();
- expect(mock$.mock.calls).toMatchInlineSnapshot(`
- [
- [
- [
- "pnpx all-contributors-cli@6.25 add ",
- " ",
- "",
- ],
- "gh-api-user",
- "code,content,doc,ideas,infra,maintenance,projectManagement,tool",
- ],
- ]
- `);
- });
-
- it("defaults the user to the owner when gh api user fails", async () => {
- const octokit = createMockOctokit(
- vi.fn().mockRejectedValue(new Error("Oh no!")),
- );
-
- await getGitHubUserAsAllContributor(octokit, { owner });
-
- expect(mockConsoleWarn).toHaveBeenCalledWith(
- chalk.gray(
- `Couldn't authenticate GitHub user, falling back to the provided owner name '${owner}'.`,
- ),
- );
- expect(mock$.mock.calls).toMatchInlineSnapshot(`
- [
- [
- [
- "pnpx all-contributors-cli@6.25 add ",
- " ",
- "",
- ],
- "TestOwner",
- "code,content,doc,ideas,infra,maintenance,projectManagement,tool",
- ],
- ]
- `);
- });
-});
diff --git a/src/shared/getGitHubUserAsAllContributor.ts b/src/shared/getGitHubUserAsAllContributor.ts
deleted file mode 100644
index 95948e26f..000000000
--- a/src/shared/getGitHubUserAsAllContributor.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import chalk from "chalk";
-import { $ } from "execa";
-import { Octokit } from "octokit";
-
-import { Options } from "./types.js";
-
-export async function getGitHubUserAsAllContributor(
- octokit: Octokit | undefined,
- options: Pick,
-) {
- if (options.offline) {
- console.warn(
- chalk.gray(
- `Skipping populating all-contributors contributions for ${options.owner} because in --offline mode.`,
- ),
- );
- return options.owner;
- }
-
- let user: string;
-
- if (octokit) {
- try {
- user = (await octokit.rest.users.getAuthenticated()).data.login;
- } catch {
- console.warn(
- chalk.gray(
- `Couldn't authenticate GitHub user, falling back to the provided owner name '${options.owner}'.`,
- ),
- );
- user = options.owner;
- }
- } else {
- user = options.owner;
- }
-
- const contributions = [
- "code",
- "content",
- "doc",
- "ideas",
- "infra",
- "maintenance",
- "projectManagement",
- "tool",
- ].join(",");
- await $`pnpx all-contributors-cli@6.25 add ${user} ${contributions}`;
-
- return user;
-}
diff --git a/src/shared/isUsingCreateEngine.ts b/src/shared/isUsingCreateEngine.ts
deleted file mode 100644
index da251858c..000000000
--- a/src/shared/isUsingCreateEngine.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export function isUsingCreateEngine() {
- return (
- !!process.env.CTA_CREATE_ENGINE && Boolean(process.env.CTA_CREATE_ENGINE)
- );
-}
diff --git a/src/shared/options/args.ts b/src/shared/options/args.ts
deleted file mode 100644
index 670197edb..000000000
--- a/src/shared/options/args.ts
+++ /dev/null
@@ -1,332 +0,0 @@
-import chalk from "chalk";
-
-export const allArgOptions = {
- access: {
- description: `(${chalk.cyanBright(
- '"public" | "restricted"',
- )}): Which ${chalk.cyanBright("npm publish --access")} to
- release npm packages with (by default, "public")`,
- docsSection: "optional",
- type: "string",
- },
- author: {
- description: `Username on npm to publish packages under (by
- default, an existing npm author, or the currently logged in npm user, or
- ${chalk.cyanBright("owner.toLowerCase()")})`,
- docsSection: "optional",
- type: "string",
- },
- auto: {
- description: `Whether to infer all options from files on disk.`,
- docsSection: "optional",
- type: "boolean",
- },
- base: {
- description: `Whether to scaffold the repository with:
- • everything: that comes with the template (${chalk.cyanBright.bold(
- "recommended",
- )})
- • common: additions to the minimal starters such as releases and tests
- • minimal: amounts of tooling, essentially opting out of everything
- • prompt: for which portions to exclude`,
- docsSection: "core",
- type: "string",
- },
- bin: {
- description: `package.json bin value to include for npx-style running.`,
- docsSection: "optional",
- type: "string",
- },
- "create-repository": {
- description: `Whether to create a corresponding repository on github.com
- (if it doesn't yet exist)`,
- docsSection: "core",
- type: "boolean",
- },
- description: {
- description: `Sentence case description of the repository
- (e.g. A quickstart-friendly TypeScript package with lots of great
- repository tooling. ✨)`,
- docsSection: "core",
- type: "string",
- },
- directory: {
- description: `Directory to create the repository in (by default, the same
- name as the repository)`,
- docsSection: "optional",
- type: "string",
- },
- email: {
- description: `Email address to be listed as the point of contact in docs
- and packages (e.g. example@joshuakgoldberg.com)`,
- docsSection: "optional",
- type: "string",
- },
- "email-github": {
- description: `Optionally, may be provided to use different emails in ${chalk.cyanBright(
- ".md",
- )}
- files`,
- docsSection: "optional",
- type: "string",
- },
- "email-npm": {
- description: `Optionally, may be provided to use different emails in
- ${chalk.cyanBright("package.json")}`,
- docsSection: "optional",
- type: "string",
- },
- "exclude-all-contributors": {
- description: `Don't add all-contributors to track contributions
- and display them in a README.md table.`,
- docsSection: "opt-out",
- type: "boolean",
- },
- "exclude-compliance": {
- description: `Don't add a GitHub Actions workflow to verify that PRs match
- an expected format.`,
- docsSection: "opt-out",
- type: "boolean",
- },
- "exclude-lint-jsdoc": {
- description: `Don't use eslint-plugin-jsdoc to enforce good practices around
- JSDoc comments.`,
- docsSection: "opt-out",
- type: "boolean",
- },
- "exclude-lint-json": {
- description: `Don't apply linting and sorting to ${chalk.cyanBright(
- "*.json",
- )}, and
- ${chalk.cyanBright("*.jsonc")} files.`,
- docsSection: "opt-out",
- type: "boolean",
- },
- "exclude-lint-knip": {
- description: `Don't add Knip to detect unused files, dependencies, and code
- exports.`,
- docsSection: "opt-out",
- type: "boolean",
- },
- "exclude-lint-md": {
- description: `Don't apply linting to ${chalk.cyanBright("*.md")} files.`,
- docsSection: "opt-out",
- type: "boolean",
- },
- "exclude-lint-package-json": {
- description: `Don't add eslint-plugin-package-json to lint for
- package.json correctness.`,
- docsSection: "opt-out",
- type: "boolean",
- },
- "exclude-lint-packages": {
- description: `Don't add a pnpm dedupe workflow to ensure packages
- aren't duplicated unnecessarily.`,
- docsSection: "opt-out",
- type: "boolean",
- },
- "exclude-lint-perfectionist": {
- description: `Don't apply eslint-plugin-perfectionist to ensure
- imports, keys, and so on are in sorted order.`,
- docsSection: "opt-out",
- type: "boolean",
- },
- "exclude-lint-regexp": {
- description: `Don't add eslint-plugin-regexp to enforce good practices around
- regular expressions.`,
- docsSection: "opt-out",
- type: "boolean",
- },
- "exclude-lint-spelling": {
- description: `Don't add cspell to spell check against dictionaries
- of known words.`,
- docsSection: "opt-out",
- type: "boolean",
- },
- "exclude-lint-strict": {
- description: `Don't augment the recommended logical lint rules with
- typescript-eslint's strict config.`,
- docsSection: "opt-out",
- type: "boolean",
- },
- "exclude-lint-stylistic": {
- description: `Don't add stylistic rules such as typescript-eslint's
- stylistic config.`,
- docsSection: "opt-out",
- type: "boolean",
- },
- "exclude-lint-yml": {
- description: `Don't apply linting and sorting to ${chalk.cyanBright(
- "*.yaml",
- )} and ${chalk.cyanBright("*.yml")} files.`,
- docsSection: "opt-out",
- type: "boolean",
- },
- "exclude-releases": {
- description: `Don't add release-it to generate changelogs, package bumps,
- and publishes based on conventional commits.`,
- docsSection: "opt-out",
- type: "boolean",
- },
- "exclude-renovate": {
- description: `Don't add a Renovate config to dependencies up-to-date with
- PRs.`,
- docsSection: "opt-out",
- type: "boolean",
- },
- "exclude-templated-by": {
- description: `Don't add a _"This package was templated with create-typescript-app"_ notice at the end of the README.md.`,
- docsSection: "opt-out",
- type: "boolean",
- },
- "exclude-tests": {
- description: `Don't add Vitest tooling for fast unit tests, configured
- with coverage tracking.`,
- docsSection: "opt-out",
- type: "boolean",
- },
- funding: {
- description: `GitHub organization or username to mention in ${chalk.cyanBright(
- "funding.yml",
- )}
- (by default, owner)`,
- docsSection: "optional",
- type: "string",
- },
- guide: {
- description: `Link to a contribution guide to place at the top of the
- development docs`,
- docsSection: "optional",
- type: "string",
- },
- "guide-title": {
- description: `If ${chalk.cyanBright(
- "--guide",
- )} is provided or detected from an existing
- DEVELOPMENT.md, the text title to place in the guide link`,
- docsSection: "optional",
- type: "string",
- },
- keywords: {
- description: `Any number of keywords to include in ${chalk.cyanBright(
- "package.json",
- )} (by default,
- none). This can be specified any number of times, like
- ${chalk.cyanBright('--keywords apple --keywords "banana cherry"')}`,
- docsSection: "optional",
- multiple: true,
- type: "string",
- },
- logo: {
- description: `Local image file in the repository to display near the top of
- the README.md as a logo`,
- docsSection: "optional",
- type: "string",
- },
- "logo-alt": {
- description: `If ${chalk.cyanBright(
- "--logo",
- )} is provided or detected from an existing README.md,
- alt text that describes the image will be prompted for if not provided`,
- docsSection: "optional",
- type: "string",
- },
- "logo-height": {
- description: `If ${chalk.cyanBright(
- "--logo",
- )} is provided or detected from an existing README.md,
- an explicit height style`,
- docsSection: "optional",
- type: "string",
- },
- "logo-width": {
- description: `If ${chalk.cyanBright(
- "--logo",
- )} is provided or detected from an existing README.md,
- an explicit width style`,
- docsSection: "optional",
- type: "string",
- },
- mode: {
- description: `Whether to:
- • create: a new repository in a child directory
- • initialize: a freshly repository in the current directory
- • migrate: an existing repository in the current directory`,
- docsSection: "core",
- type: "string",
- },
- offline: {
- description: `You can run ${chalk.cyanBright(
- "create-typescript-app",
- )} in an "offline" mode.
- Doing so will:
- • Enable ${chalk.cyanBright(
- "--exclude-all-contributors-api",
- )} and ${chalk.cyanBright("--skip-github-api")}
- • Skip network calls when setting up contributors
- • Run pnpm commands with pnpm's ${chalk.cyanBright("--offline")} mode`,
- docsSection: "offline",
- type: "boolean",
- },
- owner: {
- description: `GitHub organization or user the repository is underneath
- (e.g. JoshuaKGoldberg)`,
- docsSection: "core",
- type: "string",
- },
- "preserve-generated-from": {
- description: `Whether to keep the GitHub repository generated from
- notice (by default, false)`,
- docsSection: "optional",
- type: "boolean",
- },
- repository: {
- description: `The kebab-case name of the repository
- (e.g. create-typescript-app)`,
- docsSection: "core",
- type: "string",
- },
- "skip-all-contributors-api": {
- description: `Skips network calls that fetch all-contributors data from
- GitHub. This flag does nothing if ${chalk.cyanBright(
- "--exclude-all-contributors",
- )} was specified.`,
- docsSection: "skip-net",
- type: "boolean",
- },
- "skip-github-api": {
- description: `Skips calling to GitHub APIs.`,
- docsSection: "skip-net",
- type: "boolean",
- },
- "skip-install": {
- description: `Skips installing all the new template packages with pnpm.`,
- docsSection: "skip-net",
- type: "boolean",
- },
- "skip-removal": {
- description: `Skips removing setup docs and scripts, including this ${chalk.cyanBright(
- "docs/",
- )}
- directory`,
- docsSection: "skip-disk",
- type: "boolean",
- },
- "skip-restore": {
- description: `Skips the prompt offering to restore the repository if an
- error occurs during setup`,
- docsSection: "skip-disk",
- type: "boolean",
- },
- "skip-uninstall": {
- description: `Skips uninstalling packages only used for setup scripts`,
- docsSection: "skip-disk",
- type: "boolean",
- },
- title: {
- description: `Title Case title for the repository to be used in
- documentation (e.g. Create TypeScript App)`,
- docsSection: "core",
- type: "string",
- },
-} as const;
diff --git a/src/shared/options/augmentOptionsWithExcludes.test.ts b/src/shared/options/augmentOptionsWithExcludes.test.ts
deleted file mode 100644
index ed95d1354..000000000
--- a/src/shared/options/augmentOptionsWithExcludes.test.ts
+++ /dev/null
@@ -1,189 +0,0 @@
-import { describe, expect, it, vi } from "vitest";
-
-import { Options } from "../types.js";
-import { augmentOptionsWithExcludes } from "./augmentOptionsWithExcludes.js";
-
-const mockMultiselect = vi.fn();
-const mockSelect = vi.fn();
-
-vi.mock("@clack/prompts", () => ({
- isCancel: () => false,
- get multiselect() {
- return mockMultiselect;
- },
- get select() {
- return mockSelect;
- },
-}));
-
-const optionsBase = {
- access: "public",
- author: undefined,
- base: undefined,
- description: "",
- directory: ".",
- email: {
- github: "github@email.com",
- npm: "npm@email.com",
- },
- excludeAllContributors: undefined,
- excludeBuild: undefined,
- excludeCompliance: undefined,
- excludeLintESLint: undefined,
- excludeLintJSDoc: undefined,
- excludeLintJson: undefined,
- excludeLintKnip: undefined,
- excludeLintMd: undefined,
- excludeLintPackageJson: undefined,
- excludeLintPackages: undefined,
- excludeLintPerfectionist: undefined,
- excludeLintRegexp: undefined,
- excludeLintSpelling: undefined,
- excludeLintStrict: undefined,
- excludeLintStylistic: undefined,
- excludeLintYml: undefined,
- excludeReleases: undefined,
- excludeRenovate: undefined,
- excludeTemplatedBy: undefined,
- excludeTests: undefined,
- funding: undefined,
- logo: undefined,
- mode: "create",
- offline: true,
- owner: "",
- repository: "",
- skipGitHubApi: false,
- skipInstall: undefined,
- skipRemoval: undefined,
- skipRestore: undefined,
- skipUninstall: undefined,
- title: "",
-} satisfies Options;
-
-describe("augmentOptionsWithExcludes", () => {
- it("returns options directly when no exclusions are provided and 'base' is provided for the prompt", async () => {
- const base = "everything";
-
- mockSelect.mockResolvedValueOnce(base);
-
- const actual = await augmentOptionsWithExcludes(optionsBase);
-
- expect(actual).toEqual({
- ...optionsBase,
- base,
- });
- });
-
- it("returns options based on the select when no exclusions are provided and 'prompt' is provided for the prompt", async () => {
- const base = "prompt";
-
- mockSelect.mockResolvedValueOnce(base);
- mockMultiselect.mockResolvedValue([]);
-
- const actual = await augmentOptionsWithExcludes(optionsBase);
-
- expect(actual).toEqual({
- ...optionsBase,
- base,
- excludeAllContributors: true,
- excludeBuild: true,
- excludeCompliance: true,
- excludeLintESLint: true,
- excludeLintJSDoc: true,
- excludeLintJson: true,
- excludeLintKnip: true,
- excludeLintMd: true,
- excludeLintPackageJson: true,
- excludeLintPackages: true,
- excludeLintPerfectionist: true,
- excludeLintRegexp: true,
- excludeLintSpelling: true,
- excludeLintStrict: true,
- excludeLintStylistic: true,
- excludeLintYml: true,
- excludeReleases: true,
- excludeRenovate: true,
- excludeTemplatedBy: true,
- excludeTests: true,
- });
- });
-
- it("skips prompting returns options directly when exclusions are provided manually", async () => {
- const options = {
- ...optionsBase,
- excludeCompliance: true,
- } satisfies Options;
-
- const actual = await augmentOptionsWithExcludes(options);
-
- expect(actual).toBe(options);
- });
-
- it("uses the 'common' base without prompting when provided manually", async () => {
- const options = {
- ...optionsBase,
- base: "common",
- } satisfies Options;
-
- const actual = await augmentOptionsWithExcludes(options);
-
- expect(actual).toEqual({
- ...options,
- excludeCompliance: true,
- excludeLintESLint: true,
- excludeLintJSDoc: true,
- excludeLintJson: true,
- excludeLintMd: true,
- excludeLintPackageJson: true,
- excludeLintPackages: true,
- excludeLintPerfectionist: true,
- excludeLintRegexp: true,
- excludeLintSpelling: true,
- excludeLintStrict: true,
- excludeLintStylistic: true,
- excludeLintYml: true,
- });
- });
-
- it("uses the 'minimal' base without prompting when provided manually", async () => {
- const options = {
- ...optionsBase,
- base: "minimal",
- } satisfies Options;
-
- const actual = await augmentOptionsWithExcludes(options);
-
- expect(actual).toEqual({
- ...options,
- excludeAllContributors: true,
- excludeCompliance: true,
- excludeLintESLint: true,
- excludeLintJSDoc: true,
- excludeLintJson: true,
- excludeLintKnip: true,
- excludeLintMd: true,
- excludeLintPackageJson: true,
- excludeLintPackages: true,
- excludeLintPerfectionist: true,
- excludeLintRegexp: true,
- excludeLintSpelling: true,
- excludeLintStrict: true,
- excludeLintStylistic: true,
- excludeLintYml: true,
- excludeReleases: true,
- excludeRenovate: true,
- excludeTests: true,
- });
- });
-
- it("uses the 'everything' base without prompting when provided manually", async () => {
- const options = {
- ...optionsBase,
- base: "everything",
- } satisfies Options;
-
- const actual = await augmentOptionsWithExcludes(options);
-
- expect(actual).toStrictEqual(options);
- });
-});
diff --git a/src/shared/options/augmentOptionsWithExcludes.ts b/src/shared/options/augmentOptionsWithExcludes.ts
deleted file mode 100644
index 47070d669..000000000
--- a/src/shared/options/augmentOptionsWithExcludes.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-import * as prompts from "@clack/prompts";
-import chalk from "chalk";
-
-import { filterPromptCancel } from "../prompts.js";
-import { Options, OptionsBase } from "../types.js";
-import {
- exclusionDescriptions,
- ExclusionKey,
- exclusionKeys,
- getExclusions,
-} from "./exclusionKeys.js";
-
-export async function augmentOptionsWithExcludes(
- options: Options,
-): Promise {
- if (
- Object.keys(options).some(
- (key) =>
- key in exclusionDescriptions &&
- options[key as keyof typeof options] !== undefined,
- )
- ) {
- return options;
- }
-
- const base =
- options.base ??
- filterPromptCancel(
- await prompts.select({
- initialValue: "common" as OptionsBase,
- message: `How much tooling would you like the template to set up for you?`,
- options: [
- {
- label: makeLabel(
- "everything",
- "The most comprehensive tooling imaginable: sorting, spellchecking, and more!",
- ),
- value: "everything",
- },
- {
- hint: "recommended",
- label: makeLabel(
- "common",
- "Bare starters plus testing and automation for all-contributors and releases.",
- ),
- value: "common",
- },
- {
- label: makeLabel(
- "minimal",
- "Just bare starter tooling: building, formatting, linting, and type checking.",
- ),
- value: "minimal",
- },
- {
- label: makeLabel("prompt", "(allow me to customize)"),
- value: "prompt",
- },
- ],
- }),
- );
-
- switch (base) {
- case "common":
- case "everything":
- case "minimal":
- return {
- ...options,
- base,
- ...getExclusions(options, base),
- };
- case "prompt": {
- const exclusionsNotEnabled = new Set(
- filterPromptCancel(
- await prompts.multiselect({
- initialValues: exclusionKeys,
- message:
- "Select the tooling portions you'd like to remove. All are enabled by default. Press ↑ or ↓ to change the selected item, then space to select.",
- options: Object.entries(exclusionDescriptions).map(
- ([value, { hint, label }]) => ({
- hint,
- label,
- value: value as ExclusionKey,
- }),
- ),
- }),
- ),
- );
-
- return {
- ...options,
- base,
- ...Object.fromEntries(
- exclusionKeys.map(
- (exclusionKey) =>
- [exclusionKey, !exclusionsNotEnabled.has(exclusionKey)] as const,
- ),
- ),
- };
- }
- case undefined:
- return undefined;
- }
-}
-
-function makeLabel(label: string, message: string) {
- return [chalk.bold(label), message].join("\t ");
-}
diff --git a/src/shared/options/createOptionDefaults/index.test.ts b/src/shared/options/createOptionDefaults/index.test.ts
deleted file mode 100644
index efb36a8fc..000000000
--- a/src/shared/options/createOptionDefaults/index.test.ts
+++ /dev/null
@@ -1,218 +0,0 @@
-import { beforeEach, describe, expect, it, vi } from "vitest";
-
-import { createOptionDefaults } from "./index.js";
-
-const mock$ = vi.fn();
-
-vi.mock("execa", () => ({
- get $() {
- return mock$;
- },
-}));
-
-const mockGitUrlParse = vi.fn();
-
-vi.mock("git-url-parse", () => ({
- get default() {
- return mockGitUrlParse;
- },
-}));
-
-const mockNpmUser = vi.fn();
-
-vi.mock("npm-user", () => ({
- get default() {
- return mockNpmUser;
- },
-}));
-
-const mockReadPackageData = vi.fn();
-
-vi.mock("../../packages.js", () => ({
- get readPackageData() {
- return mockReadPackageData;
- },
-}));
-
-const mockReadGitHubEmail = vi.fn();
-
-vi.mock("./readGitHubEmail.js", () => ({
- get readGitHubEmail() {
- return mockReadGitHubEmail;
- },
-}));
-
-describe("createOptionDefaults", () => {
- describe("bin", () => {
- it("returns undefined when package data does not have a bin", async () => {
- mockReadPackageData.mockResolvedValue({});
-
- const actual = await createOptionDefaults().bin();
-
- expect(actual).toBeUndefined();
- });
-
- it("returns the bin when package data has a bin", async () => {
- const bin = "lib/index.js";
-
- mockReadPackageData.mockResolvedValue({ bin });
-
- const actual = await createOptionDefaults().bin();
-
- expect(actual).toBe(bin);
- });
- });
-
- describe("email", () => {
- beforeEach(() => {
- mockNpmUser.mockImplementation((username: string) => ({
- email: `npm-${username}@test.com`,
- }));
- });
-
- it("returns the npm whoami email from npm when only an npm exists", async () => {
- mock$.mockImplementation(([command]: string[]) =>
- command === "npm whoami" ? { stdout: "username" } : undefined,
- );
- mockReadGitHubEmail.mockResolvedValueOnce(undefined);
-
- const actual = await createOptionDefaults().email();
-
- expect(actual).toEqual({
- github: "npm-username@test.com",
- npm: "npm-username@test.com",
- });
- });
-
- it("returns the npm whoami email from npm when only a package author email exists", async () => {
- mock$.mockResolvedValue({ stdout: "" });
- mockReadGitHubEmail.mockResolvedValueOnce(undefined);
- mockReadPackageData.mockResolvedValue({
- author: {
- email: "test@package.com",
- },
- });
-
- const actual = await createOptionDefaults().email();
-
- expect(actual).toEqual({
- github: "test@package.com",
- npm: "test@package.com",
- });
- });
-
- it("returns the github email when only a github email exists", async () => {
- mock$.mockResolvedValue({ stdout: "" });
- mockReadPackageData.mockResolvedValueOnce({});
- mockReadGitHubEmail.mockResolvedValueOnce("github@test.com");
-
- const actual = await createOptionDefaults().email();
-
- expect(actual).toEqual({
- github: "github@test.com",
- npm: "github@test.com",
- });
- });
-
- it("returns the git user email when only a git user email exists", async () => {
- mock$.mockImplementation(([command]: string[]) =>
- command === "git config --get user.email"
- ? { stdout: "git@test.com" }
- : undefined,
- );
- mockReadGitHubEmail.mockResolvedValueOnce(undefined);
- mockReadPackageData.mockResolvedValue({});
-
- const actual = await createOptionDefaults().email();
-
- expect(actual).toEqual({
- github: "git@test.com",
- npm: "git@test.com",
- });
- });
-
- it("returns both the git user email and the npm user email when only those two exist", async () => {
- mock$.mockImplementation(([command]: string[]) => ({
- stdout:
- command === "git config --get user.email"
- ? "git@test.com"
- : "username",
- }));
- mockReadGitHubEmail.mockResolvedValueOnce(undefined);
- mockReadPackageData.mockResolvedValue({});
-
- const actual = await createOptionDefaults().email();
-
- expect(actual).toEqual({
- github: "git@test.com",
- npm: "npm-username@test.com",
- });
- });
-
- it("returns all three emails when they all exist", async () => {
- mock$.mockImplementation(([command]: string[]) => ({
- stdout:
- command === "git config --get user.email"
- ? "git@test.com"
- : "username",
- }));
- mockReadGitHubEmail.mockResolvedValueOnce("github@test.com");
- mockReadPackageData.mockResolvedValue({});
-
- const actual = await createOptionDefaults().email();
-
- expect(actual).toEqual({
- github: "github@test.com",
- npm: "npm-username@test.com",
- });
- });
-
- it("returns undefined when none of the emails exist", async () => {
- mock$.mockResolvedValue({ stdout: "" });
- mockReadGitHubEmail.mockResolvedValueOnce(undefined);
- mockReadPackageData.mockResolvedValue({});
-
- const actual = await createOptionDefaults().email();
-
- expect(actual).toBeUndefined();
- });
- });
-
- describe("repository", () => {
- it("returns promptedOptions.repository when it exists", async () => {
- const repository = "test-prompted-repository";
- const promptedOptions = { repository };
- const actual = await createOptionDefaults(promptedOptions).repository();
-
- expect(actual).toBe(repository);
- });
-
- it("returns the Git name when it exists and promptedOptions.repository doesn't", async () => {
- const name = "test-git-repository";
- mockGitUrlParse.mockResolvedValueOnce({ name });
-
- const actual = await createOptionDefaults().repository();
-
- expect(actual).toBe(name);
- });
-
- it("returns the package name when it exists and promptedOptions.repository and Git name don't", async () => {
- const name = "test-package-name";
- mockReadPackageData.mockResolvedValueOnce({ name });
-
- const actual = await createOptionDefaults().repository();
-
- expect(actual).toBe(name);
- });
-
- it("returns the directory when it exists and promptedOptions.repository, Git name, and package name don't", async () => {
- mockReadPackageData.mockResolvedValueOnce({});
- const directory = "test-prompted-directory";
- const promptedOptions = { directory };
-
- const actual = await createOptionDefaults(promptedOptions).repository();
-
- expect(actual).toBe(directory);
- });
- });
-});
diff --git a/src/shared/options/createOptionDefaults/index.ts b/src/shared/options/createOptionDefaults/index.ts
deleted file mode 100644
index 3049463c8..000000000
--- a/src/shared/options/createOptionDefaults/index.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import { $ } from "execa";
-import gitRemoteOriginUrl from "git-remote-origin-url";
-import gitUrlParse from "git-url-parse";
-import lazyValue from "lazy-value";
-import * as fs from "node:fs/promises";
-import npmUser from "npm-user";
-
-import { readDescription } from "../../../next/readDescription.js";
-import { readPackageData } from "../../packages.js";
-import { readFileSafe } from "../../readFileSafe.js";
-import { tryCatchAsync } from "../../tryCatchAsync.js";
-import { tryCatchLazyValueAsync } from "../../tryCatchLazyValueAsync.js";
-import { PromptedOptions } from "../../types.js";
-import { parsePackageAuthor } from "./parsePackageAuthor.js";
-import { readDefaultsFromReadme } from "./readDefaultsFromReadme.js";
-import { readEmails } from "./readEmails.js";
-import { readGuide } from "./readGuide.js";
-
-export function createOptionDefaults(promptedOptions?: PromptedOptions) {
- const gitDefaults = tryCatchLazyValueAsync(async () =>
- gitUrlParse(await gitRemoteOriginUrl()),
- );
-
- const npmDefaults = tryCatchLazyValueAsync(async () => {
- const whoami = (await $`npm whoami`).stdout;
- return whoami ? await npmUser(whoami) : undefined;
- });
-
- const packageData = lazyValue(readPackageData);
- const packageAuthor = lazyValue(async () =>
- parsePackageAuthor(await packageData()),
- );
-
- const readme = lazyValue(async () => await readFileSafe("README.md", ""));
-
- return {
- author: async () =>
- (await packageAuthor()).author ?? (await npmDefaults())?.name,
- bin: async () => (await packageData()).bin,
- description: async () => await readDescription(packageData, readme),
- email: async () => readEmails(npmDefaults, packageAuthor),
- funding: async () =>
- await tryCatchAsync(async () =>
- (await fs.readFile(".github/FUNDING.yml"))
- .toString()
- .split(":")[1]
- ?.trim(),
- ),
- guide: readGuide,
- owner: async () =>
- (await gitDefaults())?.organization ?? (await packageAuthor()).author,
- repository: async () =>
- promptedOptions?.repository ??
- (await gitDefaults())?.name ??
- (await packageData()).name ??
- promptedOptions?.directory,
- ...readDefaultsFromReadme(readme, () =>
- Promise.resolve(promptedOptions?.repository),
- ),
- };
-}
diff --git a/src/shared/options/createRepositoryWithApi.test.ts b/src/shared/options/createRepositoryWithApi.test.ts
deleted file mode 100644
index 5f4ca68e9..000000000
--- a/src/shared/options/createRepositoryWithApi.test.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import { Octokit } from "octokit";
-import { describe, expect, it, vi } from "vitest";
-
-import { createRepositoryWithApi } from "./createRepositoryWithApi.js";
-
-const options = { owner: "StubOwner", repository: "stub-repository" };
-
-const mockCreateUsingTemplate = vi.fn();
-const mockCreateInOrg = vi.fn();
-const mockCreateForAuthenticatedUser = vi.fn();
-const mockGetAuthenticated = vi.fn();
-
-const createMockOctokit = () =>
- ({
- rest: {
- repos: {
- createForAuthenticatedUser: mockCreateForAuthenticatedUser,
- createInOrg: mockCreateInOrg,
- createUsingTemplate: mockCreateUsingTemplate,
- },
- users: {
- getAuthenticated: mockGetAuthenticated,
- },
- },
- }) as unknown as Octokit;
-
-describe("createRepositoryWithApi", () => {
- it("creates using a template when preserveGeneratedFrom is true", async () => {
- await createRepositoryWithApi(createMockOctokit(), {
- ...options,
- preserveGeneratedFrom: true,
- });
-
- expect(mockCreateForAuthenticatedUser).not.toHaveBeenCalled();
- expect(mockCreateInOrg).not.toHaveBeenCalled();
- expect(mockCreateUsingTemplate).toHaveBeenCalledWith({
- name: options.repository,
- owner: options.owner,
- template_owner: "JoshuaKGoldberg",
- template_repo: "create-typescript-app",
- });
- });
-
- it("creates under the user when the user is the owner", async () => {
- mockGetAuthenticated.mockResolvedValueOnce({
- data: {
- login: options.owner,
- },
- });
- await createRepositoryWithApi(createMockOctokit(), options);
-
- expect(mockCreateForAuthenticatedUser).toHaveBeenCalledWith({
- name: options.repository,
- });
- expect(mockCreateInOrg).not.toHaveBeenCalled();
- expect(mockCreateUsingTemplate).not.toHaveBeenCalled();
- });
-
- it("creates under an org when the user is not the owner", async () => {
- const login = "other-user";
- mockGetAuthenticated.mockResolvedValueOnce({ data: { login } });
- await createRepositoryWithApi(createMockOctokit(), options);
-
- expect(mockCreateForAuthenticatedUser).not.toHaveBeenCalled();
- expect(mockCreateInOrg).toHaveBeenCalledWith({
- name: options.repository,
- org: options.owner,
- });
- expect(mockCreateUsingTemplate).not.toHaveBeenCalled();
- });
-});
diff --git a/src/shared/options/createRepositoryWithApi.ts b/src/shared/options/createRepositoryWithApi.ts
deleted file mode 100644
index f8be9b3fd..000000000
--- a/src/shared/options/createRepositoryWithApi.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Octokit } from "octokit";
-
-export interface CreateRepositoryWithApiOptions {
- owner: string;
- preserveGeneratedFrom?: boolean;
- repository: string;
-}
-
-export async function createRepositoryWithApi(
- octokit: Octokit,
- options: CreateRepositoryWithApiOptions,
-) {
- if (options.preserveGeneratedFrom) {
- await octokit.rest.repos.createUsingTemplate({
- name: options.repository,
- owner: options.owner,
- template_owner: "JoshuaKGoldberg",
- template_repo: "create-typescript-app",
- });
- return;
- }
-
- const currentUser = await octokit.rest.users.getAuthenticated();
-
- try {
- if (currentUser.data.login === options.owner) {
- await octokit.rest.repos.createForAuthenticatedUser({
- name: options.repository,
- });
- } else {
- await octokit.rest.repos.createInOrg({
- name: options.repository,
- org: options.owner,
- });
- }
- } catch (error) {
- throw new Error("Failed to create new repository on GitHub.", {
- cause: error,
- });
- }
-}
diff --git a/src/shared/options/detectEmailRedundancy.test.ts b/src/shared/options/detectEmailRedundancy.test.ts
deleted file mode 100644
index 3091a6096..000000000
--- a/src/shared/options/detectEmailRedundancy.test.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { describe, expect, it } from "vitest";
-
-import { detectEmailRedundancy } from "./detectEmailRedundancy.js";
-
-describe("detectEmailRedundancy", () => {
- it("returns undefined when only email is specified", () => {
- expect(detectEmailRedundancy({ email: "test@email.com" })).toBeUndefined();
- });
-
- it("returns undefined when email-github and email-npm are specified while email is not", () => {
- expect(
- detectEmailRedundancy({
- "email-github": "test@email.com",
- "email-npm": "test@email.com",
- }),
- ).toBeUndefined();
- });
-
- it("returns a complaint when email-github is specified while email and email-npm are not", () => {
- expect(
- detectEmailRedundancy({
- "email-github": "test@email.com",
- }),
- ).toBe(
- "If --email-github is specified, either --email or --email-npm should be.",
- );
- });
-
- it("returns a complaint when email-npm is specified while email and email-github are not", () => {
- expect(
- detectEmailRedundancy({
- "email-npm": "test@email.com",
- }),
- ).toBe(
- "If --email-npm is specified, either --email or --email-github should be.",
- );
- });
-});
diff --git a/src/shared/options/detectEmailRedundancy.ts b/src/shared/options/detectEmailRedundancy.ts
deleted file mode 100644
index 15044b475..000000000
--- a/src/shared/options/detectEmailRedundancy.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-export interface EmailValues {
- email?: boolean | string;
- "email-github"?: boolean | string;
- "email-npm"?: boolean | string;
-}
-
-export function detectEmailRedundancy(values: EmailValues) {
- if (values.email) {
- return values["email-github"] && values["email-npm"]
- ? "--email should not be specified if both --email-github and --email-npm are specified."
- : undefined;
- }
-
- if (values["email-github"] && !values["email-npm"]) {
- return "If --email-github is specified, either --email or --email-npm should be.";
- }
-
- if (values["email-npm"] && !values["email-github"]) {
- return "If --email-npm is specified, either --email or --email-github should be.";
- }
-
- return undefined;
-}
diff --git a/src/shared/options/ensureRepositoryExists.test.ts b/src/shared/options/ensureRepositoryExists.test.ts
deleted file mode 100644
index 3345f3adf..000000000
--- a/src/shared/options/ensureRepositoryExists.test.ts
+++ /dev/null
@@ -1,170 +0,0 @@
-import { Octokit } from "octokit";
-import { describe, expect, it, vi } from "vitest";
-
-import { ensureRepositoryExists } from "./ensureRepositoryExists.js";
-
-const mockSelect = vi.fn();
-const mockText = vi.fn();
-
-vi.mock("@clack/prompts", () => ({
- intro: vi.fn(),
- isCancel: vi.fn(),
- outro: vi.fn(),
- get select() {
- return mockSelect;
- },
- get text() {
- return mockText;
- },
-}));
-
-const mockDoesRepositoryExist = vi.fn();
-
-vi.mock("../doesRepositoryExist.js", () => ({
- get doesRepositoryExist() {
- return mockDoesRepositoryExist;
- },
-}));
-
-const owner = "StubOwner";
-const repository = "stub-repository";
-
-const mockCreateRepositoryWithApi = vi.fn();
-
-vi.mock("./createRepositoryWithApi.js", () => ({
- get createRepositoryWithApi() {
- return mockCreateRepositoryWithApi;
- },
-}));
-
-const createMockOctokit = () => ({}) as unknown as Octokit;
-
-describe("ensureRepositoryExists", () => {
- it("returns the repository when octokit is undefined", async () => {
- const actual = await ensureRepositoryExists(undefined, {
- mode: "initialize",
- owner,
- repository,
- });
-
- expect(actual).toEqual({ octokit: undefined, repository });
- });
-
- it("returns the repository when octokit is defined and the repository exists", async () => {
- mockDoesRepositoryExist.mockResolvedValue(true);
- const octokit = createMockOctokit();
- const actual = await ensureRepositoryExists(octokit, {
- mode: "initialize",
- owner,
- repository,
- });
-
- expect(actual).toEqual({ octokit, repository });
- });
-
- it("creates a new repository when the prompt is 'create' and the repository does not exist", async () => {
- const octokit = createMockOctokit();
-
- mockDoesRepositoryExist.mockResolvedValue(false);
- mockSelect.mockResolvedValue("create");
-
- const actual = await ensureRepositoryExists(octokit, {
- mode: "initialize",
- owner,
- repository,
- });
-
- expect(actual).toEqual({ octokit, repository });
- expect(mockCreateRepositoryWithApi).toHaveBeenCalledWith(octokit, {
- owner,
- preserveGeneratedFrom: undefined,
- repository,
- });
- });
-
- it("defaults to creating a repository when mode is 'create'", async () => {
- const octokit = createMockOctokit();
-
- mockDoesRepositoryExist.mockResolvedValue(false);
-
- const actual = await ensureRepositoryExists(octokit, {
- mode: "create",
- owner,
- repository,
- });
-
- expect(actual).toEqual({ octokit, repository });
- expect(mockCreateRepositoryWithApi).toHaveBeenCalledWith(octokit, {
- owner,
- preserveGeneratedFrom: undefined,
- repository,
- });
- expect(mockSelect).not.toHaveBeenCalled();
- });
-
- it("returns the second repository when the prompt is 'different', the first repository does not exist, and the second repository exists", async () => {
- const octokit = createMockOctokit();
- const newRepository = "new-repository";
-
- mockDoesRepositoryExist
- .mockResolvedValueOnce(false)
- .mockResolvedValueOnce(true);
- mockSelect.mockResolvedValueOnce("different");
- mockText.mockResolvedValue(newRepository);
-
- const actual = await ensureRepositoryExists(octokit, {
- mode: "initialize",
- owner,
- repository,
- });
-
- expect(actual).toEqual({
- octokit,
- repository: newRepository,
- });
- expect(mockCreateRepositoryWithApi).not.toHaveBeenCalled();
- });
-
- it("creates the second repository when the prompt is 'different', the first repository does not exist, and the second repository does not exist", async () => {
- const octokit = createMockOctokit();
- const newRepository = "new-repository";
-
- mockDoesRepositoryExist.mockResolvedValue(false);
- mockSelect
- .mockResolvedValueOnce("different")
- .mockResolvedValueOnce("create");
- mockText.mockResolvedValue(newRepository);
-
- const actual = await ensureRepositoryExists(octokit, {
- mode: "initialize",
- owner,
- repository,
- });
-
- expect(actual).toEqual({
- octokit,
- repository: newRepository,
- });
- expect(mockCreateRepositoryWithApi).toHaveBeenCalledWith(octokit, {
- owner,
- preserveGeneratedFrom: undefined,
- repository: newRepository,
- });
- });
-
- it("switches octokit to undefined when the prompt is 'local' and the repository does not exist", async () => {
- const octokit = createMockOctokit();
-
- mockDoesRepositoryExist.mockResolvedValue(false);
- mockSelect.mockResolvedValue("local");
-
- const actual = await ensureRepositoryExists(octokit, {
- mode: "initialize",
- owner,
- repository,
- });
-
- expect(actual).toEqual({ octokit: undefined, repository });
- expect(mockCreateRepositoryWithApi).not.toHaveBeenCalled();
- });
-});
diff --git a/src/shared/options/ensureRepositoryExists.ts b/src/shared/options/ensureRepositoryExists.ts
deleted file mode 100644
index a04c9b707..000000000
--- a/src/shared/options/ensureRepositoryExists.ts
+++ /dev/null
@@ -1,95 +0,0 @@
-import * as prompts from "@clack/prompts";
-import { Octokit } from "octokit";
-
-import { doesRepositoryExist } from "../doesRepositoryExist.js";
-import { isUsingCreateEngine } from "../isUsingCreateEngine.js";
-import { filterPromptCancel } from "../prompts.js";
-import { Options } from "../types.js";
-import { createRepositoryWithApi } from "./createRepositoryWithApi.js";
-
-export type EnsureRepositoryExistsOptions = Pick<
- Options,
- "mode" | "owner" | "preserveGeneratedFrom" | "repository"
->;
-
-export interface RepositoryExistsResult {
- octokit: Octokit | undefined;
- repository: string;
-}
-
-export async function ensureRepositoryExists(
- octokit: Octokit | undefined,
- options: EnsureRepositoryExistsOptions,
-): Promise> {
- // We'll only respect input options once before prompting for them
- let { repository } = options;
- let createRepository = options.mode === "create";
-
- // We'll continuously pester the user for a repository
- // until they bail, create a new one, or it exists.
- while (octokit) {
- if (
- isUsingCreateEngine() ||
- (await doesRepositoryExist(octokit, options))
- ) {
- return { octokit, repository };
- }
-
- const selection = createRepository
- ? "create"
- : filterPromptCancel(
- (await prompts.select({
- message: `Repository ${options.repository} doesn't seem to exist under ${options.owner}. What would you like to do?`,
- options: [
- { label: "Create a new repository", value: "create" },
- {
- label: "Switch to a different repository name",
- value: "different",
- },
- {
- label: "Keep changes local",
- value: "local",
- },
- { label: "Bail out and maybe try again later", value: "bail" },
- ],
- })) as "bail" | "create" | "different" | "local",
- );
-
- createRepository = false;
-
- switch (selection) {
- case "bail":
- case undefined:
- return {};
-
- case "create":
- await createRepositoryWithApi(octokit, {
- owner: options.owner,
- preserveGeneratedFrom: options.preserveGeneratedFrom,
- repository,
- });
- return { octokit, repository };
-
- case "different": {
- const newRepository = filterPromptCancel(
- await prompts.text({
- message: `What would you like to call the repository?`,
- }),
- );
-
- if (!newRepository) {
- return {};
- }
-
- repository = newRepository;
- break;
- }
-
- case "local":
- octokit = undefined;
- break;
- }
- }
-
- return { octokit, repository };
-}
diff --git a/src/shared/options/exclusionKeys.ts b/src/shared/options/exclusionKeys.ts
deleted file mode 100644
index 8d3b03425..000000000
--- a/src/shared/options/exclusionKeys.ts
+++ /dev/null
@@ -1,158 +0,0 @@
-import { Options, OptionsBase } from "../types.js";
-
-export interface ExclusionDescription {
- hint: string;
- label: string;
- level?: "common" | "minimal";
-}
-
-export type ExclusionKey = `exclude${string}` & keyof Options;
-
-export const exclusionDescriptions: Record =
- {
- excludeAllContributors: {
- hint: "--exclude-all-contributors",
- label:
- "Add all-contributors to track contributions and display them in a README.md table.",
- },
- excludeBuild: {
- hint: "--exclude-build",
- label: "Add a tsup build step to generate built output files.",
- level: "minimal",
- },
- excludeCompliance: {
- hint: "--exclude-compliance",
- label:
- "Add a GitHub Actions workflow to verify that PRs match an expected format.",
- level: "common",
- },
- excludeLintESLint: {
- hint: "--exclude-lint-eslint",
- label:
- "Include eslint-plugin-eslint-comment to enforce good practices around ESLint comment directives.",
- level: "common",
- },
- excludeLintJSDoc: {
- hint: "--exclude-lint-jsdoc",
- label:
- "Include eslint-plugin-jsdoc to enforce good practices around JSDoc comments.",
- level: "common",
- },
- excludeLintJson: {
- hint: "--exclude-lint-json",
- label: "Apply linting and sorting to *.json and *.jsonc files.",
- level: "common",
- },
- excludeLintKnip: {
- hint: "--exclude-lint-knip",
- label: "Add Knip to detect unused files, dependencies, and code exports.",
- },
- excludeLintMd: {
- hint: "--exclude-lint-md",
- label: "Apply linting to *.md files.",
- level: "common",
- },
- excludeLintPackageJson: {
- hint: "--exclude-lint-package-json",
- label:
- "Add eslint-plugin-package-json to lint for package.json correctness.",
- level: "common",
- },
- excludeLintPackages: {
- hint: "--exclude-lint-packages",
- label:
- "Add a pnpm dedupe workflow to ensure packages aren't duplicated unnecessarily.",
- level: "common",
- },
- excludeLintPerfectionist: {
- hint: "--exclude-lint-perfectionist",
- label:
- "Apply eslint-plugin-perfectionist to ensure imports, keys, and so on are in sorted order.",
- level: "common",
- },
- excludeLintRegexp: {
- hint: "--exclude-lint-regexp",
- label:
- "Include eslint-plugin-regexp to enforce good practices around regular expressions.",
- level: "common",
- },
- excludeLintSpelling: {
- hint: "--exclude-lint-spelling",
- label: "Add cspell to spell check against dictionaries of known words.",
- level: "common",
- },
- excludeLintStrict: {
- hint: "--exclude-lint-strict",
- label:
- "Include strict logical lint rules such as typescript-eslint's strict config. ",
- level: "common",
- },
- excludeLintStylistic: {
- hint: "--exclude-lint-stylistic",
- label:
- "Include stylistic lint rules such as typescript-eslint's stylistic config.",
- level: "common",
- },
- excludeLintYml: {
- hint: "--exclude-lint-yml",
- label: "Apply linting and sorting to *.yaml and *.yml files.",
- level: "common",
- },
- excludeReleases: {
- hint: "--exclude-releases",
- label:
- "Add release-it to generate changelogs, package bumps, and publishes based on conventional commits.",
- },
- excludeRenovate: {
- hint: "--exclude-renovate",
- label: "Add a Renovate config to keep dependencies up-to-date with PRs.",
- },
- excludeTemplatedBy: {
- hint: "--exclude-templated-by",
- label:
- 'Add a _"This package was templated with create-typescript-app"_ notice at the end of the README.md.',
- level: "minimal",
- },
- excludeTests: {
- hint: "--exclude-tests",
- label:
- "Add Vitest tooling for fast unit tests, configured with coverage tracking.",
- },
- };
-
-export const exclusionKeys = Object.keys(
- exclusionDescriptions,
-) as ExclusionKey[];
-
-export function getExclusions(
- options: Partial,
- base?: OptionsBase,
-): Partial {
- switch (base) {
- case "common":
- return {
- ...Object.fromEntries(
- exclusionKeys
- .filter(
- (exclusion) =>
- exclusionDescriptions[exclusion].level === "common",
- )
- .map((exclusion) => [exclusion, options[exclusion] ?? true]),
- ),
- };
- case "minimal":
- return {
- ...Object.fromEntries(
- exclusionKeys
- .filter(
- (exclusion) =>
- exclusionDescriptions[exclusion].level !== "minimal",
- )
- .map((exclusion) => [exclusion, options[exclusion] ?? true]),
- ),
- };
- // We only really care about exclusions on the common and minimal bases
- default:
- return {};
- }
-}
diff --git a/src/shared/options/getBase.test.ts b/src/shared/options/getBase.test.ts
deleted file mode 100644
index 9f50ce440..000000000
--- a/src/shared/options/getBase.test.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import { describe, expect, it, vi } from "vitest";
-
-import { getBase } from "./getBase.js";
-
-const mockReadPackageData = vi.fn();
-vi.mock("../packages.js", () => ({
- get readPackageData() {
- return mockReadPackageData;
- },
-}));
-
-describe("getBase", () => {
- it("should return minimal with minimal scripts", async () => {
- mockReadPackageData.mockImplementationOnce(() =>
- Promise.resolve({
- scripts: {
- build: "build",
- lint: "lint",
- test: "test",
- },
- }),
- );
-
- expect(await getBase()).toBe("minimal");
- });
-
- it("should return common with common scripts", async () => {
- mockReadPackageData.mockImplementationOnce(() =>
- Promise.resolve({
- scripts: {
- build: "build",
- lint: "lint",
- "lint:knip": "knip",
- test: "test",
- },
- }),
- );
-
- expect(await getBase()).toBe("common");
- });
-
- it("should return everything with everything scripts", async () => {
- mockReadPackageData.mockImplementationOnce(() =>
- Promise.resolve({
- scripts: {
- build: "build",
- lint: "lint",
- "lint:knip": "knip",
- "lint:md": "md",
- "lint:packages": "packages",
- "lint:spelling": "spelling",
- test: "test",
- },
- }),
- );
-
- expect(await getBase()).toBe("everything");
- });
-});
diff --git a/src/shared/options/getBase.ts b/src/shared/options/getBase.ts
deleted file mode 100644
index af5e8bf6e..000000000
--- a/src/shared/options/getBase.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { readPackageData } from "../packages.js";
-import { OptionsBase } from "../types.js";
-
-const commonScripts = new Set(["lint:knip", "test"]);
-
-const everythingScripts = new Set([
- "lint:md",
- "lint:packages",
- "lint:spelling",
-]);
-
-export async function getBase(): Promise {
- const scripts = Object.keys((await readPackageData()).scripts ?? {});
-
- if (
- scripts.reduce(
- (acc, curr) => (everythingScripts.has(curr) ? acc + 1 : acc),
- 0,
- ) >= 3
- ) {
- return "everything";
- }
-
- if (
- scripts.reduce(
- (acc, curr) => (commonScripts.has(curr) ? acc + 1 : acc),
- 0,
- ) >= 2
- ) {
- return "common";
- }
-
- return "minimal";
-}
diff --git a/src/shared/options/getPrefillOrPromptedOption.test.ts b/src/shared/options/getPrefillOrPromptedOption.test.ts
deleted file mode 100644
index ef190dd49..000000000
--- a/src/shared/options/getPrefillOrPromptedOption.test.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-import { TextOptions } from "@clack/prompts";
-import { describe, expect, it, vi } from "vitest";
-
-import { getPrefillOrPromptedOption } from "./getPrefillOrPromptedOption.js";
-
-const mockText = vi.fn();
-
-vi.mock("@clack/prompts", () => ({
- isCancel: () => false,
- get text() {
- return mockText;
- },
-}));
-
-describe("getPrefillOrPromptedValue", () => {
- it("returns the provided when it exists", async () => {
- const value = "Test Value";
-
- const actual = await getPrefillOrPromptedOption({
- auto: true,
- getDefaultValue: vi.fn().mockResolvedValue("default value"),
- message: "Input message.",
- name: "field",
- provided: value,
- });
-
- expect(actual).toEqual({ error: undefined, value });
- });
-
- it("returns the default value when auto is true and it exists", async () => {
- const value = "Test Value";
-
- const actual = await getPrefillOrPromptedOption({
- auto: true,
- getDefaultValue: vi.fn().mockResolvedValue(value),
- message: "Input message.",
- name: "field",
- });
-
- expect(actual).toEqual({ error: undefined, value });
- });
-
- it("returns an error when auto is true and no default value exists", async () => {
- const actual = await getPrefillOrPromptedOption({
- auto: true,
- getDefaultValue: vi.fn().mockResolvedValue(undefined),
- message: "Input message.",
- name: "field",
- });
-
- expect(actual).toEqual({
- error: "Could not infer a default value for field.",
- value: undefined,
- });
- });
-
- it("provides no placeholder when one is not provided and auto is false", async () => {
- const message = "Test message";
-
- await getPrefillOrPromptedOption({ auto: false, message, name: "field" });
-
- expect(mockText).toHaveBeenCalledWith({
- message,
- placeholder: undefined,
- validate: expect.any(Function),
- });
- });
-
- it("prompts with the default value as a placeholder when a placeholder function is provided and auto is false", async () => {
- const message = "Test message";
- const placeholder = "Test placeholder";
-
- await getPrefillOrPromptedOption({
- auto: false,
- getDefaultValue: vi.fn().mockResolvedValue(placeholder),
- message,
- name: "field",
- });
-
- expect(mockText).toHaveBeenCalledWith({
- message,
- placeholder,
- validate: expect.any(Function),
- });
- });
-
- it("validates entered text when it's not blank and auto is false", async () => {
- const message = "Test message";
-
- await getPrefillOrPromptedOption({ auto: false, message, name: "field" });
-
- const { validate } = (mockText.mock.calls[0] as [Required])[0];
-
- expect(validate(message)).toBeUndefined();
- });
-
- it("invalidates entered text when it's blank and auto is false", async () => {
- const message = "";
-
- await getPrefillOrPromptedOption({ auto: false, message, name: "field" });
-
- const { validate } = (mockText.mock.calls[0] as [Required])[0];
-
- expect(validate(message)).toBe("Please enter a value.");
- });
-});
diff --git a/src/shared/options/getPrefillOrPromptedOption.ts b/src/shared/options/getPrefillOrPromptedOption.ts
deleted file mode 100644
index 17384ba34..000000000
--- a/src/shared/options/getPrefillOrPromptedOption.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import * as prompts from "@clack/prompts";
-
-import { filterPromptCancel } from "../prompts.js";
-
-export interface GetPrefillOrPromptedOptionOptions {
- auto: boolean;
- getDefaultValue?: () => Promise;
- message: string;
- name: string;
- provided?: string | undefined;
-}
-
-export async function getPrefillOrPromptedOption({
- auto,
- getDefaultValue,
- message,
- name,
- provided,
-}: GetPrefillOrPromptedOptionOptions) {
- if (provided) {
- return { value: provided };
- }
-
- const defaultValue = await getDefaultValue?.();
-
- if (auto) {
- return {
- error: defaultValue
- ? undefined
- : `Could not infer a default value for ${name}.`,
- value: defaultValue,
- };
- }
-
- return {
- value: filterPromptCancel(
- await prompts.text({
- message,
- placeholder: defaultValue,
- validate: (val) => {
- if (val.length === 0) {
- return "Please enter a value.";
- }
- },
- }),
- ),
- };
-}
diff --git a/src/shared/options/logInferredOptions.test.ts b/src/shared/options/logInferredOptions.test.ts
deleted file mode 100644
index f3a8ec9e2..000000000
--- a/src/shared/options/logInferredOptions.test.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-import { describe, expect, it, vi } from "vitest";
-
-import { InferredOptions, logInferredOptions } from "./logInferredOptions.js";
-
-function makeProxy(receiver: T): T {
- return new Proxy(receiver, {
- get: () => makeProxy((input: string) => input),
- });
-}
-
-vi.mock("chalk", () => ({
- default: makeProxy({}),
-}));
-
-const mockLogLine = vi.fn();
-
-vi.mock("../cli/lines.js", () => ({
- get logLine() {
- return mockLogLine;
- },
-}));
-
-const options = {
- description: "Test description.",
- email: {
- github: "github@email.com",
- npm: "npm@email.com",
- },
- owner: "TestOwner",
- repository: "test-repository",
- title: "Test Title",
-} satisfies InferredOptions;
-
-describe("logInferredOptions", () => {
- it("logs the required inferred values when only they exist", () => {
- logInferredOptions(options);
-
- expect(mockLogLine.mock.calls).toMatchInlineSnapshot(`
- [
- [],
- [
- "--auto inferred the following values:",
- ],
- [
- "- description: Test description.",
- ],
- [
- "- email-github: github@email.com",
- ],
- [
- "- email-npm: github@email.com",
- ],
- [
- "- owner: TestOwner",
- ],
- [
- "- repository: test-repository",
- ],
- [
- "- title: Test Title",
- ],
- ]
- `);
- });
-
- it("logs additional and required inferred values when all they exist", () => {
- logInferredOptions({
- ...options,
- guide: {
- href: "https://example.com/guide",
- title: "Example Guide",
- },
- logo: {
- alt: "Logo text.",
- src: "https://example.com/logo",
- },
- });
-
- expect(mockLogLine.mock.calls).toMatchInlineSnapshot(`
- [
- [],
- [
- "--auto inferred the following values:",
- ],
- [
- "- description: Test description.",
- ],
- [
- "- email-github: github@email.com",
- ],
- [
- "- email-npm: github@email.com",
- ],
- [
- "- guide: https://example.com/guide",
- ],
- [
- "- guide-title: Example Guide",
- ],
- [
- "- logo: https://example.com/logo",
- ],
- [
- "- logo-alt: Logo text.",
- ],
- [
- "- owner: TestOwner",
- ],
- [
- "- repository: test-repository",
- ],
- [
- "- title: Test Title",
- ],
- ]
- `);
- });
-});
diff --git a/src/shared/options/logInferredOptions.ts b/src/shared/options/logInferredOptions.ts
deleted file mode 100644
index 833d25c78..000000000
--- a/src/shared/options/logInferredOptions.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import chalk from "chalk";
-
-import { logLine } from "../cli/lines.js";
-import { Options } from "../types.js";
-
-export type InferredOptions = Pick<
- Options,
- "description" | "email" | "guide" | "logo" | "owner" | "repository" | "title"
->;
-
-export function logInferredOptions(augmentedOptions: InferredOptions) {
- logLine();
- logLine(chalk.gray("--auto inferred the following values:"));
- logLine(chalk.gray(`- description: ${augmentedOptions.description}`));
- logLine(chalk.gray(`- email-github: ${augmentedOptions.email.github}`));
- logLine(chalk.gray(`- email-npm: ${augmentedOptions.email.github}`));
-
- if (augmentedOptions.guide) {
- logLine(chalk.gray(`- guide: ${augmentedOptions.guide.href}`));
- logLine(chalk.gray(`- guide-title: ${augmentedOptions.guide.title}`));
- }
-
- if (augmentedOptions.logo) {
- logLine(chalk.gray(`- logo: ${augmentedOptions.logo.src}`));
- logLine(chalk.gray(`- logo-alt: ${augmentedOptions.logo.alt}`));
-
- if (augmentedOptions.logo.height) {
- logLine(chalk.gray(`- logo-height: ${augmentedOptions.logo.height}`));
- }
-
- if (augmentedOptions.logo.width) {
- logLine(chalk.gray(`- logo-width: ${augmentedOptions.logo.width}`));
- }
- }
-
- logLine(chalk.gray(`- owner: ${augmentedOptions.owner}`));
- logLine(chalk.gray(`- repository: ${augmentedOptions.repository}`));
- logLine(chalk.gray(`- title: ${augmentedOptions.title}`));
-}
diff --git a/src/shared/options/optionsSchema.ts b/src/shared/options/optionsSchema.ts
deleted file mode 100644
index 3ac1aa70c..000000000
--- a/src/shared/options/optionsSchema.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import { z } from "zod";
-
-export const optionsSchemaShape = {
- access: z.union([z.literal("public"), z.literal("restricted")]).optional(),
- author: z.string().optional(),
- auto: z.boolean().optional(),
- base: z
- .union([
- z.literal("common"),
- z.literal("everything"),
- z.literal("minimal"),
- z.literal("prompt"),
- ])
- .optional(),
- bin: z.string().optional(),
- description: z.string().optional(),
- directory: z.string().optional(),
- email: z
- .object({
- github: z.string().email(),
- npm: z.string().email(),
- })
- .optional(),
- excludeAllContributors: z.boolean().optional(),
- excludeBuild: z.boolean().optional(),
- excludeCompliance: z.boolean().optional(),
- excludeLintESLint: z.boolean().optional(),
- excludeLintJSDoc: z.boolean().optional(),
- excludeLintJson: z.boolean().optional(),
- excludeLintKnip: z.boolean().optional(),
- excludeLintMd: z.boolean().optional(),
- excludeLintPackageJson: z.boolean().optional(),
- excludeLintPackages: z.boolean().optional(),
- excludeLintPerfectionist: z.boolean().optional(),
- excludeLintRegexp: z.boolean().optional(),
- excludeLintSpelling: z.boolean().optional(),
- excludeLintStrict: z.boolean().optional(),
- excludeLintStylistic: z.boolean().optional(),
- excludeLintYml: z.boolean().optional(),
- excludeReleases: z.boolean().optional(),
- excludeRenovate: z.boolean().optional(),
- excludeTemplatedBy: z.boolean().optional(),
- excludeTests: z.boolean().optional(),
- funding: z.string().optional(),
- guide: z.string().url().optional(),
- guideTitle: z.string().optional(),
- keywords: z.array(z.string()).optional(),
- logo: z.string().optional(),
- logoAlt: z.string().optional(),
- mode: z
- .union([z.literal("create"), z.literal("initialize"), z.literal("migrate")])
- .optional(),
- offline: z.boolean().optional(),
- owner: z.string().optional(),
- preserveGeneratedFrom: z.boolean().optional(),
- repository: z.string().optional(),
- skipAllContributorsApi: z.boolean().optional(),
- skipGitHubApi: z.boolean().optional(),
- skipInstall: z.boolean().optional(),
- skipRemoval: z.boolean().optional(),
- skipRestore: z.boolean().optional(),
- skipUninstall: z.boolean().optional(),
- title: z.string().optional(),
-};
-
-export const optionsSchema = z.object(optionsSchemaShape);
diff --git a/src/shared/options/readOptions.test.ts b/src/shared/options/readOptions.test.ts
deleted file mode 100644
index e9c741bfc..000000000
--- a/src/shared/options/readOptions.test.ts
+++ /dev/null
@@ -1,843 +0,0 @@
-import { describe, expect, it, vi } from "vitest";
-import z from "zod";
-
-import { Options } from "../types.js";
-import { GetPrefillOrPromptedOptionOptions } from "./getPrefillOrPromptedOption.js";
-import { optionsSchemaShape } from "./optionsSchema.js";
-import { readOptions } from "./readOptions.js";
-
-const emptyOptions = {
- access: undefined,
- author: undefined,
- auto: false,
- base: undefined,
- bin: undefined,
- description: undefined,
- directory: undefined,
- email: undefined,
- excludeAllContributors: undefined,
- excludeCompliance: undefined,
- excludeLintESLint: undefined,
- excludeLintJSDoc: undefined,
- excludeLintJson: undefined,
- excludeLintKnip: undefined,
- excludeLintMd: undefined,
- excludeLintPackageJson: undefined,
- excludeLintPackages: undefined,
- excludeLintPerfectionist: undefined,
- excludeLintRegexp: undefined,
- excludeLintSpelling: undefined,
- excludeLintStrict: undefined,
- excludeLintYml: undefined,
- excludeReleases: undefined,
- excludeRenovate: undefined,
- excludeTemplatedBy: undefined,
- excludeTests: undefined,
- funding: undefined,
- guide: undefined,
- guideTitle: undefined,
- logo: undefined,
- logoAlt: undefined,
- offline: undefined,
- owner: undefined,
- preserveGeneratedFrom: false,
- repository: undefined,
- skipAllContributorsApi: undefined,
- skipGitHubApi: undefined,
- skipInstall: undefined,
- skipRemoval: undefined,
- skipRestore: false,
- skipUninstall: undefined,
- title: undefined,
-};
-
-const mockOptions = {
- base: "prompt",
- github: "mock.git",
- repository: "mock.repository",
-};
-
-vi.mock("../cli/spinners.ts", () => ({
- withSpinner() {
- return () => ({});
- },
-}));
-
-const mockReadPackageData = vi.fn().mockResolvedValue({});
-
-vi.mock("../packages.js", () => ({
- get readPackageData() {
- return mockReadPackageData;
- },
-}));
-
-const mockAugmentOptionsWithExcludes = vi.fn();
-
-vi.mock("./augmentOptionsWithExcludes.js", () => ({
- get augmentOptionsWithExcludes() {
- return mockAugmentOptionsWithExcludes;
- },
-}));
-
-const mockDetectEmailRedundancy = vi.fn();
-
-vi.mock("./detectEmailRedundancy.js", () => ({
- get detectEmailRedundancy() {
- return mockDetectEmailRedundancy;
- },
-}));
-
-const mockGetPrefillOrPromptedOption = vi.fn();
-
-vi.mock("./getPrefillOrPromptedOption.js", () => ({
- get getPrefillOrPromptedOption() {
- return mockGetPrefillOrPromptedOption;
- },
-}));
-
-const mockEnsureRepositoryExists = vi.fn();
-
-vi.mock("./ensureRepositoryExists.js", () => ({
- get ensureRepositoryExists() {
- return mockEnsureRepositoryExists;
- },
-}));
-
-vi.mock("./getGitHub.js", () => ({
- getGitHub() {
- return undefined;
- },
-}));
-
-vi.mock("./createOptionDefaults/index.js", () => ({
- createOptionDefaults() {
- return {
- author: vi.fn(),
- bin: vi.fn(),
- description: vi.fn(),
- email: vi.fn(),
- funding: vi.fn(),
- guide: vi.fn(),
- logo: vi.fn(),
- owner: vi.fn(),
- repository: vi.fn(),
- title: vi.fn(),
- };
- },
-}));
-
-const mockLogInferredOptions = vi.fn();
-
-vi.mock("./logInferredOptions.js", () => ({
- get logInferredOptions() {
- return mockLogInferredOptions;
- },
-}));
-
-describe("readOptions", () => {
- it("returns a cancellation when an arg is invalid", async () => {
- const validationResult = z
- .object({ base: optionsSchemaShape.base })
- .safeParse({ base: "b" });
-
- const actual = await readOptions(["--base", "b"], "migrate");
-
- expect(actual).toStrictEqual({
- cancelled: true,
- error: (validationResult as z.SafeParseError<{ base: string }>).error,
- options: { ...emptyOptions, base: "b" },
- });
- });
-
- it("returns a cancellation when an email redundancy is detected", async () => {
- const error = "Too many emails!";
- mockDetectEmailRedundancy.mockReturnValue(error);
- mockGetPrefillOrPromptedOption.mockImplementation(() => ({
- value: undefined,
- }));
-
- expect(await readOptions([], "migrate")).toStrictEqual({
- cancelled: true,
- error,
- options: {
- ...emptyOptions,
- base: "minimal",
- },
- });
- });
-
- it("returns a cancellation when the owner prompt is cancelled", async () => {
- mockDetectEmailRedundancy.mockReturnValue(false);
- mockGetPrefillOrPromptedOption.mockImplementation(() => ({
- value: undefined,
- }));
-
- expect(await readOptions([], "migrate")).toStrictEqual({
- cancelled: true,
- error: undefined,
- options: {
- ...emptyOptions,
- base: "minimal",
- },
- });
- });
-
- it("returns a cancellation when the repository prompt is cancelled", async () => {
- mockDetectEmailRedundancy.mockReturnValue(false);
- mockGetPrefillOrPromptedOption
- .mockImplementationOnce(() => ({ value: "MockOwner" }))
- .mockImplementation(() => ({ value: undefined }));
-
- expect(await readOptions([], "migrate")).toStrictEqual({
- cancelled: true,
- error: undefined,
- options: {
- ...emptyOptions,
- base: "minimal",
- owner: "MockOwner",
- },
- });
- });
-
- it("returns a cancellation when ensureRepositoryPrompt does not return a repository", async () => {
- mockDetectEmailRedundancy.mockReturnValue(false);
- mockGetPrefillOrPromptedOption
- .mockImplementationOnce(() => ({ value: "MockOwner" }))
- .mockImplementationOnce(() => ({ value: "MockRepository" }))
- .mockImplementation(() => ({ value: undefined }));
- mockEnsureRepositoryExists.mockResolvedValue({});
-
- expect(await readOptions([], "migrate")).toStrictEqual({
- cancelled: true,
- error: undefined,
- options: {
- ...emptyOptions,
- base: "minimal",
- owner: "MockOwner",
- repository: "MockRepository",
- },
- });
- });
-
- it("returns a cancellation when the description prompt is cancelled", async () => {
- mockDetectEmailRedundancy.mockReturnValue(false);
- mockGetPrefillOrPromptedOption
- .mockImplementationOnce(() => ({ value: "MockOwner" }))
- .mockImplementationOnce(() => ({ value: "MockRepository" }))
- .mockImplementation(() => ({ value: undefined }));
- mockEnsureRepositoryExists.mockResolvedValue({
- octokit: undefined,
- repository: mockOptions.repository,
- });
-
- expect(await readOptions([], "migrate")).toStrictEqual({
- cancelled: true,
- error: undefined,
- options: {
- ...emptyOptions,
- base: "minimal",
- owner: "MockOwner",
- repository: "MockRepository",
- },
- });
- });
-
- it("returns a cancellation when the title prompt is cancelled", async () => {
- mockDetectEmailRedundancy.mockReturnValue(false);
- mockGetPrefillOrPromptedOption
- .mockImplementationOnce(() => ({ value: "MockOwner" }))
- .mockImplementationOnce(() => ({ value: "MockRepository" }))
- .mockImplementationOnce(() => ({ value: "Mock description." }))
- .mockImplementation(() => ({ value: undefined }));
- mockEnsureRepositoryExists.mockResolvedValue({
- octokit: undefined,
- repository: mockOptions.repository,
- });
-
- expect(await readOptions([], "migrate")).toStrictEqual({
- cancelled: true,
- error: undefined,
- options: {
- ...emptyOptions,
- base: "minimal",
- description: "Mock description.",
- owner: "MockOwner",
- repository: "MockRepository",
- },
- });
- });
-
- it("returns a cancellation when the guide title prompt is cancelled", async () => {
- mockDetectEmailRedundancy.mockReturnValue(false);
- mockGetPrefillOrPromptedOption
- .mockImplementationOnce(() => ({ value: "MockOwner" }))
- .mockImplementationOnce(() => ({ value: "MockRepository" }))
- .mockImplementationOnce(() => ({ value: "Mock description." }))
- .mockImplementationOnce(() => ({ value: "Mock Title" }))
- .mockImplementation(() => ({ value: undefined }));
- mockEnsureRepositoryExists.mockResolvedValue({
- octokit: undefined,
- repository: mockOptions.repository,
- });
-
- expect(
- await readOptions(["--guide", "https://example.com"], "migrate"),
- ).toStrictEqual({
- cancelled: true,
- error: undefined,
- options: {
- ...emptyOptions,
- base: "minimal",
- description: "Mock description.",
- guide: "https://example.com",
- owner: "MockOwner",
- repository: "MockRepository",
- title: "Mock Title",
- },
- });
- });
-
- it("returns a cancellation when the guide alt prompt is cancelled", async () => {
- mockDetectEmailRedundancy.mockReturnValue(false);
- mockGetPrefillOrPromptedOption
- .mockImplementationOnce(() => ({ value: "MockOwner" }))
- .mockImplementationOnce(() => ({ value: "MockRepository" }))
- .mockImplementationOnce(() => ({ value: "Mock description." }))
- .mockImplementationOnce(() => ({ value: "Mock Title" }))
- .mockImplementation(() => ({ value: undefined }));
- mockEnsureRepositoryExists.mockResolvedValue({
- octokit: undefined,
- repository: mockOptions.repository,
- });
-
- expect(
- await readOptions(["--guide", "https://example.com"], "migrate"),
- ).toStrictEqual({
- cancelled: true,
- error: undefined,
- options: {
- ...emptyOptions,
- base: "minimal",
- description: "Mock description.",
- guide: "https://example.com",
- owner: "MockOwner",
- repository: "MockRepository",
- title: "Mock Title",
- },
- });
- });
-
- it("returns a cancellation when the logo alt prompt is cancelled", async () => {
- mockDetectEmailRedundancy.mockReturnValue(false);
- mockGetPrefillOrPromptedOption
- .mockImplementationOnce(() => ({ value: "MockOwner" }))
- .mockImplementationOnce(() => ({ value: "MockRepository" }))
- .mockImplementationOnce(() => ({ value: "Mock description." }))
- .mockImplementation(() => ({ value: undefined }));
- mockEnsureRepositoryExists.mockResolvedValue({
- octokit: undefined,
- repository: mockOptions.repository,
- });
-
- expect(await readOptions(["--logo", "logo.svg"], "migrate")).toStrictEqual({
- cancelled: true,
- error: undefined,
- options: {
- ...emptyOptions,
- base: "minimal",
- description: "Mock description.",
- logo: "logo.svg",
- owner: "MockOwner",
- repository: "MockRepository",
- },
- });
- });
-
- it("returns a cancellation when the email prompt is cancelled", async () => {
- mockDetectEmailRedundancy.mockReturnValue(false);
- mockGetPrefillOrPromptedOption
- .mockImplementationOnce(() => ({ value: "MockOwner" }))
- .mockImplementationOnce(() => ({ value: "MockRepository" }))
- .mockImplementationOnce(() => ({ value: "Mock description." }))
- .mockImplementationOnce(() => ({ value: "Mock title." }))
- .mockImplementation(() => ({ value: undefined }));
- mockEnsureRepositoryExists.mockResolvedValue({
- octokit: undefined,
- repository: mockOptions.repository,
- });
-
- expect(await readOptions([], "migrate")).toStrictEqual({
- cancelled: true,
- error: undefined,
- options: {
- ...emptyOptions,
- base: "minimal",
- description: "Mock description.",
- owner: "MockOwner",
- repository: "MockRepository",
- title: "Mock title.",
- },
- });
- });
-
- it("returns a cancellation when augmentOptionsWithExcludes returns undefined", async () => {
- mockDetectEmailRedundancy.mockReturnValue(false);
- mockGetPrefillOrPromptedOption
- .mockImplementationOnce(() => ({ value: "MockOwner" }))
- .mockImplementationOnce(() => ({ value: "MockRepository" }))
- .mockImplementationOnce(() => ({ value: "Mock description." }))
- .mockImplementationOnce(() => ({ value: "Mock title." }))
- .mockImplementation(() => ({ value: undefined }));
- mockEnsureRepositoryExists.mockResolvedValue({
- octokit: undefined,
- repository: mockOptions.repository,
- });
- mockAugmentOptionsWithExcludes.mockResolvedValue(undefined);
-
- expect(await readOptions([], "migrate")).toStrictEqual({
- cancelled: true,
- error: undefined,
- options: {
- ...emptyOptions,
- base: "minimal",
- description: "Mock description.",
- owner: "MockOwner",
- repository: "MockRepository",
- title: "Mock title.",
- },
- });
- });
-
- it("returns success options when --base is valid", async () => {
- mockAugmentOptionsWithExcludes.mockResolvedValue({
- ...emptyOptions,
- ...mockOptions,
- });
- mockGetPrefillOrPromptedOption.mockImplementation(() => ({
- value: "mock",
- }));
- mockEnsureRepositoryExists.mockResolvedValue({
- octokit: undefined,
- repository: mockOptions.repository,
- });
-
- expect(
- await readOptions(["--base", mockOptions.base], "migrate"),
- ).toStrictEqual({
- cancelled: false,
- octokit: undefined,
- options: {
- ...emptyOptions,
- ...mockOptions,
- },
- });
- });
-
- it("returns success options when --base is valid with all optional options", async () => {
- mockAugmentOptionsWithExcludes.mockResolvedValue({
- ...emptyOptions,
- ...mockOptions,
- });
- mockGetPrefillOrPromptedOption.mockImplementation(() => ({
- value: "mock",
- }));
- mockEnsureRepositoryExists.mockResolvedValue({
- octokit: undefined,
- repository: mockOptions.repository,
- });
-
- expect(
- await readOptions(
- [
- "--base",
- mockOptions.base,
- "--guide",
- "https://example.com",
- "--logo",
- "logo.svg",
- ],
- "migrate",
- ),
- ).toStrictEqual({
- cancelled: false,
- octokit: undefined,
- options: {
- ...emptyOptions,
- ...mockOptions,
- },
- });
- });
-
- it("returns cancelled options when augmentOptionsWithExcludes returns undefined", async () => {
- mockAugmentOptionsWithExcludes.mockResolvedValue(undefined);
- mockGetPrefillOrPromptedOption.mockImplementation(() => ({
- value: "mock",
- }));
-
- expect(
- await readOptions(["--base", mockOptions.base], "migrate"),
- ).toStrictEqual({
- cancelled: true,
- options: {
- ...emptyOptions,
- base: mockOptions.base,
- description: "mock",
- owner: "mock",
- repository: "mock",
- title: "mock",
- },
- });
- });
-
- it("defaults preserveGeneratedFrom to false when the owner is not JoshuaKGoldberg", async () => {
- mockAugmentOptionsWithExcludes.mockImplementationOnce(
- (options: Partial) => ({
- ...options,
- ...mockOptions,
- }),
- );
- mockEnsureRepositoryExists.mockResolvedValue({
- octokit: undefined,
- repository: mockOptions.repository,
- });
- mockGetPrefillOrPromptedOption.mockImplementation(() => ({
- value: "mock",
- }));
-
- expect(
- await readOptions(["--base", mockOptions.base], "migrate"),
- ).toStrictEqual({
- cancelled: false,
- octokit: undefined,
- options: expect.objectContaining({
- preserveGeneratedFrom: false,
- }),
- });
- });
-
- it("defaults preserveGeneratedFrom to true when the owner is JoshuaKGoldberg", async () => {
- mockAugmentOptionsWithExcludes.mockImplementationOnce(
- (options: Partial) => ({
- ...options,
- ...mockOptions,
- }),
- );
- mockEnsureRepositoryExists.mockResolvedValue({
- octokit: undefined,
- repository: mockOptions.repository,
- });
- mockGetPrefillOrPromptedOption.mockImplementation(() => ({
- value: "mock",
- }));
-
- expect(
- await readOptions(
- ["--base", mockOptions.base, "--owner", "JoshuaKGoldberg"],
- "migrate",
- ),
- ).toStrictEqual({
- cancelled: false,
- octokit: undefined,
- options: expect.objectContaining({
- preserveGeneratedFrom: true,
- }),
- });
- });
-
- it("defaults skipRestore to false when the mode is not create", async () => {
- mockAugmentOptionsWithExcludes.mockImplementationOnce(
- (options: Partial) => ({
- ...options,
- ...mockOptions,
- }),
- );
- mockEnsureRepositoryExists.mockResolvedValue({
- octokit: undefined,
- repository: mockOptions.repository,
- });
- mockGetPrefillOrPromptedOption.mockImplementation(() => ({
- value: "mock",
- }));
-
- expect(
- await readOptions(["--base", mockOptions.base], "migrate"),
- ).toStrictEqual({
- cancelled: false,
- octokit: undefined,
- options: expect.objectContaining({
- skipRestore: false,
- }),
- });
- });
-
- it("defaults skipRestore to true when the mode is create", async () => {
- mockAugmentOptionsWithExcludes.mockImplementationOnce(
- (options: Partial) => ({
- ...options,
- ...mockOptions,
- }),
- );
- mockEnsureRepositoryExists.mockResolvedValue({
- octokit: undefined,
- repository: mockOptions.repository,
- });
- mockGetPrefillOrPromptedOption.mockImplementation(() => ({
- value: "mock",
- }));
-
- expect(
- await readOptions(["--base", mockOptions.base], "create"),
- ).toStrictEqual({
- cancelled: false,
- octokit: undefined,
- options: expect.objectContaining({
- skipRestore: true,
- }),
- });
- });
-
- it("skips API calls when --offline is true", async () => {
- mockAugmentOptionsWithExcludes.mockImplementation((options: Options) => ({
- ...emptyOptions,
- ...mockOptions,
- ...options,
- }));
- mockGetPrefillOrPromptedOption.mockImplementation(() => ({
- value: "mock",
- }));
- mockEnsureRepositoryExists.mockResolvedValue({
- octokit: undefined,
- repository: mockOptions.repository,
- });
-
- expect(
- await readOptions(["--base", mockOptions.base, "--offline"], "migrate"),
- ).toStrictEqual({
- cancelled: false,
- octokit: undefined,
- options: {
- ...emptyOptions,
- ...mockOptions,
- access: "public",
- description: "mock",
- directory: "mock",
- email: {
- github: "mock",
- npm: "mock",
- },
- guide: undefined,
- logo: undefined,
- mode: "migrate",
- offline: true,
- owner: "mock",
- skipAllContributorsApi: true,
- skipGitHubApi: true,
- title: "mock",
- },
- });
- });
-
- it("infers base from package scripts during migration", async () => {
- mockReadPackageData.mockImplementationOnce(() =>
- Promise.resolve({
- scripts: {
- build: "build",
- lint: "lint",
- test: "test",
- },
- }),
- );
- expect(await readOptions(["--offline"], "migrate")).toStrictEqual({
- cancelled: false,
- octokit: undefined,
- options: {
- ...emptyOptions,
- ...mockOptions,
- access: "public",
- base: "minimal",
- description: "mock",
- directory: "mock",
- email: {
- github: "mock",
- npm: "mock",
- },
- guide: undefined,
- logo: undefined,
- mode: "migrate",
- offline: true,
- owner: "mock",
- skipAllContributorsApi: true,
- skipGitHubApi: true,
- title: "mock",
- },
- });
- });
-
- it("uses values when provided on the CLI", async () => {
- mockReadPackageData.mockImplementationOnce(() => ({}));
- mockGetPrefillOrPromptedOption.mockImplementation(
- async ({ getDefaultValue }: GetPrefillOrPromptedOptionOptions) => ({
- value: (await getDefaultValue?.()) ?? "mock",
- }),
- );
-
- const description = "Test description.";
- const owner = "TestOwner";
- const repository = "test-repository";
- const title = "Test Title";
-
- expect(
- await readOptions(
- [
- "--offline",
- "--description",
- description,
- "--owner",
- owner,
- "--repository",
- repository,
- "--title",
- title,
- ],
- "migrate",
- ),
- ).toStrictEqual({
- cancelled: false,
- octokit: undefined,
- options: {
- ...emptyOptions,
- ...mockOptions,
- access: "public",
- base: "minimal",
- description,
- directory: repository,
- email: {
- github: "mock",
- npm: "mock",
- },
- guide: undefined,
- logo: undefined,
- mode: "migrate",
- offline: true,
- owner,
- skipAllContributorsApi: true,
- skipGitHubApi: true,
- title,
- },
- });
-
- expect(mockLogInferredOptions).not.toHaveBeenCalled();
- });
-
- it("uses and logs values when provided on the CLI with auto", async () => {
- mockReadPackageData.mockImplementationOnce(() => ({}));
- mockGetPrefillOrPromptedOption.mockImplementation(
- async ({ getDefaultValue }: GetPrefillOrPromptedOptionOptions) => ({
- value: (await getDefaultValue?.()) ?? "mock",
- }),
- );
-
- const description = "Test description.";
- const owner = "TestOwner";
- const repository = "test-repository";
- const title = "Test Title";
-
- expect(
- await readOptions(
- [
- "--auto",
- "--offline",
- "--description",
- description,
- "--owner",
- owner,
- "--repository",
- repository,
- "--title",
- title,
- ],
- "migrate",
- ),
- ).toStrictEqual({
- cancelled: false,
- octokit: undefined,
- options: {
- ...emptyOptions,
- ...mockOptions,
- access: "public",
- auto: true,
- base: "minimal",
- description,
- directory: repository,
- email: {
- github: "mock",
- npm: "mock",
- },
- guide: undefined,
- logo: undefined,
- mode: "migrate",
- offline: true,
- owner,
- skipAllContributorsApi: true,
- skipGitHubApi: true,
- title,
- },
- });
-
- expect(mockLogInferredOptions.mock.calls).toMatchInlineSnapshot(`
- [
- [
- {
- "access": "public",
- "author": undefined,
- "auto": true,
- "base": "minimal",
- "bin": undefined,
- "description": "Test description.",
- "directory": "test-repository",
- "email": {
- "github": "mock",
- "npm": "mock",
- },
- "excludeAllContributors": undefined,
- "excludeCompliance": undefined,
- "excludeLintESLint": undefined,
- "excludeLintJSDoc": undefined,
- "excludeLintJson": undefined,
- "excludeLintKnip": undefined,
- "excludeLintMd": undefined,
- "excludeLintPackageJson": undefined,
- "excludeLintPackages": undefined,
- "excludeLintPerfectionist": undefined,
- "excludeLintRegexp": undefined,
- "excludeLintSpelling": undefined,
- "excludeLintStrict": undefined,
- "excludeLintYml": undefined,
- "excludeReleases": undefined,
- "excludeRenovate": undefined,
- "excludeTemplatedBy": undefined,
- "excludeTests": undefined,
- "funding": undefined,
- "github": "mock.git",
- "guide": undefined,
- "guideTitle": undefined,
- "logo": undefined,
- "logoAlt": undefined,
- "mode": "migrate",
- "offline": true,
- "owner": "TestOwner",
- "preserveGeneratedFrom": false,
- "repository": "mock.repository",
- "skipAllContributorsApi": true,
- "skipGitHubApi": true,
- "skipInstall": undefined,
- "skipRemoval": undefined,
- "skipRestore": false,
- "skipUninstall": undefined,
- "title": "Test Title",
- },
- ],
- ]
- `);
- });
-});
diff --git a/src/shared/options/readOptions.ts b/src/shared/options/readOptions.ts
deleted file mode 100644
index 181bde21e..000000000
--- a/src/shared/options/readOptions.ts
+++ /dev/null
@@ -1,305 +0,0 @@
-import { parseArgs } from "node:util";
-import { Octokit } from "octokit";
-import { octokitFromAuth } from "octokit-from-auth";
-import { titleCase } from "title-case";
-import { z } from "zod";
-
-import { withSpinner } from "../cli/spinners.js";
-import { Mode, OptionsGuide, PromptedOptions } from "../types.js";
-import { Options, OptionsLogo } from "../types.js";
-import { allArgOptions } from "./args.js";
-import { augmentOptionsWithExcludes } from "./augmentOptionsWithExcludes.js";
-import { createOptionDefaults } from "./createOptionDefaults/index.js";
-import { detectEmailRedundancy } from "./detectEmailRedundancy.js";
-import { ensureRepositoryExists } from "./ensureRepositoryExists.js";
-import { getBase } from "./getBase.js";
-import { getPrefillOrPromptedOption } from "./getPrefillOrPromptedOption.js";
-import { logInferredOptions } from "./logInferredOptions.js";
-import { optionsSchema } from "./optionsSchema.js";
-import { readLogoSizing } from "./readLogoSizing.js";
-
-export interface OctokitAndOptions {
- octokit: Octokit | undefined;
- options: Options;
-}
-
-export interface OptionsParseCancelled {
- cancelled: true;
- error?: string | z.ZodError