@lonewolfyx/setup 0.0.5 → 0.0.7

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/dist/cli.mjs CHANGED
@@ -1,21 +1,12 @@
1
1
  import { access, mkdir, readdir, rm, writeFile } from "node:fs/promises";
2
- import path from "node:path";
3
2
  import { confirm, intro, isCancel, outro, spinner } from "@clack/prompts";
4
3
  import { createMain, defineCommand } from "citty";
5
4
  import { readPackageJSON, writePackageJSON, writeTSConfig } from "pkg-types";
5
+ import path, { resolve } from "node:path";
6
6
  import { x } from "tinyexec";
7
- //#region package.json
8
- var name = "@lonewolfyx/setup";
9
- var version = "0.0.5";
10
- var description = "Instant project boilerplate setup";
11
- //#endregion
12
7
  //#region src/task/addGitHooksConfig.ts
13
- /**
14
- * 添加 git hooks 配置到 package.json
15
- * @param cwd 当前工作目录
16
- * @param packageJsonPath package.json 文件路径
17
- */
18
- async function addGitHooksConfig(cwd, packageJsonPath) {
8
+ async function addGitHooksConfig(config) {
9
+ const { cwd, packageJsonPath } = config;
19
10
  const newPackageJson = await readPackageJSON(cwd);
20
11
  newPackageJson.simpleGitHooks = {
21
12
  "pre-commit": "npx lint-staged",
@@ -44,12 +35,8 @@ async function clearDirectory(dirPath) {
44
35
  }
45
36
  //#endregion
46
37
  //#region src/task/configPackageJson.ts
47
- /**
48
- * 配置 package.json,添加 "type": "module"
49
- * @param cwd 当前工作目录
50
- * @param packageJsonPath package.json 文件路径
51
- */
52
- async function configPackageJson(cwd, packageJsonPath) {
38
+ async function configPackageJson(config) {
39
+ const { cwd, packageJsonPath } = config;
53
40
  const packageJson = await readPackageJSON(cwd);
54
41
  if (packageJson.main) delete packageJson.main;
55
42
  packageJson.type = "module";
@@ -63,12 +50,8 @@ async function configPackageJson(cwd, packageJsonPath) {
63
50
  }
64
51
  //#endregion
65
52
  //#region src/task/createEslintConfig.ts
66
- /**
67
- * 创建 ESLint 配置文件
68
- * @param cwd 当前工作目录
69
- */
70
- async function createEslintConfig(cwd) {
71
- await writeFile(path.join(cwd, "eslint.config.ts"), `import type { Linter } from 'eslint'
53
+ async function createEslintConfig(config) {
54
+ await writeFile(path.join(config.cwd, "eslint.config.ts"), `import type { Linter } from 'eslint'
72
55
  import antfu from '@antfu/eslint-config'
73
56
 
74
57
  const config = antfu({
@@ -94,47 +77,163 @@ export default config`);
94
77
  }
95
78
  //#endregion
96
79
  //#region src/task/createGitHooks.ts
97
- /**
98
- * 创建 git hooks 配置文件
99
- * @param cwd 当前工作目录
100
- */
101
- async function createGitHooks(cwd) {
102
- const scriptsDir = path.join(cwd, "scripts");
80
+ async function createGitHooks(config) {
81
+ const scriptsDir = path.join(config.cwd, "scripts");
103
82
  await mkdir(scriptsDir, { recursive: true });
104
83
  await writeFile(path.join(scriptsDir, "verify-commit.js"), "import { readFileSync } from 'node:fs'\nimport path from 'node:path'\n// @ts-check\nimport pico from 'picocolors'\n\nconst msgPath = path.resolve('.git/COMMIT_EDITMSG')\nconst msg = readFileSync(msgPath, 'utf-8').trim()\n\nconst commitRE\n = /^(revert: )?(feat|fix|docs|dx|style|refactor|perf|test|workflow|build|ci|chore|types|wip|release)(\\(.+\\))?(!)?: .{1,50}/\n\nif (!commitRE.test(msg)) {\n console.log()\n console.error(\n ` ${pico.white(pico.bgRed(' ERROR '))} ${pico.red(\n `invalid commit message format.`,\n )}\\n\\n${\n pico.red(\n ` Proper commit message format is required for automated changelog generation. Examples:\\n\\n`,\n )\n } ${pico.green(`feat(compiler): add 'comments' option`)}\\n`\n + ` ${pico.green(\n `fix(v-model): handle events on blur (close #28)`,\n )}\\n`\n + ` ${pico.green(\n `feat(api)!: remove legacy token endpoint`,\n )}\\n\\n${\n pico.red(` See .github/commit-convention.md for more details.\\n`)}`,\n )\n process.exit(1)\n}\n");
105
84
  }
106
85
  //#endregion
107
- //#region src/task/utils.ts
108
- /**
109
- * 检测包管理器是否存在
110
- * @param command 包管理器命令名称
111
- */
112
- async function hasPackageManager(command) {
113
- try {
114
- await x(command, ["--version"], { throwOnError: true });
115
- return true;
116
- } catch {
117
- return false;
86
+ //#region src/task/createGithubWorkflows.ts
87
+ const workflows = [
88
+ {
89
+ filename: "autofix.yml",
90
+ content: `name: autofix.ci
91
+
92
+ on:
93
+ pull_request:
94
+ permissions:
95
+ contents: write
96
+
97
+ jobs:
98
+ autofix:
99
+ runs-on: ubuntu-latest
100
+ timeout-minutes: 10
101
+
102
+ steps:
103
+ - uses: actions/checkout@v4
104
+
105
+ - name: Use Node.js lts/*
106
+ uses: actions/setup-node@v4
107
+ with:
108
+ node-version: lts/*
109
+
110
+ - name: Install pnpm
111
+ uses: pnpm/action-setup@v4
112
+
113
+ - name: Install
114
+ run: pnpm i
115
+
116
+ - name: Lint
117
+ run: pnpm run lint:fix
118
+
119
+ - uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27
120
+ `
121
+ },
122
+ {
123
+ filename: "ci.yml",
124
+ content: `name: CI
125
+
126
+ on:
127
+ pull_request:
128
+
129
+ jobs:
130
+ lint:
131
+ runs-on: ubuntu-latest
132
+ steps:
133
+ - uses: actions/checkout@v4
134
+
135
+ - name: Install pnpm
136
+ uses: pnpm/action-setup@v4
137
+
138
+ - name: Set node
139
+ uses: actions/setup-node@v4
140
+ with:
141
+ node-version: lts/*
142
+ cache: pnpm
143
+
144
+ - name: Install
145
+ run: pnpm i
146
+
147
+ - name: Lint
148
+ run: pnpm run lint
149
+ `
150
+ },
151
+ {
152
+ filename: "pr-contributor-welcome.yml",
153
+ content: `name: PullRequest Contributor Welcome
154
+
155
+ on:
156
+ pull_request_target:
157
+ types:
158
+ - closed
159
+ # paths:
160
+ # - 'components/**'
161
+
162
+ permissions:
163
+ contents: read
164
+
165
+ jobs:
166
+ comment:
167
+ permissions:
168
+ issues: write # for actions-cool/maintain-one-comment to modify or create issue comments
169
+ pull-requests: write # for actions-cool/maintain-one-comment to modify or create PR comments
170
+ if: github.event.pull_request.merged == true && github.repository == 'lonewolfyx/xxxx'
171
+ runs-on: ubuntu-latest
172
+ steps:
173
+ - name: get commit count
174
+ id: get_commit_count
175
+ run: |
176
+ PR_AUTHOR=$(echo "\${{ github.event.pull_request.user.login }}")
177
+ RESULT_DATA=$(curl -s "https://api.github.com/repos/\${{ github.repository }}/commits?author=\${PR_AUTHOR}&per_page=5")
178
+ DATA_LENGTH=$(echo \$RESULT_DATA | jq 'if type == "array" then length else 0 end')
179
+ echo "COUNT=\$DATA_LENGTH" >> \$GITHUB_OUTPUT
180
+ - name: Comment on PR
181
+ if: steps.get_commit_count.outputs.COUNT < 3
182
+ uses: actions-cool/maintain-one-comment@v3
183
+ with:
184
+ token: \${{ secrets.GITHUB_TOKEN }}
185
+ body: |
186
+ 🎉 Thx for the PR @\${{ github.event.pull_request.user.login }}
187
+
188
+ <!-- WELCOME_CONTRIBUTION -->
189
+ body-include: <!-- WELCOME_CONTRIBUTION -->
190
+ `
191
+ },
192
+ {
193
+ filename: "release.yml",
194
+ content: `name: Release
195
+
196
+ permissions:
197
+ contents: write
198
+
199
+ on:
200
+ push:
201
+ tags:
202
+ - 'v*'
203
+
204
+ jobs:
205
+ release:
206
+ runs-on: ubuntu-latest
207
+ steps:
208
+ - uses: actions/checkout@v4
209
+ with:
210
+ fetch-depth: 0
211
+
212
+ - uses: actions/setup-node@v4
213
+ with:
214
+ node-version: lts/*
215
+
216
+ - run: npx genereleaselog
217
+ env:
218
+ GITHUB_TOKEN: \${{secrets.GITHUB_TOKEN}}
219
+ `
118
220
  }
221
+ ];
222
+ async function createGithubWorkflows(config) {
223
+ const workflowsDir = path.join(config.cwd, ".github", "workflows");
224
+ await mkdir(workflowsDir, { recursive: true });
225
+ for (const { filename, content } of workflows) await writeFile(path.join(workflowsDir, filename), content);
119
226
  }
120
227
  //#endregion
121
228
  //#region src/task/createPackageJson.ts
122
- /**
123
- * 创建 package.json 文件
124
- * @param cwd 当前工作目录
125
- */
126
- async function createPackageJson(cwd) {
127
- const hasPnpm = await hasPackageManager("pnpm");
128
- await x(hasPnpm ? "pnpm" : "npm", hasPnpm ? ["init"] : ["init", "-y"], { nodeOptions: { cwd } });
229
+ async function createPackageJson(config) {
230
+ const { cwd, packageManager } = config;
231
+ await x(packageManager, packageManager === "pnpm" ? ["init"] : ["init", "-y"], { nodeOptions: { cwd } });
129
232
  }
130
233
  //#endregion
131
234
  //#region src/task/createTsConfig.ts
132
- /**
133
- * 创建 tsconfig.json 文件
134
- * @param cwd 当前工作目录
135
- */
136
- async function createTsConfig(cwd) {
137
- await writeTSConfig(path.resolve(cwd, "tsconfig.json"), {
235
+ async function createTsConfig(config) {
236
+ await writeTSConfig(resolve(config.cwd, "tsconfig.json"), {
138
237
  extends: "@lonewolfyx/tsconfig/tsconfig.lib.json",
139
238
  compilerOptions: {
140
239
  baseUrl: "./",
@@ -152,11 +251,8 @@ async function createTsConfig(cwd) {
152
251
  }
153
252
  //#endregion
154
253
  //#region src/task/installDevDeps.ts
155
- /**
156
- * 安装开发依赖
157
- * @param cwd 当前工作目录
158
- */
159
- async function installDevDeps(cwd) {
254
+ async function installDevDeps(config) {
255
+ const { cwd, packageManager } = config;
160
256
  const devDeps = [
161
257
  "eslint",
162
258
  "@antfu/eslint-config",
@@ -170,8 +266,7 @@ async function installDevDeps(cwd) {
170
266
  "tsx",
171
267
  "tsdown"
172
268
  ];
173
- const hasPnpm = await hasPackageManager("pnpm");
174
- await x(hasPnpm ? "pnpm" : "npm", hasPnpm ? [
269
+ await x(packageManager, packageManager === "pnpm" ? [
175
270
  "add",
176
271
  "-D",
177
272
  ...devDeps
@@ -182,6 +277,64 @@ async function installDevDeps(cwd) {
182
277
  ], { nodeOptions: { cwd } });
183
278
  }
184
279
  //#endregion
280
+ //#region src/task/createGitignore.ts
281
+ async function createGitignore(config) {
282
+ await writeFile(path.join(config.cwd, ".gitignore"), "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs.org/api/report.html)\nreport.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n*.lcov\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# Snowpack dependency directory (https://snowpack.dev/)\nweb_modules/\n\n# TypeScript cache\n*.tsbuildinfo\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional stylelint cache\n.stylelintcache\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variable files\n.env\n.env.*\n!.env.example\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n.parcel-cache\n\n# Next.js build output\n.next\nout\n\n# Nuxt.js build / generate output\n.nuxt\ndist\n\n# Gatsby files\n.cache/\n# Comment in the public line in if your project uses Gatsby and not Next.js\n# https://nextjs.org/blog/next-9-1#public-directory-support\n# public\n\n# vuepress build output\n.vuepress/dist\n\n# vuepress v2.x temp and cache directory\n.temp\n.cache\n\n# Sveltekit cache directory\n.svelte-kit/\n\n# vitepress build output\n**/.vitepress/dist\n\n# vitepress cache directory\n**/.vitepress/cache\n\n# Docusaurus cache and generated files\n.docusaurus\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n\n# Firebase cache directory\n.firebase/\n\n# TernJS port file\n.tern-port\n\n# Stores VSCode versions used for testing VSCode extensions\n.vscode-test\n\n# yarn v3\n.pnp.*\n.yarn/*\n!.yarn/patches\n!.yarn/plugins\n!.yarn/releases\n!.yarn/sdks\n!.yarn/versions\n\n# Vite logs files\nvite.config.js.timestamp-*\nvite.config.ts.timestamp-*\n.idea");
283
+ }
284
+ //#endregion
285
+ //#region package.json
286
+ var name = "@lonewolfyx/setup";
287
+ var version = "0.0.7";
288
+ var description = "Instant project boilerplate setup";
289
+ //#endregion
290
+ //#region src/utils.ts
291
+ /**
292
+ * 检测包管理器是否存在
293
+ * @param command 包管理器命令名称
294
+ */
295
+ async function hasPackageManager(command) {
296
+ try {
297
+ await x(command, ["--version"], { throwOnError: true });
298
+ return true;
299
+ } catch {
300
+ return false;
301
+ }
302
+ }
303
+ //#endregion
304
+ //#region src/config.ts
305
+ async function resolveConfig(cwd) {
306
+ const hasPnpm = await hasPackageManager("pnpm");
307
+ return {
308
+ cwd,
309
+ packageJsonPath: path.join(cwd, "package.json"),
310
+ packageManager: hasPnpm ? "pnpm" : "npm"
311
+ };
312
+ }
313
+ //#endregion
314
+ //#region src/schedule.ts
315
+ function schedule() {
316
+ const s = spinner();
317
+ const tasks = [];
318
+ const chain = {
319
+ step(startMessage, fn, doneMessage) {
320
+ tasks.push({
321
+ startMessage,
322
+ fn,
323
+ doneMessage
324
+ });
325
+ return chain;
326
+ },
327
+ async done() {
328
+ for (const { startMessage, fn, doneMessage } of tasks) {
329
+ s.start(startMessage);
330
+ await fn();
331
+ s.stop(doneMessage);
332
+ }
333
+ }
334
+ };
335
+ return chain;
336
+ }
337
+ //#endregion
185
338
  //#region src/cli.ts
186
339
  createMain(defineCommand({
187
340
  meta: {
@@ -203,42 +356,16 @@ createMain(defineCommand({
203
356
  } },
204
357
  async run({ args }) {
205
358
  const cwd = args.cwd;
206
- const packageJsonPath = path.join(cwd, "package.json");
207
- const packageJsonExists = await access(packageJsonPath).then(() => true).catch(() => false);
208
- const progress = spinner();
209
- if (packageJsonExists) {
359
+ const config = await resolveConfig(cwd);
360
+ if (await access(config.packageJsonPath).then(() => true).catch(() => false)) {
210
361
  const shouldOverwrite = await confirm({ message: "检测到当前目录已存在项目,是否覆盖创建新项目?(将清空当前目录下所有文件)" });
211
362
  if (isCancel(shouldOverwrite) || !shouldOverwrite) {
212
363
  outro("已取消操作");
213
364
  return;
214
365
  }
215
- progress.start("正在清空目录...");
216
- await clearDirectory(cwd);
217
- progress.stop("目录已清空");
366
+ await clearDirectory(config.cwd);
218
367
  }
219
- progress.start("正在检测包管理器...");
220
- await hasPackageManager("pnpm");
221
- progress.message("项目初始化...");
222
- await createPackageJson(cwd);
223
- progress.stop("package.json 创建完成");
224
- progress.start("正在配置 package.json...");
225
- await configPackageJson(cwd, packageJsonPath);
226
- progress.stop("package.json 配置完成");
227
- progress.start("正在安装开发依赖...");
228
- await installDevDeps(cwd);
229
- progress.stop("开发依赖安装完成");
230
- progress.start("正在创建 git hooks 配置文件...");
231
- await createGitHooks(cwd);
232
- progress.stop("git hooks 配置文件创建完成");
233
- progress.start("正在创建 tsconfig.json...");
234
- await createTsConfig(cwd);
235
- progress.stop("tsconfig.json 创建完成");
236
- progress.start("正在添加 git hooks 配置...");
237
- await addGitHooksConfig(cwd, packageJsonPath);
238
- progress.stop("git hooks 配置添加完成");
239
- progress.start("正在创建 ESLint 配置文件...");
240
- await createEslintConfig(cwd);
241
- progress.stop("ESLint 配置文件创建完成");
368
+ await schedule().step("正在创建 package.json...", () => createPackageJson(config), "package.json 创建完成").step("正在配置 package.json...", () => configPackageJson(config), "package.json 配置完成").step("正在安装开发依赖...", () => installDevDeps(config), "开发依赖安装完成").step("正在创建 git hooks 配置文件...", () => createGitHooks(config), "git hooks 配置文件创建完成").step("正在创建 tsconfig.json...", () => createTsConfig(config), "tsconfig.json 创建完成").step("正在添加 git hooks 配置...", () => addGitHooksConfig(config), "git hooks 配置添加完成").step("正在创建 .gitignore 文件", () => createGitignore(config), ".gitignore 创建完成").step("正在创建 ESLint 配置文件...", () => createEslintConfig(config), "ESLint 配置文件创建完成").step("正在创建 GitHub Workflows...", () => createGithubWorkflows(config), "GitHub Workflows 创建完成").done();
242
369
  }
243
370
  }))({});
244
371
  //#endregion
package/dist/cli.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.mjs","names":[],"sources":["../package.json","../src/task/addGitHooksConfig.ts","../src/task/clearDirectory.ts","../src/task/configPackageJson.ts","../src/task/createEslintConfig.ts","../src/task/createGitHooks.ts","../src/task/utils.ts","../src/task/createPackageJson.ts","../src/task/createTsConfig.ts","../src/task/installDevDeps.ts","../src/cli.ts"],"sourcesContent":["","import { readPackageJSON, writePackageJSON } from 'pkg-types'\n\n/**\n * 添加 git hooks 配置到 package.json\n * @param cwd 当前工作目录\n * @param packageJsonPath package.json 文件路径\n */\nexport async function addGitHooksConfig(cwd: string, packageJsonPath: string): Promise<void> {\n const newPackageJson = await readPackageJSON(cwd)\n newPackageJson.simpleGitHooks = {\n 'pre-commit': 'npx lint-staged',\n 'commit-msg': 'node scripts/verify-commit.js',\n }\n newPackageJson.lintStaged = {\n '*': 'eslint --fix',\n }\n\n await writePackageJSON(packageJsonPath, newPackageJson)\n}\n","import { readdir, rm } from 'node:fs/promises'\nimport path from 'node:path'\n\n/**\n * 清空目录内容,保留 .git 目录\n * @param dirPath 目录路径\n */\nexport async function clearDirectory(dirPath: string): Promise<void> {\n const entries = await readdir(dirPath, { withFileTypes: true })\n\n for (const entry of entries) {\n // 保留 .git 目录\n if (entry.name === '.git') {\n continue\n }\n\n const fullPath = path.join(dirPath, entry.name)\n\n if (entry.isDirectory()) {\n await rm(fullPath, { recursive: true, force: true })\n }\n else {\n await rm(fullPath, { force: true })\n }\n }\n}\n","import { readPackageJSON, writePackageJSON } from 'pkg-types'\n\n/**\n * 配置 package.json,添加 \"type\": \"module\"\n * @param cwd 当前工作目录\n * @param packageJsonPath package.json 文件路径\n */\nexport async function configPackageJson(cwd: string, packageJsonPath: string): Promise<void> {\n const packageJson = await readPackageJSON(cwd)\n\n if (packageJson.main) {\n delete packageJson.main\n }\n\n packageJson.type = 'module'\n packageJson.scripts = {\n ...packageJson.scripts,\n 'lint': 'eslint .',\n 'lint:fix': 'eslint --fix',\n 'prepare': 'simple-git-hooks',\n }\n\n await writePackageJSON(packageJsonPath, packageJson)\n}\n","import { writeFile } from 'node:fs/promises'\nimport path from 'node:path'\n\n/**\n * 创建 ESLint 配置文件\n * @param cwd 当前工作目录\n */\nexport async function createEslintConfig(cwd: string): Promise<void> {\n const eslintConfigContent = `import type { Linter } from 'eslint'\nimport antfu from '@antfu/eslint-config'\n\nconst config = antfu({\n type: 'lib',\n stylistic: {\n indent: 4,\n quotes: 'single',\n },\n rules: {\n 'no-console': 'off',\n 'node/prefer-global/process': 'off',\n 'antfu/top-level-function': 'off',\n 'regexp/no-unused-capturing-group': 'off',\n },\n yaml: {\n overrides: {\n 'yaml/indent': ['error', 2],\n },\n },\n}) as Linter.Config\n\nexport default config`\n\n const eslintConfigPath = path.join(cwd, 'eslint.config.ts')\n await writeFile(eslintConfigPath, eslintConfigContent)\n}\n","import { mkdir, writeFile } from 'node:fs/promises'\nimport path from 'node:path'\n\n/**\n * 创建 git hooks 配置文件\n * @param cwd 当前工作目录\n */\nexport async function createGitHooks(cwd: string): Promise<void> {\n const scriptsDir = path.join(cwd, 'scripts')\n await mkdir(scriptsDir, { recursive: true })\n\n const verifyCommitPath = path.join(scriptsDir, 'verify-commit.js')\n const verifyCommitContent = 'import { readFileSync } from \\'node:fs\\'\\n'\n + 'import path from \\'node:path\\'\\n'\n + '// @ts-check\\n'\n + 'import pico from \\'picocolors\\'\\n'\n + '\\n'\n + 'const msgPath = path.resolve(\\'.git/COMMIT_EDITMSG\\')\\n'\n + 'const msg = readFileSync(msgPath, \\'utf-8\\').trim()\\n'\n + '\\n'\n + 'const commitRE\\n'\n + ' = /^(revert: )?(feat|fix|docs|dx|style|refactor|perf|test|workflow|build|ci|chore|types|wip|release)(\\\\(.+\\\\))?(!)?: .{1,50}/\\n'\n + '\\n'\n + 'if (!commitRE.test(msg)) {\\n'\n + ' console.log()\\n'\n + ' console.error(\\n'\n // eslint-disable-next-line no-template-curly-in-string\n + ' ` ${pico.white(pico.bgRed(\\' ERROR \\'))} ${pico.red(\\n'\n + ' `invalid commit message format.`,\\n'\n + ' )}\\\\n\\\\n${\\n'\n + ' pico.red(\\n'\n + ' ` Proper commit message format is required for automated changelog generation. Examples:\\\\n\\\\n`,\\n'\n + ' )\\n'\n // eslint-disable-next-line no-template-curly-in-string\n + ' } ${pico.green(`feat(compiler): add \\'comments\\' option`)}\\\\n`\\n'\n + ' + ` ${pico.green(\\n'\n + ' `fix(v-model): handle events on blur (close #28)`,\\n'\n + ' )}\\\\n`\\n'\n + ' + ` ${pico.green(\\n'\n + ' `feat(api)!: remove legacy token endpoint`,\\n'\n + ' )}\\\\n\\\\n${\\n'\n + ' pico.red(` See .github/commit-convention.md for more details.\\\\n`)}`,\\n'\n + ' )\\n'\n + ' process.exit(1)\\n'\n + '}\\n'\n\n await writeFile(verifyCommitPath, verifyCommitContent)\n}\n","import { x } from 'tinyexec'\n\n/**\n * 检测包管理器是否存在\n * @param command 包管理器命令名称\n */\nexport async function hasPackageManager(command: string): Promise<boolean> {\n try {\n await x(command, ['--version'], { throwOnError: true })\n return true\n }\n catch {\n return false\n }\n}\n","import { x } from 'tinyexec'\nimport { hasPackageManager } from './utils'\n\n/**\n * 创建 package.json 文件\n * @param cwd 当前工作目录\n */\nexport async function createPackageJson(cwd: string): Promise<void> {\n const hasPnpm = await hasPackageManager('pnpm')\n\n await x(hasPnpm ? 'pnpm' : 'npm', hasPnpm ? ['init'] : ['init', '-y'], { nodeOptions: { cwd } })\n}\n","import path from 'node:path'\nimport { writeTSConfig } from 'pkg-types'\n\n/**\n * 创建 tsconfig.json 文件\n * @param cwd 当前工作目录\n */\nexport async function createTsConfig(cwd: string): Promise<void> {\n const tsconfigConfig = {\n extends: '@lonewolfyx/tsconfig/tsconfig.lib.json',\n compilerOptions: {\n baseUrl: './',\n paths: {\n '@/*': [\n './src/*',\n ],\n '#/*': [\n './src/types/*',\n './types/*',\n ],\n },\n resolveJsonModule: true,\n types: [\n 'node',\n ],\n noUnusedLocals: false,\n noUnusedParameters: false,\n declarationMap: false,\n },\n }\n\n await writeTSConfig(path.resolve(cwd, 'tsconfig.json'), tsconfigConfig)\n}\n","import { x } from 'tinyexec'\nimport { hasPackageManager } from './utils'\n\n/**\n * 安装开发依赖\n * @param cwd 当前工作目录\n */\nexport async function installDevDeps(cwd: string): Promise<void> {\n const devDeps = [\n 'eslint',\n '@antfu/eslint-config',\n 'jiti',\n 'typescript',\n '@lonewolfyx/tsconfig',\n '@types/node',\n 'lint-staged',\n 'simple-git-hooks',\n 'picocolors',\n 'tsx',\n 'tsdown',\n ]\n\n const hasPnpm = await hasPackageManager('pnpm')\n const addCmd = hasPnpm ? 'pnpm' : 'npm'\n const addArgs = hasPnpm\n ? ['add', '-D', ...devDeps]\n : ['install', '-D', ...devDeps]\n\n await x(addCmd, addArgs, { nodeOptions: { cwd } })\n}\n","import { access } from 'node:fs/promises'\nimport path from 'node:path'\nimport { confirm, intro, isCancel, outro, spinner } from '@clack/prompts'\nimport { createMain, defineCommand } from 'citty'\nimport { description, name, version } from '../package.json'\nimport { addGitHooksConfig } from './task/addGitHooksConfig'\nimport { clearDirectory } from './task/clearDirectory'\nimport { configPackageJson } from './task/configPackageJson'\nimport { createEslintConfig } from './task/createEslintConfig'\nimport { createGitHooks } from './task/createGitHooks'\nimport { createPackageJson } from './task/createPackageJson'\nimport { createTsConfig } from './task/createTsConfig'\nimport { installDevDeps } from './task/installDevDeps'\nimport { hasPackageManager } from './task/utils'\n\nconst command = defineCommand({\n meta: {\n name,\n version,\n description,\n },\n setup() {\n intro('项目初始化')\n },\n cleanup() {\n outro('Done. 项目初始化完成')\n },\n args: {\n cwd: {\n type: 'string',\n description: 'Current working directory',\n alias: 'c',\n default: process.cwd(),\n },\n },\n async run({ args }) {\n const cwd = args.cwd as string\n const packageJsonPath = path.join(cwd, 'package.json')\n\n // 检测 package.json 是否存在\n const packageJsonExists = await access(packageJsonPath)\n .then(() => true)\n .catch(() => false)\n\n const progress = spinner()\n\n if (packageJsonExists) {\n const shouldOverwrite = await confirm({\n message: '检测到当前目录已存在项目,是否覆盖创建新项目?(将清空当前目录下所有文件)',\n })\n\n if (isCancel(shouldOverwrite) || !shouldOverwrite) {\n outro('已取消操作')\n return\n }\n\n // 清空目录内容\n progress.start('正在清空目录...')\n await clearDirectory(cwd)\n progress.stop('目录已清空')\n }\n\n // 创建 package.json 文件\n progress.start('正在检测包管理器...')\n\n const hasPnpm = await hasPackageManager('pnpm')\n progress.message('项目初始化...')\n\n await createPackageJson(cwd)\n\n progress.stop('package.json 创建完成')\n\n // 添加 \"type\": \"module\" 配置\n progress.start('正在配置 package.json...')\n\n await configPackageJson(cwd, packageJsonPath)\n\n progress.stop('package.json 配置完成')\n\n // 安装开发依赖\n progress.start('正在安装开发依赖...')\n\n await installDevDeps(cwd)\n\n progress.stop('开发依赖安装完成')\n\n // 创建 scripts/verify-commit.js 文件\n progress.start('正在创建 git hooks 配置文件...')\n\n await createGitHooks(cwd)\n\n progress.stop('git hooks 配置文件创建完成')\n\n // 创建 tsconfig.json 文件\n progress.start('正在创建 tsconfig.json...')\n\n await createTsConfig(cwd)\n\n progress.stop('tsconfig.json 创建完成')\n\n // 添加 git hooks 配置到 package.json\n progress.start('正在添加 git hooks 配置...')\n\n await addGitHooksConfig(cwd, packageJsonPath)\n\n progress.stop('git hooks 配置添加完成')\n\n // 创建 eslint.config.ts 文件\n progress.start('正在创建 ESLint 配置文件...')\n\n await createEslintConfig(cwd)\n\n progress.stop('ESLint 配置文件创建完成')\n },\n})\n\ncreateMain(command)({})\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.mjs","names":[],"sources":["../src/task/addGitHooksConfig.ts","../src/task/clearDirectory.ts","../src/task/configPackageJson.ts","../src/task/createEslintConfig.ts","../src/task/createGitHooks.ts","../src/task/createGithubWorkflows.ts","../src/task/createPackageJson.ts","../src/task/createTsConfig.ts","../src/task/installDevDeps.ts","../src/task/createGitignore.ts","../package.json","../src/utils.ts","../src/config.ts","../src/schedule.ts","../src/cli.ts"],"sourcesContent":["import type { IConfig } from '../types'\nimport { readPackageJSON, writePackageJSON } from 'pkg-types'\n\nexport async function addGitHooksConfig(config: IConfig): Promise<void> {\n const { cwd, packageJsonPath } = config\n const newPackageJson = await readPackageJSON(cwd)\n newPackageJson.simpleGitHooks = {\n 'pre-commit': 'npx lint-staged',\n 'commit-msg': 'node scripts/verify-commit.js',\n }\n newPackageJson.lintStaged = {\n '*': 'eslint --fix',\n }\n\n await writePackageJSON(packageJsonPath, newPackageJson)\n}\n","import { readdir, rm } from 'node:fs/promises'\nimport path from 'node:path'\n\n/**\n * 清空目录内容,保留 .git 目录\n * @param dirPath 目录路径\n */\nexport async function clearDirectory(dirPath: string): Promise<void> {\n const entries = await readdir(dirPath, { withFileTypes: true })\n\n for (const entry of entries) {\n // 保留 .git 目录\n if (entry.name === '.git') {\n continue\n }\n\n const fullPath = path.join(dirPath, entry.name)\n\n if (entry.isDirectory()) {\n await rm(fullPath, { recursive: true, force: true })\n }\n else {\n await rm(fullPath, { force: true })\n }\n }\n}\n","import type { IConfig } from '../types'\nimport { readPackageJSON, writePackageJSON } from 'pkg-types'\n\nexport async function configPackageJson(config: IConfig): Promise<void> {\n const { cwd, packageJsonPath } = config\n const packageJson = await readPackageJSON(cwd)\n\n if (packageJson.main) {\n delete packageJson.main\n }\n\n packageJson.type = 'module'\n packageJson.scripts = {\n ...packageJson.scripts,\n 'lint': 'eslint .',\n 'lint:fix': 'eslint --fix',\n 'prepare': 'simple-git-hooks',\n }\n\n await writePackageJSON(packageJsonPath, packageJson)\n}\n","import type { IConfig } from '../types'\nimport { writeFile } from 'node:fs/promises'\nimport path from 'node:path'\n\nexport async function createEslintConfig(config: IConfig): Promise<void> {\n const eslintConfigContent = `import type { Linter } from 'eslint'\nimport antfu from '@antfu/eslint-config'\n\nconst config = antfu({\n type: 'lib',\n stylistic: {\n indent: 4,\n quotes: 'single',\n },\n rules: {\n 'no-console': 'off',\n 'node/prefer-global/process': 'off',\n 'antfu/top-level-function': 'off',\n 'regexp/no-unused-capturing-group': 'off',\n },\n yaml: {\n overrides: {\n 'yaml/indent': ['error', 2],\n },\n },\n}) as Linter.Config\n\nexport default config`\n\n const eslintConfigPath = path.join(config.cwd, 'eslint.config.ts')\n await writeFile(eslintConfigPath, eslintConfigContent)\n}\n","import type { IConfig } from '../types'\nimport { mkdir, writeFile } from 'node:fs/promises'\nimport path from 'node:path'\n\nexport async function createGitHooks(config: IConfig): Promise<void> {\n const scriptsDir = path.join(config.cwd, 'scripts')\n await mkdir(scriptsDir, { recursive: true })\n\n const verifyCommitPath = path.join(scriptsDir, 'verify-commit.js')\n const verifyCommitContent = 'import { readFileSync } from \\'node:fs\\'\\n'\n + 'import path from \\'node:path\\'\\n'\n + '// @ts-check\\n'\n + 'import pico from \\'picocolors\\'\\n'\n + '\\n'\n + 'const msgPath = path.resolve(\\'.git/COMMIT_EDITMSG\\')\\n'\n + 'const msg = readFileSync(msgPath, \\'utf-8\\').trim()\\n'\n + '\\n'\n + 'const commitRE\\n'\n + ' = /^(revert: )?(feat|fix|docs|dx|style|refactor|perf|test|workflow|build|ci|chore|types|wip|release)(\\\\(.+\\\\))?(!)?: .{1,50}/\\n'\n + '\\n'\n + 'if (!commitRE.test(msg)) {\\n'\n + ' console.log()\\n'\n + ' console.error(\\n'\n // eslint-disable-next-line no-template-curly-in-string\n + ' ` ${pico.white(pico.bgRed(\\' ERROR \\'))} ${pico.red(\\n'\n + ' `invalid commit message format.`,\\n'\n + ' )}\\\\n\\\\n${\\n'\n + ' pico.red(\\n'\n + ' ` Proper commit message format is required for automated changelog generation. Examples:\\\\n\\\\n`,\\n'\n + ' )\\n'\n // eslint-disable-next-line no-template-curly-in-string\n + ' } ${pico.green(`feat(compiler): add \\'comments\\' option`)}\\\\n`\\n'\n + ' + ` ${pico.green(\\n'\n + ' `fix(v-model): handle events on blur (close #28)`,\\n'\n + ' )}\\\\n`\\n'\n + ' + ` ${pico.green(\\n'\n + ' `feat(api)!: remove legacy token endpoint`,\\n'\n + ' )}\\\\n\\\\n${\\n'\n + ' pico.red(` See .github/commit-convention.md for more details.\\\\n`)}`,\\n'\n + ' )\\n'\n + ' process.exit(1)\\n'\n + '}\\n'\n\n await writeFile(verifyCommitPath, verifyCommitContent)\n}\n","import type { IConfig } from '../types'\nimport { mkdir, writeFile } from 'node:fs/promises'\nimport path from 'node:path'\n\nconst workflows: Array<{ filename: string, content: string }> = [\n {\n filename: 'autofix.yml',\n content: `name: autofix.ci\n\non:\n pull_request:\npermissions:\n contents: write\n\njobs:\n autofix:\n runs-on: ubuntu-latest\n timeout-minutes: 10\n\n steps:\n - uses: actions/checkout@v4\n\n - name: Use Node.js lts/*\n uses: actions/setup-node@v4\n with:\n node-version: lts/*\n\n - name: Install pnpm\n uses: pnpm/action-setup@v4\n\n - name: Install\n run: pnpm i\n\n - name: Lint\n run: pnpm run lint:fix\n\n - uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27\n`,\n },\n {\n filename: 'ci.yml',\n content: `name: CI\n\non:\n pull_request:\n\njobs:\n lint:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n\n - name: Install pnpm\n uses: pnpm/action-setup@v4\n\n - name: Set node\n uses: actions/setup-node@v4\n with:\n node-version: lts/*\n cache: pnpm\n\n - name: Install\n run: pnpm i\n\n - name: Lint\n run: pnpm run lint\n`,\n },\n {\n filename: 'pr-contributor-welcome.yml',\n content: `name: PullRequest Contributor Welcome\n\non:\n pull_request_target:\n types:\n - closed\n# paths:\n# - 'components/**'\n\npermissions:\n contents: read\n\njobs:\n comment:\n permissions:\n issues: write # for actions-cool/maintain-one-comment to modify or create issue comments\n pull-requests: write # for actions-cool/maintain-one-comment to modify or create PR comments\n if: github.event.pull_request.merged == true && github.repository == 'lonewolfyx/xxxx'\n runs-on: ubuntu-latest\n steps:\n - name: get commit count\n id: get_commit_count\n run: |\n PR_AUTHOR=$(echo \"\\${{ github.event.pull_request.user.login }}\")\n RESULT_DATA=$(curl -s \"https://api.github.com/repos/\\${{ github.repository }}/commits?author=\\${PR_AUTHOR}&per_page=5\")\n DATA_LENGTH=$(echo \\$RESULT_DATA | jq 'if type == \"array\" then length else 0 end')\n echo \"COUNT=\\$DATA_LENGTH\" >> \\$GITHUB_OUTPUT\n - name: Comment on PR\n if: steps.get_commit_count.outputs.COUNT < 3\n uses: actions-cool/maintain-one-comment@v3\n with:\n token: \\${{ secrets.GITHUB_TOKEN }}\n body: |\n 🎉 Thx for the PR @\\${{ github.event.pull_request.user.login }}\n\n <!-- WELCOME_CONTRIBUTION -->\n body-include: <!-- WELCOME_CONTRIBUTION -->\n`,\n },\n {\n filename: 'release.yml',\n content: `name: Release\n\npermissions:\n contents: write\n\non:\n push:\n tags:\n - 'v*'\n\njobs:\n release:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n with:\n fetch-depth: 0\n\n - uses: actions/setup-node@v4\n with:\n node-version: lts/*\n\n - run: npx genereleaselog\n env:\n GITHUB_TOKEN: \\${{secrets.GITHUB_TOKEN}}\n`,\n },\n]\n\nexport async function createGithubWorkflows(config: IConfig): Promise<void> {\n const workflowsDir = path.join(config.cwd, '.github', 'workflows')\n await mkdir(workflowsDir, { recursive: true })\n\n for (const { filename, content } of workflows) {\n const filePath = path.join(workflowsDir, filename)\n await writeFile(filePath, content)\n }\n}\n","import type { IConfig } from '../types'\nimport { x } from 'tinyexec'\n\nexport async function createPackageJson(config: IConfig): Promise<void> {\n const { cwd, packageManager } = config\n\n await x(packageManager, packageManager === 'pnpm' ? ['init'] : ['init', '-y'], { nodeOptions: { cwd } })\n}\n","import type { IConfig } from '../types'\nimport { resolve } from 'node:path'\nimport { writeTSConfig } from 'pkg-types'\n\nexport async function createTsConfig(config: IConfig): Promise<void> {\n const tsconfigConfig = {\n extends: '@lonewolfyx/tsconfig/tsconfig.lib.json',\n compilerOptions: {\n baseUrl: './',\n paths: {\n '@/*': [\n './src/*',\n ],\n '#/*': [\n './src/types/*',\n './types/*',\n ],\n },\n resolveJsonModule: true,\n types: [\n 'node',\n ],\n noUnusedLocals: false,\n noUnusedParameters: false,\n declarationMap: false,\n },\n }\n\n await writeTSConfig(resolve(config.cwd, 'tsconfig.json'), tsconfigConfig)\n}\n","import type { IConfig } from '../types'\nimport { x } from 'tinyexec'\n\nexport async function installDevDeps(config: IConfig): Promise<void> {\n const { cwd, packageManager } = config\n const devDeps = [\n 'eslint',\n '@antfu/eslint-config',\n 'jiti',\n 'typescript',\n '@lonewolfyx/tsconfig',\n '@types/node',\n 'lint-staged',\n 'simple-git-hooks',\n 'picocolors',\n 'tsx',\n 'tsdown',\n ]\n\n const addArgs = packageManager === 'pnpm'\n ? ['add', '-D', ...devDeps]\n : ['install', '-D', ...devDeps]\n\n await x(packageManager, addArgs, { nodeOptions: { cwd } })\n}\n","import type { IConfig } from '@/types.ts'\nimport { writeFile } from 'node:fs/promises'\nimport path from 'node:path'\n\nexport async function createGitignore(config: IConfig): Promise<void> {\n const ignorePath = path.join(config.cwd, '.gitignore')\n const content = '# Logs\\n'\n + 'logs\\n'\n + '*.log\\n'\n + 'npm-debug.log*\\n'\n + 'yarn-debug.log*\\n'\n + 'yarn-error.log*\\n'\n + 'lerna-debug.log*\\n'\n + '\\n'\n + '# Diagnostic reports (https://nodejs.org/api/report.html)\\n'\n + 'report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json\\n'\n + '\\n'\n + '# Runtime data\\n'\n + 'pids\\n'\n + '*.pid\\n'\n + '*.seed\\n'\n + '*.pid.lock\\n'\n + '\\n'\n + '# Directory for instrumented libs generated by jscoverage/JSCover\\n'\n + 'lib-cov\\n'\n + '\\n'\n + '# Coverage directory used by tools like istanbul\\n'\n + 'coverage\\n'\n + '*.lcov\\n'\n + '\\n'\n + '# nyc test coverage\\n'\n + '.nyc_output\\n'\n + '\\n'\n + '# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\\n'\n + '.grunt\\n'\n + '\\n'\n + '# Bower dependency directory (https://bower.io/)\\n'\n + 'bower_components\\n'\n + '\\n'\n + '# node-waf configuration\\n'\n + '.lock-wscript\\n'\n + '\\n'\n + '# Compiled binary addons (https://nodejs.org/api/addons.html)\\n'\n + 'build/Release\\n'\n + '\\n'\n + '# Dependency directories\\n'\n + 'node_modules/\\n'\n + 'jspm_packages/\\n'\n + '\\n'\n + '# Snowpack dependency directory (https://snowpack.dev/)\\n'\n + 'web_modules/\\n'\n + '\\n'\n + '# TypeScript cache\\n'\n + '*.tsbuildinfo\\n'\n + '\\n'\n + '# Optional npm cache directory\\n'\n + '.npm\\n'\n + '\\n'\n + '# Optional eslint cache\\n'\n + '.eslintcache\\n'\n + '\\n'\n + '# Optional stylelint cache\\n'\n + '.stylelintcache\\n'\n + '\\n'\n + '# Optional REPL history\\n'\n + '.node_repl_history\\n'\n + '\\n'\n + '# Output of \\'npm pack\\'\\n'\n + '*.tgz\\n'\n + '\\n'\n + '# Yarn Integrity file\\n'\n + '.yarn-integrity\\n'\n + '\\n'\n + '# dotenv environment variable files\\n'\n + '.env\\n'\n + '.env.*\\n'\n + '!.env.example\\n'\n + '\\n'\n + '# parcel-bundler cache (https://parceljs.org/)\\n'\n + '.cache\\n'\n + '.parcel-cache\\n'\n + '\\n'\n + '# Next.js build output\\n'\n + '.next\\n'\n + 'out\\n'\n + '\\n'\n + '# Nuxt.js build / generate output\\n'\n + '.nuxt\\n'\n + 'dist\\n'\n + '\\n'\n + '# Gatsby files\\n'\n + '.cache/\\n'\n + '# Comment in the public line in if your project uses Gatsby and not Next.js\\n'\n + '# https://nextjs.org/blog/next-9-1#public-directory-support\\n'\n + '# public\\n'\n + '\\n'\n + '# vuepress build output\\n'\n + '.vuepress/dist\\n'\n + '\\n'\n + '# vuepress v2.x temp and cache directory\\n'\n + '.temp\\n'\n + '.cache\\n'\n + '\\n'\n + '# Sveltekit cache directory\\n'\n + '.svelte-kit/\\n'\n + '\\n'\n + '# vitepress build output\\n'\n + '**/.vitepress/dist\\n'\n + '\\n'\n + '# vitepress cache directory\\n'\n + '**/.vitepress/cache\\n'\n + '\\n'\n + '# Docusaurus cache and generated files\\n'\n + '.docusaurus\\n'\n + '\\n'\n + '# Serverless directories\\n'\n + '.serverless/\\n'\n + '\\n'\n + '# FuseBox cache\\n'\n + '.fusebox/\\n'\n + '\\n'\n + '# DynamoDB Local files\\n'\n + '.dynamodb/\\n'\n + '\\n'\n + '# Firebase cache directory\\n'\n + '.firebase/\\n'\n + '\\n'\n + '# TernJS port file\\n'\n + '.tern-port\\n'\n + '\\n'\n + '# Stores VSCode versions used for testing VSCode extensions\\n'\n + '.vscode-test\\n'\n + '\\n'\n + '# yarn v3\\n'\n + '.pnp.*\\n'\n + '.yarn/*\\n'\n + '!.yarn/patches\\n'\n + '!.yarn/plugins\\n'\n + '!.yarn/releases\\n'\n + '!.yarn/sdks\\n'\n + '!.yarn/versions\\n'\n + '\\n'\n + '# Vite logs files\\n'\n + 'vite.config.js.timestamp-*\\n'\n + 'vite.config.ts.timestamp-*\\n'\n + '.idea'\n await writeFile(ignorePath, content)\n}\n","","import { x } from 'tinyexec'\n\n/**\n * 检测包管理器是否存在\n * @param command 包管理器命令名称\n */\nexport async function hasPackageManager(command: string): Promise<boolean> {\n try {\n await x(command, ['--version'], { throwOnError: true })\n return true\n }\n catch {\n return false\n }\n}\n","import type { IConfig } from './types'\nimport path from 'node:path'\nimport { hasPackageManager } from './utils'\n\nexport async function resolveConfig(cwd: string): Promise<IConfig> {\n const hasPnpm = await hasPackageManager('pnpm')\n\n return {\n cwd,\n packageJsonPath: path.join(cwd, 'package.json'),\n packageManager: hasPnpm ? 'pnpm' : 'npm',\n }\n}\n","import { spinner } from '@clack/prompts'\n\ninterface Schedule {\n step: (startMessage: string, fn: () => Promise<void>, doneMessage: string) => Schedule\n done: () => Promise<void>\n}\n\nexport function schedule(): Schedule {\n const s = spinner()\n const tasks: Array<{ startMessage: string, fn: () => Promise<void>, doneMessage: string }> = []\n\n const chain: Schedule = {\n step(startMessage, fn, doneMessage) {\n tasks.push({ startMessage, fn, doneMessage })\n return chain\n },\n async done() {\n for (const { startMessage, fn, doneMessage } of tasks) {\n s.start(startMessage)\n await fn()\n s.stop(doneMessage)\n }\n },\n }\n\n return chain\n}\n","import { access } from 'node:fs/promises'\nimport { confirm, intro, isCancel, outro } from '@clack/prompts'\nimport { createMain, defineCommand } from 'citty'\nimport { addGitHooksConfig, clearDirectory, configPackageJson, createEslintConfig, createGitHooks, createGithubWorkflows, createPackageJson, createTsConfig, installDevDeps } from '@/task'\nimport { createGitignore } from '@/task/createGitignore.ts'\nimport { description, name, version } from '../package.json'\nimport { resolveConfig } from './config'\nimport { schedule } from './schedule.ts'\n\nconst command = defineCommand({\n meta: {\n name,\n version,\n description,\n },\n setup() {\n intro('项目初始化')\n },\n cleanup() {\n outro('Done. 项目初始化完成')\n },\n args: {\n cwd: {\n type: 'string',\n description: 'Current working directory',\n alias: 'c',\n default: process.cwd(),\n },\n },\n async run({ args }) {\n const cwd = args.cwd as string\n const config = await resolveConfig(cwd)\n\n // 检测 package.json 是否存在\n const packageJsonExists = await access(config.packageJsonPath)\n .then(() => true)\n .catch(() => false)\n\n if (packageJsonExists) {\n const shouldOverwrite = await confirm({\n message: '检测到当前目录已存在项目,是否覆盖创建新项目?(将清空当前目录下所有文件)',\n })\n\n if (isCancel(shouldOverwrite) || !shouldOverwrite) {\n outro('已取消操作')\n return\n }\n\n await clearDirectory(config.cwd)\n }\n\n await schedule()\n .step('正在创建 package.json...', () => createPackageJson(config), 'package.json 创建完成')\n .step('正在配置 package.json...', () => configPackageJson(config), 'package.json 配置完成')\n .step('正在安装开发依赖...', () => installDevDeps(config), '开发依赖安装完成')\n .step('正在创建 git hooks 配置文件...', () => createGitHooks(config), 'git hooks 配置文件创建完成')\n .step('正在创建 tsconfig.json...', () => createTsConfig(config), 'tsconfig.json 创建完成')\n .step('正在添加 git hooks 配置...', () => addGitHooksConfig(config), 'git hooks 配置添加完成')\n .step('正在创建 .gitignore 文件', () => createGitignore(config), '.gitignore 创建完成')\n .step('正在创建 ESLint 配置文件...', () => createEslintConfig(config), 'ESLint 配置文件创建完成')\n .step('正在创建 GitHub Workflows...', () => createGithubWorkflows(config), 'GitHub Workflows 创建完成')\n .done()\n },\n})\n\ncreateMain(command)({})\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lonewolfyx/setup",
3
3
  "type": "module",
4
- "version": "0.0.5",
4
+ "version": "0.0.7",
5
5
  "packageManager": "pnpm@10.33.2",
6
6
  "description": "Instant project boilerplate setup",
7
7
  "author": "lonewolfyx <olddrivero.king@qq.com>",
@@ -49,7 +49,7 @@
49
49
  "@lonewolfyx/tsconfig": "^0.0.6",
50
50
  "@types/node": "^25.6.0",
51
51
  "eslint": "^10.3.0",
52
- "lint-staged": "^16.4.0",
52
+ "nano-staged": "^1.0.2",
53
53
  "picocolors": "^1.1.1",
54
54
  "simple-git-hooks": "^2.13.1",
55
55
  "tsdown": "^0.21.10",
@@ -58,10 +58,10 @@
58
58
  "typescript": "^6.0.3"
59
59
  },
60
60
  "simple-git-hooks": {
61
- "pre-commit": "npx lint-staged",
61
+ "pre-commit": "npx nano-staged",
62
62
  "commit-msg": "node scripts/verify-commit.js"
63
63
  },
64
- "lint-staged": {
64
+ "nano-staged": {
65
65
  "*": "eslint --fix"
66
66
  }
67
67
  }