@lntvow/dev 6.2.0 → 6.4.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 CHANGED
@@ -19,3 +19,70 @@
19
19
  [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-brightgreen?logo=typescript)](https://www.typescriptlang.org/)
20
20
  [![npm version](https://img.shields.io/npm/v/@lntvow/dev.svg?logo=npm)](https://www.npmjs.com/package/@lntvow/dev)
21
21
  [![package size](https://img.shields.io/npm/unpacked-size/@lntvow/dev?logo=npm)](https://www.npmjs.com/package/@lntvow/dev)
22
+
23
+ A small CLI that sets up a development environment: copies config files, installs the shared dev dependencies and adds the standard npm scripts.
24
+
25
+ ## Requirements
26
+
27
+ - Node.js **22.0.0** or later
28
+
29
+ ## Usage
30
+
31
+ Run it in the project you want to set up:
32
+
33
+ ```bash
34
+ # pnpm
35
+ pnpm dlx @lntvow/dev init
36
+
37
+ # npm
38
+ npx @lntvow/dev init
39
+ ```
40
+
41
+ Or install it globally:
42
+
43
+ ```bash
44
+ pnpm add -g @lntvow/dev
45
+ dev init
46
+ ```
47
+
48
+ ### `dev init`
49
+
50
+ Initializes the current directory:
51
+
52
+ 1. Copies the template config files (existing files are left untouched).
53
+ 2. Installs `@lntvow/cli`, `@lntvow/eslint-config`, `eslint`, `prettier` and `typescript` as dev dependencies.
54
+ 3. Merges the default scripts into `package.json` (existing scripts win).
55
+
56
+ Options:
57
+
58
+ | Option | Description |
59
+ | ------------------------ | ---------------------------------------------------------------------------------------------- |
60
+ | `--no-temp` | Skip copying template files |
61
+ | `--no-scripts` | Skip updating `package.json` scripts |
62
+ | `--pm <pnpm\|yarn\|npm>` | Package manager; auto-detected from the lockfile / `npm_config_user_agent`, otherwise prompted |
63
+
64
+ The generated `upgrade`, `prerelease` and `version` scripts use the selected package manager; the optional test step always uses `npm run --if-present test`.
65
+
66
+ Files copied when missing:
67
+
68
+ ```
69
+ .editorconfig
70
+ .gitignore
71
+ .npmrc
72
+ .prettierignore
73
+ .prettierrc
74
+ .vscode/settings.json
75
+ eslint.config.mjs
76
+ README.md
77
+ tsconfig.json
78
+ ```
79
+
80
+ Scripts added when missing: `prepare`, `rimraf`, `upgrade`, `tidy`, `commit`, `prerelease`, `release`, `changelog`, `version`, `lint:eslint`, `lint:tsc`, `lint`.
81
+
82
+ ### `dev release`
83
+
84
+ Pulls, stages, commits and pushes the current repository. The commit message is the date in `YYYYMMDD` form.
85
+
86
+ ## License
87
+
88
+ [MIT](LICENSE)
package/dist/cli.mjs CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- (e=>e.major>20||e.major===20&&e.minor>=19)((e=>{let[t=`0`,n=`0`]=e.split(`.`);return{major:Number(t),minor:Number(n)}})(process.versions.node))||(process.stderr.write(`@lntvow/dev: Node.js v20.19+ is required (current: v${process.versions.node}).\nIf you use nvm, run:\n nvm install 20\n nvm use 20\n nvm alias default 20\n`),process.exit(1)),import(`./main-Mexl6ofW.mjs`);export{};
2
+ (e=>e.major>22||e.major===22&&e.minor>=0)((e=>{let[t=`0`,n=`0`]=e.split(`.`);return{major:Number(t),minor:Number(n)}})(process.versions.node))||(process.stderr.write(`@lntvow/dev: Node.js v22.0+ is required (current: v${process.versions.node}).\nIf you use nvm, run:\n nvm install 22\n nvm use 22\n nvm alias default 22\n`),process.exit(1)),import(`./main-wW69u2gl.mjs`);export{};
@@ -0,0 +1,77 @@
1
+ # Logs
2
+ logs/
3
+ *.log
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+ pnpm-debug.log*
8
+ lerna-debug.log*
9
+
10
+ # Runtime data
11
+ pids/
12
+ *.pid
13
+ *.seed
14
+ *.pid.lock
15
+
16
+
17
+ # Temporary and cache folders
18
+ tmp/
19
+ temp/
20
+ .temp/
21
+ .cache/
22
+ .npm/
23
+ *.tsbuildinfo
24
+ .eslintcache
25
+ .stylelintcache
26
+
27
+ # OS-generated files
28
+ .DS_Store
29
+ .AppleDouble
30
+ .LSOverride
31
+ Thumbs.db
32
+ ehthumbs.db
33
+ Desktop.ini
34
+
35
+ # Coverage reports (generated by testing tools)
36
+ coverage/
37
+ codecov*
38
+ *.lcov
39
+ .nyc_output/
40
+ __coverage__/
41
+ coverage-final.json
42
+ coverage-summary.json
43
+
44
+ # Test/automation outputs
45
+ test-results/
46
+ playwright-report/
47
+ cypress/screenshots/
48
+ cypress/videos/
49
+
50
+
51
+ # Editor directories and files
52
+ .idea/
53
+ *.suo
54
+ *.ntvs*
55
+ *.njsproj
56
+ *.sln
57
+ *.sw?
58
+
59
+ # Build output directories
60
+ dist/
61
+ build/
62
+ out/
63
+ .next/
64
+ .nuxt/
65
+ .svelte-kit/
66
+ .storybook-out/
67
+ out-storybook/
68
+
69
+ # Dependency directories
70
+ node_modules/
71
+ jspm_packages/
72
+
73
+
74
+ # Local files
75
+ *.local
76
+
77
+ # Custom
@@ -0,0 +1,3 @@
1
+ # registry=https://registry.npmmirror.com
2
+ # registry=https://registry.npmjs.org
3
+
@@ -0,0 +1,5 @@
1
+ import{Option as e,program as t}from"commander";import{isCancel as n,select as r}from"@clack/prompts";import{execFileSync as i}from"node:child_process";import{copyFileSync as a,existsSync as o,lstatSync as s,mkdirSync as c,readFileSync as l,readdirSync as u,rmSync as d,rmdirSync as f,writeFileSync as p}from"node:fs";import{basename as m,dirname as h,relative as g,resolve as _}from"node:path";import v from"picocolors";import{fileURLToPath as y}from"node:url";import b from"simple-git";var x=`@lntvow/dev`,S=`6.4.0`;const C={gitignore:`.gitignore`,npmrc:`.npmrc`},w={info:e=>console.log(v.blue(`● ${e}`)),success:e=>console.log(v.green(`✓ ${e}`)),warn:e=>console.log(v.yellow(`▲ ${e}`)),error:e=>console.error(v.red(`✗ ${e}`))};function T(e,t){let n=e instanceof Error?e.message:String(e);w.error(t?`${t}: ${n}`:n),process.exitCode=1}function E(e,t,n={}){return i(e,t,{stdio:`inherit`,shell:process.platform===`win32`,...n})}async function D(){for(let{file:e,manager:t}of[{file:`pnpm-lock.yaml`,manager:`pnpm`},{file:`yarn.lock`,manager:`yarn`},{file:`package-lock.json`,manager:`npm`}])if(o(_(process.cwd(),e)))return t;let e=process.env.npm_config_user_agent||``;return e.startsWith(`pnpm`)?`pnpm`:e.startsWith(`yarn`)?`yarn`:e.startsWith(`npm`)?`npm`:O()}async function O(){if(!process.stdin.isTTY)throw Error(`No lock file found and stdin is not interactive. Pass --pm <pnpm|yarn|npm>.`);let e=await r({message:`No lock file found. Please select a package manager`,options:[{label:`pnpm`,value:`pnpm`},{label:`yarn`,value:`yarn`},{label:`npm`,value:`npm`}],initialValue:`pnpm`});if(n(e))throw Error(`Package manager selection canceled.`);return e}function k(e,t,n={created:[],skipped:[]}){let r=s(e);if(r.isSymbolicLink())throw Error(`Template contains a symbolic link, which is not supported: ${e}`);if(r.isDirectory()){if(m(e)===`node_modules`)return n;c(t,{recursive:!0}),u(e).forEach(r=>{k(_(e,r),_(t,r),n)})}else{let r=_(h(t),C[m(t)]??m(t));if(o(r))return n.skipped.push(r),n;a(e,r),n.created.push(r)}return n}function A(e){return{prepare:`cli hooks`,rimraf:`cli rimraf ./node_modules/`,upgrade:`cli upgrade -u -x "@types/node" && ${e} install`,tidy:`cli tidy`,commit:`git add -A && cli commit`,prerelease:`${e} run lint && npm run --if-present test`,release:`git add -A && cli release -r -a`,changelog:`cli changelog -p angular -i CHANGELOG.md -s`,version:`${e} run changelog && git add -A`,"lint:eslint":`eslint --fix --cache`,"lint:tsc":`tsc --noEmit`,lint:`cli run lint:eslint lint:tsc`}}const j=[[`@lntvow/cli`,`latest`],[`@lntvow/eslint-config`,`latest`],[`eslint`,`latest`],[`prettier`,`latest`],[`typescript`,`6.x`]];function M(t){t.command(`init`).description(`init project`).option(`-t, --temp`,`copy template files`,!0).option(`--no-temp`,`not copy template files`).option(`-s, --scripts`,`init scripts`,!0).option(`--no-scripts`,`not init scripts`).addOption(new e(`--pm <manager>`,`package manager (auto-detect from lockfile/userAgent; prompt if ambiguous)`).choices([`pnpm`,`yarn`,`npm`])).action(N)}async function N(e){w.success(`Init project by @lntvow/dev`),w.info(`Cwd is ${process.cwd()}`);let{temp:t,scripts:n,pm:r}=e,i={created:[],skipped:[]},a=null;try{let e=r??await D();a=P(),t&&I(i),B(e),n&&R(e),w.success(`Project initialization completed successfully!`)}catch(e){L(i.created),F(a),T(e,`Initialization failed`)}}function P(){let e=_(process.cwd(),`package.json`);if(o(e))return null;let t=m(process.cwd()).toLowerCase().replace(/[^a-z0-9._-]+/g,`-`).replace(/^[-.]+|[-.]+$/g,``)||`project`,n=`${JSON.stringify({name:t,version:`0.0.0`},null,2)}\n`;return p(e,n),w.info(`Created package.json for "${t}"`),n}function F(e){if(!e)return;let t=_(process.cwd(),`package.json`);o(t)&&l(t,`utf8`)===e&&(d(t,{force:!0}),w.warn(`Rolled back generated package.json`))}function I(e){let t=y(new URL(`./configs`,import.meta.url)),n=process.cwd();w.info(`Copying template files from "${t}" to "${n}"`),k(t,n,e);for(let t of e.created)w.info(` created ${g(n,t)}`);for(let t of e.skipped)w.warn(` skipped ${g(n,t)} (already exists)`);w.success(`Template files copied (${e.created.length} created, ${e.skipped.length} skipped)`)}function L(e){if(e.length!==0){for(let t of e){d(t,{force:!0});let e=h(t);if(e!==process.cwd())try{f(e)}catch{}}w.warn(`Rolled back ${e.length} copied template file(s)`)}}function R(e){let t,n=_(process.cwd(),`package.json`);try{w.info(`Updating package.json scripts...`),t=l(n,`utf-8`);let r=JSON.parse(t),i={...r,scripts:{...A(e),...r.scripts}};p(n,z(i,t)),w.success(`Package.json scripts updated successfully`)}catch(e){throw t&&p(n,t),e}}function z(e,t){let n=/^([ \t]+)"/m.exec(t)?.[1],r=t.includes(`\r
2
+ `)?`\r
3
+ `:`
4
+ `;return(n?JSON.stringify(e,null,n):JSON.stringify(e)).replaceAll(`
5
+ `,r)+(/\r?\n$/.test(t)?r:``)}function B(e){let t=j.map(([e,t])=>`${e}@${t}`),{command:n,args:r}={pnpm:{command:`pnpm`,args:[`add`,`-D`,...t]},yarn:{command:`yarn`,args:[`add`,`-D`,...t]},npm:{command:`npm`,args:[`install`,`-D`,...t]}}[e];w.info(`Installing dependencies: ${n} ${r.join(` `)}`),E(n,r),w.success(`Dependencies installed successfully`)}function V(e){e.command(`release`).description(`git release`).action(H)}async function H(){console.log(v.green(`Release project...`));try{await U(),w.success(`Release completed successfully!`)}catch(e){T(e,`Release failed`)}}async function U(){let e=b(process.cwd()),t=W(/* @__PURE__ */ new Date);await e.pull(),await e.add(`.`),await e.commit(t,[`--no-verify`]),await e.push(`origin`),w.success(`Committed: ${t}`)}function W(e){return`${e.getFullYear()}${String(e.getMonth()+1).padStart(2,`0`)}${String(e.getDate()).padStart(2,`0`)}`}t.name(x).version(S,`-v, --version`,`output the version number`),M(t),V(t),t.parseAsync().catch(T);export{};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lntvow/dev",
3
- "version": "6.2.0",
4
- "description": "Development environment dependencies package",
3
+ "version": "6.4.0",
4
+ "description": "CLI for scaffolding development environment configs, dependencies and scripts",
5
5
  "keywords": [
6
6
  "dev"
7
7
  ],
@@ -16,48 +16,48 @@
16
16
  ".": "./dist/cli.mjs",
17
17
  "./package.json": "./package.json"
18
18
  },
19
- "types": "./dist/cli.d.mts",
20
19
  "bin": {
21
20
  "dev": "./dist/cli.mjs",
22
21
  "lntvow": "./dist/cli.mjs"
23
22
  },
24
23
  "files": [
25
- "dist",
26
- "dist/configs/*"
24
+ "dist"
27
25
  ],
28
26
  "dependencies": {
29
27
  "@clack/prompts": "^1.6.0",
30
28
  "commander": "^15.0.0",
31
- "dayjs": "^1.11.21",
32
- "local-pkg": "^1.2.1",
33
29
  "picocolors": "^1.1.1",
34
30
  "simple-git": "^3.36.0"
35
31
  },
36
32
  "devDependencies": {
37
- "@lntvow/cli": "^0.2.0",
33
+ "@lntvow/cli": "0.3.0",
38
34
  "@lntvow/eslint-config": "^10.3.1",
39
- "@types/node": "^20.19.39",
35
+ "@types/node": "^22.0.0",
40
36
  "eslint": "^10.5.0",
41
37
  "prettier": "^3.8.4",
42
38
  "publint": "^0.3.21",
43
39
  "tsdown": "^0.22.3",
44
40
  "tsx": "^4.22.4",
45
- "typescript": "^6.0.3"
41
+ "typescript": "^6.0.3",
42
+ "vitest": "^5.0.5"
46
43
  },
47
44
  "engines": {
48
- "node": "22.x"
45
+ "node": ">=22.0.0"
49
46
  },
50
47
  "scripts": {
51
48
  "rimraf": "cli rimraf ./node_modules/",
52
49
  "upgrade": "cli upgrade -u -x \"@types/node\" && pnpm install",
53
50
  "tidy": "cli tidy",
54
51
  "commit": "git add -A && cli commit",
55
- "release": "pnpm lint && git add -A && cli release -r -a",
52
+ "prerelease": "pnpm lint && pnpm run --if-present test",
53
+ "release": "git add -A && cli release -r -a",
56
54
  "changelog": "cli changelog -p angular -i CHANGELOG.md -s",
57
55
  "version": "pnpm changelog && git add -A",
58
56
  "lint:eslint": "eslint --fix --cache",
59
57
  "lint:tsc": "tsc --noEmit",
60
58
  "lint": "cli run lint:eslint lint:tsc",
59
+ "pretest": "pnpm build",
60
+ "test": "vitest run",
61
61
  "build": "tsdown",
62
62
  "dev": "tsx src/cli.ts"
63
63
  }
package/dist/cli.d.mts DELETED
@@ -1 +0,0 @@
1
- export {}
@@ -1 +0,0 @@
1
- import{Option as e,program as t}from"commander";import{copyFileSync as n,existsSync as r,mkdirSync as i,readFileSync as a,readdirSync as o,statSync as s,writeFileSync as c}from"node:fs";import{basename as l,resolve as u}from"node:path";import{fileURLToPath as d}from"node:url";import{isCancel as f,select as p}from"@clack/prompts";import{execSync as m}from"node:child_process";import h from"picocolors";import g from"dayjs";import _ from"simple-git";var v=`@lntvow/dev`,y=`6.2.0`;const b={prepare:`cli hooks`,rimraf:`cli rimraf ./node_modules/`,upgrade:`cli upgrade -u -x "@types/node" && pnpm install`,tidy:`cli tidy`,commit:`git add -A && cli commit`,release:`pnpm lint && git add -A && cli release -r -a`,changelog:`cli changelog -p angular -i CHANGELOG.md -s`,version:`pnpm changelog && git add -A`,"lint:eslint":`eslint --fix --cache`,"lint:tsc":`tsc --noEmit`,lint:`cli parallel lint:eslint lint:tsc`},x=[`@lntvow/cli`,`@lntvow/eslint-config`,`eslint`,`prettier`,`typescript`].sort((e,t)=>e.localeCompare(t)),S={info:e=>console.log(h.blue(`● ${e}`)),success:e=>console.log(h.green(`✓ ${e}`)),warn:e=>console.log(h.yellow(`▲ ${e}`)),error:e=>console.log(h.red(`✗ ${e}`))};function C(e,t={}){try{return m(e,{stdio:`inherit`,...t})}catch(t){throw S.error(`命令执行失败: ${e}`),t}}async function w(){for(let{file:e,manager:t}of[{file:`pnpm-lock.yaml`,manager:`pnpm`},{file:`yarn.lock`,manager:`yarn`},{file:`package-lock.json`,manager:`npm`}])if(r(u(process.cwd(),e)))return t;let e=process.env.npm_config_user_agent||``;return e.startsWith(`pnpm`)?`pnpm`:e.startsWith(`yarn`)?`yarn`:T()}async function T(){let e=await p({message:`No lock file found. Please select a package manager`,options:[{label:`pnpm`,value:`pnpm`},{label:`yarn`,value:`yarn`},{label:`npm`,value:`npm`}],initialValue:`pnpm`});if(f(e))throw Error(`Package manager selection canceled.`);return e}function E(e,t){if(s(e).isDirectory()){if(l(e)===`node_modules`)return;i(t,{recursive:!0}),o(e).forEach(n=>{E(u(e,n),u(t,n))})}else{if(r(t))return;n(e,t)}}function D(t){t.command(`init`).description(`init project`).option(`-t, --temp`,`copy template files`,!0).option(`--no-temp`,`not copy template files`).option(`-s, --scripts`,`init scripts`,!0).option(`--no-scripts`,`not init scripts`).addOption(new e(`--pm <manager>`,`package manager (auto-detect from lockfile/userAgent; prompt if ambiguous)`).choices([`pnpm`,`yarn`,`npm`])).action(O)}async function O(e){S.success(`Init project by @lntvow/dev`),S.info(`Cwd is ${process.cwd()}`);let{temp:t,scripts:n,pm:r}=e;try{t&&k(),await j(r),n&&A(),S.success(`Project initialization completed successfully!`)}catch(e){S.error(`Initialization failed: ${e.message}`),process.exit(1)}}function k(){try{let e=d(new URL(`./configs`,import.meta.url)),t=process.cwd();S.info(`Copying template files from "${e}" to "${t}"`),E(e,t),S.success(`Template files copied successfully`)}catch(e){throw S.error(`Failed to copy template files: ${e.message}`),e}}function A(){let e,t=u(process.cwd(),`package.json`);try{S.info(`Updating package.json scripts...`),e=a(t,`utf-8`);let n=JSON.parse(e),r={...n,scripts:{...b,...n.scripts}};c(t,JSON.stringify(r,null,2)),S.success(`Package.json scripts updated successfully`)}catch(n){throw e&&c(t,e),S.error(`Failed to update package.json: ${n.message}`),n}}async function j(e){try{let t=x.map(e=>`${e}@latest`).join(` `),n=e??await w(),r={pnpm:`pnpm add -D ${t}`,yarn:`yarn add -D ${t}`,npm:`npm install -D ${t}`}[n];S.info(`Installing dependencies: ${r}`),C(r),S.success(`Dependencies installed successfully`)}catch(e){throw S.error(`Dependency installation failed: ${e.message}`),e}}function M(e){e.command(`release`).description(`git release`).action(N)}async function N(){console.log(h.green(`Release project...`));try{await P(),S.success(`Release completed successfully!`)}catch(e){S.error(`Release failed: ${e.message}`),process.exit(1)}}async function P(){let e=_(process.cwd());try{let t=g().format(`YYYYMMDD`);await e.pull(),await e.add(`.`),await e.commit(t,[`--no-verify`]),await e.push(`origin`),S.success(`提交成功: ${t}`)}catch(e){S.error(`Git操作失败: ${e.message}`),process.exit(1)}}t.name(v).version(y,`-v, --version`,`output the version number`),D(t),M(t),t.parse();export{};