@cbnventures/nova 0.13.1 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -0
- package/bin/nova.mjs +3 -0
- package/build/package.json +38 -32
- package/build/src/api/node-releases.d.ts +4 -4
- package/build/src/api/node-releases.d.ts.map +1 -1
- package/build/src/api/node-releases.js +31 -26
- package/build/src/api/node-releases.js.map +1 -1
- package/build/src/api/spdx-licenses.d.ts +4 -4
- package/build/src/api/spdx-licenses.d.ts.map +1 -1
- package/build/src/api/spdx-licenses.js +21 -18
- package/build/src/api/spdx-licenses.js.map +1 -1
- package/build/src/cli/generate/github/funding.d.ts +5 -0
- package/build/src/cli/generate/github/funding.d.ts.map +1 -0
- package/build/src/cli/generate/github/funding.js +68 -0
- package/build/src/cli/generate/github/funding.js.map +1 -0
- package/build/src/cli/generate/github/issue-template.d.ts +5 -0
- package/build/src/cli/generate/github/issue-template.d.ts.map +1 -0
- package/build/src/cli/generate/github/issue-template.js +267 -0
- package/build/src/cli/generate/github/issue-template.js.map +1 -0
- package/build/src/cli/generate/github/workflows.d.ts +10 -0
- package/build/src/cli/generate/github/workflows.d.ts.map +1 -0
- package/build/src/cli/generate/github/workflows.js +464 -0
- package/build/src/cli/generate/github/workflows.js.map +1 -0
- package/build/src/cli/generate/must-haves/agent-conventions.d.ts +5 -0
- package/build/src/cli/generate/must-haves/agent-conventions.d.ts.map +1 -0
- package/build/src/cli/generate/must-haves/agent-conventions.js +114 -0
- package/build/src/cli/generate/must-haves/agent-conventions.js.map +1 -0
- package/build/src/cli/generate/must-haves/dotenv.d.ts +12 -0
- package/build/src/cli/generate/must-haves/dotenv.d.ts.map +1 -0
- package/build/src/cli/generate/must-haves/dotenv.js +504 -0
- package/build/src/cli/generate/must-haves/dotenv.js.map +1 -0
- package/build/src/cli/generate/must-haves/editorconfig.d.ts +5 -0
- package/build/src/cli/generate/must-haves/editorconfig.d.ts.map +1 -0
- package/build/src/cli/generate/must-haves/editorconfig.js +37 -0
- package/build/src/cli/generate/must-haves/editorconfig.js.map +1 -0
- package/build/src/cli/generate/must-haves/gitignore.d.ts +13 -0
- package/build/src/cli/generate/must-haves/gitignore.d.ts.map +1 -0
- package/build/src/cli/generate/must-haves/gitignore.js +446 -0
- package/build/src/cli/generate/must-haves/gitignore.js.map +1 -0
- package/build/src/cli/generate/must-haves/license.d.ts +5 -0
- package/build/src/cli/generate/must-haves/license.d.ts.map +1 -0
- package/build/src/cli/generate/must-haves/license.js +131 -0
- package/build/src/cli/generate/must-haves/license.js.map +1 -0
- package/build/src/cli/generate/must-haves/read-me.d.ts +8 -0
- package/build/src/cli/generate/must-haves/read-me.d.ts.map +1 -0
- package/build/src/cli/generate/must-haves/read-me.js +255 -0
- package/build/src/cli/generate/must-haves/read-me.js.map +1 -0
- package/build/src/cli/index.js +421 -107
- package/build/src/cli/index.js.map +1 -1
- package/build/src/cli/recipe/index.d.ts +3 -0
- package/build/src/cli/recipe/index.d.ts.map +1 -0
- package/build/src/cli/recipe/index.js +57 -0
- package/build/src/cli/recipe/index.js.map +1 -0
- package/build/src/cli/recipe/package-json/cleanup.d.ts +8 -0
- package/build/src/cli/recipe/package-json/cleanup.d.ts.map +1 -0
- package/build/src/cli/recipe/package-json/cleanup.js +183 -0
- package/build/src/cli/recipe/package-json/cleanup.js.map +1 -0
- package/build/src/cli/recipe/package-json/normalize-artifacts.d.ts +8 -0
- package/build/src/cli/recipe/package-json/normalize-artifacts.d.ts.map +1 -0
- package/build/src/cli/recipe/package-json/normalize-artifacts.js +250 -0
- package/build/src/cli/recipe/package-json/normalize-artifacts.js.map +1 -0
- package/build/src/cli/recipe/package-json/normalize-bundler.d.ts +6 -0
- package/build/src/cli/recipe/package-json/normalize-bundler.d.ts.map +1 -0
- package/build/src/cli/recipe/package-json/normalize-bundler.js +146 -0
- package/build/src/cli/recipe/package-json/normalize-bundler.js.map +1 -0
- package/build/src/cli/recipe/package-json/normalize-dependencies.d.ts +9 -0
- package/build/src/cli/recipe/package-json/normalize-dependencies.d.ts.map +1 -0
- package/build/src/cli/recipe/package-json/normalize-dependencies.js +268 -0
- package/build/src/cli/recipe/package-json/normalize-dependencies.js.map +1 -0
- package/build/src/cli/recipe/package-json/normalize-modules.d.ts +6 -0
- package/build/src/cli/recipe/package-json/normalize-modules.d.ts.map +1 -0
- package/build/src/cli/recipe/package-json/normalize-modules.js +263 -0
- package/build/src/cli/recipe/package-json/normalize-modules.js.map +1 -0
- package/build/src/cli/recipe/package-json/normalize-tooling.d.ts +7 -0
- package/build/src/cli/recipe/package-json/normalize-tooling.d.ts.map +1 -0
- package/build/src/cli/recipe/package-json/normalize-tooling.js +163 -0
- package/build/src/cli/recipe/package-json/normalize-tooling.js.map +1 -0
- package/build/src/cli/recipe/package-json/sync-environment.d.ts +9 -0
- package/build/src/cli/recipe/package-json/sync-environment.d.ts.map +1 -0
- package/build/src/cli/recipe/package-json/sync-environment.js +283 -0
- package/build/src/cli/recipe/package-json/sync-environment.js.map +1 -0
- package/build/src/cli/recipe/package-json/sync-identity.d.ts +6 -0
- package/build/src/cli/recipe/package-json/sync-identity.d.ts.map +1 -0
- package/build/src/cli/recipe/package-json/sync-identity.js +224 -0
- package/build/src/cli/recipe/package-json/sync-identity.js.map +1 -0
- package/build/src/cli/recipe/package-json/sync-ownership.d.ts +6 -0
- package/build/src/cli/recipe/package-json/sync-ownership.d.ts.map +1 -0
- package/build/src/cli/recipe/package-json/sync-ownership.js +349 -0
- package/build/src/cli/recipe/package-json/sync-ownership.js.map +1 -0
- package/build/src/cli/scaffold/app/expressjs.d.ts +5 -0
- package/build/src/cli/scaffold/app/expressjs.d.ts.map +1 -0
- package/build/src/cli/scaffold/app/expressjs.js +8 -0
- package/build/src/cli/scaffold/app/expressjs.js.map +1 -0
- package/build/src/cli/scaffold/app/nextjs.d.ts +5 -0
- package/build/src/cli/scaffold/app/nextjs.d.ts.map +1 -0
- package/build/src/cli/scaffold/app/nextjs.js +8 -0
- package/build/src/cli/scaffold/app/nextjs.js.map +1 -0
- package/build/src/cli/scaffold/app/vite.d.ts +5 -0
- package/build/src/cli/scaffold/app/vite.d.ts.map +1 -0
- package/build/src/cli/scaffold/app/vite.js +8 -0
- package/build/src/cli/scaffold/app/vite.js.map +1 -0
- package/build/src/cli/scaffold/app/workers.d.ts +5 -0
- package/build/src/cli/scaffold/app/workers.d.ts.map +1 -0
- package/build/src/cli/scaffold/app/workers.js +8 -0
- package/build/src/cli/scaffold/app/workers.js.map +1 -0
- package/build/src/cli/scaffold/docs/docusaurus.d.ts +5 -0
- package/build/src/cli/scaffold/docs/docusaurus.d.ts.map +1 -0
- package/build/src/cli/scaffold/docs/docusaurus.js +8 -0
- package/build/src/cli/scaffold/docs/docusaurus.js.map +1 -0
- package/build/src/cli/scaffold/starter/base.d.ts +5 -0
- package/build/src/cli/scaffold/starter/base.d.ts.map +1 -0
- package/build/src/cli/scaffold/starter/base.js +132 -0
- package/build/src/cli/scaffold/starter/base.js.map +1 -0
- package/build/src/cli/utility/changelog.d.ts +3 -3
- package/build/src/cli/utility/changelog.d.ts.map +1 -1
- package/build/src/cli/utility/changelog.js +207 -173
- package/build/src/cli/utility/changelog.js.map +1 -1
- package/build/src/cli/utility/initialize.d.ts +6 -3
- package/build/src/cli/utility/initialize.d.ts.map +1 -1
- package/build/src/cli/utility/initialize.js +1194 -284
- package/build/src/cli/utility/initialize.js.map +1 -1
- package/build/src/cli/utility/run-recipes.d.ts +5 -0
- package/build/src/cli/utility/run-recipes.d.ts.map +1 -0
- package/build/src/cli/utility/run-recipes.js +43 -0
- package/build/src/cli/utility/run-recipes.js.map +1 -0
- package/build/src/cli/utility/run-scripts.d.ts +10 -0
- package/build/src/cli/utility/run-scripts.d.ts.map +1 -0
- package/build/src/cli/utility/run-scripts.js +257 -0
- package/build/src/cli/utility/run-scripts.js.map +1 -0
- package/build/src/cli/utility/transpile.d.ts +9 -0
- package/build/src/cli/utility/transpile.d.ts.map +1 -0
- package/build/src/cli/utility/transpile.js +64 -0
- package/build/src/cli/utility/transpile.js.map +1 -0
- package/build/src/cli/utility/type-check.d.ts +3 -3
- package/build/src/cli/utility/type-check.d.ts.map +1 -1
- package/build/src/cli/utility/type-check.js +26 -21
- package/build/src/cli/utility/type-check.js.map +1 -1
- package/build/src/cli/utility/version.d.ts +3 -3
- package/build/src/cli/utility/version.d.ts.map +1 -1
- package/build/src/cli/utility/version.js +126 -68
- package/build/src/cli/utility/version.js.map +1 -1
- package/build/src/lib/item.d.ts +31 -24
- package/build/src/lib/item.d.ts.map +1 -1
- package/build/src/lib/item.js +129 -39
- package/build/src/lib/item.js.map +1 -1
- package/build/src/lib/nova-config.d.ts +6 -5
- package/build/src/lib/nova-config.d.ts.map +1 -1
- package/build/src/lib/nova-config.js +252 -69
- package/build/src/lib/nova-config.js.map +1 -1
- package/build/src/lib/regex.d.ts +92 -26
- package/build/src/lib/regex.d.ts.map +1 -1
- package/build/src/lib/regex.js +92 -26
- package/build/src/lib/regex.js.map +1 -1
- package/build/src/lib/scaffold.d.ts +10 -0
- package/build/src/lib/scaffold.d.ts.map +1 -0
- package/build/src/lib/scaffold.js +535 -0
- package/build/src/lib/scaffold.js.map +1 -0
- package/build/src/lib/schema.d.ts +2 -9
- package/build/src/lib/schema.d.ts.map +1 -1
- package/build/src/lib/schema.js +6 -8
- package/build/src/lib/schema.js.map +1 -1
- package/build/src/lib/utility.d.ts +21 -18
- package/build/src/lib/utility.d.ts.map +1 -1
- package/build/src/lib/utility.js +176 -79
- package/build/src/lib/utility.js.map +1 -1
- package/build/src/lib/workflow-templates.d.ts +3 -0
- package/build/src/lib/workflow-templates.d.ts.map +1 -0
- package/build/src/lib/workflow-templates.js +187 -0
- package/build/src/lib/workflow-templates.js.map +1 -0
- package/build/src/presets/eslint/dx-code-style.d.ts +4 -0
- package/build/src/presets/eslint/dx-code-style.d.ts.map +1 -0
- package/build/src/presets/eslint/dx-code-style.js +523 -0
- package/build/src/presets/eslint/dx-code-style.js.map +1 -0
- package/build/src/presets/eslint/dx-ignore.d.ts +4 -0
- package/build/src/presets/eslint/dx-ignore.d.ts.map +1 -0
- package/build/src/presets/eslint/{dx-ignore.mjs → dx-ignore.js} +1 -1
- package/build/src/presets/eslint/dx-ignore.js.map +1 -0
- package/build/src/presets/eslint/fw-docusaurus.d.ts +4 -0
- package/build/src/presets/eslint/fw-docusaurus.d.ts.map +1 -0
- package/build/src/presets/eslint/fw-docusaurus.js +6 -0
- package/build/src/presets/eslint/fw-docusaurus.js.map +1 -0
- package/build/src/presets/eslint/fw-expressjs.d.ts +4 -0
- package/build/src/presets/eslint/fw-expressjs.d.ts.map +1 -0
- package/build/src/presets/eslint/{fw-expressjs.mjs → fw-expressjs.js} +3 -5
- package/build/src/presets/eslint/fw-expressjs.js.map +1 -0
- package/build/src/presets/eslint/fw-nextjs.d.ts +4 -0
- package/build/src/presets/eslint/fw-nextjs.d.ts.map +1 -0
- package/build/src/presets/eslint/{fw-nextjs.mjs → fw-nextjs.js} +3 -5
- package/build/src/presets/eslint/fw-nextjs.js.map +1 -0
- package/build/src/presets/eslint/index.d.ts +16 -0
- package/build/src/presets/eslint/index.d.ts.map +1 -0
- package/build/src/presets/eslint/index.js +16 -0
- package/build/src/presets/eslint/index.js.map +1 -0
- package/build/src/presets/eslint/lang-javascript.d.ts +4 -0
- package/build/src/presets/eslint/lang-javascript.d.ts.map +1 -0
- package/build/src/presets/eslint/lang-javascript.js +34 -0
- package/build/src/presets/eslint/lang-javascript.js.map +1 -0
- package/build/src/presets/eslint/lang-mdx.d.ts +4 -0
- package/build/src/presets/eslint/lang-mdx.d.ts.map +1 -0
- package/build/src/presets/eslint/{lang-mdx.mjs → lang-mdx.js} +4 -8
- package/build/src/presets/eslint/lang-mdx.js.map +1 -0
- package/build/src/presets/eslint/lang-typescript.d.ts +4 -0
- package/build/src/presets/eslint/lang-typescript.d.ts.map +1 -0
- package/build/src/presets/eslint/lang-typescript.js +148 -0
- package/build/src/presets/eslint/lang-typescript.js.map +1 -0
- package/build/src/presets/eslint/runtime-browser.d.ts +4 -0
- package/build/src/presets/eslint/runtime-browser.d.ts.map +1 -0
- package/build/src/presets/eslint/{env-web-worker.mjs → runtime-browser.js} +1 -1
- package/build/src/presets/eslint/runtime-browser.js.map +1 -0
- package/build/src/presets/eslint/runtime-cloudflare-workers.d.ts +4 -0
- package/build/src/presets/eslint/runtime-cloudflare-workers.d.ts.map +1 -0
- package/build/src/presets/eslint/runtime-cloudflare-workers.js +6 -0
- package/build/src/presets/eslint/runtime-cloudflare-workers.js.map +1 -0
- package/build/src/presets/eslint/runtime-edge.d.ts +4 -0
- package/build/src/presets/eslint/runtime-edge.d.ts.map +1 -0
- package/build/src/presets/eslint/{env-edge.mjs → runtime-edge.js} +1 -1
- package/build/src/presets/eslint/runtime-edge.js.map +1 -0
- package/build/src/presets/eslint/runtime-node.d.ts +4 -0
- package/build/src/presets/eslint/runtime-node.d.ts.map +1 -0
- package/build/src/presets/eslint/{env-node.mjs → runtime-node.js} +4 -4
- package/build/src/presets/eslint/runtime-node.js.map +1 -0
- package/build/src/presets/eslint/runtime-service-worker.d.ts +4 -0
- package/build/src/presets/eslint/runtime-service-worker.d.ts.map +1 -0
- package/build/src/presets/eslint/runtime-service-worker.js +3 -0
- package/build/src/presets/eslint/runtime-service-worker.js.map +1 -0
- package/build/src/presets/eslint/runtime-web-worker.d.ts +4 -0
- package/build/src/presets/eslint/runtime-web-worker.d.ts.map +1 -0
- package/build/src/presets/eslint/runtime-web-worker.js +3 -0
- package/build/src/presets/eslint/runtime-web-worker.js.map +1 -0
- package/build/src/presets/eslint/tool-vite.d.ts +4 -0
- package/build/src/presets/eslint/tool-vite.d.ts.map +1 -0
- package/build/src/presets/eslint/{tool-vite.mjs → tool-vite.js} +3 -5
- package/build/src/presets/eslint/tool-vite.js.map +1 -0
- package/build/src/presets/tsconfig/dx-strict.json +1 -0
- package/build/src/presets/tsconfig/runtime-cloudflare-workers.json +12 -0
- package/build/src/presets/tsconfig/{platform-cloudflare-workers.json → runtime-web-worker.json} +2 -2
- package/build/src/rules/eslint/conventions/no-default-export-declaration.d.ts +11 -0
- package/build/src/rules/eslint/conventions/no-default-export-declaration.d.ts.map +1 -0
- package/build/src/rules/eslint/conventions/no-default-export-declaration.js +73 -0
- package/build/src/rules/eslint/conventions/no-default-export-declaration.js.map +1 -0
- package/build/src/rules/eslint/conventions/no-implicit-boolean.d.ts +15 -0
- package/build/src/rules/eslint/conventions/no-implicit-boolean.d.ts.map +1 -0
- package/build/src/rules/eslint/conventions/no-implicit-boolean.js +140 -0
- package/build/src/rules/eslint/conventions/no-implicit-boolean.js.map +1 -0
- package/build/src/rules/eslint/conventions/require-explicit-return.d.ts +15 -0
- package/build/src/rules/eslint/conventions/require-explicit-return.d.ts.map +1 -0
- package/build/src/rules/eslint/conventions/require-explicit-return.js +184 -0
- package/build/src/rules/eslint/conventions/require-explicit-return.js.map +1 -0
- package/build/src/rules/eslint/conventions/require-hash-private.d.ts +12 -0
- package/build/src/rules/eslint/conventions/require-hash-private.d.ts.map +1 -0
- package/build/src/rules/eslint/conventions/require-hash-private.js +67 -0
- package/build/src/rules/eslint/conventions/require-hash-private.js.map +1 -0
- package/build/src/rules/eslint/conventions/require-kebab-case-filename.d.ts +14 -0
- package/build/src/rules/eslint/conventions/require-kebab-case-filename.d.ts.map +1 -0
- package/build/src/rules/eslint/conventions/require-kebab-case-filename.js +95 -0
- package/build/src/rules/eslint/conventions/require-kebab-case-filename.js.map +1 -0
- package/build/src/rules/eslint/conventions/require-naming-convention.d.ts +34 -0
- package/build/src/rules/eslint/conventions/require-naming-convention.d.ts.map +1 -0
- package/build/src/rules/eslint/conventions/require-naming-convention.js +382 -0
- package/build/src/rules/eslint/conventions/require-naming-convention.js.map +1 -0
- package/build/src/rules/eslint/conventions/require-undefined-init.d.ts +11 -0
- package/build/src/rules/eslint/conventions/require-undefined-init.d.ts.map +1 -0
- package/build/src/rules/eslint/conventions/require-undefined-init.js +71 -0
- package/build/src/rules/eslint/conventions/require-undefined-init.js.map +1 -0
- package/build/src/rules/eslint/conventions/switch-case-blocks.d.ts +13 -0
- package/build/src/rules/eslint/conventions/switch-case-blocks.d.ts.map +1 -0
- package/build/src/rules/eslint/conventions/switch-case-blocks.js +82 -0
- package/build/src/rules/eslint/conventions/switch-case-blocks.js.map +1 -0
- package/build/src/rules/eslint/formatting/no-complex-arrow-concise.d.ts +15 -0
- package/build/src/rules/eslint/formatting/no-complex-arrow-concise.d.ts.map +1 -0
- package/build/src/rules/eslint/formatting/no-complex-arrow-concise.js +166 -0
- package/build/src/rules/eslint/formatting/no-complex-arrow-concise.js.map +1 -0
- package/build/src/rules/eslint/formatting/no-multiline-strings.d.ts +15 -0
- package/build/src/rules/eslint/formatting/no-multiline-strings.d.ts.map +1 -0
- package/build/src/rules/eslint/formatting/no-multiline-strings.js +162 -0
- package/build/src/rules/eslint/formatting/no-multiline-strings.js.map +1 -0
- package/build/src/rules/eslint/formatting/no-raw-text-in-code.d.ts +11 -0
- package/build/src/rules/eslint/formatting/no-raw-text-in-code.d.ts.map +1 -0
- package/build/src/rules/eslint/formatting/no-raw-text-in-code.js +57 -0
- package/build/src/rules/eslint/formatting/no-raw-text-in-code.js.map +1 -0
- package/build/src/rules/eslint/formatting/no-ternary-in-template-literal.d.ts +11 -0
- package/build/src/rules/eslint/formatting/no-ternary-in-template-literal.d.ts.map +1 -0
- package/build/src/rules/eslint/formatting/no-ternary-in-template-literal.js +55 -0
- package/build/src/rules/eslint/formatting/no-ternary-in-template-literal.js.map +1 -0
- package/build/src/rules/eslint/formatting/require-import-order.d.ts +14 -0
- package/build/src/rules/eslint/formatting/require-import-order.d.ts.map +1 -0
- package/build/src/rules/eslint/formatting/require-import-order.js +187 -0
- package/build/src/rules/eslint/formatting/require-import-order.js.map +1 -0
- package/build/src/rules/eslint/formatting/require-multiline-condition-groups.d.ts +13 -0
- package/build/src/rules/eslint/formatting/require-multiline-condition-groups.d.ts.map +1 -0
- package/build/src/rules/eslint/formatting/require-multiline-condition-groups.js +138 -0
- package/build/src/rules/eslint/formatting/require-multiline-condition-groups.js.map +1 -0
- package/build/src/rules/eslint/formatting/require-multiline-conditions.d.ts +13 -0
- package/build/src/rules/eslint/formatting/require-multiline-conditions.d.ts.map +1 -0
- package/build/src/rules/eslint/formatting/require-multiline-conditions.js +94 -0
- package/build/src/rules/eslint/formatting/require-multiline-conditions.js.map +1 -0
- package/build/src/rules/eslint/formatting/require-padding-lines.d.ts +25 -0
- package/build/src/rules/eslint/formatting/require-padding-lines.d.ts.map +1 -0
- package/build/src/rules/eslint/formatting/require-padding-lines.js +309 -0
- package/build/src/rules/eslint/formatting/require-padding-lines.js.map +1 -0
- package/build/src/rules/eslint/formatting/require-ternary-parens.d.ts +11 -0
- package/build/src/rules/eslint/formatting/require-ternary-parens.d.ts.map +1 -0
- package/build/src/rules/eslint/formatting/require-ternary-parens.js +76 -0
- package/build/src/rules/eslint/formatting/require-ternary-parens.js.map +1 -0
- package/build/src/rules/eslint/index.d.ts +44 -5
- package/build/src/rules/eslint/index.d.ts.map +1 -1
- package/build/src/rules/eslint/index.js +44 -5
- package/build/src/rules/eslint/index.js.map +1 -1
- package/build/src/rules/eslint/jsdoc/require-jsdoc-body.d.ts +15 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-body.d.ts.map +1 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-body.js +176 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-body.js.map +1 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-hierarchy.d.ts +26 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-hierarchy.d.ts.map +1 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-hierarchy.js +495 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-hierarchy.js.map +1 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-param-alignment.d.ts +12 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-param-alignment.d.ts.map +1 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-param-alignment.js +144 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-param-alignment.js.map +1 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-param-name.d.ts +12 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-param-name.d.ts.map +1 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-param-name.js +97 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-param-name.js.map +1 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-private.d.ts +11 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-private.d.ts.map +1 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-private.js +90 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-private.js.map +1 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-since.d.ts +11 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-since.d.ts.map +1 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-since.js +88 -0
- package/build/src/rules/eslint/jsdoc/require-jsdoc-since.js.map +1 -0
- package/build/src/rules/eslint/nova/no-logger-dev.d.ts +13 -0
- package/build/src/rules/eslint/nova/no-logger-dev.d.ts.map +1 -0
- package/build/src/rules/eslint/nova/no-logger-dev.js +112 -0
- package/build/src/rules/eslint/nova/no-logger-dev.js.map +1 -0
- package/build/src/rules/eslint/patterns/no-assign-then-return.d.ts +11 -0
- package/build/src/rules/eslint/patterns/no-assign-then-return.d.ts.map +1 -0
- package/build/src/rules/eslint/patterns/no-assign-then-return.js +96 -0
- package/build/src/rules/eslint/patterns/no-assign-then-return.js.map +1 -0
- package/build/src/rules/eslint/patterns/no-await-in-loop.d.ts +17 -0
- package/build/src/rules/eslint/patterns/no-await-in-loop.d.ts.map +1 -0
- package/build/src/rules/eslint/patterns/no-await-in-loop.js +103 -0
- package/build/src/rules/eslint/patterns/no-await-in-loop.js.map +1 -0
- package/build/src/rules/eslint/patterns/no-boolean-var-for-if.d.ts +11 -0
- package/build/src/rules/eslint/patterns/no-boolean-var-for-if.d.ts.map +1 -0
- package/build/src/rules/eslint/patterns/no-boolean-var-for-if.js +100 -0
- package/build/src/rules/eslint/patterns/no-boolean-var-for-if.js.map +1 -0
- package/build/src/rules/eslint/patterns/no-bracket-assignment.d.ts +11 -0
- package/build/src/rules/eslint/patterns/no-bracket-assignment.d.ts.map +1 -0
- package/build/src/rules/eslint/patterns/no-bracket-assignment.js +69 -0
- package/build/src/rules/eslint/patterns/no-bracket-assignment.js.map +1 -0
- package/build/src/rules/eslint/patterns/no-bracket-method-call.d.ts +12 -0
- package/build/src/rules/eslint/patterns/no-bracket-method-call.d.ts.map +1 -0
- package/build/src/rules/eslint/patterns/no-bracket-method-call.js +86 -0
- package/build/src/rules/eslint/patterns/no-bracket-method-call.js.map +1 -0
- package/build/src/rules/eslint/patterns/no-template-curly-in-string.d.ts +11 -0
- package/build/src/rules/eslint/patterns/no-template-curly-in-string.d.ts.map +1 -0
- package/build/src/rules/eslint/patterns/no-template-curly-in-string.js +77 -0
- package/build/src/rules/eslint/patterns/no-template-curly-in-string.js.map +1 -0
- package/build/src/rules/eslint/patterns/no-use-before-define.d.ts +15 -0
- package/build/src/rules/eslint/patterns/no-use-before-define.d.ts.map +1 -0
- package/build/src/rules/eslint/patterns/no-use-before-define.js +148 -0
- package/build/src/rules/eslint/patterns/no-use-before-define.js.map +1 -0
- package/build/src/rules/eslint/regex/no-regex-literal-flags.d.ts +11 -0
- package/build/src/rules/eslint/regex/no-regex-literal-flags.d.ts.map +1 -0
- package/build/src/rules/eslint/regex/no-regex-literal-flags.js +55 -0
- package/build/src/rules/eslint/regex/no-regex-literal-flags.js.map +1 -0
- package/build/src/rules/eslint/regex/no-regex-literals.d.ts +12 -0
- package/build/src/rules/eslint/regex/no-regex-literals.d.ts.map +1 -0
- package/build/src/rules/eslint/regex/no-regex-literals.js +72 -0
- package/build/src/rules/eslint/regex/no-regex-literals.js.map +1 -0
- package/build/src/rules/eslint/safety/no-script-url.d.ts +12 -0
- package/build/src/rules/eslint/safety/no-script-url.d.ts.map +1 -0
- package/build/src/rules/eslint/safety/no-script-url.js +71 -0
- package/build/src/rules/eslint/safety/no-script-url.js.map +1 -0
- package/build/src/rules/eslint/syntax/no-destructuring.d.ts +21 -0
- package/build/src/rules/eslint/syntax/no-destructuring.d.ts.map +1 -0
- package/build/src/rules/eslint/syntax/no-destructuring.js +219 -0
- package/build/src/rules/eslint/syntax/no-destructuring.js.map +1 -0
- package/build/src/rules/eslint/syntax/no-numeric-literals.d.ts +14 -0
- package/build/src/rules/eslint/syntax/no-numeric-literals.d.ts.map +1 -0
- package/build/src/rules/eslint/syntax/no-numeric-literals.js +108 -0
- package/build/src/rules/eslint/syntax/no-numeric-literals.js.map +1 -0
- package/build/src/rules/eslint/syntax/no-optional-chaining.d.ts +11 -0
- package/build/src/rules/eslint/syntax/no-optional-chaining.d.ts.map +1 -0
- package/build/src/rules/eslint/syntax/no-optional-chaining.js +51 -0
- package/build/src/rules/eslint/syntax/no-optional-chaining.js.map +1 -0
- package/build/src/rules/eslint/syntax/no-rest-params.d.ts +15 -0
- package/build/src/rules/eslint/syntax/no-rest-params.d.ts.map +1 -0
- package/build/src/rules/eslint/syntax/no-rest-params.js +158 -0
- package/build/src/rules/eslint/syntax/no-rest-params.js.map +1 -0
- package/build/src/rules/eslint/typescript/no-catch-unknown-annotation.d.ts +11 -0
- package/build/src/rules/eslint/typescript/no-catch-unknown-annotation.d.ts.map +1 -0
- package/build/src/rules/eslint/typescript/no-catch-unknown-annotation.js +65 -0
- package/build/src/rules/eslint/typescript/no-catch-unknown-annotation.js.map +1 -0
- package/build/src/rules/eslint/typescript/no-explicit-any.d.ts +11 -0
- package/build/src/rules/eslint/typescript/no-explicit-any.d.ts.map +1 -0
- package/build/src/rules/eslint/typescript/no-explicit-any.js +51 -0
- package/build/src/rules/eslint/typescript/no-explicit-any.js.map +1 -0
- package/build/src/rules/eslint/typescript/no-inline-type-annotation.d.ts +16 -0
- package/build/src/rules/eslint/typescript/no-inline-type-annotation.d.ts.map +1 -0
- package/build/src/rules/eslint/typescript/no-inline-type-annotation.js +186 -0
- package/build/src/rules/eslint/typescript/no-inline-type-annotation.js.map +1 -0
- package/build/src/rules/eslint/typescript/no-shared-type-import.d.ts +12 -0
- package/build/src/rules/eslint/typescript/no-shared-type-import.d.ts.map +1 -0
- package/build/src/rules/eslint/typescript/no-shared-type-import.js +71 -0
- package/build/src/rules/eslint/typescript/no-shared-type-import.js.map +1 -0
- package/build/src/rules/eslint/typescript/require-bracket-property-access.d.ts +12 -0
- package/build/src/rules/eslint/typescript/require-bracket-property-access.d.ts.map +1 -0
- package/build/src/rules/eslint/typescript/require-bracket-property-access.js +115 -0
- package/build/src/rules/eslint/typescript/require-bracket-property-access.js.map +1 -0
- package/build/src/rules/eslint/typescript/require-type-naming.d.ts +12 -0
- package/build/src/rules/eslint/typescript/require-type-naming.d.ts.map +1 -0
- package/build/src/rules/eslint/typescript/require-type-naming.js +98 -0
- package/build/src/rules/eslint/typescript/require-type-naming.js.map +1 -0
- package/build/src/toolkit/bootstrap.d.ts +13 -0
- package/build/src/toolkit/bootstrap.d.ts.map +1 -0
- package/build/src/toolkit/bootstrap.js +175 -0
- package/build/src/toolkit/bootstrap.js.map +1 -0
- package/build/src/toolkit/cli-header.d.ts +5 -4
- package/build/src/toolkit/cli-header.d.ts.map +1 -1
- package/build/src/toolkit/cli-header.js +77 -63
- package/build/src/toolkit/cli-header.js.map +1 -1
- package/build/src/toolkit/index.d.ts +1 -0
- package/build/src/toolkit/index.d.ts.map +1 -1
- package/build/src/toolkit/index.js +1 -0
- package/build/src/toolkit/index.js.map +1 -1
- package/build/src/toolkit/logger.d.ts +9 -8
- package/build/src/toolkit/logger.d.ts.map +1 -1
- package/build/src/toolkit/logger.js +51 -32
- package/build/src/toolkit/logger.js.map +1 -1
- package/build/src/toolkit/markdown-table.d.ts +6 -5
- package/build/src/toolkit/markdown-table.d.ts.map +1 -1
- package/build/src/toolkit/markdown-table.js +36 -20
- package/build/src/toolkit/markdown-table.js.map +1 -1
- package/build/src/types/api/node-releases.d.ts +51 -0
- package/build/src/types/api/spdx-licenses.d.ts +41 -0
- package/build/src/types/cli/generate/github/funding.d.ts +59 -0
- package/build/src/types/cli/generate/github/issue-template.d.ts +142 -0
- package/build/src/types/cli/generate/github/workflows.d.ts +336 -0
- package/build/src/types/cli/generate/must-haves/agent-conventions.d.ts +43 -0
- package/build/src/types/cli/generate/must-haves/dotenv.d.ts +414 -0
- package/build/src/types/cli/generate/must-haves/editorconfig.d.ts +33 -0
- package/build/src/types/cli/generate/must-haves/gitignore.d.ts +344 -0
- package/build/src/types/cli/generate/must-haves/license.d.ts +72 -0
- package/build/src/types/cli/generate/must-haves/read-me.d.ts +175 -0
- package/build/src/types/cli/index.d.ts +182 -0
- package/build/src/types/cli/recipe/index.d.ts +36 -0
- package/build/src/types/cli/recipe/package-json/cleanup.d.ts +125 -0
- package/build/src/types/cli/recipe/package-json/normalize-artifacts.d.ts +104 -0
- package/build/src/types/cli/recipe/package-json/normalize-bundler.d.ts +78 -0
- package/build/src/types/cli/recipe/package-json/normalize-dependencies.d.ts +150 -0
- package/build/src/types/cli/recipe/package-json/normalize-modules.d.ts +76 -0
- package/build/src/types/cli/recipe/package-json/normalize-tooling.d.ts +89 -0
- package/build/src/types/cli/recipe/package-json/sync-environment.d.ts +140 -0
- package/build/src/types/cli/recipe/package-json/sync-identity.d.ts +107 -0
- package/build/src/types/cli/recipe/package-json/sync-ownership.d.ts +152 -0
- package/build/src/types/cli/scaffold/app/expressjs.d.ts +21 -0
- package/build/src/types/cli/scaffold/app/nextjs.d.ts +21 -0
- package/build/src/types/cli/scaffold/app/vite.d.ts +21 -0
- package/build/src/types/cli/scaffold/app/workers.d.ts +21 -0
- package/build/src/types/cli/scaffold/docs/docusaurus.d.ts +21 -0
- package/build/src/types/cli/scaffold/starter/base.d.ts +57 -0
- package/build/src/types/cli/utility/changelog.d.ts +381 -0
- package/build/src/types/cli/utility/initialize.d.ts +1185 -0
- package/build/src/types/cli/utility/run-recipes.d.ts +25 -0
- package/build/src/types/cli/utility/run-scripts.d.ts +133 -0
- package/build/src/types/cli/utility/transpile.d.ts +90 -0
- package/build/src/types/cli/utility/type-check.d.ts +88 -0
- package/build/src/types/cli/utility/version.d.ts +286 -0
- package/build/src/types/fetch-response.d.ts +12 -0
- package/build/src/types/lib/item.d.ts +536 -0
- package/build/src/types/lib/nova-config.d.ts +421 -0
- package/build/src/types/lib/scaffold.d.ts +342 -0
- package/build/src/types/lib/utility.d.ts +486 -0
- package/build/src/types/lib/workflow-templates.d.ts +48 -0
- package/build/src/types/presets/eslint/dx-code-style.d.ts +8 -0
- package/build/src/types/presets/eslint/dx-ignore.d.ts +8 -0
- package/build/src/types/presets/eslint/fw-docusaurus.d.ts +8 -0
- package/build/src/types/presets/eslint/fw-expressjs.d.ts +8 -0
- package/build/src/types/presets/eslint/fw-nextjs.d.ts +8 -0
- package/build/src/types/presets/eslint/lang-javascript.d.ts +8 -0
- package/build/src/types/presets/eslint/lang-mdx.d.ts +8 -0
- package/build/src/types/presets/eslint/lang-typescript.d.ts +8 -0
- package/build/src/types/presets/eslint/runtime-browser.d.ts +8 -0
- package/build/src/types/presets/eslint/runtime-cloudflare-workers.d.ts +8 -0
- package/build/src/types/presets/eslint/runtime-edge.d.ts +8 -0
- package/build/src/types/presets/eslint/runtime-node.d.ts +8 -0
- package/build/src/types/presets/eslint/runtime-service-worker.d.ts +8 -0
- package/build/src/types/presets/eslint/runtime-web-worker.d.ts +8 -0
- package/build/src/types/presets/eslint/tool-vite.d.ts +8 -0
- package/build/src/types/rules/eslint/conventions/no-default-export-declaration.d.ts +32 -0
- package/build/src/types/rules/eslint/conventions/no-implicit-boolean.d.ts +72 -0
- package/build/src/types/rules/eslint/conventions/require-explicit-return.d.ts +73 -0
- package/build/src/types/rules/eslint/conventions/require-hash-private.d.ts +31 -0
- package/build/src/types/rules/eslint/conventions/require-kebab-case-filename.d.ts +64 -0
- package/build/src/types/rules/eslint/conventions/require-naming-convention.d.ts +265 -0
- package/build/src/types/rules/eslint/conventions/require-undefined-init.d.ts +30 -0
- package/build/src/types/rules/eslint/conventions/switch-case-blocks.d.ts +48 -0
- package/build/src/types/rules/eslint/formatting/no-complex-arrow-concise.d.ts +74 -0
- package/build/src/types/rules/eslint/formatting/no-multiline-strings.d.ts +104 -0
- package/build/src/types/rules/eslint/formatting/no-raw-text-in-code.d.ts +28 -0
- package/build/src/types/rules/eslint/formatting/no-ternary-in-template-literal.d.ts +26 -0
- package/build/src/types/rules/eslint/formatting/require-import-order.d.ts +91 -0
- package/build/src/types/rules/eslint/formatting/require-multiline-condition-groups.d.ts +64 -0
- package/build/src/types/rules/eslint/formatting/require-multiline-conditions.d.ts +52 -0
- package/build/src/types/rules/eslint/formatting/require-padding-lines.d.ts +212 -0
- package/build/src/types/rules/eslint/formatting/require-ternary-parens.d.ts +32 -0
- package/build/src/types/rules/eslint/jsdoc/require-jsdoc-body.d.ts +56 -0
- package/build/src/types/rules/eslint/jsdoc/require-jsdoc-hierarchy.d.ts +302 -0
- package/build/src/types/rules/eslint/jsdoc/require-jsdoc-param-alignment.d.ts +108 -0
- package/build/src/types/rules/eslint/jsdoc/require-jsdoc-param-name.d.ts +61 -0
- package/build/src/types/rules/eslint/jsdoc/require-jsdoc-private.d.ts +40 -0
- package/build/src/types/rules/eslint/jsdoc/require-jsdoc-since.d.ts +30 -0
- package/build/src/types/rules/eslint/nova/no-logger-dev.d.ts +60 -0
- package/build/src/types/rules/eslint/patterns/no-assign-then-return.d.ts +42 -0
- package/build/src/types/rules/eslint/patterns/no-await-in-loop.d.ts +87 -0
- package/build/src/types/rules/eslint/patterns/no-boolean-var-for-if.d.ts +48 -0
- package/build/src/types/rules/eslint/patterns/no-bracket-assignment.d.ts +34 -0
- package/build/src/types/rules/eslint/patterns/no-bracket-method-call.d.ts +46 -0
- package/build/src/types/rules/eslint/patterns/no-template-curly-in-string.d.ts +32 -0
- package/build/src/types/rules/eslint/patterns/no-use-before-define.d.ts +84 -0
- package/build/src/types/rules/eslint/regex/no-regex-literal-flags.d.ts +26 -0
- package/build/src/types/rules/eslint/regex/no-regex-literals.d.ts +40 -0
- package/build/src/types/rules/eslint/safety/no-script-url.d.ts +37 -0
- package/build/src/types/rules/eslint/syntax/no-destructuring.d.ts +131 -0
- package/build/src/types/rules/eslint/syntax/no-numeric-literals.d.ts +57 -0
- package/build/src/types/rules/eslint/syntax/no-optional-chaining.d.ts +26 -0
- package/build/src/types/rules/eslint/syntax/no-rest-params.d.ts +78 -0
- package/build/src/types/rules/eslint/typescript/no-catch-unknown-annotation.d.ts +30 -0
- package/build/src/types/rules/eslint/typescript/no-explicit-any.d.ts +26 -0
- package/build/src/types/rules/eslint/typescript/no-inline-type-annotation.d.ts +94 -0
- package/build/src/types/rules/eslint/typescript/no-shared-type-import.d.ts +43 -0
- package/build/src/types/rules/eslint/typescript/require-bracket-property-access.d.ts +53 -0
- package/build/src/types/rules/eslint/typescript/require-type-naming.d.ts +51 -0
- package/build/src/types/shared.d.ts +724 -0
- package/build/src/types/tests/api/node-releases.test.d.ts +14 -0
- package/build/src/types/tests/api/spdx-licenses.test.d.ts +18 -0
- package/build/src/types/tests/cli/generate/github/funding.test.d.ts +26 -0
- package/build/src/types/tests/cli/generate/github/issue-template.test.d.ts +14 -0
- package/build/src/types/tests/cli/generate/github/workflows.test.d.ts +38 -0
- package/build/src/types/tests/cli/generate/must-haves/agent-conventions.test.d.ts +32 -0
- package/build/src/types/tests/cli/generate/must-haves/dotenv.test.d.ts +14 -0
- package/build/src/types/tests/cli/generate/must-haves/editorconfig.test.d.ts +22 -0
- package/build/src/types/tests/cli/generate/must-haves/gitignore.test.d.ts +14 -0
- package/build/src/types/tests/cli/generate/must-haves/license.test.d.ts +26 -0
- package/build/src/types/tests/cli/generate/must-haves/read-me.test.d.ts +26 -0
- package/build/src/types/tests/cli/recipe/package-json/cleanup.test.d.ts +42 -0
- package/build/src/types/tests/cli/recipe/package-json/normalize-artifacts.test.d.ts +32 -0
- package/build/src/types/tests/cli/recipe/package-json/normalize-bundler.test.d.ts +32 -0
- package/build/src/types/tests/cli/recipe/package-json/normalize-dependencies.test.d.ts +40 -0
- package/build/src/types/tests/cli/recipe/package-json/normalize-modules.test.d.ts +32 -0
- package/build/src/types/tests/cli/recipe/package-json/normalize-tooling.test.d.ts +32 -0
- package/build/src/types/tests/cli/recipe/package-json/sync-environment.test.d.ts +32 -0
- package/build/src/types/tests/cli/recipe/package-json/sync-identity.test.d.ts +32 -0
- package/build/src/types/tests/cli/recipe/package-json/sync-ownership.test.d.ts +32 -0
- package/build/src/types/tests/cli/scaffold/app/expressjs.test.d.ts +40 -0
- package/build/src/types/tests/cli/scaffold/app/nextjs.test.d.ts +42 -0
- package/build/src/types/tests/cli/scaffold/app/vite.test.d.ts +42 -0
- package/build/src/types/tests/cli/scaffold/app/workers.test.d.ts +40 -0
- package/build/src/types/tests/cli/scaffold/docs/docusaurus.test.d.ts +40 -0
- package/build/src/types/tests/cli/scaffold/starter/base.test.d.ts +40 -0
- package/build/src/types/tests/cli/utility/changelog.test.d.ts +68 -0
- package/build/src/types/tests/cli/utility/initialize.test.d.ts +14 -0
- package/build/src/types/tests/cli/utility/run-recipes.test.d.ts +22 -0
- package/build/src/types/tests/cli/utility/run-scripts.test.d.ts +52 -0
- package/build/src/types/tests/cli/utility/transpile.test.d.ts +26 -0
- package/build/src/types/tests/cli/utility/type-check.test.d.ts +22 -0
- package/build/src/types/tests/cli/utility/version.test.d.ts +12 -0
- package/build/src/types/tests/lib/item.test.d.ts +88 -0
- package/build/src/types/tests/lib/nova-config.test.d.ts +138 -0
- package/build/src/types/tests/lib/regex.test.d.ts +122 -0
- package/build/src/types/tests/lib/scaffold.test.d.ts +26 -0
- package/build/src/types/tests/lib/schema.test.d.ts +36 -0
- package/build/src/types/tests/lib/utility.test.d.ts +324 -0
- package/build/src/types/tests/lib/workflow-templates.test.d.ts +77 -0
- package/build/src/types/tests/rules/eslint/conventions/no-default-export-declaration.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/conventions/no-implicit-boolean.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/conventions/require-explicit-return.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/conventions/require-hash-private.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/conventions/require-kebab-case-filename.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/conventions/require-naming-convention.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/conventions/require-undefined-init.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/conventions/switch-case-blocks.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/formatting/no-complex-arrow-concise.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/formatting/no-multiline-strings.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/formatting/no-raw-text-in-code.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/formatting/no-ternary-in-template-literal.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/formatting/require-import-order.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/formatting/require-multiline-condition-groups.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/formatting/require-multiline-conditions.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/formatting/require-padding-lines.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/formatting/require-ternary-parens.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/jsdoc/require-jsdoc-body.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/jsdoc/require-jsdoc-hierarchy.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/jsdoc/require-jsdoc-param-alignment.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/jsdoc/require-jsdoc-param-name.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/jsdoc/require-jsdoc-private.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/jsdoc/require-jsdoc-since.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/nova/no-logger-dev.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/patterns/no-assign-then-return.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/patterns/no-await-in-loop.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/patterns/no-boolean-var-for-if.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/patterns/no-bracket-assignment.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/patterns/no-bracket-method-call.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/patterns/no-template-curly-in-string.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/patterns/no-use-before-define.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/regex/no-regex-literal-flags.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/regex/no-regex-literals.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/safety/no-script-url.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/syntax/no-destructuring.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/syntax/no-numeric-literals.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/syntax/no-optional-chaining.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/syntax/no-rest-params.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/typescript/no-catch-unknown-annotation.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/typescript/no-explicit-any.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/typescript/no-inline-type-annotation.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/typescript/no-shared-type-import.test.d.ts +8 -0
- package/build/src/types/tests/rules/eslint/typescript/require-bracket-property-access.test.d.ts +12 -0
- package/build/src/types/tests/rules/eslint/typescript/require-type-naming.test.d.ts +8 -0
- package/build/src/types/tests/toolkit/bootstrap.test.d.ts +108 -0
- package/build/src/types/tests/toolkit/cli-header.test.d.ts +46 -0
- package/build/src/types/tests/toolkit/logger.test.d.ts +20 -0
- package/build/src/types/tests/toolkit/markdown-table.test.d.ts +65 -0
- package/build/src/types/tests/type-declarations.test.d.ts +564 -0
- package/build/src/types/toolkit/bootstrap.d.ts +133 -0
- package/build/src/types/toolkit/cli-header.d.ts +203 -0
- package/build/src/types/toolkit/logger.d.ts +160 -0
- package/build/src/types/toolkit/markdown-table.d.ts +159 -0
- package/build/templates/.novaignore +0 -0
- package/build/templates/generators/github/funding/FUNDING.yml +12 -0
- package/build/templates/generators/github/issue-template/BUG-REPORT.yml +86 -0
- package/build/templates/generators/github/issue-template/FEATURE-REQUEST.yml +61 -0
- package/build/templates/generators/github/issue-template/SUPPORT-REQUEST.yml +50 -0
- package/build/templates/generators/github/issue-template/bug-report-fields/android.yml +16 -0
- package/build/templates/generators/github/issue-template/bug-report-fields/apple.yml +23 -0
- package/build/templates/generators/github/issue-template/bug-report-fields/csharp.yml +20 -0
- package/build/templates/generators/github/issue-template/bug-report-fields/docker.yml +33 -0
- package/build/templates/generators/github/issue-template/bug-report-fields/homebridge.yml +16 -0
- package/build/templates/generators/github/issue-template/bug-report-fields/nodejs.yml +8 -0
- package/build/templates/generators/github/issue-template/bug-report-fields/pfsense.yml +8 -0
- package/build/templates/generators/github/issue-template/bug-report-fields/php.yml +8 -0
- package/build/templates/generators/github/issue-template/bug-report-fields/python.yml +8 -0
- package/build/templates/generators/github/issue-template/bug-report-fields/screenshots.yml +7 -0
- package/build/templates/generators/github/issue-template/bug-report-fields/synology.yml +8 -0
- package/build/templates/generators/github/issue-template/bug-report-fields/web.yml +21 -0
- package/build/templates/generators/github/issue-template/config.yml +1 -0
- package/build/templates/generators/github/issue-template/legal-agreements/bug-report.yml +8 -0
- package/build/templates/generators/github/issue-template/legal-agreements/feature-request.yml +8 -0
- package/build/templates/generators/github/issue-template/legal-agreements/support-request.yml +8 -0
- package/build/templates/generators/github/workflows/check-sponsor-gated-issues/base.yml +57 -0
- package/build/templates/generators/github/workflows/lock-inactive-issues/base.yml +43 -0
- package/build/templates/generators/github/workflows/lock-inactive-issues/triggers/schedule.yml +5 -0
- package/build/templates/generators/github/workflows/publish-to-aws-amplify-nextjs/base.yml +53 -0
- package/build/templates/generators/github/workflows/publish-to-aws-amplify-nextjs/triggers/push.yml +5 -0
- package/build/templates/generators/github/workflows/publish-to-aws-amplify-nextjs/triggers/release.yml +5 -0
- package/build/templates/generators/github/workflows/publish-to-cloudflare-pages-docusaurus/base.yml +62 -0
- package/build/templates/generators/github/workflows/publish-to-cloudflare-pages-docusaurus/triggers/push.yml +5 -0
- package/build/templates/generators/github/workflows/publish-to-cloudflare-pages-docusaurus/triggers/release.yml +5 -0
- package/build/templates/generators/github/workflows/publish-to-docker-hub/base.yml +58 -0
- package/build/templates/generators/github/workflows/publish-to-docker-hub/triggers/release.yml +5 -0
- package/build/templates/generators/github/workflows/publish-to-docker-hub/triggers/workflow-run-any.yml +7 -0
- package/build/templates/generators/github/workflows/publish-to-docker-hub/triggers/workflow-run-failure.yml +8 -0
- package/build/templates/generators/github/workflows/publish-to-docker-hub/triggers/workflow-run-success.yml +8 -0
- package/build/templates/generators/github/workflows/publish-to-github-packages/base.yml +108 -0
- package/build/templates/generators/github/workflows/publish-to-github-packages/triggers/release.yml +5 -0
- package/build/templates/generators/github/workflows/publish-to-github-packages/triggers/workflow-run-any.yml +7 -0
- package/build/templates/generators/github/workflows/publish-to-github-packages/triggers/workflow-run-failure.yml +8 -0
- package/build/templates/generators/github/workflows/publish-to-github-packages/triggers/workflow-run-success.yml +8 -0
- package/build/templates/generators/github/workflows/publish-to-github-pages-docusaurus/base.yml +79 -0
- package/build/templates/generators/github/workflows/publish-to-github-pages-docusaurus/triggers/push.yml +5 -0
- package/build/templates/generators/github/workflows/publish-to-github-pages-docusaurus/triggers/release.yml +5 -0
- package/build/templates/generators/github/workflows/publish-to-npm/base.yml +91 -0
- package/build/templates/generators/github/workflows/publish-to-npm/triggers/release.yml +5 -0
- package/build/templates/generators/github/workflows/publish-to-npm/triggers/workflow-run-any.yml +7 -0
- package/build/templates/generators/github/workflows/publish-to-npm/triggers/workflow-run-failure.yml +8 -0
- package/build/templates/generators/github/workflows/publish-to-npm/triggers/workflow-run-success.yml +8 -0
- package/build/templates/generators/must-haves/agent-conventions/.cursorrules +54 -0
- package/build/templates/generators/must-haves/agent-conventions/AGENTS.md +54 -0
- package/build/templates/generators/must-haves/agent-conventions/CLAUDE.md +54 -0
- package/build/templates/generators/must-haves/agent-conventions/PROJECT_RULES.md +290 -0
- package/build/templates/generators/must-haves/agent-conventions/VISION.md +62 -0
- package/build/templates/generators/must-haves/agent-conventions/conventions/csharp.md +317 -0
- package/build/templates/generators/must-haves/agent-conventions/conventions/css.md +188 -0
- package/build/templates/generators/must-haves/agent-conventions/conventions/docker.md +131 -0
- package/build/templates/generators/must-haves/agent-conventions/conventions/documentation.md +615 -0
- package/build/templates/generators/must-haves/agent-conventions/conventions/java.md +285 -0
- package/build/templates/generators/must-haves/agent-conventions/conventions/kotlin.md +297 -0
- package/build/templates/generators/must-haves/agent-conventions/conventions/php.md +257 -0
- package/build/templates/generators/must-haves/agent-conventions/conventions/python.md +260 -0
- package/build/templates/generators/must-haves/agent-conventions/conventions/shell.md +205 -0
- package/build/templates/generators/must-haves/agent-conventions/conventions/swift.md +312 -0
- package/build/templates/generators/must-haves/agent-conventions/conventions/typescript.md +1530 -0
- package/build/templates/generators/must-haves/agent-conventions/conventions/universal.md +202 -0
- package/build/templates/generators/must-haves/dotenv/.env.sample +14 -0
- package/build/templates/generators/must-haves/editorconfig/.editorconfig +212 -0
- package/build/templates/generators/must-haves/license/AGPL-3.0 +662 -0
- package/build/templates/generators/must-haves/license/Apache-2.0 +202 -0
- package/build/templates/generators/must-haves/license/BSD-2-Clause +25 -0
- package/build/templates/generators/must-haves/license/BSD-3-Clause +29 -0
- package/build/templates/generators/must-haves/license/BSL-1.0 +24 -0
- package/build/templates/generators/must-haves/license/CC0-1.0 +122 -0
- package/build/templates/generators/must-haves/license/EPL-2.0 +278 -0
- package/build/templates/generators/must-haves/license/GPL-2.0 +340 -0
- package/build/templates/generators/must-haves/license/GPL-3.0 +675 -0
- package/build/templates/generators/must-haves/license/LGPL-2.1 +505 -0
- package/build/templates/generators/must-haves/license/MIT +22 -0
- package/build/templates/generators/must-haves/license/MPL-2.0 +374 -0
- package/build/templates/generators/must-haves/license/Proprietary +22 -0
- package/build/templates/generators/must-haves/license/Unlicense +25 -0
- package/build/templates/generators/must-haves/read-me/README.md +17 -0
- package/build/templates/scaffold/app/express/package.json +20 -0
- package/build/templates/scaffold/app/express/src/index.ts +12 -0
- package/build/templates/scaffold/app/express/tsconfig.json +15 -0
- package/build/templates/scaffold/app/nextjs/next.config.mjs +4 -0
- package/build/templates/scaffold/app/nextjs/package.json +22 -0
- package/build/templates/scaffold/app/nextjs/src/app/globals.css +11 -0
- package/build/templates/scaffold/app/nextjs/src/app/layout.tsx +18 -0
- package/build/templates/scaffold/app/nextjs/src/app/page.tsx +8 -0
- package/build/templates/scaffold/app/nextjs/tsconfig.json +26 -0
- package/build/templates/scaffold/app/vite/index.html +12 -0
- package/build/templates/scaffold/app/vite/package.json +17 -0
- package/build/templates/scaffold/app/vite/src/main.ts +5 -0
- package/build/templates/scaffold/app/vite/tsconfig.json +16 -0
- package/build/templates/scaffold/app/vite/vite.config.mts +3 -0
- package/build/templates/scaffold/app/workers/package.json +16 -0
- package/build/templates/scaffold/app/workers/src/index.ts +13 -0
- package/build/templates/scaffold/app/workers/tsconfig.json +17 -0
- package/build/templates/scaffold/app/workers/wrangler.toml +3 -0
- package/build/templates/scaffold/docs/docusaurus/docs/intro.md +9 -0
- package/build/templates/scaffold/docs/docusaurus/docusaurus.config.ts +33 -0
- package/build/templates/scaffold/docs/docusaurus/package.json +20 -0
- package/build/templates/scaffold/docs/docusaurus/sidebars.ts +9 -0
- package/build/templates/scaffold/docs/docusaurus/static/.gitkeep +0 -0
- package/build/templates/scaffold/docs/docusaurus/tsconfig.json +8 -0
- package/package.json +38 -32
- package/build/eslint.config.d.ts +0 -34
- package/build/eslint.config.d.ts.map +0 -1
- package/build/eslint.config.js +0 -40
- package/build/eslint.config.js.map +0 -1
- package/build/src/cli/recipe/pin-versions.d.ts +0 -7
- package/build/src/cli/recipe/pin-versions.d.ts.map +0 -1
- package/build/src/cli/recipe/pin-versions.js +0 -145
- package/build/src/cli/recipe/pin-versions.js.map +0 -1
- package/build/src/cli/recipe/sync-lts-engines.d.ts +0 -6
- package/build/src/cli/recipe/sync-lts-engines.d.ts.map +0 -1
- package/build/src/cli/recipe/sync-lts-engines.js +0 -118
- package/build/src/cli/recipe/sync-lts-engines.js.map +0 -1
- package/build/src/cli/recipe/sync-packages.d.ts +0 -18
- package/build/src/cli/recipe/sync-packages.d.ts.map +0 -1
- package/build/src/cli/recipe/sync-packages.js +0 -1212
- package/build/src/cli/recipe/sync-packages.js.map +0 -1
- package/build/src/presets/eslint/dx-code-style.d.mts +0 -4
- package/build/src/presets/eslint/dx-code-style.d.mts.map +0 -1
- package/build/src/presets/eslint/dx-code-style.mjs +0 -211
- package/build/src/presets/eslint/dx-code-style.mjs.map +0 -1
- package/build/src/presets/eslint/dx-ignore.d.mts +0 -4
- package/build/src/presets/eslint/dx-ignore.d.mts.map +0 -1
- package/build/src/presets/eslint/dx-ignore.mjs.map +0 -1
- package/build/src/presets/eslint/env-browser.d.mts +0 -4
- package/build/src/presets/eslint/env-browser.d.mts.map +0 -1
- package/build/src/presets/eslint/env-browser.mjs +0 -3
- package/build/src/presets/eslint/env-browser.mjs.map +0 -1
- package/build/src/presets/eslint/env-edge.d.mts +0 -4
- package/build/src/presets/eslint/env-edge.d.mts.map +0 -1
- package/build/src/presets/eslint/env-edge.mjs.map +0 -1
- package/build/src/presets/eslint/env-node.d.mts +0 -4
- package/build/src/presets/eslint/env-node.d.mts.map +0 -1
- package/build/src/presets/eslint/env-node.mjs.map +0 -1
- package/build/src/presets/eslint/env-service-worker.d.mts +0 -4
- package/build/src/presets/eslint/env-service-worker.d.mts.map +0 -1
- package/build/src/presets/eslint/env-service-worker.mjs +0 -3
- package/build/src/presets/eslint/env-service-worker.mjs.map +0 -1
- package/build/src/presets/eslint/env-web-worker.d.mts +0 -4
- package/build/src/presets/eslint/env-web-worker.d.mts.map +0 -1
- package/build/src/presets/eslint/env-web-worker.mjs.map +0 -1
- package/build/src/presets/eslint/fw-docusaurus.d.mts +0 -4
- package/build/src/presets/eslint/fw-docusaurus.d.mts.map +0 -1
- package/build/src/presets/eslint/fw-docusaurus.mjs +0 -10
- package/build/src/presets/eslint/fw-docusaurus.mjs.map +0 -1
- package/build/src/presets/eslint/fw-expressjs.d.mts +0 -4
- package/build/src/presets/eslint/fw-expressjs.d.mts.map +0 -1
- package/build/src/presets/eslint/fw-expressjs.mjs.map +0 -1
- package/build/src/presets/eslint/fw-nextjs.d.mts +0 -4
- package/build/src/presets/eslint/fw-nextjs.d.mts.map +0 -1
- package/build/src/presets/eslint/fw-nextjs.mjs.map +0 -1
- package/build/src/presets/eslint/index.d.mts +0 -16
- package/build/src/presets/eslint/index.d.mts.map +0 -1
- package/build/src/presets/eslint/index.mjs +0 -16
- package/build/src/presets/eslint/index.mjs.map +0 -1
- package/build/src/presets/eslint/lang-javascript.d.mts +0 -4
- package/build/src/presets/eslint/lang-javascript.d.mts.map +0 -1
- package/build/src/presets/eslint/lang-javascript.mjs +0 -3
- package/build/src/presets/eslint/lang-javascript.mjs.map +0 -1
- package/build/src/presets/eslint/lang-mdx.d.mts +0 -4
- package/build/src/presets/eslint/lang-mdx.d.mts.map +0 -1
- package/build/src/presets/eslint/lang-mdx.mjs.map +0 -1
- package/build/src/presets/eslint/lang-typescript.d.mts +0 -4
- package/build/src/presets/eslint/lang-typescript.d.mts.map +0 -1
- package/build/src/presets/eslint/lang-typescript.mjs +0 -88
- package/build/src/presets/eslint/lang-typescript.mjs.map +0 -1
- package/build/src/presets/eslint/platform-cloudflare-workers.d.mts +0 -4
- package/build/src/presets/eslint/platform-cloudflare-workers.d.mts.map +0 -1
- package/build/src/presets/eslint/platform-cloudflare-workers.mjs +0 -8
- package/build/src/presets/eslint/platform-cloudflare-workers.mjs.map +0 -1
- package/build/src/presets/eslint/tool-vite.d.mts +0 -4
- package/build/src/presets/eslint/tool-vite.d.mts.map +0 -1
- package/build/src/presets/eslint/tool-vite.mjs.map +0 -1
- package/build/src/presets/tsconfig/env-web-worker.json +0 -12
- package/build/src/rules/eslint/no-logger-dev.d.ts +0 -6
- package/build/src/rules/eslint/no-logger-dev.d.ts.map +0 -1
- package/build/src/rules/eslint/no-logger-dev.js +0 -88
- package/build/src/rules/eslint/no-logger-dev.js.map +0 -1
- package/build/src/rules/eslint/no-raw-text-in-code.d.ts +0 -6
- package/build/src/rules/eslint/no-raw-text-in-code.d.ts.map +0 -1
- package/build/src/rules/eslint/no-raw-text-in-code.js +0 -34
- package/build/src/rules/eslint/no-raw-text-in-code.js.map +0 -1
- package/build/src/rules/eslint/no-regex-literal-flags.d.ts +0 -6
- package/build/src/rules/eslint/no-regex-literal-flags.d.ts.map +0 -1
- package/build/src/rules/eslint/no-regex-literal-flags.js +0 -30
- package/build/src/rules/eslint/no-regex-literal-flags.js.map +0 -1
- package/build/src/rules/eslint/no-regex-literals.d.ts +0 -9
- package/build/src/rules/eslint/no-regex-literals.d.ts.map +0 -1
- package/build/src/rules/eslint/no-regex-literals.js +0 -55
- package/build/src/rules/eslint/no-regex-literals.js.map +0 -1
- package/build/src/rules/eslint/switch-case-blocks.d.ts +0 -6
- package/build/src/rules/eslint/switch-case-blocks.d.ts.map +0 -1
- package/build/src/rules/eslint/switch-case-blocks.js +0 -36
- package/build/src/rules/eslint/switch-case-blocks.js.map +0 -1
- package/build/src/tests/api/node-releases.test.d.ts +0 -2
- package/build/src/tests/api/node-releases.test.d.ts.map +0 -1
- package/build/src/tests/api/node-releases.test.js +0 -193
- package/build/src/tests/api/node-releases.test.js.map +0 -1
- package/build/src/tests/api/spdx-licenses.test.d.ts +0 -2
- package/build/src/tests/api/spdx-licenses.test.d.ts.map +0 -1
- package/build/src/tests/api/spdx-licenses.test.js +0 -91
- package/build/src/tests/api/spdx-licenses.test.js.map +0 -1
- package/build/src/tests/cli/recipe/pin-versions.test.d.ts +0 -2
- package/build/src/tests/cli/recipe/pin-versions.test.d.ts.map +0 -1
- package/build/src/tests/cli/recipe/pin-versions.test.js +0 -197
- package/build/src/tests/cli/recipe/pin-versions.test.js.map +0 -1
- package/build/src/tests/cli/recipe/sync-lts-engines.test.d.ts +0 -2
- package/build/src/tests/cli/recipe/sync-lts-engines.test.d.ts.map +0 -1
- package/build/src/tests/cli/recipe/sync-lts-engines.test.js +0 -131
- package/build/src/tests/cli/recipe/sync-lts-engines.test.js.map +0 -1
- package/build/src/tests/lib/item.test.d.ts +0 -2
- package/build/src/tests/lib/item.test.d.ts.map +0 -1
- package/build/src/tests/lib/item.test.js +0 -142
- package/build/src/tests/lib/item.test.js.map +0 -1
- package/build/src/tests/lib/nova-config.test.d.ts +0 -2
- package/build/src/tests/lib/nova-config.test.d.ts.map +0 -1
- package/build/src/tests/lib/nova-config.test.js +0 -489
- package/build/src/tests/lib/nova-config.test.js.map +0 -1
- package/build/src/tests/lib/regex.test.d.ts +0 -2
- package/build/src/tests/lib/regex.test.d.ts.map +0 -1
- package/build/src/tests/lib/regex.test.js +0 -342
- package/build/src/tests/lib/regex.test.js.map +0 -1
- package/build/src/tests/lib/schema.test.d.ts +0 -2
- package/build/src/tests/lib/schema.test.d.ts.map +0 -1
- package/build/src/tests/lib/schema.test.js +0 -260
- package/build/src/tests/lib/schema.test.js.map +0 -1
- package/build/src/tests/lib/utility.test.d.ts +0 -2
- package/build/src/tests/lib/utility.test.d.ts.map +0 -1
- package/build/src/tests/lib/utility.test.js +0 -744
- package/build/src/tests/lib/utility.test.js.map +0 -1
- package/build/src/tests/rules/eslint/no-logger-dev.test.d.ts +0 -2
- package/build/src/tests/rules/eslint/no-logger-dev.test.d.ts.map +0 -1
- package/build/src/tests/rules/eslint/no-logger-dev.test.js +0 -55
- package/build/src/tests/rules/eslint/no-logger-dev.test.js.map +0 -1
- package/build/src/tests/rules/eslint/no-raw-text-in-code.test.d.ts +0 -2
- package/build/src/tests/rules/eslint/no-raw-text-in-code.test.d.ts.map +0 -1
- package/build/src/tests/rules/eslint/no-raw-text-in-code.test.js +0 -47
- package/build/src/tests/rules/eslint/no-raw-text-in-code.test.js.map +0 -1
- package/build/src/tests/rules/eslint/no-regex-literal-flags.test.d.ts +0 -2
- package/build/src/tests/rules/eslint/no-regex-literal-flags.test.d.ts.map +0 -1
- package/build/src/tests/rules/eslint/no-regex-literal-flags.test.js +0 -47
- package/build/src/tests/rules/eslint/no-regex-literal-flags.test.js.map +0 -1
- package/build/src/tests/rules/eslint/no-regex-literals.test.d.ts +0 -2
- package/build/src/tests/rules/eslint/no-regex-literals.test.d.ts.map +0 -1
- package/build/src/tests/rules/eslint/no-regex-literals.test.js +0 -49
- package/build/src/tests/rules/eslint/no-regex-literals.test.js.map +0 -1
- package/build/src/tests/rules/eslint/switch-case-blocks.test.d.ts +0 -2
- package/build/src/tests/rules/eslint/switch-case-blocks.test.d.ts.map +0 -1
- package/build/src/tests/rules/eslint/switch-case-blocks.test.js +0 -43
- package/build/src/tests/rules/eslint/switch-case-blocks.test.js.map +0 -1
- package/build/src/tests/toolkit/cli-header.test.d.ts +0 -2
- package/build/src/tests/toolkit/cli-header.test.d.ts.map +0 -1
- package/build/src/tests/toolkit/cli-header.test.js +0 -143
- package/build/src/tests/toolkit/cli-header.test.js.map +0 -1
- package/build/src/tests/toolkit/logger.test.d.ts +0 -2
- package/build/src/tests/toolkit/logger.test.d.ts.map +0 -1
- package/build/src/tests/toolkit/logger.test.js +0 -96
- package/build/src/tests/toolkit/logger.test.js.map +0 -1
- package/build/src/tests/toolkit/markdown-table.test.d.ts +0 -2
- package/build/src/tests/toolkit/markdown-table.test.d.ts.map +0 -1
- package/build/src/tests/toolkit/markdown-table.test.js +0 -138
- package/build/src/tests/toolkit/markdown-table.test.js.map +0 -1
- /package/build/src/presets/tsconfig/{env-browser.json → runtime-browser.json} +0 -0
- /package/build/src/presets/tsconfig/{env-edge.json → runtime-edge.json} +0 -0
- /package/build/src/presets/tsconfig/{env-node.json → runtime-node.json} +0 -0
- /package/build/src/presets/tsconfig/{env-service-worker.json → runtime-service-worker.json} +0 -0
|
@@ -0,0 +1,1530 @@
|
|
|
1
|
+
# TypeScript / JavaScript Conventions
|
|
2
|
+
|
|
3
|
+
Quotes: Single. Indentation: 2-space. File naming: kebab-case (e.g., `markdown-table.ts`, `cli-header.d.ts`).
|
|
4
|
+
|
|
5
|
+
## Documentation Style
|
|
6
|
+
|
|
7
|
+
- Comment syntax: `/** */`
|
|
8
|
+
- Padding tag: `@since 1.0.0` (JSDoc)
|
|
9
|
+
- Param format: `@param {TypeName} name - Name.` (description matches the parameter name, capitalized, with a trailing period)
|
|
10
|
+
- Return format: `@returns {TypeName}`
|
|
11
|
+
- Include `@private` tag for private members.
|
|
12
|
+
|
|
13
|
+
### JSDoc `@param` Alignment
|
|
14
|
+
|
|
15
|
+
- When multiple `@param` lines exist, pad so **both** param names AND `-` dashes align vertically.
|
|
16
|
+
- Pad after `}` so param names start at the same column (minimum 1 space).
|
|
17
|
+
- Pad after param name so all `-` dashes align at the same column.
|
|
18
|
+
- Optional params use `[name]` syntax in JSDoc.
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
// GOOD — param names aligned, dashes aligned
|
|
22
|
+
/**
|
|
23
|
+
* @param {CliChangelogWritePackageDir} packageDir - Package dir.
|
|
24
|
+
* @param {CliChangelogWritePackageName} packageName - Package name.
|
|
25
|
+
* @param {CliChangelogWriteVersion} version - Version.
|
|
26
|
+
* @param {CliChangelogWriteEntries} entries - Entries.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
// GOOD — same-length types, 1 space after } suffices
|
|
30
|
+
/**
|
|
31
|
+
* @param {TaskRunnerConstructorHeaders} headers - Headers.
|
|
32
|
+
* @param {TaskRunnerConstructorOptions} [options] - Options.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
// BAD — no alignment
|
|
36
|
+
/**
|
|
37
|
+
* @param {CliChangelogWritePackageDir} packageDir - Package dir.
|
|
38
|
+
* @param {CliChangelogWritePackageName} packageName - Package name.
|
|
39
|
+
* @param {CliChangelogWriteVersion} version - Version.
|
|
40
|
+
*/
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Doc Comment Hierarchy
|
|
44
|
+
|
|
45
|
+
Class doc uses pretty name derived from directory path with ` - ` separators. All path segments are included. Member docs chain from the class pretty name. Files named `index` skip the filename — the directory path is the identity. Known names (brands, abbreviations, compounds) are preserved: e.g., `eslint` → `ESLint`, `package-json` → `package.json`, `nextjs` → `Next.js`.
|
|
46
|
+
|
|
47
|
+
### Full Documentation Example
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
/**
|
|
51
|
+
* CLI - Utility - Runner.
|
|
52
|
+
*
|
|
53
|
+
* @since 1.0.0
|
|
54
|
+
*/
|
|
55
|
+
export class CliUtilityRunner {
|
|
56
|
+
/**
|
|
57
|
+
* CLI - Utility - Runner - Run.
|
|
58
|
+
*
|
|
59
|
+
* @param {CliUtilityRunnerRunOptions} options - Options.
|
|
60
|
+
*
|
|
61
|
+
* @returns {CliUtilityRunnerRunReturns}
|
|
62
|
+
*
|
|
63
|
+
* @since 1.0.0
|
|
64
|
+
*/
|
|
65
|
+
public static async run(options: CliUtilityRunnerRunOptions): CliUtilityRunnerRunReturns {
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* CLI - Utility - Runner - Fetch Data.
|
|
70
|
+
*
|
|
71
|
+
* @private
|
|
72
|
+
*
|
|
73
|
+
* @returns {CliUtilityRunnerFetchDataReturns}
|
|
74
|
+
*
|
|
75
|
+
* @since 1.0.0
|
|
76
|
+
*/
|
|
77
|
+
private static async fetchData(): CliUtilityRunnerFetchDataReturns {
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* CLI - Utility - Runner - Format Line.
|
|
82
|
+
*
|
|
83
|
+
* @param {CliUtilityRunnerFormatLinePrefix} prefix - Prefix.
|
|
84
|
+
* @param {CliUtilityRunnerFormatLineMessage} message - Message.
|
|
85
|
+
*
|
|
86
|
+
* @private
|
|
87
|
+
*
|
|
88
|
+
* @returns {CliUtilityRunnerFormatLineReturns}
|
|
89
|
+
*
|
|
90
|
+
* @since 1.0.0
|
|
91
|
+
*/
|
|
92
|
+
private static formatLine(prefix: CliUtilityRunnerFormatLinePrefix, message: CliUtilityRunnerFormatLineMessage): CliUtilityRunnerFormatLineReturns {
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Type System
|
|
98
|
+
|
|
99
|
+
### No Inline Types in Code Files
|
|
100
|
+
|
|
101
|
+
Every `const`/`let` declaration in a method body uses a named alias from a `.d.ts` file. No exceptions — even when TypeScript can infer the type, the explicit named annotation is required for traceability. This applies to all forms: array literals, Sets, Records, Maps, union types, generics, and inferred primitives.
|
|
102
|
+
|
|
103
|
+
**Excluded from this rule** (rely on TypeScript inference):
|
|
104
|
+
- Callback parameters (`.map((item) => ...)`, `.filter((key) => ...)`)
|
|
105
|
+
- `for...of` loop variables (`for (const entry of entries)`)
|
|
106
|
+
- `for...in` loop variables (`for (const property in object)`)
|
|
107
|
+
- `for` loop indices (`for (let i = 0; ...)`)
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
// BAD — inline types
|
|
111
|
+
const entries: TaskEntry[] = [];
|
|
112
|
+
const files: string[] = [];
|
|
113
|
+
let selectedPackage: string | undefined;
|
|
114
|
+
const allowedKeys = new Set<string>([...]);
|
|
115
|
+
const reordered: Record<string, unknown> = {};
|
|
116
|
+
|
|
117
|
+
// BAD — relying on inference for body variable
|
|
118
|
+
const header = this.formatRow(this.#headers, columnWidths);
|
|
119
|
+
const directory = path.dirname(filePath);
|
|
120
|
+
|
|
121
|
+
// GOOD — named types from .d.ts
|
|
122
|
+
const entries: RunnerParseEntries = [];
|
|
123
|
+
const files: RunnerParseFiles = [];
|
|
124
|
+
let selectedPackage: RunnerRunSelectedPackage;
|
|
125
|
+
const allowedKeys: ValidatorCheckAllowedKeys = new Set([...]);
|
|
126
|
+
const reordered: SyncerHandleReorderReordered = {};
|
|
127
|
+
|
|
128
|
+
// GOOD — named types even for inferred primitives
|
|
129
|
+
const header: MarkdownTableRenderHeader = this.formatRow(this.#headers, columnWidths);
|
|
130
|
+
const directory: RunnerSaveFileDirectory = path.dirname(filePath);
|
|
131
|
+
|
|
132
|
+
// GOOD — inference OK for these (excluded from rule)
|
|
133
|
+
items.filter((item) => item.length > 0);
|
|
134
|
+
for (const entry of entries) { ... }
|
|
135
|
+
for (let i = 0; i < count; i += 1) { ... }
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Types in Separate `.d.ts` Files
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
src/cli/utility/changelog.ts → types live in:
|
|
142
|
+
src/types/cli/utility.d.ts → domain types
|
|
143
|
+
src/types/shared.d.ts → shared types (only imported by .d.ts files)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Mirrored Directory Structure
|
|
147
|
+
|
|
148
|
+
Category folders (`types/`, `tests/`, and in Next.js `styles/`) mirror the source path. Each source file gets its own corresponding file. Exception: `.d.ts` files are only created when there are actual types to export — don't create empty stubs just to satisfy the mirror structure.
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
src/lib/utility.ts → src/types/lib/utility.d.ts
|
|
152
|
+
src/lib/utility.ts → src/tests/lib/utility.test.ts
|
|
153
|
+
src/toolkit/markdown-table.ts → src/types/toolkit/markdown-table.d.ts
|
|
154
|
+
src/cli/utility/changelog.ts → src/types/cli/utility/changelog.d.ts
|
|
155
|
+
src/cli/utility/initialize.ts → src/types/cli/utility/initialize.d.ts
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Type Layering
|
|
159
|
+
|
|
160
|
+
`shared.d.ts` → domain `.d.ts` files → `.ts` code files. Shared types only imported by `.d.ts` files, never by `.ts` code.
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
// shared.d.ts
|
|
164
|
+
export type EntryCategory = 'added' | 'updated' | 'fixed' | 'removed';
|
|
165
|
+
|
|
166
|
+
// types/cli/runner.d.ts — imports from shared.d.ts
|
|
167
|
+
import type { EntryCategory } from '@/types/shared.d.ts';
|
|
168
|
+
export type RunnerRecordSelectedCategory = EntryCategory;
|
|
169
|
+
|
|
170
|
+
// cli/runner.ts — imports from runner.d.ts, NEVER from shared.d.ts
|
|
171
|
+
import type { RunnerRecordSelectedCategory } from '@/types/cli/runner.d.ts';
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Type Ordering in `.d.ts` Files
|
|
175
|
+
|
|
176
|
+
**Sections** are in alphabetical order by method name. **Within each section**, types are ordered by first-use, first-listed (first come, first serve): parameters first (used first in the signature), then return/typeguard (used next in the signature), then body variable types in the sequential order they appear in the method body. This is strictly code-order, NOT alphabetical.
|
|
177
|
+
|
|
178
|
+
The reason for first-come-first-serve ordering: the `.d.ts` file reads as a parallel of the `.ts` file. When reading the implementation top to bottom and encountering a type, it appears at the same relative position in the `.d.ts`. The `.d.ts` is a table of contents for the implementation — same order, same flow, no hunting.
|
|
179
|
+
|
|
180
|
+
The **only** valid forward reference: `Returns` referencing a type defined later in the same section — `Returns` still comes first because it's used first (in the signature). This covers two patterns: `Returns` referencing a body variable the method returns, and `Returns` referencing a return object type whose properties are defined after `Returns`. All other types must be defined before use.
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
/** Runner - Execute. */
|
|
184
|
+
export type RunnerExecuteOptions = { ... }; // param (used first)
|
|
185
|
+
export type RunnerExecuteReturns = Promise<void>; // return (used next)
|
|
186
|
+
export type RunnerExecuteConfig = Record<...>; // body variable (used later, sequential order)
|
|
187
|
+
|
|
188
|
+
/** Runner - Group items. */
|
|
189
|
+
export type RunnerGroupItemsItems = ...; // param (used first)
|
|
190
|
+
export type RunnerGroupItemsReturns = RunnerGroupItemsGrouped; // return (used next, forward ref OK)
|
|
191
|
+
export type RunnerGroupItemsGrouped = Map<...>; // body variable (used later, owns the definition)
|
|
192
|
+
export type RunnerGroupItemsProcessed = Set<...>; // body variable (used later, sequential order)
|
|
193
|
+
|
|
194
|
+
/** Runner - Detect platform. */
|
|
195
|
+
export type RunnerDetectPlatformUrl = string; // param (used first)
|
|
196
|
+
export type RunnerDetectPlatformReturns = RunnerDetectPlatformPlatform; // return (forward ref OK)
|
|
197
|
+
export type RunnerDetectPlatformPlatformId = 'a' | 'b'; // return object property
|
|
198
|
+
export type RunnerDetectPlatformPlatformUrl = string; // return object property
|
|
199
|
+
export type RunnerDetectPlatformPlatform = { // return object (owns the definition)
|
|
200
|
+
id: RunnerDetectPlatformPlatformId;
|
|
201
|
+
url: RunnerDetectPlatformPlatformUrl;
|
|
202
|
+
};
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Named Type Naming
|
|
206
|
+
|
|
207
|
+
Pattern: `{PathPrefix}{MethodName}{VariableName}`. The path prefix is derived from the file path using simple PascalCase — each path segment and hyphenated word gets its first letter capitalized, no abbreviation expansion. The type naming system does NOT use brand casing (e.g., `Cli` not `CLI`, `Api` not `API`, `Eslint` not `ESLint`). Brand casing is reserved for JSDoc hierarchy display only.
|
|
208
|
+
|
|
209
|
+
Files named `index` skip the filename — the directory path is the identity.
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
src/cli/ → Cli (namespace)
|
|
213
|
+
src/cli/utility/ → CliUtility (sub-namespace)
|
|
214
|
+
src/cli/utility/changelog.ts → CliUtilityChangelog (class)
|
|
215
|
+
src/cli/generate/must-haves/dotenv.ts → CliGenerateMustHavesDotenv (class)
|
|
216
|
+
src/cli/recipe/package-json/cleanup.ts → CliRecipePackageJsonCleanup (class)
|
|
217
|
+
src/cli/index.ts → Cli (index skipped)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Inside a class, the namespace keeps extending — method adds a level, variable adds a level, object property adds a level:
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
CliUtilityChangelog → directory path (class)
|
|
224
|
+
Release → method
|
|
225
|
+
Release → object variable
|
|
226
|
+
PackageName → property
|
|
227
|
+
= CliUtilityChangelogReleaseReleasePackageName
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Repetition in names (e.g., `ReleaseRelease`) is expected when the method name matches the variable name — the `release()` method produces `release` objects. The convention does not deduplicate — each segment maps to one level, keeping the namespace unambiguous.
|
|
231
|
+
|
|
232
|
+
The variable name must match the actual parameter/variable name in the code. The method name must match the method where the type is used — don't reuse a type from another method even if the underlying type is the same.
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
// BAD — type name references filter, but used in categorize
|
|
236
|
+
private static categorize(items: RunnerFilterItems): ...
|
|
237
|
+
|
|
238
|
+
// GOOD — type name matches the method it's used in
|
|
239
|
+
private static categorize(items: RunnerCategorizeItems): ...
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Named Type Alias per Param and Return
|
|
243
|
+
|
|
244
|
+
Each function parameter and return value gets its own named type alias.
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
// types/toolkit/markdown-table.d.ts
|
|
248
|
+
export type MarkdownTableConstructorHeaders = string[];
|
|
249
|
+
export type MarkdownTableAddRowRow = string[];
|
|
250
|
+
export type MarkdownTableAddRowReturns = void;
|
|
251
|
+
|
|
252
|
+
// toolkit/markdown-table.ts
|
|
253
|
+
/**
|
|
254
|
+
* Markdown Table - Add row.
|
|
255
|
+
*
|
|
256
|
+
* @param {MarkdownTableAddRowRow} row - Row.
|
|
257
|
+
*
|
|
258
|
+
* @returns {MarkdownTableAddRowReturns}
|
|
259
|
+
*
|
|
260
|
+
* @since 1.0.0
|
|
261
|
+
*/
|
|
262
|
+
public addRow(row: MarkdownTableAddRowRow): MarkdownTableAddRowReturns { ... }
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### `satisfies` vs `:` Type Annotation
|
|
266
|
+
|
|
267
|
+
- `satisfies` — shape validation while keeping specific literal types. Use for object literals and config objects where you want autocomplete on exact keys and typo detection.
|
|
268
|
+
- `:` annotation — when the variable should be treated as the broader type. Use for function params, class fields, and variables that get reassigned.
|
|
269
|
+
|
|
270
|
+
```ts
|
|
271
|
+
// satisfies — keeps literal types, catches bad key access
|
|
272
|
+
const config = {
|
|
273
|
+
name: 'nova',
|
|
274
|
+
version: '1.0.0',
|
|
275
|
+
} satisfies Record<string, string>;
|
|
276
|
+
config.name; // type is 'nova' (literal)
|
|
277
|
+
config.anything; // ERROR
|
|
278
|
+
|
|
279
|
+
// : annotation — widens to the annotated type
|
|
280
|
+
const config: Record<string, string> = {
|
|
281
|
+
name: 'nova',
|
|
282
|
+
version: '1.0.0',
|
|
283
|
+
};
|
|
284
|
+
config.name; // type is string
|
|
285
|
+
config.anything; // no error
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Type Guards Use `TypeGuard` Suffix, Not `Returns`
|
|
289
|
+
|
|
290
|
+
Type guard methods/functions use `TypeGuard` instead of `Returns` for the narrowed type. No `Returns` type exists for type guards.
|
|
291
|
+
|
|
292
|
+
```ts
|
|
293
|
+
// .d.ts
|
|
294
|
+
export type RunnerIsErrorResponseValue = unknown;
|
|
295
|
+
export type RunnerIsErrorResponseTypeGuard = ErrorResponse;
|
|
296
|
+
|
|
297
|
+
// .ts
|
|
298
|
+
private static isErrorResponse(value: RunnerIsErrorResponseValue): value is RunnerIsErrorResponseTypeGuard {
|
|
299
|
+
return (
|
|
300
|
+
typeof value === 'object'
|
|
301
|
+
&& value !== null
|
|
302
|
+
&& 'code' in value
|
|
303
|
+
&& 'message' in value
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Also works inline in .filter()
|
|
308
|
+
.filter((value): value is SyncPropertiesTypeGuard => allowedProperties.has(value))
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### No Redundant Intermediate Type Aliases
|
|
312
|
+
|
|
313
|
+
Don't create a type alias that only exists to be referenced by one other type. But if param and return have the same underlying type, keep them separate — they're semantically different (input vs output). Don't reference the param type from the return type.
|
|
314
|
+
|
|
315
|
+
```ts
|
|
316
|
+
// BAD — Filtered only exists to be referenced by Returns
|
|
317
|
+
export type RunnerFilterItems = Item[];
|
|
318
|
+
export type RunnerFilterFiltered = Item[];
|
|
319
|
+
export type RunnerFilterReturns = RunnerFilterFiltered;
|
|
320
|
+
|
|
321
|
+
// BAD — Returns references Items (input ≠ output semantically)
|
|
322
|
+
export type RunnerFilterItems = Item[];
|
|
323
|
+
export type RunnerFilterReturns = RunnerFilterItems;
|
|
324
|
+
|
|
325
|
+
// GOOD — same underlying type, but defined independently
|
|
326
|
+
export type RunnerFilterItems = Item[];
|
|
327
|
+
export type RunnerFilterReturns = Item[];
|
|
328
|
+
|
|
329
|
+
// BAD — Response only exists to be referenced by Returns
|
|
330
|
+
export type FetcherGetDataResponse = z.infer<typeof FetcherResponseSchema>;
|
|
331
|
+
export type FetcherGetDataReturns = Promise<FetcherGetDataResponse | undefined>;
|
|
332
|
+
|
|
333
|
+
// GOOD — z.infer inlined directly into Returns
|
|
334
|
+
export type FetcherGetDataReturns = Promise<z.infer<typeof FetcherResponseSchema> | undefined>;
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Never Flatten Types in `.d.ts` Files
|
|
338
|
+
|
|
339
|
+
Always reference named types, never resolve to their primitive. Maintains the type path so changes propagate.
|
|
340
|
+
|
|
341
|
+
```ts
|
|
342
|
+
// shared.d.ts
|
|
343
|
+
export type EntryPackage = string;
|
|
344
|
+
export type EntryMessage = string;
|
|
345
|
+
|
|
346
|
+
// BAD — flattened to primitive, loses the type path
|
|
347
|
+
export type RunnerParseEntryPackage = string | undefined;
|
|
348
|
+
export type RunnerWriteByCategory = Map<EntryCategory, string[]>;
|
|
349
|
+
|
|
350
|
+
// GOOD — references the shared type
|
|
351
|
+
export type RunnerParseEntryPackage = EntryPackage | undefined;
|
|
352
|
+
export type RunnerWriteByCategory = Map<EntryCategory, EntryMessage[]>;
|
|
353
|
+
|
|
354
|
+
// BAD — nested array, loses the type path
|
|
355
|
+
export type RunnerGroupRows = string[][];
|
|
356
|
+
|
|
357
|
+
// GOOD — singular references primitive, plural references singular
|
|
358
|
+
export type RunnerGroupRow = string[];
|
|
359
|
+
export type RunnerGroupRows = RunnerGroupRow[];
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
When creating a `= string` type, check if it represents a domain concept that has a shared type. If so, reference it. Genuinely `string` types include: generated file names, directory paths, version strings, CLI formatting strings, generic utility returns, external API data, prompt output keys, test setup paths.
|
|
363
|
+
|
|
364
|
+
### Shared Type Consolidation Rule
|
|
365
|
+
|
|
366
|
+
Two triggers for moving a type into `shared.d.ts`:
|
|
367
|
+
|
|
368
|
+
1. **Cross-section reference**: A type in one section of a `.d.ts` file references a type from another section in the same file. Even a single cross-section reference means the dependency belongs in `shared.d.ts`.
|
|
369
|
+
2. **Multiple dependents**: More than 1 type in a `.d.ts` file depends on the same type (from the same file or another domain `.d.ts` file).
|
|
370
|
+
|
|
371
|
+
Both prevent fragile cross-references where removing one type silently breaks others.
|
|
372
|
+
|
|
373
|
+
```ts
|
|
374
|
+
// GOOD — shared type in shared.d.ts, imported once by domain .d.ts
|
|
375
|
+
import type { EntryBump } from '@/types/shared.d.ts';
|
|
376
|
+
export type RunnerRecordSelectedBump = EntryBump;
|
|
377
|
+
export type RunnerReleaseHighestBump = EntryBump;
|
|
378
|
+
export type RunnerParseEntryBump = EntryBump | undefined;
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Object Property Types Form a Hierarchy
|
|
382
|
+
|
|
383
|
+
Object property types belong to their parent object — they are scoped to that specific context. Each property gets its own named type, defined before the object type that references them. The property types are part of the object's namespace hierarchy.
|
|
384
|
+
|
|
385
|
+
If a variable in a different method needs the same underlying type, it must NOT import from another method's object hierarchy. That creates cross-dependencies between unrelated methods. Instead, the common base type goes into `shared.d.ts`. Both the object property type and the unrelated variable type reference `shared.d.ts` independently — no lateral dependencies.
|
|
386
|
+
|
|
387
|
+
```ts
|
|
388
|
+
// shared.d.ts
|
|
389
|
+
export type ChangelogEntryPackage = string;
|
|
390
|
+
|
|
391
|
+
// GOOD — release method's object hierarchy references shared.d.ts
|
|
392
|
+
export type RunnerReleaseReleasePackageName = ChangelogEntryPackage;
|
|
393
|
+
export type RunnerReleaseRelease = {
|
|
394
|
+
packageName: RunnerReleaseReleasePackageName;
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
// GOOD — record method also references shared.d.ts independently
|
|
398
|
+
export type RunnerRecordSelectedPackage = ChangelogEntryPackage | undefined;
|
|
399
|
+
|
|
400
|
+
// BAD — record method reaching into release method's object hierarchy
|
|
401
|
+
export type RunnerRecordSelectedPackage = RunnerReleaseReleasePackageName | undefined;
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
Within the same method, a standalone variable and an object property that share the same domain concept also define their types independently — both reference the base type, neither references the other.
|
|
405
|
+
|
|
406
|
+
```ts
|
|
407
|
+
// GOOD — both reference shared.d.ts, neither references the other
|
|
408
|
+
export type RunnerReleaseReleaseHighestBump = ChangelogEntryBump;
|
|
409
|
+
export type RunnerReleaseRelease = {
|
|
410
|
+
highestBump: RunnerReleaseReleaseHighestBump;
|
|
411
|
+
};
|
|
412
|
+
export type RunnerReleaseHighestBump = ChangelogEntryBump;
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### Tight Types over Loose Types
|
|
416
|
+
|
|
417
|
+
Define the exact shape. No `Record<string, string>` when fields are known.
|
|
418
|
+
|
|
419
|
+
```ts
|
|
420
|
+
// BAD — frontmatter has known fields
|
|
421
|
+
export type RunnerParseFrontMatter = Record<string, string>;
|
|
422
|
+
|
|
423
|
+
// GOOD — define exact shape with named field types
|
|
424
|
+
export type RunnerParseFrontMatterPackage = string;
|
|
425
|
+
export type RunnerParseFrontMatterCategory = EntryCategory;
|
|
426
|
+
export type RunnerParseFrontMatterBump = EntryBump;
|
|
427
|
+
export type RunnerParseFrontMatter = {
|
|
428
|
+
package: RunnerParseFrontMatterPackage;
|
|
429
|
+
category: RunnerParseFrontMatterCategory;
|
|
430
|
+
bump: RunnerParseFrontMatterBump;
|
|
431
|
+
};
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### `as` Casts — Avoid Unless Compiler-Forced
|
|
435
|
+
|
|
436
|
+
Avoid `as` casts — they bypass type safety and can crash at runtime. Prefer `.find()` or type guards.
|
|
437
|
+
|
|
438
|
+
However, some `as` casts are unavoidable because TypeScript's type system loses information. The forced patterns:
|
|
439
|
+
|
|
440
|
+
| Pattern | Why forced |
|
|
441
|
+
|------------------------------------------|-------------------------------------------------------------|
|
|
442
|
+
| `Object.fromEntries()` | Returns `{ [k: string]: any }` — can't narrow keys |
|
|
443
|
+
| `Object.keys()` | Returns `string[]` — TypeScript won't narrow to actual keys |
|
|
444
|
+
| `new Command()` | Commander's generic type doesn't match custom CLI type |
|
|
445
|
+
| String indexing a union-keyed object | `string` can't index a union-key type |
|
|
446
|
+
| Literal array to tuple/union type | Widens to `string` without cast |
|
|
447
|
+
| Regex captures | Always `string`, can't narrow to union |
|
|
448
|
+
| `Record<string, unknown>` bracket access | Returns `unknown`, can't narrow |
|
|
449
|
+
|
|
450
|
+
Type guard internals do NOT need `as` — use `in` narrowing instead after `null`/`typeof` guard.
|
|
451
|
+
|
|
452
|
+
```ts
|
|
453
|
+
// BAD — as cast when .find() can replace it
|
|
454
|
+
selectedCategory = options.category as RunnerRecordSelectedCategory;
|
|
455
|
+
|
|
456
|
+
// GOOD — .find() validates AND narrows
|
|
457
|
+
const validCategory = validCategories.find(
|
|
458
|
+
(validCategory) => validCategory === options.category,
|
|
459
|
+
);
|
|
460
|
+
selectedCategory = validCategory;
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### External API Responses — Validate with Zod
|
|
464
|
+
|
|
465
|
+
`response.json()` returns `unknown`. Don't blindly cast with `as` — the data comes from an external source and its shape is not guaranteed. Define a Zod schema in `src/lib/schema.ts` and use `.parse()` for runtime validation. Derive the `.d.ts` type with `z.infer<typeof Schema>`.
|
|
466
|
+
|
|
467
|
+
```ts
|
|
468
|
+
// GOOD — Zod runtime validation
|
|
469
|
+
const responseData = await response.json();
|
|
470
|
+
const data: FetcherGetDataResponse = FetcherResponseSchema.parse(responseData);
|
|
471
|
+
|
|
472
|
+
// BAD — blind cast, no runtime validation
|
|
473
|
+
const data: FetcherGetDataResponse = await response.json() as FetcherGetDataResponse;
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
This applies to all external API boundaries (`fetch`, webhook payloads, etc.). Internal typed data (e.g., `Object.fromEntries`, `Object.keys`) still uses `as` casts where compiler-forced.
|
|
477
|
+
|
|
478
|
+
### Local Files with Unpredictable Shapes
|
|
479
|
+
|
|
480
|
+
Files like `package.json` have too many optional/third-party fields to define a Zod schema. Use the absorb-into-typed-container pattern with `Record<string, unknown>` and `as` casts for bracket access.
|
|
481
|
+
|
|
482
|
+
```ts
|
|
483
|
+
const config: RunnerRunConfig = JSON.parse(configRaw);
|
|
484
|
+
const configItems = config['items'] as RunnerFilterItems;
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
### `JSON.parse` — Type the Result Immediately
|
|
488
|
+
|
|
489
|
+
`JSON.parse` returns implicit `any`. Never let it float around — annotate with a named type (e.g., `Record<string, unknown>`) immediately. Then access fields via bracket notation. Don't wrap in an extra object unless the surrounding code already needs one (like pushing into an array with multiple fields).
|
|
490
|
+
|
|
491
|
+
```ts
|
|
492
|
+
// GOOD — typed directly
|
|
493
|
+
const config: RunnerRunConfig = JSON.parse(configRaw);
|
|
494
|
+
const configItems = config['items'] as RunnerFilterItems;
|
|
495
|
+
|
|
496
|
+
// GOOD — absorbed into existing structure
|
|
497
|
+
const parsedFile = JSON.parse(rawFile);
|
|
498
|
+
dataFiles.push({
|
|
499
|
+
manifest: itemManifest,
|
|
500
|
+
filePath: absolutePath,
|
|
501
|
+
fileContents: parsedFile, // absorbed into Record<string, unknown>
|
|
502
|
+
});
|
|
503
|
+
// later: fileContents['name'], fileContents['version'], etc.
|
|
504
|
+
|
|
505
|
+
// BAD — implicit any floating around
|
|
506
|
+
const config = JSON.parse(configRaw);
|
|
507
|
+
const items = config.items ?? []; // any propagates
|
|
508
|
+
|
|
509
|
+
// BAD — unnecessary wrapping object
|
|
510
|
+
const config: RunnerRunConfig = {
|
|
511
|
+
fileContents: JSON.parse(configRaw),
|
|
512
|
+
};
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
### Variables from `Record<string, unknown>` Need Explicit Types
|
|
516
|
+
|
|
517
|
+
When accessing a field from a `Record<string, unknown>` container (e.g., from `JSON.parse`), the result is `unknown`. Annotate with a named type.
|
|
518
|
+
|
|
519
|
+
```ts
|
|
520
|
+
// BAD — result is unknown, no annotation
|
|
521
|
+
const configItems = config.fileContents['items'];
|
|
522
|
+
|
|
523
|
+
// GOOD — explicit type annotation
|
|
524
|
+
const configItems: RunnerFilterItems = config.fileContents['items'];
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
### `as const` Is Acceptable
|
|
528
|
+
|
|
529
|
+
Used for narrowing literals. Consistent patterns:
|
|
530
|
+
- Prompt choices — `{ type: 'select' as const }` (required by prompts library)
|
|
531
|
+
- `Object.fromEntries()` tuples — `['key', value] as const` (preserves tuple position types)
|
|
532
|
+
- Fixed arrays for property access — `['author', 'contributor'] as const`
|
|
533
|
+
|
|
534
|
+
### Use `.find()` to Validate AND Narrow Types
|
|
535
|
+
|
|
536
|
+
Replaces `.includes()` + `as` casts in one step.
|
|
537
|
+
|
|
538
|
+
```ts
|
|
539
|
+
// BAD — .includes() doesn't narrow, needs unsafe cast
|
|
540
|
+
if (!validCategories.includes(options.category as typeof selectedCategory)) { ... }
|
|
541
|
+
selectedCategory = options.category as typeof selectedCategory;
|
|
542
|
+
|
|
543
|
+
// GOOD — .find() narrows the return type
|
|
544
|
+
const matchedCategory = validCategories.find(
|
|
545
|
+
(validCategory) => validCategory === options.category,
|
|
546
|
+
);
|
|
547
|
+
if (matchedCategory === undefined) { ... return; }
|
|
548
|
+
selectedCategory = matchedCategory;
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
## Import Rules
|
|
552
|
+
|
|
553
|
+
### Import Ordering (6 Groups)
|
|
554
|
+
|
|
555
|
+
Groups separated by a blank line, alphabetical within each group. Specifiers within each `import { ... }` must also be alphabetical.
|
|
556
|
+
|
|
557
|
+
1. Node built-ins (e.g., `child_process`, `fs`, `os`, `path`) — detected by name, `node:` prefix not required
|
|
558
|
+
2. Third-party packages (e.g., `chalk`, `prompts`)
|
|
559
|
+
3. Local imports (e.g., `@/lib/utility`, `@/toolkit/logger`)
|
|
560
|
+
4. `import type` from Node built-ins
|
|
561
|
+
5. `import type` from third-party
|
|
562
|
+
6. `import type` from local (`@/`, `./`, `../`)
|
|
563
|
+
|
|
564
|
+
Type imports maintain the same node → third-party → local sub-ordering as regular imports. In practice, `.ts` source files only have group 6 (type imports from local `@/types/...`). Groups 4 and 5 only appear in `.d.ts` files (e.g., `import type { Dirent } from 'fs'`).
|
|
565
|
+
|
|
566
|
+
```ts
|
|
567
|
+
import { promises as fs } from 'fs';
|
|
568
|
+
import { resolve } from 'path';
|
|
569
|
+
|
|
570
|
+
import chalk from 'chalk';
|
|
571
|
+
import prompts from 'prompts';
|
|
572
|
+
|
|
573
|
+
import { validCategories } from '@/lib/item.js';
|
|
574
|
+
import { Logger } from '@/toolkit/index.js';
|
|
575
|
+
|
|
576
|
+
import type {
|
|
577
|
+
RunnerRecordOptions,
|
|
578
|
+
RunnerRecordReturns,
|
|
579
|
+
} from '@/types/cli/runner.d.ts';
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
### Barrel Exports
|
|
583
|
+
|
|
584
|
+
Some directories have an `index.ts` barrel file that re-exports sibling modules. Not every directory gets one.
|
|
585
|
+
|
|
586
|
+
- All files (`.ts` and `.d.ts`) import through the barrel when one exists.
|
|
587
|
+
- Siblings within the barrel directory still go through the barrel (not `./sibling.js`).
|
|
588
|
+
- Directories without a barrel — import directly from the source module.
|
|
589
|
+
|
|
590
|
+
```ts
|
|
591
|
+
// Barrel file — src/toolkit/index.ts
|
|
592
|
+
export { default as CliHeader } from './cli-header.js';
|
|
593
|
+
export { default as Logger } from './logger.js';
|
|
594
|
+
export { default as MarkdownTable } from './markdown-table.js';
|
|
595
|
+
|
|
596
|
+
// .ts code files — through the barrel
|
|
597
|
+
import { CliHeader, Logger } from '@/toolkit/index.js';
|
|
598
|
+
|
|
599
|
+
// .d.ts type files — also through the barrel
|
|
600
|
+
import type { MarkdownTable } from '@/toolkit/index.ts';
|
|
601
|
+
|
|
602
|
+
// Siblings within the barrel directory — still through the barrel
|
|
603
|
+
// src/toolkit/cli-header.ts
|
|
604
|
+
import { Logger } from '@/toolkit/index.js';
|
|
605
|
+
|
|
606
|
+
// No barrel exists — import directly
|
|
607
|
+
import { CliRecipeSyncPackages } from '@/cli/recipe/sync-packages.js';
|
|
608
|
+
import { LIB_REGEX_PATTERN_LEADING_V } from '@/lib/regex.js';
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
### Prefer Named Imports over Namespace/Default
|
|
612
|
+
|
|
613
|
+
When a module supports named exports, use `import { specific } from 'module'` instead of `import * as module` or `import module from 'module'`. Only use default/namespace imports when the module doesn't support named exports (e.g., `chalk` only has a default export).
|
|
614
|
+
|
|
615
|
+
**Compiler-forced `import * as`:** CJS packages with `module.exports` and no default export (e.g., `eslint-mdx`, `eslint-plugin-mdx`) require `import * as`. Default import causes TS1192. This is not a convention violation.
|
|
616
|
+
|
|
617
|
+
When a named import conflicts with a local variable, keep the import name unchanged and rename only the conflicting local variable (e.g., `current` prefix). Use `as` aliasing on the import only when renaming the local variable is impractical. Only rename what's forced — don't cascade renames to variables that don't conflict.
|
|
618
|
+
|
|
619
|
+
```ts
|
|
620
|
+
// BAD — namespace import when named exports are available
|
|
621
|
+
import * as path from 'path';
|
|
622
|
+
path.resolve(process.cwd(), 'config.json');
|
|
623
|
+
|
|
624
|
+
// GOOD — named import (tree-shakeable)
|
|
625
|
+
import { resolve } from 'path';
|
|
626
|
+
resolve(process.cwd(), 'config.json');
|
|
627
|
+
|
|
628
|
+
// GOOD — import keeps its name, local variable gets `current` prefix
|
|
629
|
+
import { platform, version } from 'os';
|
|
630
|
+
const currentPlatform = platform();
|
|
631
|
+
let currentVersion = version();
|
|
632
|
+
|
|
633
|
+
// OK — chalk only has a default export
|
|
634
|
+
import chalk from 'chalk';
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
### One Specifier per Line
|
|
638
|
+
|
|
639
|
+
ESLint `@stylistic/object-curly-newline` triggers at 4+ properties for `ImportDeclaration`.
|
|
640
|
+
|
|
641
|
+
```ts
|
|
642
|
+
// BAD — squished on one line
|
|
643
|
+
import type { TypeA, TypeB, TypeC, TypeD } from '@/types/cli/runner.d.ts';
|
|
644
|
+
|
|
645
|
+
// GOOD — one per line
|
|
646
|
+
import type {
|
|
647
|
+
TypeA,
|
|
648
|
+
TypeB,
|
|
649
|
+
TypeC,
|
|
650
|
+
TypeD,
|
|
651
|
+
} from '@/types/cli/runner.d.ts';
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
## Class Structure
|
|
655
|
+
|
|
656
|
+
### Explicit Accessibility Modifiers
|
|
657
|
+
|
|
658
|
+
All class members require explicit `public` or `private`.
|
|
659
|
+
|
|
660
|
+
```ts
|
|
661
|
+
public static async run(options: ...): ... { }
|
|
662
|
+
private static getConfigPath(project: ...): ... { }
|
|
663
|
+
public constructor(headers: ...) { }
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
### Class Shapes
|
|
667
|
+
|
|
668
|
+
Two shapes, chosen by whether the module holds per-instance state:
|
|
669
|
+
|
|
670
|
+
| Shape | When to use | Constructor | Fields | Methods |
|
|
671
|
+
|-----------------|----------------------------------|------------------------|-------------------|------------------------------------|
|
|
672
|
+
| **Static-only** | Stateless utilities, API clients | None | `static #field` | `public static` / `private static` |
|
|
673
|
+
| **Instance** | Per-caller isolated state | `public constructor()` | `readonly #field` | `public` / `private` instance |
|
|
674
|
+
|
|
675
|
+
Static-only (stateless utilities):
|
|
676
|
+
```ts
|
|
677
|
+
export class CliUtilityChangelog {
|
|
678
|
+
public static async run(options: ...): ... { }
|
|
679
|
+
private static async record(options: ...): ... { }
|
|
680
|
+
private static generateFileName(): ... { }
|
|
681
|
+
}
|
|
682
|
+
// Called as: CliUtilityChangelog.run(options)
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
Instance (per-caller state):
|
|
686
|
+
```ts
|
|
687
|
+
export default class MarkdownTable {
|
|
688
|
+
readonly #headers: MarkdownTableHeaders;
|
|
689
|
+
|
|
690
|
+
public constructor(headers: ..., options?: ...) {
|
|
691
|
+
this.#headers = headers;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
public addRow(row: ...): ... { }
|
|
695
|
+
}
|
|
696
|
+
// Called as: new MarkdownTable(headers).addRow(row)
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
### `#` Private Fields over `private` Keyword
|
|
700
|
+
|
|
701
|
+
Use `#` (runtime-enforced) for private class **fields only**. Methods stay as `private static` / `private`. Originally an IntelliJ recommendation — kept for consistency.
|
|
702
|
+
|
|
703
|
+
```ts
|
|
704
|
+
// GOOD — field uses #hash
|
|
705
|
+
static #cache: SomeType;
|
|
706
|
+
readonly #headers: MarkdownTableHeaders;
|
|
707
|
+
|
|
708
|
+
// GOOD — method uses private keyword
|
|
709
|
+
private static async fetchData(): FetcherFetchDataReturns { }
|
|
710
|
+
private static formatLine(prefix: ...): FormatLineReturns { }
|
|
711
|
+
|
|
712
|
+
// BAD — don't use #hash for methods
|
|
713
|
+
static #fetchData(): FetcherFetchDataReturns { }
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
### `readonly` on Private Fields
|
|
717
|
+
|
|
718
|
+
- `readonly` — field set once in the constructor, never reassigned after. Prevents `=` reassignment, not mutation (`.push()`, `.set()` still allowed).
|
|
719
|
+
- No `readonly` — field that gets reassigned during the class lifecycle.
|
|
720
|
+
|
|
721
|
+
### Private Fields and Caching
|
|
722
|
+
|
|
723
|
+
```ts
|
|
724
|
+
// Private fields use #hash notation
|
|
725
|
+
readonly #headers: MarkdownTableHeaders;
|
|
726
|
+
|
|
727
|
+
// Static caching pattern
|
|
728
|
+
static #cache: SomeType;
|
|
729
|
+
static #populated: boolean = false;
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
### Export Rules
|
|
733
|
+
|
|
734
|
+
- `export default class` — public API classes (barrel indexes, package `exports`).
|
|
735
|
+
- `export class` — internal classes.
|
|
736
|
+
- Default to `export class` (named export) — this is the preference.
|
|
737
|
+
- `export default class` only for public API classes — so consumers can choose named or default import style. It's an accommodation, not a preference.
|
|
738
|
+
|
|
739
|
+
### Method Ordering
|
|
740
|
+
|
|
741
|
+
1. Public methods first.
|
|
742
|
+
2. Private async methods (grouped).
|
|
743
|
+
3. Private non-async helpers (grouped).
|
|
744
|
+
|
|
745
|
+
Each method separated by a blank line. No blank line after opening brace or before closing brace of the class.
|
|
746
|
+
|
|
747
|
+
### Alphabetical Ordering (Broad Rule)
|
|
748
|
+
|
|
749
|
+
Most named declarations are ordered alphabetically:
|
|
750
|
+
- Constant arrays in `src/lib/item.ts`
|
|
751
|
+
- Regex patterns in `src/lib/regex.ts`
|
|
752
|
+
- Type sections in `.d.ts` files (by method name)
|
|
753
|
+
- Import specifiers within each group
|
|
754
|
+
|
|
755
|
+
**Exception**: class methods — grouped by visibility/async, not alphabetical.
|
|
756
|
+
|
|
757
|
+
## Code Style
|
|
758
|
+
|
|
759
|
+
### Comment Placement in Method Bodies
|
|
760
|
+
|
|
761
|
+
Comments describe the process/intent — written so the code makes sense 6 months later. Placement rules:
|
|
762
|
+
- Comment sits above the code block it describes.
|
|
763
|
+
- Blank line before the comment (except at the start of a scope).
|
|
764
|
+
- No comment needed on the first block if it's self-explanatory.
|
|
765
|
+
- No trailing comments (same-line comments after code). Exception: multi-line conditions may use inline `//` comments after each condition line to explain the check.
|
|
766
|
+
|
|
767
|
+
```ts
|
|
768
|
+
const configPath = resolve(process.cwd(), 'config.json');
|
|
769
|
+
const configRaw = await fs.readFile(configPath, 'utf-8');
|
|
770
|
+
|
|
771
|
+
// Parse the configuration file.
|
|
772
|
+
const config: RunnerRunConfig = JSON.parse(configRaw);
|
|
773
|
+
const configItems = config['items'] as RunnerRunConfigItems;
|
|
774
|
+
|
|
775
|
+
// Filter and group items by category.
|
|
776
|
+
const filtered = Runner.filterItems(configItems);
|
|
777
|
+
const grouped = Runner.groupItems(filtered);
|
|
778
|
+
```
|
|
779
|
+
|
|
780
|
+
### Switch Statements — Always Block-Scoped
|
|
781
|
+
|
|
782
|
+
Every `case` and `default` uses block scoping with `{ }`. Always include a `default` case, even if there's nothing to handle. Separate non-empty cases with a blank line. Empty fallthrough cases may be grouped without blank lines.
|
|
783
|
+
|
|
784
|
+
```ts
|
|
785
|
+
switch (category) {
|
|
786
|
+
case 'added': {
|
|
787
|
+
Logger.info('New feature.');
|
|
788
|
+
break;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
case 'fixed': {
|
|
792
|
+
Logger.info('Bug fix.');
|
|
793
|
+
break;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
default: {
|
|
797
|
+
Logger.warn('Unknown category.');
|
|
798
|
+
break;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
```
|
|
802
|
+
|
|
803
|
+
### Function Overloads vs Union Parameters
|
|
804
|
+
|
|
805
|
+
- Prefer overloads when the return type or behavior differs per input type — stricter for callers.
|
|
806
|
+
- Union parameter is fine when the handling is identical regardless of input type.
|
|
807
|
+
|
|
808
|
+
```ts
|
|
809
|
+
// GOOD — overloads (different behavior per type)
|
|
810
|
+
private static format(value: string): FormatReturns;
|
|
811
|
+
private static format(value: number): FormatReturns;
|
|
812
|
+
private static format(value: string | number): FormatReturns {
|
|
813
|
+
if (typeof value === 'string') {
|
|
814
|
+
return value.trim();
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
return value.toFixed(2);
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
// GOOD — union (same handling regardless)
|
|
821
|
+
private static validate(value: string | number): ValidateReturns {
|
|
822
|
+
return value !== undefined;
|
|
823
|
+
}
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
### No Rest Parameters
|
|
827
|
+
|
|
828
|
+
List function parameters explicitly. Rest parameters (`...args`) obscure the expected inputs and bypass arity checks. Variadic utility functions (e.g., logging wrappers) are an acceptable exception.
|
|
829
|
+
|
|
830
|
+
```ts
|
|
831
|
+
// BAD — rest parameters
|
|
832
|
+
function log(...args: string[]): void { ... }
|
|
833
|
+
const sum = (...numbers: number[]) => ...;
|
|
834
|
+
|
|
835
|
+
// GOOD — explicit parameters
|
|
836
|
+
function log(message: string, level: string, context: string): void { ... }
|
|
837
|
+
```
|
|
838
|
+
|
|
839
|
+
### `Reflect.set()` for Dynamic Property Assignment
|
|
840
|
+
|
|
841
|
+
Prefer `Reflect.set()` over direct bracket assignment (`target[key] = value`). Also required by `no-param-reassign` with `props: true` when the target is a function parameter.
|
|
842
|
+
|
|
843
|
+
```ts
|
|
844
|
+
// GOOD
|
|
845
|
+
Reflect.set(target, key, value);
|
|
846
|
+
|
|
847
|
+
// BAD
|
|
848
|
+
target[key] = value;
|
|
849
|
+
```
|
|
850
|
+
|
|
851
|
+
### Dot Notation for Method Calls
|
|
852
|
+
|
|
853
|
+
Don't call methods using bracket notation with static string keys. Use dot notation for readability. Bracket notation for property *reads* on `Record`/plain objects is fine — this applies only to method *calls*.
|
|
854
|
+
|
|
855
|
+
```ts
|
|
856
|
+
// BAD — bracket notation for method call
|
|
857
|
+
obj['toString']();
|
|
858
|
+
arr['push'](item);
|
|
859
|
+
|
|
860
|
+
// GOOD — dot notation for method calls
|
|
861
|
+
obj.toString();
|
|
862
|
+
arr.push(item);
|
|
863
|
+
|
|
864
|
+
// OK — dynamic key (not a static string)
|
|
865
|
+
obj[methodName]();
|
|
866
|
+
|
|
867
|
+
// OK — bracket notation for property reads on Record/plain objects
|
|
868
|
+
const configItems = config['items'] as RunnerFilterItems;
|
|
869
|
+
```
|
|
870
|
+
|
|
871
|
+
### No Exponentiation Operator
|
|
872
|
+
|
|
873
|
+
Use `Math.pow()` instead of `**`. Clearer intent and consistent with other `Math` utilities.
|
|
874
|
+
|
|
875
|
+
```ts
|
|
876
|
+
// BAD
|
|
877
|
+
const area = r ** 2;
|
|
878
|
+
value **= 10;
|
|
879
|
+
|
|
880
|
+
// GOOD
|
|
881
|
+
const area = Math.pow(r, 2);
|
|
882
|
+
value = Math.pow(value, 10);
|
|
883
|
+
```
|
|
884
|
+
|
|
885
|
+
### No Binary, Octal, or Hexadecimal Literals
|
|
886
|
+
|
|
887
|
+
Use `parseInt()` with an explicit radix instead of numeric literal prefixes. Hex literals for color codes, bit masks, and hardware registers are an acceptable exception.
|
|
888
|
+
|
|
889
|
+
```ts
|
|
890
|
+
// BAD
|
|
891
|
+
const mask = 0xFF;
|
|
892
|
+
const bits = 0b1010;
|
|
893
|
+
const perms = 0o755;
|
|
894
|
+
|
|
895
|
+
// GOOD
|
|
896
|
+
const mask = parseInt('FF', 16);
|
|
897
|
+
const bits = parseInt('1010', 2);
|
|
898
|
+
const perms = parseInt('755', 8);
|
|
899
|
+
```
|
|
900
|
+
|
|
901
|
+
### Spread over `Array.from()` for Converting Iterables
|
|
902
|
+
|
|
903
|
+
```ts
|
|
904
|
+
// BAD
|
|
905
|
+
const keys = Array.from(grouped.keys());
|
|
906
|
+
|
|
907
|
+
// GOOD
|
|
908
|
+
const keys = [...grouped.keys()];
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
### Optional Chaining and Nullish Coalescing
|
|
912
|
+
|
|
913
|
+
- Avoid optional chaining (`?.`) — prefer explicit checks.
|
|
914
|
+
- Nullish coalescing (`??`) is fine for providing defaults.
|
|
915
|
+
- Don't combine them (`config?.name ?? 'default'`) — break into explicit steps.
|
|
916
|
+
|
|
917
|
+
```ts
|
|
918
|
+
// BAD — optional chaining
|
|
919
|
+
const name = config?.name;
|
|
920
|
+
|
|
921
|
+
// GOOD — explicit check
|
|
922
|
+
if (config === undefined) {
|
|
923
|
+
return;
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
const name = config.name;
|
|
927
|
+
|
|
928
|
+
// GOOD — nullish coalescing for defaults
|
|
929
|
+
const timeout = options.timeout ?? 5000;
|
|
930
|
+
const label = config.name ?? 'default';
|
|
931
|
+
```
|
|
932
|
+
|
|
933
|
+
### Ternary Expressions
|
|
934
|
+
|
|
935
|
+
- Simple ternary is OK — single condition, short values.
|
|
936
|
+
- No nested ternaries.
|
|
937
|
+
- No ternaries inside template literals — extract to a variable first.
|
|
938
|
+
|
|
939
|
+
```ts
|
|
940
|
+
// GOOD — simple ternary
|
|
941
|
+
const label = (isActive === true) ? 'enabled' : 'disabled';
|
|
942
|
+
|
|
943
|
+
// BAD — nested ternary
|
|
944
|
+
const label = (isActive === true) ? 'enabled' : (isPending === true) ? 'waiting' : 'disabled';
|
|
945
|
+
|
|
946
|
+
// BAD — ternary inside template literal
|
|
947
|
+
Logger.info(`Status: ${(isActive === true) ? 'enabled' : 'disabled'}`);
|
|
948
|
+
|
|
949
|
+
// GOOD — extracted to variable
|
|
950
|
+
const label = (isActive === true) ? 'enabled' : 'disabled';
|
|
951
|
+
Logger.info(`Status: ${label}`);
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
### No Template Literal Syntax in Regular Strings
|
|
955
|
+
|
|
956
|
+
Regular strings containing `${...}` almost always mean the backticks are missing.
|
|
957
|
+
|
|
958
|
+
```ts
|
|
959
|
+
// BAD — likely a bug
|
|
960
|
+
const message = 'Hello ${name}!';
|
|
961
|
+
|
|
962
|
+
// GOOD
|
|
963
|
+
const message = `Hello ${name}!`;
|
|
964
|
+
```
|
|
965
|
+
|
|
966
|
+
### No Stacked Comments
|
|
967
|
+
|
|
968
|
+
```ts
|
|
969
|
+
// BAD — stacked comments
|
|
970
|
+
// Parse front matter.
|
|
971
|
+
|
|
972
|
+
// Split lines.
|
|
973
|
+
const lines = content.split('\n');
|
|
974
|
+
|
|
975
|
+
// GOOD — one descriptive comment per code block
|
|
976
|
+
// Parse front matter.
|
|
977
|
+
const lines = content.split('\n');
|
|
978
|
+
```
|
|
979
|
+
|
|
980
|
+
### Quote File Names in Comments and Log Messages
|
|
981
|
+
|
|
982
|
+
```ts
|
|
983
|
+
// GOOD
|
|
984
|
+
// Load "config.json" for workspace list.
|
|
985
|
+
Logger.error('Unable to read "package.json".');
|
|
986
|
+
Logger.info('Updated "CHANGELOG.md" successfully.');
|
|
987
|
+
```
|
|
988
|
+
|
|
989
|
+
### Mixed `&&`/`||` Conditions
|
|
990
|
+
|
|
991
|
+
Parenthesized groups with `(` and `)` on their own lines, each condition on its own line.
|
|
992
|
+
|
|
993
|
+
```ts
|
|
994
|
+
if (
|
|
995
|
+
(
|
|
996
|
+
options.package === undefined
|
|
997
|
+
|| options.category === undefined
|
|
998
|
+
|| options.bump === undefined
|
|
999
|
+
|| options.message === undefined
|
|
1000
|
+
)
|
|
1001
|
+
&& (
|
|
1002
|
+
options.package !== undefined
|
|
1003
|
+
|| options.category !== undefined
|
|
1004
|
+
|| options.bump !== undefined
|
|
1005
|
+
|| options.message !== undefined
|
|
1006
|
+
)
|
|
1007
|
+
) {
|
|
1008
|
+
```
|
|
1009
|
+
|
|
1010
|
+
### No `const hasAllFlags` Multi-Line Assignments
|
|
1011
|
+
|
|
1012
|
+
Inline conditions directly in `if` blocks.
|
|
1013
|
+
|
|
1014
|
+
```ts
|
|
1015
|
+
// BAD
|
|
1016
|
+
const hasAllFlags = options.package !== undefined
|
|
1017
|
+
&& options.category !== undefined
|
|
1018
|
+
&& options.bump !== undefined;
|
|
1019
|
+
if (hasAllFlags) { ... }
|
|
1020
|
+
|
|
1021
|
+
// GOOD
|
|
1022
|
+
if (
|
|
1023
|
+
options.package !== undefined
|
|
1024
|
+
&& options.category !== undefined
|
|
1025
|
+
&& options.bump !== undefined
|
|
1026
|
+
) { ... }
|
|
1027
|
+
```
|
|
1028
|
+
|
|
1029
|
+
### One Entry per Line in Arrays
|
|
1030
|
+
|
|
1031
|
+
```ts
|
|
1032
|
+
// Both .d.ts tuple types and .ts constant arrays
|
|
1033
|
+
const categoryOrder: RunnerReleaseCategoryOrder = [
|
|
1034
|
+
'updated',
|
|
1035
|
+
'fixed',
|
|
1036
|
+
'added',
|
|
1037
|
+
'removed',
|
|
1038
|
+
];
|
|
1039
|
+
```
|
|
1040
|
+
|
|
1041
|
+
### Descriptive Callback Parameter Names
|
|
1042
|
+
|
|
1043
|
+
Derive from the array/collection name in singular form. Array and iterable variable names must end with a plural noun so the singular form can be derived naturally.
|
|
1044
|
+
|
|
1045
|
+
```ts
|
|
1046
|
+
// BAD
|
|
1047
|
+
validCategories.find((c) => c === value)
|
|
1048
|
+
validBumps.find((b) => b === value)
|
|
1049
|
+
|
|
1050
|
+
// GOOD
|
|
1051
|
+
validCategories.find((validCategory) => validCategory === value)
|
|
1052
|
+
validBumps.find((validBump) => validBump === value)
|
|
1053
|
+
|
|
1054
|
+
// More examples:
|
|
1055
|
+
categoryKeys.map((categoryKey) => ...)
|
|
1056
|
+
validRoles.map((validRole) => ...)
|
|
1057
|
+
rawPaths.map((rawPath) => ...)
|
|
1058
|
+
allowedPolicies.map((allowedPolicy) => ...)
|
|
1059
|
+
```
|
|
1060
|
+
|
|
1061
|
+
### No Destructuring in Callback Parameters
|
|
1062
|
+
|
|
1063
|
+
Use the singular of the collection as the param, then access via index inside a block body with intermediate constants.
|
|
1064
|
+
|
|
1065
|
+
```ts
|
|
1066
|
+
// BAD — destructuring in callback param
|
|
1067
|
+
workspaces.filter(([, config]) => config.policy !== 'freezable')
|
|
1068
|
+
workspaces.find(([_path, config]) => config.name === options.package)
|
|
1069
|
+
|
|
1070
|
+
// GOOD — no destructuring, block body, intermediate constants
|
|
1071
|
+
workspaces.filter((workspace) => {
|
|
1072
|
+
const workspaceConfig = workspace[1];
|
|
1073
|
+
const workspaceConfigPolicy = workspaceConfig.policy;
|
|
1074
|
+
|
|
1075
|
+
return workspaceConfigPolicy !== 'freezable';
|
|
1076
|
+
});
|
|
1077
|
+
|
|
1078
|
+
// GOOD — simple direct comparison stays as expression body
|
|
1079
|
+
validCategories.find(
|
|
1080
|
+
(validCategory) => validCategory === options.category,
|
|
1081
|
+
)
|
|
1082
|
+
```
|
|
1083
|
+
|
|
1084
|
+
Note: `for...of` destructuring is used with `Object.entries()` (which returns tuples), but NOT with Maps. For Maps, use `entry[0]`/`entry[1]` pattern:
|
|
1085
|
+
```ts
|
|
1086
|
+
// GOOD — Object.entries() destructuring (returns tuples)
|
|
1087
|
+
for (const [key, entry] of Object.entries(schedule)) { ... }
|
|
1088
|
+
|
|
1089
|
+
// BAD — Map destructuring
|
|
1090
|
+
for (const [categoryName, categoryItems] of grouped) { ... }
|
|
1091
|
+
|
|
1092
|
+
// GOOD — Map iteration without destructuring
|
|
1093
|
+
for (const entry of grouped) {
|
|
1094
|
+
const entryCategory = entry[0];
|
|
1095
|
+
const entryItems = entry[1];
|
|
1096
|
+
}
|
|
1097
|
+
```
|
|
1098
|
+
|
|
1099
|
+
### Variable Names Chain from Parent
|
|
1100
|
+
|
|
1101
|
+
When extracting properties from an intermediate constant, the name chains from the parent variable name.
|
|
1102
|
+
|
|
1103
|
+
```ts
|
|
1104
|
+
// Tuple elements get semantic names
|
|
1105
|
+
const key = supportedItem[0];
|
|
1106
|
+
const appName = supportedItem[1];
|
|
1107
|
+
|
|
1108
|
+
// Domain objects chain from parent name
|
|
1109
|
+
const workspaceConfig = workspace[1];
|
|
1110
|
+
const workspaceConfigPolicy = workspaceConfig.policy;
|
|
1111
|
+
|
|
1112
|
+
const eligibleConfig = eligible[1];
|
|
1113
|
+
const eligibleConfigName = eligibleConfig.name;
|
|
1114
|
+
const eligibleConfigRole = eligibleConfig.role;
|
|
1115
|
+
const eligibleConfigPolicy = eligibleConfig.policy;
|
|
1116
|
+
```
|
|
1117
|
+
|
|
1118
|
+
### Block Body vs Expression Body in Callbacks
|
|
1119
|
+
|
|
1120
|
+
- **Block body** (`=> { ... return; }`): When accessing properties/elements of the callback param, or when multiple statements needed.
|
|
1121
|
+
- **Expression body** (`=> value`): When the callback is a direct comparison or single method call on a primitive.
|
|
1122
|
+
|
|
1123
|
+
```ts
|
|
1124
|
+
// Block body — accessing tuple elements, multiple properties
|
|
1125
|
+
items.map((item) => {
|
|
1126
|
+
const itemConfig = item[1];
|
|
1127
|
+
const itemConfigName = itemConfig.name;
|
|
1128
|
+
const itemConfigRole = itemConfig.role;
|
|
1129
|
+
|
|
1130
|
+
return {
|
|
1131
|
+
title: itemConfigName,
|
|
1132
|
+
description: itemConfigRole,
|
|
1133
|
+
value: itemConfigName,
|
|
1134
|
+
};
|
|
1135
|
+
});
|
|
1136
|
+
|
|
1137
|
+
// Expression body — direct comparison on primitive
|
|
1138
|
+
validCategories.find(
|
|
1139
|
+
(validCategory) => validCategory === value,
|
|
1140
|
+
)
|
|
1141
|
+
|
|
1142
|
+
// Expression body — single property check
|
|
1143
|
+
.filter((result) => result.status === 'fulfilled')
|
|
1144
|
+
.map((result) => result.value)
|
|
1145
|
+
.filter((value) => value !== null)
|
|
1146
|
+
```
|
|
1147
|
+
|
|
1148
|
+
### Blank Lines between Distinct Operations
|
|
1149
|
+
|
|
1150
|
+
Separate method calls, `await` statements, and different logical blocks with blank lines. Variable declarations and loops also need blank line separation.
|
|
1151
|
+
|
|
1152
|
+
```ts
|
|
1153
|
+
// BAD — everything stuck together
|
|
1154
|
+
Runner.print(grouped);
|
|
1155
|
+
await Runner.writeOutput({ ... });
|
|
1156
|
+
await Runner.runParallel();
|
|
1157
|
+
|
|
1158
|
+
// GOOD — each operation gets breathing room
|
|
1159
|
+
Runner.print(grouped);
|
|
1160
|
+
|
|
1161
|
+
await Runner.writeOutput({
|
|
1162
|
+
filePath: 'output.json',
|
|
1163
|
+
content: JSON.stringify(grouped),
|
|
1164
|
+
});
|
|
1165
|
+
|
|
1166
|
+
await Runner.runParallel();
|
|
1167
|
+
|
|
1168
|
+
// BAD — declarations and loop stuck together
|
|
1169
|
+
const grouped: RunnerGroupItemsGrouped = new Map();
|
|
1170
|
+
const processed: RunnerGroupItemsProcessed = new Set();
|
|
1171
|
+
for (const category of validPolicies) {
|
|
1172
|
+
|
|
1173
|
+
// GOOD — blank line before loop
|
|
1174
|
+
const grouped: RunnerGroupItemsGrouped = new Map();
|
|
1175
|
+
const processed: RunnerGroupItemsProcessed = new Set();
|
|
1176
|
+
|
|
1177
|
+
for (const category of validPolicies) {
|
|
1178
|
+
|
|
1179
|
+
// BAD — declaration and method call stuck together
|
|
1180
|
+
const existing = grouped.get(entry.package) ?? [];
|
|
1181
|
+
existing.push(entry);
|
|
1182
|
+
|
|
1183
|
+
// GOOD — blank line before method call on the variable
|
|
1184
|
+
const existing = grouped.get(entry.package) ?? [];
|
|
1185
|
+
|
|
1186
|
+
existing.push(entry);
|
|
1187
|
+
```
|
|
1188
|
+
|
|
1189
|
+
### Bare `await` Gets Its Own Visual Group
|
|
1190
|
+
|
|
1191
|
+
When an `await` call has no assignment (return value unused), separate it from surrounding `const` assignments with a blank line.
|
|
1192
|
+
|
|
1193
|
+
```ts
|
|
1194
|
+
// BAD — bare await mixed with const assignments
|
|
1195
|
+
await Runner.fetchData();
|
|
1196
|
+
const filtered = Runner.filterItems(configItems);
|
|
1197
|
+
|
|
1198
|
+
// GOOD — bare await has its own group
|
|
1199
|
+
await Runner.fetchData();
|
|
1200
|
+
|
|
1201
|
+
const filtered = Runner.filterItems(configItems);
|
|
1202
|
+
```
|
|
1203
|
+
|
|
1204
|
+
### Return Directly When Immediately Returned
|
|
1205
|
+
|
|
1206
|
+
Don't assign to an intermediate variable just to return it on the next line.
|
|
1207
|
+
|
|
1208
|
+
```ts
|
|
1209
|
+
// BAD — redundant intermediate variable
|
|
1210
|
+
const filtered = items.filter((item) => {
|
|
1211
|
+
...
|
|
1212
|
+
});
|
|
1213
|
+
|
|
1214
|
+
return filtered;
|
|
1215
|
+
|
|
1216
|
+
// GOOD — return directly
|
|
1217
|
+
return items.filter((item) => {
|
|
1218
|
+
...
|
|
1219
|
+
});
|
|
1220
|
+
```
|
|
1221
|
+
|
|
1222
|
+
### Explicit `return;` in Void Functions
|
|
1223
|
+
|
|
1224
|
+
Every void function and method must end with an explicit `return;` statement. Arrow function callbacks, constructors, and setters are acceptable exceptions.
|
|
1225
|
+
|
|
1226
|
+
```ts
|
|
1227
|
+
// BAD — implicit return
|
|
1228
|
+
function greet(name: string): void {
|
|
1229
|
+
Logger.info(name);
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
// GOOD — explicit return
|
|
1233
|
+
function greet(name: string): void {
|
|
1234
|
+
Logger.info(name);
|
|
1235
|
+
|
|
1236
|
+
return;
|
|
1237
|
+
}
|
|
1238
|
+
```
|
|
1239
|
+
|
|
1240
|
+
### Extract Nested Function Calls into Variables
|
|
1241
|
+
|
|
1242
|
+
Don't nest `resolve()` inside `fs.readFile()` or `fs.writeFile()`. Extract into its own variable for readability.
|
|
1243
|
+
|
|
1244
|
+
```ts
|
|
1245
|
+
// BAD — hard to read
|
|
1246
|
+
const configRaw = await fs.readFile(resolve(process.cwd(), 'config.json'), 'utf-8');
|
|
1247
|
+
await fs.writeFile(resolve(process.cwd(), options.filePath), options.content, encoding);
|
|
1248
|
+
|
|
1249
|
+
// GOOD — path on its own line
|
|
1250
|
+
const configPath = resolve(process.cwd(), 'config.json');
|
|
1251
|
+
const configRaw = await fs.readFile(configPath, 'utf-8');
|
|
1252
|
+
|
|
1253
|
+
const outputPath = resolve(process.cwd(), options.filePath);
|
|
1254
|
+
await fs.writeFile(outputPath, options.content, encoding);
|
|
1255
|
+
```
|
|
1256
|
+
|
|
1257
|
+
### `for...of` vs Array Methods vs Traditional `for`
|
|
1258
|
+
|
|
1259
|
+
- `.filter()`, `.map()`, `.find()` — transforming or searching, returns a new value.
|
|
1260
|
+
- `for...of` — side effects (logging, mutating external collections, async operations).
|
|
1261
|
+
- `.reduce()` — acceptable, but `for...of` with a mutable accumulator is also fine. Either approach works.
|
|
1262
|
+
- Traditional `for` — only when index access is needed. Otherwise always `for...of`.
|
|
1263
|
+
|
|
1264
|
+
### Static Caching Pattern
|
|
1265
|
+
|
|
1266
|
+
- Private static fields with no inline initialization — start as `undefined` naturally.
|
|
1267
|
+
- Guard field typed as `true` (not `boolean`), checked with `=== true` explicitly — don't rely on truthiness of `undefined`.
|
|
1268
|
+
- Cache field type includes `| undefined` to account for uninitialized state.
|
|
1269
|
+
- On failure, set guard to `true` to prevent retrying — return `undefined`.
|
|
1270
|
+
|
|
1271
|
+
```ts
|
|
1272
|
+
static #cache: CacheType;
|
|
1273
|
+
static #populated: PopulatedType;
|
|
1274
|
+
|
|
1275
|
+
public static async fetch(): FetchReturns {
|
|
1276
|
+
if (ClassName.#populated === true) {
|
|
1277
|
+
return ClassName.#cache;
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
// ... fetch, parse, handle errors ...
|
|
1281
|
+
|
|
1282
|
+
ClassName.#cache = result;
|
|
1283
|
+
ClassName.#populated = true;
|
|
1284
|
+
|
|
1285
|
+
return ClassName.#cache;
|
|
1286
|
+
}
|
|
1287
|
+
```
|
|
1288
|
+
|
|
1289
|
+
### `undefined` vs `null`
|
|
1290
|
+
|
|
1291
|
+
- **Value** — a box with stuff in it.
|
|
1292
|
+
- **`null`** — an empty box (explicitly set to nothing, intentionally cleared).
|
|
1293
|
+
- **`undefined`** — no box at all (never assigned, doesn't exist).
|
|
1294
|
+
|
|
1295
|
+
Use `undefined` for optional/missing values (params not passed, uninitialized). Use `null` when something was intentionally set to empty (user clears a field, external API returns null).
|
|
1296
|
+
|
|
1297
|
+
### Explicit `= undefined` for Uninitialized Variables
|
|
1298
|
+
|
|
1299
|
+
`let` declarations without a value must explicitly assign `undefined`. Makes the initial state visible.
|
|
1300
|
+
|
|
1301
|
+
```ts
|
|
1302
|
+
// BAD — implicit undefined
|
|
1303
|
+
let selectedPackage;
|
|
1304
|
+
|
|
1305
|
+
// GOOD — explicit undefined
|
|
1306
|
+
let selectedPackage: RunnerSelectedPackage = undefined;
|
|
1307
|
+
```
|
|
1308
|
+
|
|
1309
|
+
### Error Handling
|
|
1310
|
+
|
|
1311
|
+
- **Creator** (function designer): may design a function to `throw` on failure — that's the API contract.
|
|
1312
|
+
- **Consumer** (function caller): always wraps calls to throwing functions in `try/catch`.
|
|
1313
|
+
- Public `run` methods on CLI classes (CLI entry points) never `throw` — set `process.exitCode = 1` and `return`.
|
|
1314
|
+
|
|
1315
|
+
### Explicit Equality Checks — No Truthy/Falsy
|
|
1316
|
+
|
|
1317
|
+
Always use explicit checks. No truthy/falsy shortcuts.
|
|
1318
|
+
|
|
1319
|
+
- `=== undefined` — no box.
|
|
1320
|
+
- `=== null` — empty box.
|
|
1321
|
+
- `== null` — check for both undefined and null at the same time (only valid use of `==` instead of `===`).
|
|
1322
|
+
- `=== true` — explicit boolean.
|
|
1323
|
+
- `> 0` / `=== 0` — explicit length.
|
|
1324
|
+
|
|
1325
|
+
|
|
1326
|
+
### `catch (error)` — No `: unknown` Annotation
|
|
1327
|
+
|
|
1328
|
+
TypeScript defaults catch clause variables to `unknown`. Don't annotate redundantly.
|
|
1329
|
+
|
|
1330
|
+
```ts
|
|
1331
|
+
// BAD — redundant
|
|
1332
|
+
} catch (error: unknown) {
|
|
1333
|
+
|
|
1334
|
+
// GOOD
|
|
1335
|
+
} catch (error) {
|
|
1336
|
+
```
|
|
1337
|
+
|
|
1338
|
+
### `process.exitCode = 1` then Blank Line then `return`
|
|
1339
|
+
|
|
1340
|
+
Separate the exit code assignment from the return statement with a blank line.
|
|
1341
|
+
|
|
1342
|
+
```ts
|
|
1343
|
+
// BAD — too close
|
|
1344
|
+
process.exitCode = 1;
|
|
1345
|
+
return;
|
|
1346
|
+
|
|
1347
|
+
// GOOD
|
|
1348
|
+
process.exitCode = 1;
|
|
1349
|
+
|
|
1350
|
+
return;
|
|
1351
|
+
```
|
|
1352
|
+
|
|
1353
|
+
### Unused Return Values — Don't Assign
|
|
1354
|
+
|
|
1355
|
+
If a function's return value is never read, don't assign it to a variable.
|
|
1356
|
+
|
|
1357
|
+
```ts
|
|
1358
|
+
// BAD — data is never used
|
|
1359
|
+
const data = await Runner.fetchData();
|
|
1360
|
+
|
|
1361
|
+
// GOOD — just await
|
|
1362
|
+
await Runner.fetchData();
|
|
1363
|
+
```
|
|
1364
|
+
|
|
1365
|
+
### No Variables Before Definition
|
|
1366
|
+
|
|
1367
|
+
Variables and constants must be defined before use. Functions, classes, and types may be forward-referenced — this allows alphabetical method ordering without dependency issues.
|
|
1368
|
+
|
|
1369
|
+
```ts
|
|
1370
|
+
// BAD — variable used before definition
|
|
1371
|
+
const x = y + 1;
|
|
1372
|
+
const y = 5;
|
|
1373
|
+
|
|
1374
|
+
// GOOD — defined before use
|
|
1375
|
+
const y = 5;
|
|
1376
|
+
const x = y + 1;
|
|
1377
|
+
|
|
1378
|
+
// GOOD — functions can forward-reference (alphabetical ordering)
|
|
1379
|
+
function filterItems() { return processItems(); }
|
|
1380
|
+
function processItems() { ... }
|
|
1381
|
+
```
|
|
1382
|
+
|
|
1383
|
+
### Promise Parallelism — Use `Promise.all`
|
|
1384
|
+
|
|
1385
|
+
Use `Promise.all` for parallel execution. Cleaner than separate task variables, and rejects immediately if one fails instead of leaving dangling promises.
|
|
1386
|
+
|
|
1387
|
+
```ts
|
|
1388
|
+
// GOOD — Promise.all
|
|
1389
|
+
const packageJsonPath = resolve(process.cwd(), 'package.json');
|
|
1390
|
+
|
|
1391
|
+
const [data, packageJsonRaw] = await Promise.all([
|
|
1392
|
+
Runner.fetchData(),
|
|
1393
|
+
fs.readFile(packageJsonPath, 'utf-8'),
|
|
1394
|
+
]);
|
|
1395
|
+
|
|
1396
|
+
// BAD — .then() chains (hard to read)
|
|
1397
|
+
// BAD — separate task variables (dangling promises on rejection)
|
|
1398
|
+
```
|
|
1399
|
+
|
|
1400
|
+
### No `await` in Loops
|
|
1401
|
+
|
|
1402
|
+
Don't `await` inside loops. Use `Promise.all()` for parallel execution. Sequential iteration where order matters (e.g., database migrations) and polling/retry loops with backoff are acceptable exceptions.
|
|
1403
|
+
|
|
1404
|
+
```ts
|
|
1405
|
+
// BAD — sequential, one at a time
|
|
1406
|
+
for (const url of urls) {
|
|
1407
|
+
await fetch(url);
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
// GOOD — parallel
|
|
1411
|
+
await Promise.all(urls.map((url) => fetch(url)));
|
|
1412
|
+
```
|
|
1413
|
+
|
|
1414
|
+
### Return Types — Use Named Alias, Not Inline Promise
|
|
1415
|
+
|
|
1416
|
+
Method return types should use the named type alias from `.d.ts`, not an inline `Promise<Type>`.
|
|
1417
|
+
|
|
1418
|
+
```ts
|
|
1419
|
+
// BAD — inline Promise type
|
|
1420
|
+
private static async fetchData(): Promise<FetcherResponse> {
|
|
1421
|
+
|
|
1422
|
+
// GOOD — named return type
|
|
1423
|
+
private static async fetchData(): FetcherFetchDataReturns {
|
|
1424
|
+
```
|
|
1425
|
+
|
|
1426
|
+
### Readability — All Generated Code Must Be Human-Readable
|
|
1427
|
+
|
|
1428
|
+
Don't inline complex expressions into template literals or other expressions. Break them into named variables so each step is clear.
|
|
1429
|
+
|
|
1430
|
+
```ts
|
|
1431
|
+
// BAD — JSON.stringify jammed into a template literal
|
|
1432
|
+
await fs.writeFile(filePath, `${JSON.stringify({ name: 'test' }, null, 2)}\n`, 'utf-8');
|
|
1433
|
+
|
|
1434
|
+
// GOOD — separated into readable variables
|
|
1435
|
+
const packageJson = JSON.stringify({ name: 'test' }, null, 2);
|
|
1436
|
+
const packageContents = `${packageJson}\n`;
|
|
1437
|
+
|
|
1438
|
+
await fs.writeFile(filePath, packageContents, 'utf-8');
|
|
1439
|
+
```
|
|
1440
|
+
|
|
1441
|
+
### Multiline Content — Use Arrays, Not Embedded Newlines
|
|
1442
|
+
|
|
1443
|
+
Don't embed multiline content in string literals using `\n`. Instead, build an array of lines and join them.
|
|
1444
|
+
|
|
1445
|
+
```ts
|
|
1446
|
+
// BAD — multiline content embedded in a string literal
|
|
1447
|
+
const text = 'Required Secrets:\n - PERSONAL_ACCESS_TOKEN\n - DEPLOY_KEY';
|
|
1448
|
+
|
|
1449
|
+
// GOOD — array of lines joined with \n
|
|
1450
|
+
const lines = [
|
|
1451
|
+
'Required Secrets:',
|
|
1452
|
+
' - PERSONAL_ACCESS_TOKEN',
|
|
1453
|
+
' - DEPLOY_KEY',
|
|
1454
|
+
];
|
|
1455
|
+
const text = lines.join('\n');
|
|
1456
|
+
```
|
|
1457
|
+
|
|
1458
|
+
### No `javascript:` URLs
|
|
1459
|
+
|
|
1460
|
+
Disallow `javascript:` URLs. Legacy anchor elements that must prevent navigation without `href="#"` may use `javascript:void(0)` as an acceptable exception.
|
|
1461
|
+
|
|
1462
|
+
```ts
|
|
1463
|
+
// BAD
|
|
1464
|
+
href = 'javascript:alert("XSS")';
|
|
1465
|
+
href = 'javascript:doSomething()';
|
|
1466
|
+
|
|
1467
|
+
// GOOD
|
|
1468
|
+
href = '#';
|
|
1469
|
+
href = '/path/to/page';
|
|
1470
|
+
```
|
|
1471
|
+
|
|
1472
|
+
### No `any` Type
|
|
1473
|
+
|
|
1474
|
+
Don't use `any`. Use `unknown` (via a named type alias in `.d.ts`) and narrow with type guards, or define a specific type.
|
|
1475
|
+
|
|
1476
|
+
```ts
|
|
1477
|
+
// BAD
|
|
1478
|
+
function parse(input: any): any { ... }
|
|
1479
|
+
const data = response.json() as any;
|
|
1480
|
+
|
|
1481
|
+
// GOOD — named type aliases (defined as unknown in .d.ts)
|
|
1482
|
+
function parse(input: RunnerParseInput): RunnerParseReturns { ... }
|
|
1483
|
+
const data: FetcherGetDataResponse = FetcherResponseSchema.parse(response.json());
|
|
1484
|
+
```
|
|
1485
|
+
|
|
1486
|
+
## Regex Patterns
|
|
1487
|
+
|
|
1488
|
+
### Centralize Regex in a Shared File
|
|
1489
|
+
|
|
1490
|
+
Don't use inline regex literals. Define patterns in a shared file (e.g., `regex.ts`) and import them. The shared regex source file itself is excluded from this rule.
|
|
1491
|
+
|
|
1492
|
+
```ts
|
|
1493
|
+
// BAD — inline regex
|
|
1494
|
+
version.replace(/^v/, '');
|
|
1495
|
+
|
|
1496
|
+
// GOOD — centralized pattern
|
|
1497
|
+
import { LIB_REGEX_PATTERN_LEADING_V } from '@/lib/regex.js';
|
|
1498
|
+
version.replace(LIB_REGEX_PATTERN_LEADING_V, '');
|
|
1499
|
+
```
|
|
1500
|
+
|
|
1501
|
+
### No Flags on Regex Patterns
|
|
1502
|
+
|
|
1503
|
+
Keep regex patterns flag-free. Apply flags at the call site with `new RegExp()`.
|
|
1504
|
+
|
|
1505
|
+
```ts
|
|
1506
|
+
// BAD — flag on the pattern
|
|
1507
|
+
const LIB_REGEX_PATTERN_DIGITS = /\d+/g;
|
|
1508
|
+
|
|
1509
|
+
// GOOD — flag-free pattern, flag at call site
|
|
1510
|
+
const LIB_REGEX_PATTERN_DIGITS = /\d+/;
|
|
1511
|
+
const allDigits = new RegExp(LIB_REGEX_PATTERN_DIGITS, 'g');
|
|
1512
|
+
```
|
|
1513
|
+
|
|
1514
|
+
## TSConfig Conventions
|
|
1515
|
+
|
|
1516
|
+
```jsonc
|
|
1517
|
+
{
|
|
1518
|
+
"compilerOptions": {
|
|
1519
|
+
"module": "nodenext", // Always pair module with moduleResolution
|
|
1520
|
+
"moduleResolution": "nodenext",
|
|
1521
|
+
// "incremental": false, // NEVER — non-deterministic
|
|
1522
|
+
// "composite": false, // NEVER — requires incremental
|
|
1523
|
+
// "typeRoots": [], // NEVER
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
```
|
|
1527
|
+
|
|
1528
|
+
- No `assumeChangesOnlyAffectDirectDependencies` (non-deterministic).
|
|
1529
|
+
- No relative paths in exported TSConfig presets (TS resolves from config location).
|
|
1530
|
+
- If project uses own build tool: `isolatedModules: true` + `noEmit: true`.
|