@jeportie/create-tskickstart 1.6.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/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 cadienvan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.md ADDED
@@ -0,0 +1,427 @@
1
+ # tskickstart
2
+
3
+ A zero-config scaffolding CLI that wires **ESLint + Prettier + TypeScript** into any Node.js project — and optionally sets up **Vitest**, **Husky**, **lint-staged**, **Commitlint**, **CSpell**, and **Secretlint** — in one interactive command.
4
+
5
+ ```sh
6
+ npm create @jeportie/tskickstart
7
+ ```
8
+
9
+ ---
10
+
11
+ ## What it does
12
+
13
+ Running `npm create @jeportie/tskickstart` inside an existing project will ask you a series of questions and then:
14
+
15
+ 1. **Ensure `package.json` exists** — creates one with `npm init -y` if missing, or patches `"type": "module"` if it is already there but missing that field
16
+ 2. **Install** ESLint, Prettier, TypeScript and their plugins as dev dependencies
17
+ 3. **Copy** config files into your project root
18
+ 4. **Inject scripts** into your `package.json`
19
+ 5. **Set up optional tooling** based on your answers to the interactive prompts
20
+
21
+ ### Interactive prompts
22
+
23
+ | Prompt | What it sets up |
24
+ | --- | --- |
25
+ | **Your name** | Reads from `git config github.user` (then `user.name`); added to `package.json` and cspell |
26
+ | **Select more lint options** | Multi-select: `cspell`, `secretlint`, `commitlint` |
27
+ | **Set up Vitest?** | Optional test runner — choose Native or Coverage preset |
28
+ | **Set up pre-commit hook?** | Husky + lint-staged wired to your selected tools |
29
+
30
+ All existing files are left untouched (the CLI skips them with a notice).
31
+
32
+ ---
33
+
34
+ ## Quick start
35
+
36
+ ```sh
37
+ # Inside your existing project
38
+ npm create @jeportie/tskickstart
39
+
40
+ # Run all checks at once
41
+ npm run check
42
+
43
+ # Individual tools
44
+ npm run lint
45
+ npm run format
46
+ npm run typecheck
47
+ npm run spellcheck # if cspell was selected
48
+ npm run secretlint # if secretlint was selected
49
+
50
+ # If you chose the Native or Coverage Vitest preset
51
+ npm test
52
+ npm run test:unit
53
+ npm run test:integration
54
+
55
+ # If you chose the Coverage preset
56
+ npm run test:coverage
57
+ ```
58
+
59
+ ---
60
+
61
+ ## How it works internally
62
+
63
+ ```
64
+ npm create @jeportie/tskickstart
65
+
66
+ └─▶ npm downloads the create-tskickstart package
67
+ └─▶ node runs ./src/index.js (registered via "bin" in package.json)
68
+
69
+ ├─ 1. read author name (git config github.user → user.name → prompt if missing)
70
+ ├─ 2. prompt — lint options (cspell / secretlint / commitlint)
71
+ ├─ 3. prompt — Vitest preset (none / native / coverage)
72
+ ├─ 4. prompt — pre-commit hook (husky + lint-staged)
73
+ ├─ 5. ensure package.json exists and has "type": "module"
74
+ ├─ 6. npm install -D eslint prettier ... (+ selected optional deps)
75
+ ├─ 7. copy template config files → YOUR project root
76
+ ├─ 8. create src/main.ts (and test/ if Vitest chosen)
77
+ └─ 9. inject scripts + author + lint-staged config → YOUR package.json
78
+ ```
79
+
80
+ ### Template path resolution
81
+
82
+ Inside `src/index.js`:
83
+
84
+ ```js
85
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
86
+ const cwd = process.cwd();
87
+ ```
88
+
89
+ - `__dirname` always points to `create-tskickstart/src/` — the CLI's own files, wherever npm installed them
90
+ - `cwd` is **your** project's directory — where files get copied and `package.json` gets updated
91
+
92
+ This separation is what lets a `create-*` tool safely write into an unrelated target directory.
93
+
94
+ ### How `bin` mapping works in npm
95
+
96
+ ```json
97
+ "bin": {
98
+ "create-tskickstart": "./src/index.js"
99
+ }
100
+ ```
101
+
102
+ When npm installs a package that has a `bin` field, it creates a symlink in `node_modules/.bin/`. When you run `npm create foo`, npm translates that into `npm exec create-foo` and executes the registered binary. The `#!/usr/bin/env node` shebang on line 1 of `src/index.js` tells the OS to run it with Node.
103
+
104
+ ---
105
+
106
+ ## What gets installed in your project
107
+
108
+ ### Always installed
109
+
110
+ | Package | Purpose |
111
+ | ----------------------------------- | ------------------------------------------------- |
112
+ | `eslint` | JavaScript/TypeScript linter |
113
+ | `prettier` | Opinionated code formatter |
114
+ | `eslint-config-prettier` | Disables ESLint rules that conflict with Prettier |
115
+ | `typescript-eslint` | TypeScript parser and rules for ESLint |
116
+ | `@stylistic/eslint-plugin` | Code style rules (quotes, spacing, etc.) |
117
+ | `eslint-plugin-import` | Import order and resolution rules |
118
+ | `eslint-import-resolver-typescript` | Resolves TypeScript paths in import plugin |
119
+ | `typescript` | TypeScript compiler |
120
+ | `@types/node` | Node.js type definitions |
121
+
122
+ ### If **cspell** is selected
123
+
124
+ | Package | Purpose |
125
+ | ----------------------- | --------------------------------------- |
126
+ | `cspell` | Spell checker for source code and docs |
127
+ | `@cspell/eslint-plugin` | ESLint integration — flags typos inline |
128
+
129
+ When cspell is selected, `eslintCspell.config.js` is used instead of the base `eslint.config.js`, adding the `@cspell/eslint-plugin` rule directly into ESLint.
130
+
131
+ ### If **secretlint** is selected
132
+
133
+ | Package | Purpose |
134
+ | ---------------------------------------------- | ------------------------------------- |
135
+ | `secretlint` | Scans files for leaked secrets/tokens |
136
+ | `@secretlint/secretlint-rule-preset-recommend` | Default ruleset for secretlint |
137
+
138
+ ### If **commitlint** is selected
139
+
140
+ | Package | Purpose |
141
+ | --------------------------------- | ------------------------------------------- |
142
+ | `@commitlint/cli` | Lint commit messages |
143
+ | `@commitlint/config-conventional` | Conventional Commits ruleset |
144
+ | `commitlint-plugin-cspell` | Spell-check commit messages _(cspell only)_ |
145
+
146
+ ### If **pre-commit hook** is selected
147
+
148
+ | Package | Purpose |
149
+ | ------------- | -------------------------------- |
150
+ | `husky` | Git hooks manager |
151
+ | `lint-staged` | Run linters only on staged files |
152
+
153
+ The `.husky/pre-commit` hook is generated dynamically based on your selections:
154
+
155
+ ```sh
156
+ npx lint-staged
157
+ npm run typecheck
158
+ npm run test # only if a Vitest preset was chosen
159
+ ```
160
+
161
+ The `.husky/commit-msg` hook is only written if commitlint was selected:
162
+
163
+ ```sh
164
+ npx commitlint --edit
165
+ ```
166
+
167
+ The `lint-staged` config in `package.json` is also generated dynamically:
168
+
169
+ ```json
170
+ "lint-staged": {
171
+ "**/*": ["npm run format", "npm run lint", "npm run spellcheck", "npm run secretlint"]
172
+ }
173
+ ```
174
+
175
+ Only the commands for tools you selected are included.
176
+
177
+ ### Vitest preset — Native
178
+
179
+ | Package | Purpose |
180
+ | -------- | ----------------------------- |
181
+ | `vitest` | Fast, Vite-native test runner |
182
+
183
+ ### Vitest preset — Coverage
184
+
185
+ | Package | Purpose |
186
+ | --------------------- | ----------------------------- |
187
+ | `vitest` | Fast, Vite-native test runner |
188
+ | `@vitest/coverage-v8` | Code coverage powered by V8 |
189
+
190
+ ---
191
+
192
+ ## What the templates configure
193
+
194
+ ### `eslint.config.js`
195
+
196
+ Uses ESLint's flat config format (ESLint 9+). Includes:
197
+
198
+ - `@eslint/js` recommended rules
199
+ - Full TypeScript type-checked rules via `typescript-eslint`
200
+ - Stylistic rules (single quotes, spaced comments)
201
+ - Import ordering and cycle detection
202
+ - Prettier compatibility (must be last)
203
+ - Test file overrides (relaxed rules in `*.test.*`)
204
+
205
+ When cspell is selected, `eslintCspell.config.js` is used instead, which adds `@cspell/eslint-plugin` to report spelling errors directly in ESLint output.
206
+
207
+ ### `prettier.config.js`
208
+
209
+ Standard Prettier settings:
210
+
211
+ - Single quotes, trailing commas, 80-char print width
212
+ - No semicolons in prose, arrow parens always
213
+
214
+ ### `.eslintignore` / `.prettierignore`
215
+
216
+ Both ignore files are pre-populated with:
217
+
218
+ ```
219
+ dist
220
+ node_modules
221
+ package-lock.json
222
+ coverage
223
+ ```
224
+
225
+ ### `.gitignore`
226
+
227
+ Includes `node_modules`, `dist`, `coverage`, `.env*`, and `*.log`.
228
+
229
+ ### `tsconfig.base.json` / `tsconfig.json`
230
+
231
+ Strict TypeScript configuration. `tsconfig.json` includes `src`, `test`, `__tests__`, and root-level `*.ts` / `*.js` files.
232
+
233
+ ### `commitlint.config.js` (commitlint only)
234
+
235
+ Extends `@commitlint/config-conventional`. If cspell was also selected, the `commitlint-plugin-cspell` plugin is added to spell-check commit message bodies.
236
+
237
+ ### `.secretlintrc.json` (secretlint only)
238
+
239
+ Enables the full `@secretlint/secretlint-rule-preset-recommend` ruleset to catch API keys, tokens, private keys, and similar secrets.
240
+
241
+ ### `cspell.json` (cspell only)
242
+
243
+ Base CSpell config with the default English dictionary and common programming word lists enabled.
244
+
245
+ ### `vitest.config.ts` (Vitest presets only)
246
+
247
+ Both presets create a `vitest.config.ts` in your project root with:
248
+
249
+ - A `resolve.alias` mapping `@` → `src/` so your tests can import using the same path alias as your source code:
250
+
251
+ ```ts
252
+ import { myUtil } from '@/utils/myUtil';
253
+ ```
254
+
255
+ - A `test.include` that covers both `__tests__/` and `test/` directory conventions:
256
+
257
+ ```ts
258
+ include: ['**/__tests__/**/*.{test,spec}.{ts,tsx,js}', '**/test/**/*.{test,spec}.{ts,tsx,js}'];
259
+ ```
260
+
261
+ **Coverage preset** additionally adds:
262
+
263
+ ```ts
264
+ coverage: {
265
+ enabled: true,
266
+ reporter: ['json-summary', 'json', 'html'],
267
+ include: ['src/**/*'],
268
+ reportOnFailure: true,
269
+ },
270
+ ```
271
+
272
+ The `coverage/` output folder is automatically excluded from ESLint, Prettier, and Git via the installed ignore files.
273
+
274
+ ---
275
+
276
+ ## Vitest presets in detail
277
+
278
+ When the CLI runs interactively it asks:
279
+
280
+ ```
281
+ ? Do you want to set up Vitest for testing? (Y/n)
282
+ ? Which Vitest configuration would you like?
283
+ ❯ Native — vitest
284
+ Coverage — vitest + @vitest/coverage-v8
285
+ ```
286
+
287
+ ### Native preset
288
+
289
+ Installs `vitest` and adds these scripts:
290
+
291
+ ```json
292
+ "test": "vitest --run",
293
+ "test:unit": "vitest unit --run",
294
+ "test:integration": "vitest int --run"
295
+ ```
296
+
297
+ `test:unit` matches any file whose path contains `unit`. `test:integration` matches any file whose path contains `int`.
298
+
299
+ Also adds a `@` → `src/` path alias in `vitest.config.ts` and configures test discovery for both `__tests__/` and `test/` directories.
300
+
301
+ ### Coverage preset
302
+
303
+ Everything from Native, plus installs `@vitest/coverage-v8` and adds:
304
+
305
+ ```json
306
+ "test:coverage": "vitest --coverage --run"
307
+ ```
308
+
309
+ Coverage reports are written to `coverage/` and include HTML, JSON, and a JSON summary (compatible with GitHub Actions PR annotations).
310
+
311
+ ---
312
+
313
+ ## Non-interactive / CI usage
314
+
315
+ Set the `VITEST_PRESET` environment variable to bypass the Vitest interactive prompt:
316
+
317
+ ```sh
318
+ # Skip Vitest setup
319
+ VITEST_PRESET=none node ./src/index.js
320
+
321
+ # Install vitest with path alias only
322
+ VITEST_PRESET=native node ./src/index.js
323
+
324
+ # Install vitest with coverage reporting
325
+ VITEST_PRESET=coverage node ./src/index.js
326
+ ```
327
+
328
+ Set `AUTHOR_NAME` to bypass the git config lookup and author prompt:
329
+
330
+ ```sh
331
+ AUTHOR_NAME="Jane Doe" node ./src/index.js
332
+ ```
333
+
334
+ Set `NO_INSTALL=1` to skip all `npm install` calls (useful for testing):
335
+
336
+ ```sh
337
+ NO_INSTALL=1 node ./src/index.js
338
+ ```
339
+
340
+ ---
341
+
342
+ ## How to release
343
+
344
+ This repo uses [semantic-release](https://semantic-release.gitbook.io/semantic-release/). Requires `NPM_TOKEN` and `GITHUB_TOKEN` secrets in the repo.
345
+
346
+ ### Release flow
347
+
348
+ ```
349
+ git commit -m "feat: add support for --skip-install flag"
350
+ git push origin main
351
+
352
+ └─▶ GitHub Actions: semantic-release.yml
353
+ ├─ Analyzes commits since last tag
354
+ │ feat → minor bump (0.1.0 → 0.2.0)
355
+ │ fix → patch bump (0.1.0 → 0.1.1)
356
+ │ feat! → major bump (0.1.0 → 1.0.0)
357
+ ├─ Generates release notes
358
+ ├─ Publishes to npm registry
359
+ └─ Creates a GitHub Release + git tag (v0.2.0)
360
+ ```
361
+
362
+ **Never bump the version in `package.json` manually** — semantic-release owns that. The placeholder `"0.0.0-semantically-released"` is intentional and gets replaced at publish time.
363
+
364
+ ### Commit message format
365
+
366
+ ```
367
+ <type>(<scope>): <description>
368
+
369
+ feat: add --dry-run flag
370
+ fix: resolve template path on Windows
371
+ docs: update README with next steps
372
+ chore: upgrade eslint to v9
373
+ ```
374
+
375
+ ---
376
+
377
+ ## Development
378
+
379
+ Node.js 20+ required. Run `npm install` after cloning.
380
+
381
+ ### Run tests
382
+
383
+ ```sh
384
+ npm test # all tests
385
+ npm run test:integration # integration tests only
386
+ npm run test:coverage # with coverage report
387
+ ```
388
+
389
+ ### Project structure
390
+
391
+ ```
392
+ tskickstart/
393
+ ├── src/
394
+ │ ├── index.js # CLI entrypoint (#!/usr/bin/env node)
395
+ │ └── templates/
396
+ │ ├── eslint.config.js # copied when cspell is NOT selected
397
+ │ ├── eslintCspell.config.js # copied when cspell IS selected
398
+ │ ├── prettier.config.js
399
+ │ ├── .editorconfig
400
+ │ ├── .eslintignore
401
+ │ ├── .prettierignore
402
+ │ ├── _gitignore # copied as .gitignore
403
+ │ ├── tsconfig.base.json
404
+ │ ├── tsconfig.json
405
+ │ ├── cspell.json # copied when cspell is selected
406
+ │ ├── .secretlintrc.json # copied when secretlint is selected
407
+ │ ├── commitlint.config.js # copied when commitlint is selected
408
+ │ ├── .husky/
409
+ │ │ ├── pre-commit # template (generated dynamically at runtime)
410
+ │ │ └── commit-msg # template (written only when commitlint selected)
411
+ │ ├── vitest.config.native.ts # resolve alias + test:unit/integration
412
+ │ └── vitest.config.coverage.ts # + coverage block and test:coverage
413
+ ├── __tests__/
414
+ │ └── integration/
415
+ │ └── index.int.test.js
416
+ ├── .github/workflows/
417
+ │ ├── pull-request-checks.yml
418
+ │ └── semantic-release.yml
419
+ ├── release.config.mjs # semantic-release configuration
420
+ └── package.json
421
+ ```
422
+
423
+ ---
424
+
425
+ ## License
426
+
427
+ MIT
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@jeportie/create-tskickstart",
3
+ "version": "1.6.0",
4
+ "description": "Scaffolding CLI that kick-starts any TypeScript project with ESLint, Prettier, Vitest, Husky, and more",
5
+ "author": "jeportie",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git://github.com/jeportie/tskickstart.git"
9
+ },
10
+ "keywords": [
11
+ "eslint",
12
+ "prettier",
13
+ "typescript",
14
+ "scaffolding",
15
+ "create",
16
+ "cli",
17
+ "vitest",
18
+ "husky"
19
+ ],
20
+ "license": "MIT",
21
+ "private": false,
22
+ "type": "module",
23
+ "bin": {
24
+ "create-tskickstart": "src/index.js"
25
+ },
26
+ "files": [
27
+ "src"
28
+ ],
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "scripts": {
33
+ "format": "prettier . --write",
34
+ "lint": "eslint .",
35
+ "secretlint": "secretlint ./src --maskSecrets",
36
+ "spellcheck": "cspell --no-progress \"./**/*.{js,mjs,cjs,md,json,yml}\"",
37
+ "test": "vitest --run",
38
+ "test:coverage": "vitest --coverage --run",
39
+ "test:integration": "vitest int --run",
40
+ "prepare": "husky || true"
41
+ },
42
+ "dependencies": {
43
+ "execa": "^8.0.1",
44
+ "fs-extra": "^11.2.0",
45
+ "inquirer": "~10.2.2",
46
+ "picocolors": "^1.0.0"
47
+ },
48
+ "devDependencies": {
49
+ "@commitlint/cli": "^19.3.0",
50
+ "@commitlint/config-conventional": "^19.2.2",
51
+ "@eslint/js": "^9.0.0",
52
+ "@secretlint/secretlint-rule-pattern": "^8.2.4",
53
+ "@secretlint/secretlint-rule-preset-recommend": "^8.2.4",
54
+ "@vitest/coverage-v8": "^2.0.4",
55
+ "commitlint-plugin-cspell": "^0.1.1",
56
+ "conventional-changelog-conventionalcommits": "~8.0.0",
57
+ "cspell": "^8.12.1",
58
+ "eslint": "^9.0.0",
59
+ "eslint-config-prettier": "^9.1.0",
60
+ "husky": "^9.1.1",
61
+ "lint-staged": "^15.2.7",
62
+ "prettier": "^3.3.3",
63
+ "secretlint": "^8.2.4",
64
+ "semantic-release": "~24.0.0",
65
+ "vitest": "^2.0.4"
66
+ }
67
+ }