@apdesign/code-style-react 1.0.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/.eslintrc.build.js +91 -0
- package/.eslintrc.js +91 -0
- package/.prettierrc.js +11 -0
- package/.stylelintrc.js +23 -0
- package/README.md +0 -0
- package/husky/_/h +27 -0
- package/husky/_/pre-commit +2 -0
- package/husky/_/pre-push +2 -0
- package/husky/pre-commit +2 -0
- package/husky/pre-push +25 -0
- package/index.js +13 -0
- package/package.json +39 -0
- package/scripts/buildEslint.sh +23 -0
- package/scripts/buildStylelint.sh +24 -0
- package/scripts/initConfigs.js +98 -0
- package/scripts/initHusky.js +33 -0
- package/scripts/initScripts.js +36 -0
@@ -0,0 +1,91 @@
|
|
1
|
+
module.exports = {
|
2
|
+
root: true,
|
3
|
+
env: {
|
4
|
+
browser: true,
|
5
|
+
node: true,
|
6
|
+
es2021: true,
|
7
|
+
},
|
8
|
+
parser: '@typescript-eslint/parser',
|
9
|
+
extends: [
|
10
|
+
'airbnb',
|
11
|
+
'airbnb/hooks',
|
12
|
+
'plugin:@typescript-eslint/recommended',
|
13
|
+
'plugin:import/errors',
|
14
|
+
'plugin:import/warnings',
|
15
|
+
'prettier',
|
16
|
+
],
|
17
|
+
plugins: ['@typescript-eslint', 'import', 'jsx-a11y', 'react', 'react-hooks'],
|
18
|
+
rules: {
|
19
|
+
'arrow-body-style': 'off',
|
20
|
+
|
21
|
+
camelcase: 'off',
|
22
|
+
'class-methods-use-this': 'off',
|
23
|
+
|
24
|
+
'import/first': 'off',
|
25
|
+
'import/extensions': 'off',
|
26
|
+
'import/prefer-default-export': 'off',
|
27
|
+
|
28
|
+
'jsx-a11y/click-events-have-key-events': 'off',
|
29
|
+
'jsx-a11y/no-static-element-interactions': 'off',
|
30
|
+
'jsx-a11y/no-noninteractive-element-interactions': 'off',
|
31
|
+
|
32
|
+
'linebreak-style': 'off',
|
33
|
+
|
34
|
+
'max-classes-per-file': 'off',
|
35
|
+
|
36
|
+
'no-undef': 'off',
|
37
|
+
'no-plusplus': 'off',
|
38
|
+
|
39
|
+
'react/function-component-definition': 'off',
|
40
|
+
'react-hooks/exhaustive-deps': 'off',
|
41
|
+
'react/prop-types': 'off',
|
42
|
+
'react/react-in-jsx-scope': 'off',
|
43
|
+
'react/require-default-props': 'off',
|
44
|
+
'react/jsx-boolean-value': 'off',
|
45
|
+
'react/jsx-filename-extension': 'off',
|
46
|
+
'react/jsx-props-no-spreading': 'off',
|
47
|
+
'react/self-closing-comp': 'off',
|
48
|
+
'react/jsx-no-useless-fragment': 'off',
|
49
|
+
|
50
|
+
'no-unused-vars': 'off',
|
51
|
+
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
|
52
|
+
|
53
|
+
'no-useless-constructor': 'off',
|
54
|
+
'@typescript-eslint/no-useless-constructor': 'warn',
|
55
|
+
|
56
|
+
'no-shadow': 'off',
|
57
|
+
'@typescript-eslint/no-shadow': 'warn',
|
58
|
+
|
59
|
+
'no-empty-function': ['warn', { allow: ['constructors'] }],
|
60
|
+
'no-param-reassign': ['warn', { props: true, ignorePropertyModificationsFor: ['draft'] }],
|
61
|
+
'no-restricted-syntax': [
|
62
|
+
'warn',
|
63
|
+
{
|
64
|
+
selector: "CallExpression[callee.name='useMemo']",
|
65
|
+
message: 'Avoid using useMemo unless caching a computed value improves performance.',
|
66
|
+
},
|
67
|
+
{
|
68
|
+
selector: "CallExpression[callee.name='useCallback']",
|
69
|
+
message:
|
70
|
+
'Avoid using useCallback unless you need to cache a function to prevent unnecessary re-renders.',
|
71
|
+
},
|
72
|
+
],
|
73
|
+
},
|
74
|
+
parserOptions: {
|
75
|
+
sourceType: 'module',
|
76
|
+
},
|
77
|
+
ignorePatterns: ['dist/', 'node_modules/', '*.d.ts', 'mock', '.eslintrc.cjs'],
|
78
|
+
settings: {
|
79
|
+
react: {
|
80
|
+
version: 'detect',
|
81
|
+
},
|
82
|
+
'import/resolver': {
|
83
|
+
alias: {
|
84
|
+
map: [
|
85
|
+
['@', './src'], // 将 '@' 映射到 'src' 目录
|
86
|
+
],
|
87
|
+
extensions: ['.ts', '.tsx', '.js', '.jsx', '.d.ts'],
|
88
|
+
},
|
89
|
+
},
|
90
|
+
},
|
91
|
+
};
|
package/.eslintrc.js
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
module.exports = {
|
2
|
+
root: true,
|
3
|
+
env: {
|
4
|
+
browser: true,
|
5
|
+
node: true,
|
6
|
+
es2021: true,
|
7
|
+
},
|
8
|
+
parser: '@typescript-eslint/parser',
|
9
|
+
extends: [
|
10
|
+
'airbnb',
|
11
|
+
'airbnb/hooks',
|
12
|
+
'plugin:@typescript-eslint/recommended',
|
13
|
+
'plugin:import/errors',
|
14
|
+
'plugin:import/warnings',
|
15
|
+
'prettier',
|
16
|
+
],
|
17
|
+
plugins: ['@typescript-eslint', 'import', 'jsx-a11y', 'react', 'react-hooks'],
|
18
|
+
rules: {
|
19
|
+
'arrow-body-style': 'off',
|
20
|
+
|
21
|
+
camelcase: 'off',
|
22
|
+
'class-methods-use-this': 'off',
|
23
|
+
|
24
|
+
'import/first': 'off',
|
25
|
+
'import/extensions': 'off',
|
26
|
+
'import/prefer-default-export': 'off',
|
27
|
+
|
28
|
+
'jsx-a11y/click-events-have-key-events': 'off',
|
29
|
+
'jsx-a11y/no-static-element-interactions': 'off',
|
30
|
+
'jsx-a11y/no-noninteractive-element-interactions': 'off',
|
31
|
+
|
32
|
+
'linebreak-style': 'off',
|
33
|
+
|
34
|
+
'max-classes-per-file': 'off',
|
35
|
+
|
36
|
+
'no-undef': 'off',
|
37
|
+
'no-plusplus': 'off',
|
38
|
+
|
39
|
+
'react/function-component-definition': 'off',
|
40
|
+
'react-hooks/exhaustive-deps': 'off',
|
41
|
+
'react/prop-types': 'off',
|
42
|
+
'react/react-in-jsx-scope': 'off',
|
43
|
+
'react/require-default-props': 'off',
|
44
|
+
'react/jsx-boolean-value': 'off',
|
45
|
+
'react/jsx-filename-extension': 'off',
|
46
|
+
'react/jsx-props-no-spreading': 'off',
|
47
|
+
'react/self-closing-comp': 'off',
|
48
|
+
'react/jsx-no-useless-fragment': 'off',
|
49
|
+
|
50
|
+
'no-unused-vars': 'off',
|
51
|
+
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
|
52
|
+
|
53
|
+
'no-useless-constructor': 'off',
|
54
|
+
'@typescript-eslint/no-useless-constructor': 'error',
|
55
|
+
|
56
|
+
'no-shadow': 'off',
|
57
|
+
'@typescript-eslint/no-shadow': 'error',
|
58
|
+
|
59
|
+
'no-empty-function': ['error', { allow: ['constructors'] }],
|
60
|
+
'no-param-reassign': ['error', { props: true, ignorePropertyModificationsFor: ['draft'] }],
|
61
|
+
'no-restricted-syntax': [
|
62
|
+
'warn',
|
63
|
+
{
|
64
|
+
selector: "CallExpression[callee.name='useMemo']",
|
65
|
+
message: 'Avoid using useMemo unless caching a computed value improves performance.',
|
66
|
+
},
|
67
|
+
{
|
68
|
+
selector: "CallExpression[callee.name='useCallback']",
|
69
|
+
message:
|
70
|
+
'Avoid using useCallback unless you need to cache a function to prevent unnecessary re-renders.',
|
71
|
+
},
|
72
|
+
],
|
73
|
+
},
|
74
|
+
parserOptions: {
|
75
|
+
sourceType: 'module',
|
76
|
+
},
|
77
|
+
ignorePatterns: ['dist/', 'node_modules/', '*.d.ts', 'mock', '.eslintrc.cjs'],
|
78
|
+
settings: {
|
79
|
+
react: {
|
80
|
+
version: 'detect',
|
81
|
+
},
|
82
|
+
'import/resolver': {
|
83
|
+
alias: {
|
84
|
+
map: [
|
85
|
+
['@', './src'], // 将 '@' 映射到 'src' 目录
|
86
|
+
],
|
87
|
+
extensions: ['.ts', '.tsx', '.js', '.jsx', '.d.ts'],
|
88
|
+
},
|
89
|
+
},
|
90
|
+
},
|
91
|
+
};
|
package/.prettierrc.js
ADDED
package/.stylelintrc.js
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module.exports = {
|
2
|
+
extends: ['stylelint-config-standard'],
|
3
|
+
plugins: ['stylelint-less', 'stylelint-scss'],
|
4
|
+
overrides: [
|
5
|
+
{
|
6
|
+
files: ['**/*.less'],
|
7
|
+
customSyntax: 'postcss-less',
|
8
|
+
},
|
9
|
+
{
|
10
|
+
files: ['**/*.scss', '**/*.sass'],
|
11
|
+
customSyntax: 'postcss-less',
|
12
|
+
},
|
13
|
+
],
|
14
|
+
rules: {
|
15
|
+
'selector-class-pattern': '^[a-z][a-zA-Z0-9-]*$',
|
16
|
+
'selector-pseudo-class-no-unknown': [
|
17
|
+
true,
|
18
|
+
{
|
19
|
+
ignorePseudoClasses: ['global'],
|
20
|
+
},
|
21
|
+
],
|
22
|
+
},
|
23
|
+
};
|
package/README.md
ADDED
File without changes
|
package/husky/_/h
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env sh
|
2
|
+
[ "$HUSKY" = "2" ] && set -x
|
3
|
+
n=$(basename "$0")
|
4
|
+
s=$(dirname "$(dirname "$0")")/$n
|
5
|
+
|
6
|
+
if [[ "$(uname)" == "Darwin" ]]; then
|
7
|
+
elif [[ "$(uname -o)" == "Msys" || "$(uname)" == "CYGWIN" || "$(uname)" == "MINGW"* ]]; then
|
8
|
+
sed -i 's/\r//' "$0"
|
9
|
+
fi
|
10
|
+
|
11
|
+
[ ! -f "$s" ] && exit 0
|
12
|
+
|
13
|
+
if [ -f "$HOME/.huskyrc" ]; then
|
14
|
+
echo "husky - '~/.huskyrc' is DEPRECATED, please move your code to ~/.config/husky/init.sh"
|
15
|
+
fi
|
16
|
+
i="${XDG_CONFIG_HOME:-$HOME/.config}/husky/init.sh"
|
17
|
+
[ -f "$i" ] && . "$i"
|
18
|
+
|
19
|
+
[ "${HUSKY-}" = "0" ] && exit 0
|
20
|
+
|
21
|
+
export PATH="node_modules/.bin:$PATH"
|
22
|
+
sh -e "$s" "$@"
|
23
|
+
c=$?
|
24
|
+
|
25
|
+
[ $c != 0 ] && echo "husky - $n script failed (code $c)"
|
26
|
+
[ $c = 127 ] && echo "husky - command not found in PATH=$PATH"
|
27
|
+
exit $c
|
package/husky/_/pre-push
ADDED
package/husky/pre-commit
ADDED
package/husky/pre-push
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env sh
|
2
|
+
branch_name=$(git symbolic-ref --short HEAD)
|
3
|
+
|
4
|
+
branch_regex_master="^master$"
|
5
|
+
branch_regex_env="^(master|uat|dev)-[a-z]+$"
|
6
|
+
branch_regex_feature="^(feature|test|hotfix)-[a-z]+-[a-zA-Z0-9]+(-[A-Z]+[0-9]+)?$"
|
7
|
+
branch_regex_release="^release-[a-z]+-[0-9]{8}$"
|
8
|
+
|
9
|
+
if echo "$branch_name" | grep -Eq "$branch_regex_master"; then
|
10
|
+
exit 0
|
11
|
+
elif echo "$branch_name" | grep -Eq "$branch_regex_env"; then
|
12
|
+
exit 0
|
13
|
+
elif echo "$branch_name" | grep -Eq "$branch_regex_feature"; then
|
14
|
+
exit 0
|
15
|
+
elif echo "$branch_name" | grep -Eq "$branch_regex_release"; then
|
16
|
+
exit 0
|
17
|
+
else
|
18
|
+
echo -e "❌ \033[31m[ERROR] 当前分支名 '$branch_name' 不符合规范!\033[0m"
|
19
|
+
echo "分支命名规范要求如下:"
|
20
|
+
echo "✅ master"
|
21
|
+
echo "✅ master|uat|dev-[小写字母]"
|
22
|
+
echo "✅ feature|test|hotfix-[小写字母]+-[字母或数字]+(可选 -大写字母+数字)"
|
23
|
+
echo "✅ release-[小写字母]+-8位日期"
|
24
|
+
exit 1
|
25
|
+
fi
|
package/index.js
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
const initHusky = require('./scripts/initHusky');
|
4
|
+
const initScripts = require('./scripts/initScripts');
|
5
|
+
const initConfigs = require('./scripts/initConfigs');
|
6
|
+
|
7
|
+
function main() {
|
8
|
+
initHusky();
|
9
|
+
initScripts();
|
10
|
+
initConfigs();
|
11
|
+
}
|
12
|
+
|
13
|
+
main();
|
package/package.json
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
{
|
2
|
+
"name": "@apdesign/code-style-react",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"scripts": {},
|
5
|
+
"files": [
|
6
|
+
"index.js",
|
7
|
+
".prettierrc.js",
|
8
|
+
".eslintrc.js",
|
9
|
+
".eslintrc.build.js",
|
10
|
+
".stylelintrc.js",
|
11
|
+
"husky",
|
12
|
+
"scripts"
|
13
|
+
],
|
14
|
+
"keywords": [],
|
15
|
+
"author": "",
|
16
|
+
"license": "ISC",
|
17
|
+
"description": "",
|
18
|
+
"dependencies": {
|
19
|
+
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
20
|
+
"@typescript-eslint/parser": "^6.21.0",
|
21
|
+
"eslint": "^8.57.1",
|
22
|
+
"eslint-config-airbnb": "^19.0.4",
|
23
|
+
"eslint-config-prettier": "^9.1.0",
|
24
|
+
"eslint-import-resolver-alias": "^1.1.2",
|
25
|
+
"eslint-plugin-import": "^2.31.0",
|
26
|
+
"eslint-plugin-jsx-a11y": "^6.10.2",
|
27
|
+
"eslint-plugin-prettier": "^5.2.1",
|
28
|
+
"eslint-plugin-react": "^7.37.2",
|
29
|
+
"eslint-plugin-react-hooks": "^4.6.2",
|
30
|
+
"husky": "^9.1.7",
|
31
|
+
"lint-staged": "^15.3.0",
|
32
|
+
"postcss-less": "^6.0.0",
|
33
|
+
"prettier": "^3.3.3",
|
34
|
+
"stylelint": "^16.19.1",
|
35
|
+
"stylelint-config-standard": "^38.0.0",
|
36
|
+
"stylelint-less": "^3.0.1",
|
37
|
+
"stylelint-scss": "^6.12.0"
|
38
|
+
}
|
39
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env sh
|
2
|
+
echo "🔍 Starting ESLint check (Git diff files only)..."
|
3
|
+
|
4
|
+
DIFF_FILES=$(git diff --name-only origin/master...HEAD -- '*.ts' '*.tsx' '*.js' '*.jsx')
|
5
|
+
|
6
|
+
if [ -z "$DIFF_FILES" ]; then
|
7
|
+
echo "✅ No matching file changes detected, skipping ESLint check"
|
8
|
+
exit 0
|
9
|
+
fi
|
10
|
+
|
11
|
+
echo "📂 Changed files:"
|
12
|
+
echo "$DIFF_FILES"
|
13
|
+
|
14
|
+
npx eslint --config .eslintrc.build.cjs $DIFF_FILES \
|
15
|
+
--no-error-on-unmatched-pattern \
|
16
|
+
--report-unused-disable-directives
|
17
|
+
|
18
|
+
if [ $? -ne 0 ]; then
|
19
|
+
echo "❌ ESLint check failed. Aborting build process"
|
20
|
+
exit 1
|
21
|
+
fi
|
22
|
+
|
23
|
+
echo "✅ ESLint check passed"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env sh
|
2
|
+
echo "🔍 Starting Stylelint check (Git diff files only)..."
|
3
|
+
|
4
|
+
DIFF_FILES=$(git diff --name-only origin/master...HEAD -- '*.css' '*.scss' '*.sass' '*.less')
|
5
|
+
|
6
|
+
if [ -z "$DIFF_FILES" ]; then
|
7
|
+
echo "✅ No style file changes detected, skipping Stylelint check"
|
8
|
+
exit 0
|
9
|
+
fi
|
10
|
+
|
11
|
+
echo "📂 Changed files:"
|
12
|
+
echo "$DIFF_FILES"
|
13
|
+
|
14
|
+
npx stylelint $DIFF_FILES \
|
15
|
+
--allow-empty-input \
|
16
|
+
--report-needless-disables \
|
17
|
+
--report-invalid-scope-disables
|
18
|
+
|
19
|
+
if [ $? -ne 0 ]; then
|
20
|
+
echo "❌ Stylelint check failed. Aborting build process"
|
21
|
+
exit 1
|
22
|
+
fi
|
23
|
+
|
24
|
+
echo "✅ Stylelint check passed"
|
@@ -0,0 +1,98 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
const fs = require('fs');
|
4
|
+
const path = require('path');
|
5
|
+
|
6
|
+
function fileExists(filepath) {
|
7
|
+
try {
|
8
|
+
return fs.existsSync(filepath);
|
9
|
+
} catch (err) {
|
10
|
+
console.error(`❌ Check whether there are any errors in the file: ${filepath}`, err);
|
11
|
+
return false;
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
function createIfNotExists(filename, content) {
|
16
|
+
const filepath = path.resolve(process.cwd(), filename);
|
17
|
+
try {
|
18
|
+
if (!fs.existsSync(filepath)) {
|
19
|
+
fs.writeFileSync(filepath, content, { encoding: 'utf-8' });
|
20
|
+
console.log(`✅ The ${filename} has been created`);
|
21
|
+
}
|
22
|
+
} catch (err) {
|
23
|
+
console.error(`❌ Failed to create the file: ${filename}`, err);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
function hasAnyFileExist(files) {
|
28
|
+
const cwd = process.cwd();
|
29
|
+
return files.some((file) => fileExists(path.join(cwd, file)));
|
30
|
+
}
|
31
|
+
|
32
|
+
function initConfigs() {
|
33
|
+
const eslintConfigFiles = [
|
34
|
+
'.eslintrc.js',
|
35
|
+
'.eslintrc.cjs',
|
36
|
+
'.eslintrc.json',
|
37
|
+
'.eslintrc.yaml',
|
38
|
+
'.eslintrc.yml',
|
39
|
+
'.eslintrc',
|
40
|
+
'eslint.config.js',
|
41
|
+
];
|
42
|
+
|
43
|
+
const stylelintConfigFiles = [
|
44
|
+
'.stylelintrc.js',
|
45
|
+
'.stylelintrc.cjs',
|
46
|
+
'.stylelintrc.json',
|
47
|
+
'.stylelintrc.yaml',
|
48
|
+
'.stylelintrc.yml',
|
49
|
+
'.stylelintrc',
|
50
|
+
'stylelint.config.js',
|
51
|
+
];
|
52
|
+
|
53
|
+
const prettierConfigFiles = [
|
54
|
+
'.prettierrc',
|
55
|
+
'.prettierrc.js',
|
56
|
+
'.prettierrc.cjs',
|
57
|
+
'.prettierrc.json',
|
58
|
+
'.prettierrc.yaml',
|
59
|
+
'.prettierrc.yml',
|
60
|
+
'prettier.config.js',
|
61
|
+
];
|
62
|
+
|
63
|
+
try {
|
64
|
+
if (!hasAnyFileExist(eslintConfigFiles)) {
|
65
|
+
const eslintContent = `const baseConfig = require('@apdesign/rule-react/.eslintrc.js');
|
66
|
+
module.exports = {
|
67
|
+
...baseConfig,
|
68
|
+
rules: {
|
69
|
+
...baseConfig.rules,
|
70
|
+
},
|
71
|
+
};`;
|
72
|
+
createIfNotExists('.eslintrc.cjs', eslintContent);
|
73
|
+
}
|
74
|
+
|
75
|
+
if (!hasAnyFileExist(stylelintConfigFiles)) {
|
76
|
+
const stylelintContent = `const baseConfig = require('@apdesign/rule-react/.stylelintrc.js');
|
77
|
+
module.exports = {
|
78
|
+
...baseConfig,
|
79
|
+
rules: {
|
80
|
+
...baseConfig.rules,
|
81
|
+
},
|
82
|
+
};`;
|
83
|
+
createIfNotExists('.stylelintrc.cjs', stylelintContent);
|
84
|
+
}
|
85
|
+
|
86
|
+
if (!hasAnyFileExist(prettierConfigFiles)) {
|
87
|
+
const prettierContent = `const baseConfig = require('@apdesign/rule-react/.prettierrc.js');
|
88
|
+
module.exports = {
|
89
|
+
...baseConfig
|
90
|
+
};`;
|
91
|
+
createIfNotExists('.prettierrc.cjs', prettierContent);
|
92
|
+
}
|
93
|
+
} catch (err) {
|
94
|
+
console.error('❌ Failed to initialize configuration:', err);
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
module.exports = initConfigs;
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
const fs = require('fs');
|
4
|
+
const path = require('path');
|
5
|
+
const { execSync } = require('child_process');
|
6
|
+
|
7
|
+
function initHusky() {
|
8
|
+
const projectRoot = process.cwd();
|
9
|
+
const huskyTarget = path.join(projectRoot, '.husky');
|
10
|
+
const huskySource = path.join(__dirname, '../husky');
|
11
|
+
|
12
|
+
try {
|
13
|
+
if (fs.existsSync(huskyTarget)) {
|
14
|
+
fs.rmSync(huskyTarget, { recursive: true, force: true });
|
15
|
+
}
|
16
|
+
fs.cpSync(huskySource, huskyTarget, { recursive: true });
|
17
|
+
|
18
|
+
fs.readdirSync(huskyTarget).forEach((file) => {
|
19
|
+
const filePath = path.join(huskyTarget, file);
|
20
|
+
if (fs.statSync(filePath).isFile()) {
|
21
|
+
fs.chmodSync(filePath, 0o755);
|
22
|
+
}
|
23
|
+
});
|
24
|
+
|
25
|
+
execSync('git config core.hooksPath .husky');
|
26
|
+
|
27
|
+
console.log('✅ Husky hooks installed from @apdesign/rule-react');
|
28
|
+
} catch (err) {
|
29
|
+
console.error('❌ Failed to initialize husky:', err);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
module.exports = initHusky;
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
const fs = require('fs');
|
4
|
+
const path = require('path');
|
5
|
+
|
6
|
+
function initScripts() {
|
7
|
+
const projectRoot = process.cwd();
|
8
|
+
const projectScriptsDir = path.join(projectRoot, 'scripts');
|
9
|
+
const packageScriptsDir = path.join(__dirname, '../scripts');
|
10
|
+
|
11
|
+
try {
|
12
|
+
if (!fs.existsSync(projectScriptsDir)) {
|
13
|
+
fs.mkdirSync(projectScriptsDir, { recursive: true });
|
14
|
+
console.log('📁 Created scripts directory in project');
|
15
|
+
}
|
16
|
+
|
17
|
+
fs.readdirSync(packageScriptsDir)
|
18
|
+
.filter((file) => file.endsWith('.sh'))
|
19
|
+
.forEach((file) => {
|
20
|
+
const srcFile = path.join(packageScriptsDir, file);
|
21
|
+
const destFile = path.join(projectScriptsDir, file);
|
22
|
+
|
23
|
+
if (fs.existsSync(destFile)) {
|
24
|
+
return;
|
25
|
+
}
|
26
|
+
|
27
|
+
fs.copyFileSync(srcFile, destFile);
|
28
|
+
fs.chmodSync(destFile, 0o755);
|
29
|
+
console.log(`📄 Copied ${file} to scripts/`);
|
30
|
+
});
|
31
|
+
} catch (err) {
|
32
|
+
console.error('❌ Failed to initialize scripts:', err);
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
module.exports = initScripts;
|