@huaiyou/hooks-git 1.0.0 → 2.1.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @huaiyou/hooks-git
2
2
 
3
+ ## 2.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Add TypeScript declaration files (.d.ts) for better IDE support
8
+
3
9
  ## 1.0.0
4
10
 
5
11
  ### Major Changes
package/README.md CHANGED
@@ -5,12 +5,42 @@
5
5
  ## 📦 安装
6
6
 
7
7
  ```bash
8
- pnpm add -D @huaiyou/hooks-git husky @commitlint/cli lint-staged
8
+ pnpm add -D @huaiyou/hooks-git
9
9
  ```
10
10
 
11
+ > 注意:该包会自动处理所有依赖关系,无需手动安装 husky、@commitlint/cli 和 lint-staged。
12
+
11
13
  ## 🚀 快速开始
12
14
 
13
- ### 1. 安装 Husky
15
+ ### 一键初始化(推荐)
16
+
17
+ 使用以下命令一键完成所有配置:
18
+
19
+ ```bash
20
+ npx hy-hooks-git init
21
+ ```
22
+
23
+ 该命令将自动:
24
+
25
+ - 检查并初始化 Git 仓库(如果尚未初始化)
26
+ - 安装并配置 Husky
27
+ - 添加 commit-msg 和 pre-commit 钩子
28
+ - 创建 commitlint.config.js 和 lint-staged.config.js 配置文件
29
+ - 更新 package.json 脚本
30
+
31
+ ### 交互式初始化
32
+
33
+ 如需自定义配置,可以使用交互式模式:
34
+
35
+ ```bash
36
+ npx hy-hooks-git init --interactive
37
+ ```
38
+
39
+ ### 手动配置(不推荐)
40
+
41
+ 如果需要手动配置,可以按照以下步骤进行:
42
+
43
+ #### 1. 安装 Husky
14
44
 
15
45
  在项目根目录运行:
16
46
 
@@ -18,23 +48,24 @@ pnpm add -D @huaiyou/hooks-git husky @commitlint/cli lint-staged
18
48
  pnpm prepare
19
49
  ```
20
50
 
21
- ### 2. 复制配置文件
51
+ #### 2. 复制配置文件
22
52
 
23
53
  将以下文件复制到项目根目录:
24
54
 
25
55
  **commitlint.config.js**:
26
56
 
27
57
  ```javascript
28
- module.exports = require('@huaiyou/hooks-git/commitlint.config');
58
+ module.exports = require('@huaiyou/hooks-git/commitlint');
29
59
  ```
30
60
 
31
61
  **lint-staged.config.js**:
32
62
 
33
63
  ```javascript
34
- module.exports = require('@huaiyou/hooks-git/lint-staged.config');
64
+ const { createLintStagedConfig } = require('@huaiyou/hooks-git/lint-staged');
65
+ module.exports = createLintStagedConfig();
35
66
  ```
36
67
 
37
- ### 3. 配置 Husky 钩子
68
+ #### 3. 配置 Husky 钩子
38
69
 
39
70
  **创建 .husky/pre-commit**:
40
71
 
@@ -54,7 +85,7 @@ pnpm lint-staged
54
85
  pnpm commitlint --edit $1
55
86
  ```
56
87
 
57
- ### 4. 添加脚本
88
+ #### 4. 添加脚本
58
89
 
59
90
  在 `package.json` 中:
60
91
 
@@ -66,6 +97,20 @@ pnpm commitlint --edit $1
66
97
  }
67
98
  ```
68
99
 
100
+ ### 回滚初始化
101
+
102
+ 如果需要回滚所有配置,可以使用以下命令:
103
+
104
+ ```bash
105
+ npx hy-hooks-git rollback
106
+ ```
107
+
108
+ 该命令将自动:
109
+
110
+ - 删除 .husky 目录及其包含的钩子
111
+ - 删除配置文件(commitlint.config.js 和 lint-staged.config.js)
112
+ - 从 package.json 中移除 prepare 脚本
113
+
69
114
  ## ✨ 特性
70
115
 
71
116
  ### Commitlint
@@ -136,7 +181,7 @@ Closes #123
136
181
  创建 `commitlint.config.js`:
137
182
 
138
183
  ```javascript
139
- const baseConfig = require('@huaiyou/hooks-git/commitlint.config');
184
+ const baseConfig = require('@huaiyou/hooks-git/commitlint');
140
185
 
141
186
  module.exports = {
142
187
  ...baseConfig,
@@ -152,7 +197,10 @@ module.exports = {
152
197
  创建 `lint-staged.config.js`:
153
198
 
154
199
  ```javascript
155
- const baseConfig = require('@huaiyou/hooks-git/lint-staged.config');
200
+ const { createLintStagedConfig } = require('@huaiyou/hooks-git/lint-staged');
201
+
202
+ // 获取基础配置
203
+ const baseConfig = createLintStagedConfig();
156
204
 
157
205
  module.exports = {
158
206
  ...baseConfig,
@@ -164,6 +212,21 @@ module.exports = {
164
212
  };
165
213
  ```
166
214
 
215
+ 或者直接扩展配置函数:
216
+
217
+ ```javascript
218
+ const { createLintStagedConfig } = require('@huaiyou/hooks-git/lint-staged');
219
+
220
+ module.exports = {
221
+ ...createLintStagedConfig(),
222
+ '*.{ts,tsx}': [
223
+ 'eslint --fix',
224
+ 'prettier --write',
225
+ 'vitest related --run', // 添加测试
226
+ ],
227
+ };
228
+ ```
229
+
167
230
  ## 🚫 跳过钩子
168
231
 
169
232
  ### 临时跳过(不推荐)
package/dist/cli.cjs ADDED
@@ -0,0 +1,198 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const cac = require('cac');
5
+ const fs = require('fs-extra');
6
+ const node_path = require('node:path');
7
+ const consola = require('consola');
8
+ const execa = require('execa');
9
+ const picocolors = require('picocolors');
10
+
11
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
12
+
13
+ const cac__default = /*#__PURE__*/_interopDefaultCompat(cac);
14
+ const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
15
+ const picocolors__default = /*#__PURE__*/_interopDefaultCompat(picocolors);
16
+
17
+ const version = "2.1.0";
18
+
19
+ const logger = {
20
+ /**
21
+ * 输出信息日志
22
+ * @param {string} msg - 日志消息
23
+ */
24
+ info: (msg) => consola.consola.info(msg),
25
+ /**
26
+ * 输出成功日志
27
+ * @param {string} msg - 日志消息
28
+ */
29
+ success: (msg) => consola.consola.success(msg),
30
+ /**
31
+ * 输出警告日志
32
+ * @param {string} msg - 日志消息
33
+ */
34
+ warn: (msg) => consola.consola.warn(msg),
35
+ /**
36
+ * 输出错误日志
37
+ * @param {string} msg - 日志消息
38
+ */
39
+ error: (msg) => consola.consola.error(msg),
40
+ /**
41
+ * 输出带边框的日志
42
+ * @param {string} msg - 日志消息
43
+ */
44
+ box: (msg) => {
45
+ console.log(
46
+ picocolors__default.cyan("\u250C" + "\u2500".repeat(msg.length + 2) + "\u2510") + "\n" + picocolors__default.cyan("\u2502 ") + msg + picocolors__default.cyan(" \u2502") + "\n" + picocolors__default.cyan("\u2514" + "\u2500".repeat(msg.length + 2) + "\u2518")
47
+ );
48
+ }
49
+ };
50
+ const runCommand = async (command, args) => {
51
+ try {
52
+ await execa.execa(command, args, { stdio: "inherit" });
53
+ } catch (error) {
54
+ logger.error(`Failed to run command: ${command} ${args.join(" ")}`);
55
+ throw error;
56
+ }
57
+ };
58
+ const updatePackageJson = async (callback) => {
59
+ const pkgPath = node_path.resolve(process.cwd(), "package.json");
60
+ if (!fs__default.existsSync(pkgPath)) {
61
+ throw new Error("package.json not found");
62
+ }
63
+ const pkg = await fs__default.readJson(pkgPath);
64
+ const newPkg = callback(pkg);
65
+ await fs__default.writeJson(pkgPath, newPkg, { spaces: 2 });
66
+ };
67
+
68
+ const init = async () => {
69
+ logger.box("Initializing @huaiyou/hooks-git");
70
+ const gitDirPath = node_path.resolve(process.cwd(), ".git");
71
+ if (!fs__default.existsSync(gitDirPath)) {
72
+ logger.warn("Not a git repository. Initializing...");
73
+ await runCommand("git", ["init"]);
74
+ }
75
+ logger.info("Installing Husky...");
76
+ try {
77
+ await runCommand("npx", ["husky", "install"]);
78
+ } catch (e) {
79
+ logger.error("Failed to install husky. Make sure dependencies are installed.");
80
+ }
81
+ logger.info("Adding hooks...");
82
+ const huskyDir = node_path.resolve(process.cwd(), ".husky");
83
+ const commitMsgPath = node_path.resolve(huskyDir, "commit-msg");
84
+ const commitMsgContent = `npx --no -- commitlint --edit \${1}
85
+ `;
86
+ await fs__default.outputFile(commitMsgPath, commitMsgContent, { mode: 493 });
87
+ const preCommitPath = node_path.resolve(huskyDir, "pre-commit");
88
+ const preCommitContent = `npx lint-staged
89
+ `;
90
+ await fs__default.outputFile(preCommitPath, preCommitContent, { mode: 493 });
91
+ logger.info("Creating configuration files...");
92
+ const pkgPath = node_path.resolve(process.cwd(), "package.json");
93
+ const pkg = await fs__default.readJson(pkgPath);
94
+ const isModule = pkg.type === "module";
95
+ const isTsProject = fs__default.existsSync(node_path.resolve(process.cwd(), "tsconfig.json"));
96
+ const commitlintFile = isTsProject ? "commitlint.config.ts" : isModule ? "commitlint.config.cjs" : "commitlint.config.js";
97
+ if (!fs__default.existsSync(node_path.resolve(process.cwd(), commitlintFile))) {
98
+ let content = "";
99
+ if (isTsProject) {
100
+ content = `import { commitlintConfig } from '@huaiyou/hooks-git';
101
+ export default commitlintConfig;
102
+ `;
103
+ } else {
104
+ content = `module.exports = require('@huaiyou/hooks-git/commitlint');
105
+ `;
106
+ }
107
+ await fs__default.writeFile(node_path.resolve(process.cwd(), commitlintFile), content);
108
+ logger.success(`Created ${commitlintFile}`);
109
+ } else {
110
+ logger.warn("commitlint config already exists. Skipping...");
111
+ }
112
+ const lintStagedFile = isTsProject ? "lint-staged.config.ts" : isModule ? "lint-staged.config.cjs" : "lint-staged.config.js";
113
+ if (!fs__default.existsSync(node_path.resolve(process.cwd(), lintStagedFile))) {
114
+ let content = "";
115
+ if (isTsProject) {
116
+ content = `import { createLintStagedConfig } from '@huaiyou/hooks-git';
117
+ export default createLintStagedConfig();
118
+ `;
119
+ } else {
120
+ content = `const { createLintStagedConfig } = require('@huaiyou/hooks-git/lint-staged');
121
+ module.exports = createLintStagedConfig();
122
+ `;
123
+ }
124
+ await fs__default.writeFile(node_path.resolve(process.cwd(), lintStagedFile), content);
125
+ logger.success(`Created ${lintStagedFile}`);
126
+ } else {
127
+ logger.warn("lint-staged config already exists. Skipping...");
128
+ }
129
+ if (isTsProject) {
130
+ const hasTsNode = pkg.devDependencies && pkg.devDependencies["ts-node"] || pkg.dependencies && pkg.dependencies["ts-node"];
131
+ if (!hasTsNode) {
132
+ logger.info("Detected TypeScript project. Installing ts-node...");
133
+ await runCommand("pnpm", ["add", "-D", "ts-node"]);
134
+ }
135
+ }
136
+ logger.info("Updating package.json scripts...");
137
+ await updatePackageJson((pkg2) => {
138
+ pkg2.scripts = pkg2.scripts || {};
139
+ if (!pkg2.scripts.prepare || !pkg2.scripts.prepare.includes("husky")) {
140
+ pkg2.scripts.prepare = "husky install";
141
+ }
142
+ return pkg2;
143
+ });
144
+ logger.box("Initialization complete! \u{1F389}");
145
+ };
146
+
147
+ const rollback = async () => {
148
+ logger.box("Rolling back @huaiyou/hooks-git initialization");
149
+ const huskyDir = node_path.resolve(process.cwd(), ".husky");
150
+ if (fs__default.existsSync(huskyDir)) {
151
+ await fs__default.remove(huskyDir);
152
+ logger.success("Removed .husky directory");
153
+ }
154
+ const configFiles = [
155
+ "commitlint.config.js",
156
+ "commitlint.config.cjs",
157
+ "lint-staged.config.js",
158
+ "lint-staged.config.cjs"
159
+ ];
160
+ for (const file of configFiles) {
161
+ const filePath = node_path.resolve(process.cwd(), file);
162
+ if (fs__default.existsSync(filePath)) {
163
+ await fs__default.remove(filePath);
164
+ logger.success(`Removed ${file}`);
165
+ }
166
+ }
167
+ await updatePackageJson((pkg) => {
168
+ if (pkg.scripts && pkg.scripts.prepare === "husky install") {
169
+ delete pkg.scripts.prepare;
170
+ logger.success("Removed prepare script from package.json");
171
+ }
172
+ return pkg;
173
+ });
174
+ logger.box("Rollback complete! \u{1F519}");
175
+ };
176
+
177
+ const cli = cac__default("hy-hooks-git");
178
+ cli.command("init", "Initialize git hooks and configuration").action(async () => {
179
+ try {
180
+ await init();
181
+ } catch (error) {
182
+ logger.error("Initialization failed.");
183
+ console.error(error);
184
+ process.exit(1);
185
+ }
186
+ });
187
+ cli.command("rollback", "Rollback initialization").action(async () => {
188
+ try {
189
+ await rollback();
190
+ } catch (error) {
191
+ logger.error("Rollback failed.");
192
+ console.error(error);
193
+ process.exit(1);
194
+ }
195
+ });
196
+ cli.help();
197
+ cli.version(version);
198
+ cli.parse();
package/dist/cli.d.cts ADDED
@@ -0,0 +1 @@
1
+
package/dist/cli.d.mts ADDED
@@ -0,0 +1 @@
1
+
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+
package/dist/cli.mjs ADDED
@@ -0,0 +1,190 @@
1
+ #!/usr/bin/env node
2
+ import cac from 'cac';
3
+ import fs from 'fs-extra';
4
+ import { resolve } from 'node:path';
5
+ import { consola } from 'consola';
6
+ import { execa } from 'execa';
7
+ import picocolors from 'picocolors';
8
+
9
+ const version = "2.1.0";
10
+
11
+ const logger = {
12
+ /**
13
+ * 输出信息日志
14
+ * @param {string} msg - 日志消息
15
+ */
16
+ info: (msg) => consola.info(msg),
17
+ /**
18
+ * 输出成功日志
19
+ * @param {string} msg - 日志消息
20
+ */
21
+ success: (msg) => consola.success(msg),
22
+ /**
23
+ * 输出警告日志
24
+ * @param {string} msg - 日志消息
25
+ */
26
+ warn: (msg) => consola.warn(msg),
27
+ /**
28
+ * 输出错误日志
29
+ * @param {string} msg - 日志消息
30
+ */
31
+ error: (msg) => consola.error(msg),
32
+ /**
33
+ * 输出带边框的日志
34
+ * @param {string} msg - 日志消息
35
+ */
36
+ box: (msg) => {
37
+ console.log(
38
+ picocolors.cyan("\u250C" + "\u2500".repeat(msg.length + 2) + "\u2510") + "\n" + picocolors.cyan("\u2502 ") + msg + picocolors.cyan(" \u2502") + "\n" + picocolors.cyan("\u2514" + "\u2500".repeat(msg.length + 2) + "\u2518")
39
+ );
40
+ }
41
+ };
42
+ const runCommand = async (command, args) => {
43
+ try {
44
+ await execa(command, args, { stdio: "inherit" });
45
+ } catch (error) {
46
+ logger.error(`Failed to run command: ${command} ${args.join(" ")}`);
47
+ throw error;
48
+ }
49
+ };
50
+ const updatePackageJson = async (callback) => {
51
+ const pkgPath = resolve(process.cwd(), "package.json");
52
+ if (!fs.existsSync(pkgPath)) {
53
+ throw new Error("package.json not found");
54
+ }
55
+ const pkg = await fs.readJson(pkgPath);
56
+ const newPkg = callback(pkg);
57
+ await fs.writeJson(pkgPath, newPkg, { spaces: 2 });
58
+ };
59
+
60
+ const init = async () => {
61
+ logger.box("Initializing @huaiyou/hooks-git");
62
+ const gitDirPath = resolve(process.cwd(), ".git");
63
+ if (!fs.existsSync(gitDirPath)) {
64
+ logger.warn("Not a git repository. Initializing...");
65
+ await runCommand("git", ["init"]);
66
+ }
67
+ logger.info("Installing Husky...");
68
+ try {
69
+ await runCommand("npx", ["husky", "install"]);
70
+ } catch (e) {
71
+ logger.error("Failed to install husky. Make sure dependencies are installed.");
72
+ }
73
+ logger.info("Adding hooks...");
74
+ const huskyDir = resolve(process.cwd(), ".husky");
75
+ const commitMsgPath = resolve(huskyDir, "commit-msg");
76
+ const commitMsgContent = `npx --no -- commitlint --edit \${1}
77
+ `;
78
+ await fs.outputFile(commitMsgPath, commitMsgContent, { mode: 493 });
79
+ const preCommitPath = resolve(huskyDir, "pre-commit");
80
+ const preCommitContent = `npx lint-staged
81
+ `;
82
+ await fs.outputFile(preCommitPath, preCommitContent, { mode: 493 });
83
+ logger.info("Creating configuration files...");
84
+ const pkgPath = resolve(process.cwd(), "package.json");
85
+ const pkg = await fs.readJson(pkgPath);
86
+ const isModule = pkg.type === "module";
87
+ const isTsProject = fs.existsSync(resolve(process.cwd(), "tsconfig.json"));
88
+ const commitlintFile = isTsProject ? "commitlint.config.ts" : isModule ? "commitlint.config.cjs" : "commitlint.config.js";
89
+ if (!fs.existsSync(resolve(process.cwd(), commitlintFile))) {
90
+ let content = "";
91
+ if (isTsProject) {
92
+ content = `import { commitlintConfig } from '@huaiyou/hooks-git';
93
+ export default commitlintConfig;
94
+ `;
95
+ } else {
96
+ content = `module.exports = require('@huaiyou/hooks-git/commitlint');
97
+ `;
98
+ }
99
+ await fs.writeFile(resolve(process.cwd(), commitlintFile), content);
100
+ logger.success(`Created ${commitlintFile}`);
101
+ } else {
102
+ logger.warn("commitlint config already exists. Skipping...");
103
+ }
104
+ const lintStagedFile = isTsProject ? "lint-staged.config.ts" : isModule ? "lint-staged.config.cjs" : "lint-staged.config.js";
105
+ if (!fs.existsSync(resolve(process.cwd(), lintStagedFile))) {
106
+ let content = "";
107
+ if (isTsProject) {
108
+ content = `import { createLintStagedConfig } from '@huaiyou/hooks-git';
109
+ export default createLintStagedConfig();
110
+ `;
111
+ } else {
112
+ content = `const { createLintStagedConfig } = require('@huaiyou/hooks-git/lint-staged');
113
+ module.exports = createLintStagedConfig();
114
+ `;
115
+ }
116
+ await fs.writeFile(resolve(process.cwd(), lintStagedFile), content);
117
+ logger.success(`Created ${lintStagedFile}`);
118
+ } else {
119
+ logger.warn("lint-staged config already exists. Skipping...");
120
+ }
121
+ if (isTsProject) {
122
+ const hasTsNode = pkg.devDependencies && pkg.devDependencies["ts-node"] || pkg.dependencies && pkg.dependencies["ts-node"];
123
+ if (!hasTsNode) {
124
+ logger.info("Detected TypeScript project. Installing ts-node...");
125
+ await runCommand("pnpm", ["add", "-D", "ts-node"]);
126
+ }
127
+ }
128
+ logger.info("Updating package.json scripts...");
129
+ await updatePackageJson((pkg2) => {
130
+ pkg2.scripts = pkg2.scripts || {};
131
+ if (!pkg2.scripts.prepare || !pkg2.scripts.prepare.includes("husky")) {
132
+ pkg2.scripts.prepare = "husky install";
133
+ }
134
+ return pkg2;
135
+ });
136
+ logger.box("Initialization complete! \u{1F389}");
137
+ };
138
+
139
+ const rollback = async () => {
140
+ logger.box("Rolling back @huaiyou/hooks-git initialization");
141
+ const huskyDir = resolve(process.cwd(), ".husky");
142
+ if (fs.existsSync(huskyDir)) {
143
+ await fs.remove(huskyDir);
144
+ logger.success("Removed .husky directory");
145
+ }
146
+ const configFiles = [
147
+ "commitlint.config.js",
148
+ "commitlint.config.cjs",
149
+ "lint-staged.config.js",
150
+ "lint-staged.config.cjs"
151
+ ];
152
+ for (const file of configFiles) {
153
+ const filePath = resolve(process.cwd(), file);
154
+ if (fs.existsSync(filePath)) {
155
+ await fs.remove(filePath);
156
+ logger.success(`Removed ${file}`);
157
+ }
158
+ }
159
+ await updatePackageJson((pkg) => {
160
+ if (pkg.scripts && pkg.scripts.prepare === "husky install") {
161
+ delete pkg.scripts.prepare;
162
+ logger.success("Removed prepare script from package.json");
163
+ }
164
+ return pkg;
165
+ });
166
+ logger.box("Rollback complete! \u{1F519}");
167
+ };
168
+
169
+ const cli = cac("hy-hooks-git");
170
+ cli.command("init", "Initialize git hooks and configuration").action(async () => {
171
+ try {
172
+ await init();
173
+ } catch (error) {
174
+ logger.error("Initialization failed.");
175
+ console.error(error);
176
+ process.exit(1);
177
+ }
178
+ });
179
+ cli.command("rollback", "Rollback initialization").action(async () => {
180
+ try {
181
+ await rollback();
182
+ } catch (error) {
183
+ logger.error("Rollback failed.");
184
+ console.error(error);
185
+ process.exit(1);
186
+ }
187
+ });
188
+ cli.help();
189
+ cli.version(version);
190
+ cli.parse();
@@ -0,0 +1,208 @@
1
+ 'use strict';
2
+
3
+ const Configuration = {
4
+ /**
5
+ * 继承的配置
6
+ * 使用 @commitlint/config-conventional 作为基础配置
7
+ */
8
+ extends: ["@commitlint/config-conventional"],
9
+ /**
10
+ * 提交信息规则配置
11
+ */
12
+ rules: {
13
+ /**
14
+ * P0: 提交主题必须以小写字母开头
15
+ */
16
+ "subject-case": [2, "always", "lower-case"],
17
+ /**
18
+ * P0: 提交头信息最大长度为 72 个字符
19
+ */
20
+ "header-max-length": [2, "always", 72],
21
+ /**
22
+ * P0: 提交主题结尾不能有句号
23
+ */
24
+ "subject-full-stop": [2, "never", "."],
25
+ /**
26
+ * P0: 提交正文每行最大长度为 72 个字符
27
+ */
28
+ "body-max-line-length": [2, "always", 72],
29
+ /**
30
+ * P0: 提交脚注每行最大长度为 72 个字符
31
+ */
32
+ "footer-max-line-length": [2, "always", 72],
33
+ /**
34
+ * 标准提交类型枚举
35
+ * 定义了允许的提交类型及其语义
36
+ */
37
+ "type-enum": [
38
+ 2,
39
+ "always",
40
+ [
41
+ "feat",
42
+ // 新功能
43
+ "fix",
44
+ // Bug 修复
45
+ "docs",
46
+ // 文档更新
47
+ "style",
48
+ // 代码格式(不影响代码运行的变更)
49
+ "refactor",
50
+ // 代码重构(既不是修复也不是新功能)
51
+ "perf",
52
+ // 性能优化
53
+ "test",
54
+ // 添加或修正测试
55
+ "build",
56
+ // 构建系统或外部依赖变更
57
+ "ci",
58
+ // CI 配置文件和脚本变更
59
+ "chore",
60
+ // 其他不修改 src 或 test 文件的变更
61
+ "revert"
62
+ // 回退之前的提交
63
+ ]
64
+ ]
65
+ },
66
+ /**
67
+ * 交互式提交提示配置
68
+ * 用于配置 commitizen 等工具的提示信息
69
+ */
70
+ prompt: {
71
+ /**
72
+ * 提示消息配置
73
+ */
74
+ messages: {
75
+ skip: "(\u6309\u56DE\u8F66\u8DF3\u8FC7)",
76
+ max: "\u6700\u591A %d \u4E2A\u5B57\u7B26",
77
+ min: "\u81F3\u5C11 %d \u4E2A\u5B57\u7B26",
78
+ empty: "\u4E0D\u80FD\u4E3A\u7A7A",
79
+ upper: "\u5927\u5199",
80
+ lower: "\u5C0F\u5199",
81
+ title: "\u63D0\u4EA4\u4FE1\u606F"
82
+ },
83
+ /**
84
+ * 提示问题配置
85
+ */
86
+ questions: {
87
+ /**
88
+ * 提交类型选择
89
+ */
90
+ type: {
91
+ description: "\u9009\u62E9\u63D0\u4EA4\u7C7B\u578B:",
92
+ enum: {
93
+ feat: {
94
+ description: "\u65B0\u529F\u80FD",
95
+ title: "\u529F\u80FD",
96
+ emoji: "\u2728"
97
+ },
98
+ fix: {
99
+ description: "Bug \u4FEE\u590D",
100
+ title: "\u4FEE\u590D",
101
+ emoji: "\u{1F41B}"
102
+ },
103
+ docs: {
104
+ description: "\u4EC5\u6587\u6863\u53D8\u66F4",
105
+ title: "\u6587\u6863",
106
+ emoji: "\u{1F4DA}"
107
+ },
108
+ style: {
109
+ description: "\u4E0D\u5F71\u54CD\u4EE3\u7801\u542B\u4E49\u7684\u53D8\u66F4\uFF08\u7A7A\u767D\u3001\u683C\u5F0F\u3001\u7F3A\u5C11\u5206\u53F7\u7B49\uFF09",
110
+ title: "\u683C\u5F0F",
111
+ emoji: "\u{1F48E}"
112
+ },
113
+ refactor: {
114
+ description: "\u65E2\u4E0D\u662F\u4FEE\u590D\u4E5F\u4E0D\u662F\u65B0\u529F\u80FD\u7684\u4EE3\u7801\u53D8\u66F4",
115
+ title: "\u91CD\u6784",
116
+ emoji: "\u{1F4E6}"
117
+ },
118
+ perf: {
119
+ description: "\u6027\u80FD\u4F18\u5316\u7684\u4EE3\u7801\u53D8\u66F4",
120
+ title: "\u6027\u80FD",
121
+ emoji: "\u{1F680}"
122
+ },
123
+ test: {
124
+ description: "\u6DFB\u52A0\u7F3A\u5931\u7684\u6D4B\u8BD5\u6216\u4FEE\u6B63\u73B0\u6709\u6D4B\u8BD5",
125
+ title: "\u6D4B\u8BD5",
126
+ emoji: "\u{1F6A8}"
127
+ },
128
+ build: {
129
+ description: "\u5F71\u54CD\u6784\u5EFA\u7CFB\u7EDF\u6216\u5916\u90E8\u4F9D\u8D56\u7684\u53D8\u66F4\uFF08\u4F8B\u5982\uFF1Agulp\u3001broccoli\u3001npm\uFF09",
130
+ title: "\u6784\u5EFA",
131
+ emoji: "\u{1F6E0}"
132
+ },
133
+ ci: {
134
+ description: "CI \u914D\u7F6E\u6587\u4EF6\u548C\u811A\u672C\u7684\u53D8\u66F4\uFF08\u4F8B\u5982\uFF1ATravis\u3001Circle\u3001BrowserStack\u3001SauceLabs\uFF09",
135
+ title: "CI",
136
+ emoji: "\u2699\uFE0F"
137
+ },
138
+ chore: {
139
+ description: "\u4E0D\u4FEE\u6539 src \u6216 test \u6587\u4EF6\u7684\u5176\u4ED6\u53D8\u66F4",
140
+ title: "\u6742\u9879",
141
+ emoji: "\u267B\uFE0F"
142
+ },
143
+ revert: {
144
+ description: "\u56DE\u9000\u4E4B\u524D\u7684\u63D0\u4EA4",
145
+ title: "\u56DE\u9000",
146
+ emoji: "\u{1F5D1}"
147
+ }
148
+ }
149
+ },
150
+ /**
151
+ * 提交范围输入
152
+ */
153
+ scope: {
154
+ description: "\u63D0\u4EA4\u7684\u5F71\u54CD\u8303\u56F4\uFF08\u4F8B\u5982\uFF1A\u7EC4\u4EF6\u6216\u6587\u4EF6\u540D\uFF09:"
155
+ },
156
+ /**
157
+ * 提交主题输入
158
+ */
159
+ subject: {
160
+ description: "\u7B80\u77ED\u63CF\u8FF0\u53D8\u66F4\u5185\u5BB9\uFF08\u7948\u4F7F\u53E5\uFF09:"
161
+ },
162
+ /**
163
+ * 提交正文输入
164
+ */
165
+ body: {
166
+ description: "\u63D0\u4F9B\u53D8\u66F4\u7684\u8BE6\u7EC6\u63CF\u8FF0:"
167
+ },
168
+ /**
169
+ * 是否有重大变更
170
+ */
171
+ isBreaking: {
172
+ description: "\u662F\u5426\u6709\u91CD\u5927\u53D8\u66F4\uFF1F"
173
+ },
174
+ /**
175
+ * 重大变更正文输入
176
+ */
177
+ breakingBody: {
178
+ description: "\u91CD\u5927\u53D8\u66F4\u63D0\u4EA4\u9700\u8981\u6B63\u6587\u3002\u8BF7\u8F93\u5165\u63D0\u4EA4\u7684\u8BE6\u7EC6\u63CF\u8FF0:"
179
+ },
180
+ /**
181
+ * 重大变更描述输入
182
+ */
183
+ breaking: {
184
+ description: "\u63CF\u8FF0\u91CD\u5927\u53D8\u66F4:"
185
+ },
186
+ /**
187
+ * 是否影响未解决的问题
188
+ */
189
+ isIssueAffected: {
190
+ description: "\u6B64\u53D8\u66F4\u662F\u5426\u5F71\u54CD\u672A\u89E3\u51B3\u7684\u95EE\u9898\uFF1F"
191
+ },
192
+ /**
193
+ * 问题关联正文输入
194
+ */
195
+ issuesBody: {
196
+ description: "\u5982\u679C\u5173\u95ED\u4E86\u95EE\u9898\uFF0C\u63D0\u4EA4\u9700\u8981\u6B63\u6587\u3002\u8BF7\u8F93\u5165\u63D0\u4EA4\u7684\u8BE6\u7EC6\u63CF\u8FF0:"
197
+ },
198
+ /**
199
+ * 问题关联输入
200
+ */
201
+ issues: {
202
+ description: '\u6DFB\u52A0\u95EE\u9898\u5F15\u7528\uFF08\u4F8B\u5982\uFF1A"fix #123"\u3001"re #123"\uFF09:'
203
+ }
204
+ }
205
+ }
206
+ };
207
+
208
+ module.exports = Configuration;
@@ -0,0 +1,5 @@
1
+ import { UserConfig } from '@commitlint/types';
2
+
3
+ declare const Configuration: UserConfig;
4
+
5
+ export = Configuration;
@@ -0,0 +1,5 @@
1
+ import { UserConfig } from '@commitlint/types';
2
+
3
+ declare const Configuration: UserConfig;
4
+
5
+ export { Configuration as default };
@@ -0,0 +1,5 @@
1
+ import { UserConfig } from '@commitlint/types';
2
+
3
+ declare const Configuration: UserConfig;
4
+
5
+ export = Configuration;
@@ -0,0 +1,206 @@
1
+ const Configuration = {
2
+ /**
3
+ * 继承的配置
4
+ * 使用 @commitlint/config-conventional 作为基础配置
5
+ */
6
+ extends: ["@commitlint/config-conventional"],
7
+ /**
8
+ * 提交信息规则配置
9
+ */
10
+ rules: {
11
+ /**
12
+ * P0: 提交主题必须以小写字母开头
13
+ */
14
+ "subject-case": [2, "always", "lower-case"],
15
+ /**
16
+ * P0: 提交头信息最大长度为 72 个字符
17
+ */
18
+ "header-max-length": [2, "always", 72],
19
+ /**
20
+ * P0: 提交主题结尾不能有句号
21
+ */
22
+ "subject-full-stop": [2, "never", "."],
23
+ /**
24
+ * P0: 提交正文每行最大长度为 72 个字符
25
+ */
26
+ "body-max-line-length": [2, "always", 72],
27
+ /**
28
+ * P0: 提交脚注每行最大长度为 72 个字符
29
+ */
30
+ "footer-max-line-length": [2, "always", 72],
31
+ /**
32
+ * 标准提交类型枚举
33
+ * 定义了允许的提交类型及其语义
34
+ */
35
+ "type-enum": [
36
+ 2,
37
+ "always",
38
+ [
39
+ "feat",
40
+ // 新功能
41
+ "fix",
42
+ // Bug 修复
43
+ "docs",
44
+ // 文档更新
45
+ "style",
46
+ // 代码格式(不影响代码运行的变更)
47
+ "refactor",
48
+ // 代码重构(既不是修复也不是新功能)
49
+ "perf",
50
+ // 性能优化
51
+ "test",
52
+ // 添加或修正测试
53
+ "build",
54
+ // 构建系统或外部依赖变更
55
+ "ci",
56
+ // CI 配置文件和脚本变更
57
+ "chore",
58
+ // 其他不修改 src 或 test 文件的变更
59
+ "revert"
60
+ // 回退之前的提交
61
+ ]
62
+ ]
63
+ },
64
+ /**
65
+ * 交互式提交提示配置
66
+ * 用于配置 commitizen 等工具的提示信息
67
+ */
68
+ prompt: {
69
+ /**
70
+ * 提示消息配置
71
+ */
72
+ messages: {
73
+ skip: "(\u6309\u56DE\u8F66\u8DF3\u8FC7)",
74
+ max: "\u6700\u591A %d \u4E2A\u5B57\u7B26",
75
+ min: "\u81F3\u5C11 %d \u4E2A\u5B57\u7B26",
76
+ empty: "\u4E0D\u80FD\u4E3A\u7A7A",
77
+ upper: "\u5927\u5199",
78
+ lower: "\u5C0F\u5199",
79
+ title: "\u63D0\u4EA4\u4FE1\u606F"
80
+ },
81
+ /**
82
+ * 提示问题配置
83
+ */
84
+ questions: {
85
+ /**
86
+ * 提交类型选择
87
+ */
88
+ type: {
89
+ description: "\u9009\u62E9\u63D0\u4EA4\u7C7B\u578B:",
90
+ enum: {
91
+ feat: {
92
+ description: "\u65B0\u529F\u80FD",
93
+ title: "\u529F\u80FD",
94
+ emoji: "\u2728"
95
+ },
96
+ fix: {
97
+ description: "Bug \u4FEE\u590D",
98
+ title: "\u4FEE\u590D",
99
+ emoji: "\u{1F41B}"
100
+ },
101
+ docs: {
102
+ description: "\u4EC5\u6587\u6863\u53D8\u66F4",
103
+ title: "\u6587\u6863",
104
+ emoji: "\u{1F4DA}"
105
+ },
106
+ style: {
107
+ description: "\u4E0D\u5F71\u54CD\u4EE3\u7801\u542B\u4E49\u7684\u53D8\u66F4\uFF08\u7A7A\u767D\u3001\u683C\u5F0F\u3001\u7F3A\u5C11\u5206\u53F7\u7B49\uFF09",
108
+ title: "\u683C\u5F0F",
109
+ emoji: "\u{1F48E}"
110
+ },
111
+ refactor: {
112
+ description: "\u65E2\u4E0D\u662F\u4FEE\u590D\u4E5F\u4E0D\u662F\u65B0\u529F\u80FD\u7684\u4EE3\u7801\u53D8\u66F4",
113
+ title: "\u91CD\u6784",
114
+ emoji: "\u{1F4E6}"
115
+ },
116
+ perf: {
117
+ description: "\u6027\u80FD\u4F18\u5316\u7684\u4EE3\u7801\u53D8\u66F4",
118
+ title: "\u6027\u80FD",
119
+ emoji: "\u{1F680}"
120
+ },
121
+ test: {
122
+ description: "\u6DFB\u52A0\u7F3A\u5931\u7684\u6D4B\u8BD5\u6216\u4FEE\u6B63\u73B0\u6709\u6D4B\u8BD5",
123
+ title: "\u6D4B\u8BD5",
124
+ emoji: "\u{1F6A8}"
125
+ },
126
+ build: {
127
+ description: "\u5F71\u54CD\u6784\u5EFA\u7CFB\u7EDF\u6216\u5916\u90E8\u4F9D\u8D56\u7684\u53D8\u66F4\uFF08\u4F8B\u5982\uFF1Agulp\u3001broccoli\u3001npm\uFF09",
128
+ title: "\u6784\u5EFA",
129
+ emoji: "\u{1F6E0}"
130
+ },
131
+ ci: {
132
+ description: "CI \u914D\u7F6E\u6587\u4EF6\u548C\u811A\u672C\u7684\u53D8\u66F4\uFF08\u4F8B\u5982\uFF1ATravis\u3001Circle\u3001BrowserStack\u3001SauceLabs\uFF09",
133
+ title: "CI",
134
+ emoji: "\u2699\uFE0F"
135
+ },
136
+ chore: {
137
+ description: "\u4E0D\u4FEE\u6539 src \u6216 test \u6587\u4EF6\u7684\u5176\u4ED6\u53D8\u66F4",
138
+ title: "\u6742\u9879",
139
+ emoji: "\u267B\uFE0F"
140
+ },
141
+ revert: {
142
+ description: "\u56DE\u9000\u4E4B\u524D\u7684\u63D0\u4EA4",
143
+ title: "\u56DE\u9000",
144
+ emoji: "\u{1F5D1}"
145
+ }
146
+ }
147
+ },
148
+ /**
149
+ * 提交范围输入
150
+ */
151
+ scope: {
152
+ description: "\u63D0\u4EA4\u7684\u5F71\u54CD\u8303\u56F4\uFF08\u4F8B\u5982\uFF1A\u7EC4\u4EF6\u6216\u6587\u4EF6\u540D\uFF09:"
153
+ },
154
+ /**
155
+ * 提交主题输入
156
+ */
157
+ subject: {
158
+ description: "\u7B80\u77ED\u63CF\u8FF0\u53D8\u66F4\u5185\u5BB9\uFF08\u7948\u4F7F\u53E5\uFF09:"
159
+ },
160
+ /**
161
+ * 提交正文输入
162
+ */
163
+ body: {
164
+ description: "\u63D0\u4F9B\u53D8\u66F4\u7684\u8BE6\u7EC6\u63CF\u8FF0:"
165
+ },
166
+ /**
167
+ * 是否有重大变更
168
+ */
169
+ isBreaking: {
170
+ description: "\u662F\u5426\u6709\u91CD\u5927\u53D8\u66F4\uFF1F"
171
+ },
172
+ /**
173
+ * 重大变更正文输入
174
+ */
175
+ breakingBody: {
176
+ description: "\u91CD\u5927\u53D8\u66F4\u63D0\u4EA4\u9700\u8981\u6B63\u6587\u3002\u8BF7\u8F93\u5165\u63D0\u4EA4\u7684\u8BE6\u7EC6\u63CF\u8FF0:"
177
+ },
178
+ /**
179
+ * 重大变更描述输入
180
+ */
181
+ breaking: {
182
+ description: "\u63CF\u8FF0\u91CD\u5927\u53D8\u66F4:"
183
+ },
184
+ /**
185
+ * 是否影响未解决的问题
186
+ */
187
+ isIssueAffected: {
188
+ description: "\u6B64\u53D8\u66F4\u662F\u5426\u5F71\u54CD\u672A\u89E3\u51B3\u7684\u95EE\u9898\uFF1F"
189
+ },
190
+ /**
191
+ * 问题关联正文输入
192
+ */
193
+ issuesBody: {
194
+ description: "\u5982\u679C\u5173\u95ED\u4E86\u95EE\u9898\uFF0C\u63D0\u4EA4\u9700\u8981\u6B63\u6587\u3002\u8BF7\u8F93\u5165\u63D0\u4EA4\u7684\u8BE6\u7EC6\u63CF\u8FF0:"
195
+ },
196
+ /**
197
+ * 问题关联输入
198
+ */
199
+ issues: {
200
+ description: '\u6DFB\u52A0\u95EE\u9898\u5F15\u7528\uFF08\u4F8B\u5982\uFF1A"fix #123"\u3001"re #123"\uFF09:'
201
+ }
202
+ }
203
+ }
204
+ };
205
+
206
+ export { Configuration as default };
package/dist/index.cjs CHANGED
@@ -1,73 +1,12 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
3
+ const lintStaged = require('./lint-staged.cjs');
4
+ const commitlint = require('./commitlint.cjs');
5
+ require('node:fs');
6
+ require('node:path');
4
7
 
5
- const types = {
6
- feat: "\u2728 \u65B0\u529F\u80FD",
7
- fix: "\u{1F41B} \u4FEE\u590D Bug",
8
- docs: "\u{1F4DA} \u6587\u6863\u66F4\u65B0",
9
- style: "\u{1F484} \u4EE3\u7801\u683C\u5F0F\uFF08\u4E0D\u5F71\u54CD\u903B\u8F91\uFF09",
10
- refactor: "\u267B\uFE0F \u91CD\u6784\u4EE3\u7801\uFF08\u4E0D\u5F71\u54CD\u529F\u80FD\uFF09",
11
- perf: "\u26A1 \u6027\u80FD\u4F18\u5316",
12
- test: "\u{1F9EA} \u6D4B\u8BD5\u76F8\u5173",
13
- chore: "\u{1F527} \u5DE5\u5177\u6216\u811A\u624B\u67B6\u53D8\u66F4",
14
- ci: "\u2699\uFE0F CI/CD \u76F8\u5173",
15
- build: "\u{1F6E0} \u6784\u5EFA\u7CFB\u7EDF\u6216\u5916\u90E8\u4F9D\u8D56\u53D8\u66F4",
16
- revert: "\u23EA \u56DE\u6EDA\u63D0\u4EA4",
17
- update: "\u2B06\uFE0F \u66F4\u65B0\u67D0\u529F\u80FD\uFF08\u975E\u65B0\u529F\u80FD/\u975E\u4FEE\u590D\uFF09"
18
- };
19
- const allowTypes = Object.keys(types);
20
- const rule$2 = (parsed, when, value) => {
21
- const type = parsed.type;
22
- if (!type) {
23
- return [false, "\u2716 \u8BF7\u586B\u5199\u63D0\u4EA4\u7C7B\u578B\uFF08\u5982 feat / fix / docs\uFF09"];
24
- }
25
- if (!allowTypes.includes(type)) {
26
- const list = allowTypes.map((k) => `- ${k}: ${types[k]}`).join("\n");
27
- return [false, `\u2716 \u63D0\u4EA4\u7C7B\u578B\u4E0D\u5408\u6CD5\uFF0C\u8BF7\u4ECE\u4EE5\u4E0B\u7C7B\u578B\u4E2D\u9009\u62E9\uFF1A
28
- ${list}`];
29
- }
30
- return [true];
31
- };
32
8
 
33
- const rule$1 = (parsed) => {
34
- const subject = parsed.subject?.trim();
35
- if (!subject) {
36
- return [false, "\u2716 \u63D0\u4EA4\u63CF\u8FF0\uFF08subject\uFF09\u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u8BF7\u8865\u5145\u4E00\u53E5\u6E05\u6670\u63CF\u8FF0"];
37
- }
38
- return [true];
39
- };
40
9
 
41
- const rule = (parsed, _when, value = 120) => {
42
- const header = parsed.header || "";
43
- if (header.length > value) {
44
- return [false, `\u2716 \u63D0\u4EA4\u4FE1\u606F\u8FC7\u957F\uFF08\u5F53\u524D ${header.length} \u5B57\u7B26\uFF09\uFF0C\u6700\u5927\u5141\u8BB8 ${value} \u5B57\u7B26`];
45
- }
46
- return [true];
47
- };
48
-
49
- const rules = {
50
- "zh-type-enum": rule$2,
51
- "zh-subject-empty": rule$1,
52
- "zh-header-max-length": rule
53
- };
54
- const plugin = {
55
- rules
56
- };
57
- const config = {
58
- plugins: ["@huaiyou/hooks-git"],
59
- rules: {
60
- "zh-type-enum": [2, "always"],
61
- "zh-subject-empty": [2, "always"],
62
- "zh-header-max-length": [2, "always", 72],
63
- // Disable standard rules that we are replacing or don't need
64
- "type-enum": [0],
65
- "type-empty": [0],
66
- "subject-empty": [0],
67
- "header-max-length": [0]
68
- }
69
- };
70
-
71
- exports.config = config;
72
- exports.default = plugin;
73
- exports.rules = rules;
10
+ exports.createLintStagedConfig = lintStaged.createLintStagedConfig;
11
+ exports.lintStagedConfig = lintStaged.default;
12
+ exports.commitlintConfig = commitlint;
@@ -0,0 +1,3 @@
1
+ export { createLintStagedConfig, default as lintStagedConfig } from './lint-staged.cjs';
2
+ export { default as commitlintConfig } from './commitlint.cjs';
3
+ import '@commitlint/types';
@@ -0,0 +1,3 @@
1
+ export { createLintStagedConfig, default as lintStagedConfig } from './lint-staged.mjs';
2
+ export { default as commitlintConfig } from './commitlint.mjs';
3
+ import '@commitlint/types';
@@ -0,0 +1,3 @@
1
+ export { createLintStagedConfig, default as lintStagedConfig } from './lint-staged.js';
2
+ export { default as commitlintConfig } from './commitlint.js';
3
+ import '@commitlint/types';
package/dist/index.mjs ADDED
@@ -0,0 +1,4 @@
1
+ export { createLintStagedConfig, default as lintStagedConfig } from './lint-staged.mjs';
2
+ export { default as commitlintConfig } from './commitlint.mjs';
3
+ import 'node:fs';
4
+ import 'node:path';
@@ -0,0 +1,48 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const node_fs = require('node:fs');
6
+ const node_path = require('node:path');
7
+
8
+ const isPackageExists = (name) => {
9
+ try {
10
+ const packageJsonPath = node_path.resolve(process.cwd(), "package.json");
11
+ if (!node_fs.existsSync(packageJsonPath)) return false;
12
+ const packageJson = JSON.parse(node_fs.readFileSync(packageJsonPath, "utf-8"));
13
+ return packageJson.dependencies && packageJson.dependencies[name] || packageJson.devDependencies && packageJson.devDependencies[name];
14
+ } catch {
15
+ return false;
16
+ }
17
+ };
18
+ const createLintStagedConfig = () => {
19
+ const hasEslint = isPackageExists("eslint");
20
+ const hasPrettier = isPackageExists("prettier");
21
+ const hasStylelint = isPackageExists("stylelint");
22
+ const config = {};
23
+ const scripts = [];
24
+ if (hasEslint) scripts.push("eslint --fix");
25
+ if (hasPrettier) scripts.push("prettier --write");
26
+ if (scripts.length > 0) {
27
+ config["*.{js,jsx,ts,tsx}"] = scripts;
28
+ }
29
+ const vueScripts = [...scripts];
30
+ if (hasStylelint) vueScripts.push("stylelint --fix");
31
+ if (vueScripts.length > 0) {
32
+ config["*.vue"] = vueScripts;
33
+ }
34
+ const styleScripts = [];
35
+ if (hasStylelint) styleScripts.push("stylelint --fix");
36
+ if (hasPrettier) styleScripts.push("prettier --write");
37
+ if (styleScripts.length > 0) {
38
+ config["*.{css,scss,less}"] = styleScripts;
39
+ }
40
+ if (hasPrettier) {
41
+ config["*.{html,json,md,yml,yaml}"] = ["prettier --write"];
42
+ }
43
+ return config;
44
+ };
45
+ const lintStaged = createLintStagedConfig();
46
+
47
+ exports.createLintStagedConfig = createLintStagedConfig;
48
+ exports.default = lintStaged;
@@ -0,0 +1,6 @@
1
+ declare const createLintStagedConfig: () => Record<string, string[]>;
2
+ declare const _default: Record<string, string[]>;
3
+
4
+ // @ts-ignore
5
+ export = _default;
6
+ export { createLintStagedConfig };
@@ -0,0 +1,4 @@
1
+ declare const createLintStagedConfig: () => Record<string, string[]>;
2
+ declare const _default: Record<string, string[]>;
3
+
4
+ export { createLintStagedConfig, _default as default };
@@ -0,0 +1,6 @@
1
+ declare const createLintStagedConfig: () => Record<string, string[]>;
2
+ declare const _default: Record<string, string[]>;
3
+
4
+ // @ts-ignore
5
+ export = _default;
6
+ export { createLintStagedConfig };
@@ -0,0 +1,43 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+
4
+ const isPackageExists = (name) => {
5
+ try {
6
+ const packageJsonPath = resolve(process.cwd(), "package.json");
7
+ if (!existsSync(packageJsonPath)) return false;
8
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
9
+ return packageJson.dependencies && packageJson.dependencies[name] || packageJson.devDependencies && packageJson.devDependencies[name];
10
+ } catch {
11
+ return false;
12
+ }
13
+ };
14
+ const createLintStagedConfig = () => {
15
+ const hasEslint = isPackageExists("eslint");
16
+ const hasPrettier = isPackageExists("prettier");
17
+ const hasStylelint = isPackageExists("stylelint");
18
+ const config = {};
19
+ const scripts = [];
20
+ if (hasEslint) scripts.push("eslint --fix");
21
+ if (hasPrettier) scripts.push("prettier --write");
22
+ if (scripts.length > 0) {
23
+ config["*.{js,jsx,ts,tsx}"] = scripts;
24
+ }
25
+ const vueScripts = [...scripts];
26
+ if (hasStylelint) vueScripts.push("stylelint --fix");
27
+ if (vueScripts.length > 0) {
28
+ config["*.vue"] = vueScripts;
29
+ }
30
+ const styleScripts = [];
31
+ if (hasStylelint) styleScripts.push("stylelint --fix");
32
+ if (hasPrettier) styleScripts.push("prettier --write");
33
+ if (styleScripts.length > 0) {
34
+ config["*.{css,scss,less}"] = styleScripts;
35
+ }
36
+ if (hasPrettier) {
37
+ config["*.{html,json,md,yml,yaml}"] = ["prettier --write"];
38
+ }
39
+ return config;
40
+ };
41
+ const lintStaged = createLintStagedConfig();
42
+
43
+ export { createLintStagedConfig, lintStaged as default };
package/package.json CHANGED
@@ -1,45 +1,68 @@
1
1
  {
2
2
  "name": "@huaiyou/hooks-git",
3
- "version": "1.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Git hooks configuration with Husky, Commitlint and Lint-staged",
5
+ "bin": {
6
+ "hy-hooks-git": "./dist/cli.mjs"
7
+ },
5
8
  "files": [
6
- ".husky",
7
- "*.config.js",
9
+ "dist",
10
+ "bin",
8
11
  "README.md",
9
12
  "CHANGELOG.md"
10
13
  ],
11
14
  "main": "./dist/index.cjs",
12
15
  "module": "./dist/index.mjs",
16
+ "types": "./dist/index.d.ts",
13
17
  "exports": {
14
18
  ".": {
15
19
  "require": "./dist/index.cjs",
16
- "import": "./dist/index.mjs"
20
+ "import": "./dist/index.mjs",
21
+ "types": "./dist/index.d.ts"
22
+ },
23
+ "./commitlint": {
24
+ "require": "./dist/commitlint.cjs",
25
+ "import": "./dist/commitlint.mjs",
26
+ "types": "./dist/commitlint.d.ts"
27
+ },
28
+ "./lint-staged": {
29
+ "require": "./dist/lint-staged.cjs",
30
+ "import": "./dist/lint-staged.mjs",
31
+ "types": "./dist/lint-staged.d.ts"
17
32
  }
18
33
  },
19
- "devDependencies": {
20
- "@commitlint/types": "^19.8.1",
21
- "@types/minimatch": "^6.0.0",
22
- "typescript": "^5.9.3",
23
- "unbuild": "^3.6.1",
24
- "undici-types": "^7.16.0",
25
- "vitest": "^2.1.8",
26
- "@huaiyou/config-ts": "^1.0.0"
34
+ "scripts": {
35
+ "build": "unbuild",
36
+ "dev": "unbuild --stub",
37
+ "test": "vitest run",
38
+ "test:watch": "vitest",
39
+ "test:ui": "vitest --ui",
40
+ "prepublishOnly": "npm run build"
27
41
  },
28
42
  "dependencies": {
29
- "minimatch": "^10.1.1"
43
+ "@commitlint/cli": "^19.3.0",
44
+ "@commitlint/config-conventional": "^19.2.2",
45
+ "cac": "^6.7.14",
46
+ "consola": "^3.2.3",
47
+ "execa": "^8.0.1",
48
+ "fs-extra": "^11.2.0",
49
+ "husky": "^9.0.11",
50
+ "lint-staged": "^15.2.2",
51
+ "minimatch": "^10.1.1",
52
+ "picocolors": "^1.0.0"
30
53
  },
31
- "peerDependencies": {
32
- "@commitlint/lint": ">=7.6.0"
54
+ "devDependencies": {
55
+ "@commitlint/types": "^19.0.3",
56
+ "@huaiyou/config-ts": "workspace:^",
57
+ "@types/fs-extra": "^11.0.4",
58
+ "@types/minimatch": "^6.0.0",
59
+ "@types/node": "^20.12.7",
60
+ "typescript": "^5.4.5",
61
+ "unbuild": "^3.6.1",
62
+ "vitest": "catalog:"
33
63
  },
34
64
  "publishConfig": {
35
65
  "access": "public",
36
66
  "registry": "https://registry.npmjs.org/"
37
- },
38
- "scripts": {
39
- "build": "unbuild",
40
- "dev": "unbuild --stub",
41
- "test": "vitest run",
42
- "test:watch": "vitest",
43
- "test:ui": "vitest --ui"
44
67
  }
45
- }
68
+ }
package/.husky/commit-msg DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env sh
2
- . "$(dirname -- "$0")/_/husky.sh"
3
-
4
- pnpm commitlint --edit $1
package/.husky/pre-commit DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env sh
2
- . "$(dirname -- "$0")/_/husky.sh"
3
-
4
- pnpm lint-staged