@zairakai/js-dev-tools 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/.editorconfig +86 -0
- package/.gitlab/ci/pipeline-js-app.yml +75 -0
- package/.gitlab/ci/pipeline-js-package.yml +360 -0
- package/LICENSE +21 -0
- package/README.md +206 -0
- package/config/.markdownlint.json +7 -0
- package/config/.markdownlintignore +5 -0
- package/config/.prettierignore +11 -0
- package/config/.stylelintignore +7 -0
- package/config/eslint.config.js +198 -0
- package/config/knip.config.js +40 -0
- package/config/prettier.config.js +121 -0
- package/config/stylelint.config.js +56 -0
- package/config/tsconfig.base.json +20 -0
- package/config/vitest.config.js +25 -0
- package/index.js +24 -0
- package/package.json +148 -0
- package/scripts/build.sh +58 -0
- package/scripts/ci-quality.sh +51 -0
- package/scripts/config.sh +254 -0
- package/scripts/doctor.sh +74 -0
- package/scripts/eslint-fix.sh +38 -0
- package/scripts/eslint.sh +49 -0
- package/scripts/install-bats.sh +227 -0
- package/scripts/install-hooks.sh +167 -0
- package/scripts/install-markdownlint.sh +31 -0
- package/scripts/install-shellcheck.sh +232 -0
- package/scripts/knip.sh +40 -0
- package/scripts/markdownlint-fix.sh +8 -0
- package/scripts/markdownlint.sh +84 -0
- package/scripts/outdated.sh +70 -0
- package/scripts/prettier-fix.sh +52 -0
- package/scripts/prettier.sh +53 -0
- package/scripts/setup-project.sh +816 -0
- package/scripts/stylelint-fix.sh +64 -0
- package/scripts/stylelint.sh +66 -0
- package/scripts/test.sh +40 -0
- package/scripts/typecheck.sh +41 -0
- package/scripts/validate-shellcheck.sh +70 -0
- package/stubs/githooks/commit-msg +34 -0
- package/stubs/githooks/pre-commit +58 -0
- package/stubs/githooks/pre-push +57 -0
- package/stubs/githooks/prepare-commit-msg +39 -0
- package/stubs/gitlab-ci/gitlab-ci.yml.stub +18 -0
- package/stubs/gitlab-ci/gitlab-pipeline-js-app.yml.stub +16 -0
- package/stubs/governance/CODE_OF_CONDUCT.md.stub +8 -0
- package/stubs/governance/CONTRIBUTING.md.stub +39 -0
- package/stubs/governance/SECURITY.md.stub +41 -0
- package/stubs/quality/eslint.config.js.stub +18 -0
- package/stubs/quality/knip.config.js.stub +14 -0
- package/stubs/style/prettier.config.js.stub +16 -0
- package/stubs/style/stylelint.config.js.stub +17 -0
- package/stubs/testing/vitest.config.js.stub +18 -0
- package/stubs/typescript/tsconfig.json.stub +10 -0
- package/tools/make/bats.mk +49 -0
- package/tools/make/code-style.mk +20 -0
- package/tools/make/core.mk +56 -0
- package/tools/make/help.mk +32 -0
- package/tools/make/knip.mk +7 -0
- package/tools/make/markdownlint.mk +17 -0
- package/tools/make/quality.mk +19 -0
- package/tools/make/shellcheck.mk +14 -0
- package/tools/make/stylelint.mk +11 -0
- package/tools/make/test.mk +19 -0
- package/tools/make/typescript.mk +10 -0
- package/tools/make/utils.mk +44 -0
- package/tools/make/variables.mk +42 -0
- package/tools/scripts/git-cleanup.sh +53 -0
- package/tools/scripts/git-update.sh +37 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default Vitest configuration for @zairakai packages.
|
|
3
|
+
* Provides sensible defaults for TypeScript projects.
|
|
4
|
+
*
|
|
5
|
+
* To customize, publish this file to your project:
|
|
6
|
+
* bash node_modules/@zairakai/js-dev-tools/scripts/setup-project.sh --publish=vitest
|
|
7
|
+
*
|
|
8
|
+
* The published config (config/dev-tools/vitest.config.js) can extend this
|
|
9
|
+
* base config and add project-specific settings (Vue plugin, jsdom, etc.).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { defineConfig } from 'vitest/config'
|
|
13
|
+
|
|
14
|
+
export default defineConfig({
|
|
15
|
+
test: {
|
|
16
|
+
globals: true,
|
|
17
|
+
environment: 'node',
|
|
18
|
+
coverage: {
|
|
19
|
+
provider: 'v8',
|
|
20
|
+
reporter: ['text', 'lcov', 'html', 'cobertura'],
|
|
21
|
+
reportsDirectory: 'build/coverage',
|
|
22
|
+
exclude: ['node_modules/**', 'dist/**', 'build/**', '**/*.config.*', '**/*.d.ts'],
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
})
|
package/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zairakai/js-dev-tools
|
|
3
|
+
* Development toolkit - ESLint, Prettier, Stylelint, TypeScript, and Vitest.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import eslint from './config/eslint.config.js'
|
|
7
|
+
import knip from './config/knip.config.js'
|
|
8
|
+
import prettier from './config/prettier.config.js'
|
|
9
|
+
import stylelint from './config/stylelint.config.js'
|
|
10
|
+
import tsconfig from './config/tsconfig.base.json' with { type: 'json' }
|
|
11
|
+
import vitest from './config/vitest.config.js'
|
|
12
|
+
|
|
13
|
+
// Named exports
|
|
14
|
+
export { eslint, knip, prettier, stylelint, tsconfig, vitest }
|
|
15
|
+
|
|
16
|
+
// Named paths for consumers
|
|
17
|
+
export const configs = {
|
|
18
|
+
eslint: '@zairakai/js-dev-tools/config/eslint.config.js',
|
|
19
|
+
prettier: '@zairakai/js-dev-tools/config/prettier.config.js',
|
|
20
|
+
stylelint: '@zairakai/js-dev-tools/config/stylelint.config.js',
|
|
21
|
+
vitest: '@zairakai/js-dev-tools/config/vitest.config.js',
|
|
22
|
+
knip: '@zairakai/js-dev-tools/config/knip.config.js',
|
|
23
|
+
tsconfig: '@zairakai/js-dev-tools/config/tsconfig.base.json',
|
|
24
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zairakai/js-dev-tools",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "The unified and centralized development toolkit for JavaScript/TypeScript projects - ESLint, Prettier, Stylelint, Knip, Vitest, Git Hooks, and GitLab CI pipeline templates",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"dev-tools",
|
|
7
|
+
"toolkit",
|
|
8
|
+
"unified",
|
|
9
|
+
"centralized",
|
|
10
|
+
"makefile",
|
|
11
|
+
"git-hooks",
|
|
12
|
+
"gitlab-ci",
|
|
13
|
+
"eslint",
|
|
14
|
+
"prettier",
|
|
15
|
+
"stylelint",
|
|
16
|
+
"vitest",
|
|
17
|
+
"knip",
|
|
18
|
+
"typescript"
|
|
19
|
+
],
|
|
20
|
+
"homepage": "https://gitlab.com/zairakai/npm-packages/js-dev-tools",
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://gitlab.com/zairakai/npm-packages/js-dev-tools/-/issues",
|
|
23
|
+
"email": "contact-project+zairakai-npm-packages-js-dev-tools-80188322-issue-@incoming.gitlab.com"
|
|
24
|
+
},
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+https://gitlab.com/zairakai/npm-packages/js-dev-tools.git"
|
|
28
|
+
},
|
|
29
|
+
"funding": [
|
|
30
|
+
{
|
|
31
|
+
"type": "patreon",
|
|
32
|
+
"url": "https://www.patreon.com/c/zairakai"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"type": "twitch",
|
|
36
|
+
"url": "https://www.twitch.tv/zairakai"
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"author": "Stanislas Poisson <stanislas.p@the-white-rabbits.fr> (https://the-white-rabbits.fr)",
|
|
41
|
+
"contributors": [
|
|
42
|
+
{
|
|
43
|
+
"name": "Stanislas Poisson",
|
|
44
|
+
"url": "https://gitlab.com/zairakai",
|
|
45
|
+
"role": "Maintainer"
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"type": "module",
|
|
49
|
+
"exports": {
|
|
50
|
+
".": {
|
|
51
|
+
"import": "./index.js"
|
|
52
|
+
},
|
|
53
|
+
"./prettier": "./config/prettier.config.js",
|
|
54
|
+
"./eslint": "./config/eslint.config.js",
|
|
55
|
+
"./stylelint": "./config/stylelint.config.js",
|
|
56
|
+
"./vitest": "./config/vitest.config.js",
|
|
57
|
+
"./knip": "./config/knip.config.js",
|
|
58
|
+
"./tsconfig": "./config/tsconfig.base.json",
|
|
59
|
+
"./config/*": "./config/*"
|
|
60
|
+
},
|
|
61
|
+
"main": "index.js",
|
|
62
|
+
"files": [
|
|
63
|
+
".gitlab/",
|
|
64
|
+
"config/",
|
|
65
|
+
"scripts/",
|
|
66
|
+
"stubs/",
|
|
67
|
+
"tools/",
|
|
68
|
+
"index.js",
|
|
69
|
+
".editorconfig",
|
|
70
|
+
"LICENSE",
|
|
71
|
+
"README.md"
|
|
72
|
+
],
|
|
73
|
+
"scripts": {
|
|
74
|
+
"eslint": "eslint --config config/eslint.config.js config/*.{js,ts}",
|
|
75
|
+
"eslint:fix": "eslint --config config/eslint.config.js config/*.{js,ts} --fix",
|
|
76
|
+
"postinstall": "bash ./scripts/setup-project.sh --silent || true",
|
|
77
|
+
"knip": "bash ./scripts/knip.sh",
|
|
78
|
+
"markdownlint": "markdownlint-cli2 --config config/.markdownlint.json --ignore-path config/.markdownlintignore '**/*.md' '#node_modules'",
|
|
79
|
+
"markdownlint:fix": "markdownlint-cli2 --fix --config config/.markdownlint.json --ignore-path config/.markdownlintignore '**/*.md' '#node_modules'",
|
|
80
|
+
"normalize": "make package-normalize",
|
|
81
|
+
"package:validate": "make package-validate",
|
|
82
|
+
"prettier": "prettier . --check --config ./config/prettier.config.js --ignore-path ./config/.prettierignore",
|
|
83
|
+
"prettier:fix": "prettier . --write --config ./config/prettier.config.js --ignore-path ./config/.prettierignore",
|
|
84
|
+
"setup": "bash ./scripts/setup-project.sh",
|
|
85
|
+
"stylelint": "stylelint --config config/stylelint.config.js --ignore-path config/.stylelintignore '**/*.scss'",
|
|
86
|
+
"stylelint:fix": "stylelint --config config/stylelint.config.js --ignore-path config/.stylelintignore '**/*.scss' --fix",
|
|
87
|
+
"test": "make test-all",
|
|
88
|
+
"validate": "make quality"
|
|
89
|
+
},
|
|
90
|
+
"dependencies": {
|
|
91
|
+
"@eslint/js": "^10.0.0",
|
|
92
|
+
"@prettier/plugin-php": "^0.24.0",
|
|
93
|
+
"@typescript-eslint/eslint-plugin": "^8.40.0",
|
|
94
|
+
"@typescript-eslint/parser": "^8.40.0",
|
|
95
|
+
"eslint": "^10.0.0",
|
|
96
|
+
"eslint-config-prettier": "^10.0.0",
|
|
97
|
+
"eslint-plugin-vue": "^10.0.0",
|
|
98
|
+
"globals": "^17.0.0",
|
|
99
|
+
"markdownlint-cli2": "^0.21.0",
|
|
100
|
+
"prettier": "^3.0.0",
|
|
101
|
+
"prettier-plugin-blade": "^2.1.0",
|
|
102
|
+
"prettier-plugin-organize-imports": "^4.0.0",
|
|
103
|
+
"stylelint": "^17.0.0",
|
|
104
|
+
"stylelint-config-html": "^1.1.0",
|
|
105
|
+
"stylelint-config-recommended-vue": "^1.5.0",
|
|
106
|
+
"stylelint-config-standard": "^40.0.0",
|
|
107
|
+
"stylelint-config-standard-scss": "^17.0.0",
|
|
108
|
+
"stylelint-order": "^8.0.0",
|
|
109
|
+
"stylelint-scss": "^7.0.0",
|
|
110
|
+
"vue-eslint-parser": "^10.0.0"
|
|
111
|
+
},
|
|
112
|
+
"devDependencies": {
|
|
113
|
+
"@eslint/compat": "^2.0.3",
|
|
114
|
+
"@vitest/coverage-v8": "^4.0.0",
|
|
115
|
+
"knip": "^5.85.0",
|
|
116
|
+
"sort-package-json": "^3.6.1",
|
|
117
|
+
"typescript": "^5.9.3",
|
|
118
|
+
"vitest": "^4.0.0",
|
|
119
|
+
"zod": "^4.0.0"
|
|
120
|
+
},
|
|
121
|
+
"peerDependencies": {
|
|
122
|
+
"eslint": "^10.0.0",
|
|
123
|
+
"prettier": "^3.0.0",
|
|
124
|
+
"stylelint": "^17.0.0",
|
|
125
|
+
"typedoc": "^0.28.0",
|
|
126
|
+
"zod": "^3.0.0 || ^4.0.0"
|
|
127
|
+
},
|
|
128
|
+
"peerDependenciesMeta": {
|
|
129
|
+
"stylelint": {
|
|
130
|
+
"optional": true
|
|
131
|
+
},
|
|
132
|
+
"typedoc": {
|
|
133
|
+
"optional": true
|
|
134
|
+
},
|
|
135
|
+
"zod": {
|
|
136
|
+
"optional": true
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
"engines": {
|
|
140
|
+
"node": ">=22.0.0"
|
|
141
|
+
},
|
|
142
|
+
"publishConfig": {
|
|
143
|
+
"access": "public"
|
|
144
|
+
},
|
|
145
|
+
"outdatedIgnore": [
|
|
146
|
+
"prettier-plugin-blade"
|
|
147
|
+
]
|
|
148
|
+
}
|
package/scripts/build.sh
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# TypeScript Build / Transpilation
|
|
4
|
+
# Compiles TypeScript to JavaScript for distribution.
|
|
5
|
+
#
|
|
6
|
+
# Supports (in order of preference):
|
|
7
|
+
# 1. tsup — fast, esbuild-based bundler (recommended for npm packages)
|
|
8
|
+
# 2. tsc — official TypeScript compiler
|
|
9
|
+
#
|
|
10
|
+
# Usage:
|
|
11
|
+
# bash scripts/build.sh
|
|
12
|
+
#
|
|
13
|
+
# Recommendation:
|
|
14
|
+
# Use tsup for npm packages: npm install --save-dev tsup
|
|
15
|
+
# Use tsc for apps: npm install --save-dev typescript
|
|
16
|
+
#
|
|
17
|
+
|
|
18
|
+
set -euo pipefail
|
|
19
|
+
|
|
20
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
21
|
+
# shellcheck disable=SC1091
|
|
22
|
+
source "${SCRIPT_DIR}/config.sh"
|
|
23
|
+
|
|
24
|
+
TSUP_BIN="${BIN_DIR}/tsup"
|
|
25
|
+
TSC_BIN="${BIN_DIR}/tsc"
|
|
26
|
+
|
|
27
|
+
log_header "TypeScript Build"
|
|
28
|
+
|
|
29
|
+
if [[ -f "$TSUP_BIN" ]]; then
|
|
30
|
+
log_info "Builder: tsup (fast, esbuild-based)"
|
|
31
|
+
if [[ -n "$TSUP_CONFIG" ]]; then
|
|
32
|
+
"$TSUP_BIN" --config "$TSUP_CONFIG"
|
|
33
|
+
else
|
|
34
|
+
"$TSUP_BIN"
|
|
35
|
+
fi
|
|
36
|
+
log_success "Build complete — output in dist/"
|
|
37
|
+
|
|
38
|
+
elif [[ -f "$TSC_BIN" ]]; then
|
|
39
|
+
log_info "Builder: tsc (official TypeScript compiler)"
|
|
40
|
+
|
|
41
|
+
if [[ ! -f "${PROJECT_ROOT}/tsconfig.json" ]]; then
|
|
42
|
+
log_error "No tsconfig.json found at project root"
|
|
43
|
+
log_info "Publish one with:"
|
|
44
|
+
log_info " bash node_modules/@zairakai/js-dev-tools/scripts/setup-project.sh --publish=tsconfig"
|
|
45
|
+
exit 1
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
log_info "Config: tsconfig.json"
|
|
49
|
+
"$TSC_BIN"
|
|
50
|
+
log_success "Build complete"
|
|
51
|
+
|
|
52
|
+
else
|
|
53
|
+
log_error "No TypeScript builder found in node_modules/.bin/"
|
|
54
|
+
log_info "Install one of:"
|
|
55
|
+
log_info " npm install --save-dev tsup (recommended for npm packages)"
|
|
56
|
+
log_info " npm install --save-dev typescript (for apps or when you need full tsc control)"
|
|
57
|
+
exit 1
|
|
58
|
+
fi
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# CI Quality Aggregator
|
|
4
|
+
# Runs all quality checks (ESLint, Prettier, Stylelint, TypeScript)
|
|
5
|
+
# and reports all failures at once rather than stopping on the first error.
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# bash scripts/ci-quality.sh
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
14
|
+
# shellcheck disable=SC1091
|
|
15
|
+
source "$SCRIPT_DIR/config.sh"
|
|
16
|
+
|
|
17
|
+
log_header "Quality Checks"
|
|
18
|
+
|
|
19
|
+
init_error_counter
|
|
20
|
+
|
|
21
|
+
# 1. Documentation & Shell (Foundational)
|
|
22
|
+
run_check "Documentation (Markdownlint)" "bash '${SCRIPT_DIR}/markdownlint.sh'" || true
|
|
23
|
+
echo ""
|
|
24
|
+
|
|
25
|
+
run_check "Shell Scripts (ShellCheck)" "bash '${SCRIPT_DIR}/validate-shellcheck.sh'" || true
|
|
26
|
+
echo ""
|
|
27
|
+
|
|
28
|
+
# 2. Code Quality & Style (Language Specific)
|
|
29
|
+
run_check "Code Style (ESLint)" "bash '${SCRIPT_DIR}/eslint.sh'" || true
|
|
30
|
+
echo ""
|
|
31
|
+
|
|
32
|
+
run_check "Formatting (Prettier)" "bash '${SCRIPT_DIR}/prettier.sh'" || true
|
|
33
|
+
echo ""
|
|
34
|
+
|
|
35
|
+
run_check "CSS/SCSS (Stylelint)" "bash '${SCRIPT_DIR}/stylelint.sh'" || true
|
|
36
|
+
echo ""
|
|
37
|
+
|
|
38
|
+
# 3. Static Analysis (Optional, Project aware)
|
|
39
|
+
if [[ -f "${PROJECT_ROOT}/tsconfig.json" ]] && [[ -f "${BIN_DIR}/tsc" ]]; then
|
|
40
|
+
run_check "TypeScript (tsc --noEmit)" "bash '${SCRIPT_DIR}/typecheck.sh'" || true
|
|
41
|
+
echo ""
|
|
42
|
+
else
|
|
43
|
+
log_info "TypeScript: no tsconfig.json or tsc — skipping"
|
|
44
|
+
echo ""
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
if exit_with_error_count "Quality Checks"; then
|
|
48
|
+
exit 0
|
|
49
|
+
else
|
|
50
|
+
exit 1
|
|
51
|
+
fi
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Zairakai NPM Dev Tools - Central Configuration
|
|
3
|
+
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
# ─── PATH DETECTION ───────────────────────────────────────────────────────────
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
+
|
|
9
|
+
# Vendor context: node_modules/@zairakai/js-dev-tools/scripts/
|
|
10
|
+
# Dev context: npm/dev-tools/scripts/
|
|
11
|
+
if [[ "$SCRIPT_DIR" =~ /node_modules/@zairakai/js-dev-tools/scripts ]]; then
|
|
12
|
+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../../.." && pwd)"
|
|
13
|
+
DEV_TOOLS_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
14
|
+
else
|
|
15
|
+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
16
|
+
DEV_TOOLS_ROOT="$PROJECT_ROOT"
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
export PROJECT_ROOT
|
|
20
|
+
export DEV_TOOLS_ROOT
|
|
21
|
+
|
|
22
|
+
# ─── PACKAGE MANAGER DETECTION ────────────────────────────────────────────────
|
|
23
|
+
detect_package_manager() {
|
|
24
|
+
if [[ -f "$PROJECT_ROOT/yarn.lock" ]] || [[ -f "$PROJECT_ROOT/.yarnrc.yml" ]]; then
|
|
25
|
+
echo "yarn"
|
|
26
|
+
else
|
|
27
|
+
echo "npm"
|
|
28
|
+
fi
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
PM="$(detect_package_manager)"
|
|
32
|
+
export PM
|
|
33
|
+
|
|
34
|
+
# ─── PROJECT TYPE DETECTION ───────────────────────────────────────────────────
|
|
35
|
+
detect_project_type() {
|
|
36
|
+
if [[ -f "${PROJECT_ROOT}/artisan" ]] && [[ -d "${PROJECT_ROOT}/resources/js" ]]; then
|
|
37
|
+
echo "laravel-app"
|
|
38
|
+
return 0
|
|
39
|
+
fi
|
|
40
|
+
echo "npm-package"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
PROJECT_TYPE="$(detect_project_type)"
|
|
44
|
+
export PROJECT_TYPE
|
|
45
|
+
|
|
46
|
+
# ─── BINARY PATHS ─────────────────────────────────────────────────────────────
|
|
47
|
+
BIN_DIR="${PROJECT_ROOT}/node_modules/.bin"
|
|
48
|
+
export ESLINT_BIN="${BIN_DIR}/eslint"
|
|
49
|
+
export PRETTIER_BIN="${BIN_DIR}/prettier"
|
|
50
|
+
export STYLELINT_BIN="${BIN_DIR}/stylelint"
|
|
51
|
+
export VITEST_BIN="${BIN_DIR}/vitest"
|
|
52
|
+
export MARKDOWNLINT_BIN="${BIN_DIR}/markdownlint-cli2"
|
|
53
|
+
|
|
54
|
+
# ─── CONFIG RESOLUTION ────────────────────────────────────────────────────────
|
|
55
|
+
# Cascade: project root → config/dev-tools/ → config/ → bundled default
|
|
56
|
+
resolve_config() {
|
|
57
|
+
local filename="$1"
|
|
58
|
+
|
|
59
|
+
# 1. Project root (full override)
|
|
60
|
+
if [[ -f "${PROJECT_ROOT}/${filename}" ]]; then
|
|
61
|
+
echo "${PROJECT_ROOT}/${filename}"
|
|
62
|
+
return 0
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# 2. config/dev-tools/ (published — can extend bundled default)
|
|
66
|
+
if [[ -f "${PROJECT_ROOT}/config/dev-tools/${filename}" ]]; then
|
|
67
|
+
echo "${PROJECT_ROOT}/config/dev-tools/${filename}"
|
|
68
|
+
return 0
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# 3. config/ (local usage or internal package structure)
|
|
72
|
+
if [[ -f "${PROJECT_ROOT}/config/${filename}" ]]; then
|
|
73
|
+
echo "${PROJECT_ROOT}/config/${filename}"
|
|
74
|
+
return 0
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# 4. Bundled default in dev-tools package (fallback when in node_modules)
|
|
78
|
+
if [[ -f "${DEV_TOOLS_ROOT}/config/${filename}" ]]; then
|
|
79
|
+
echo "${DEV_TOOLS_ROOT}/config/${filename}"
|
|
80
|
+
return 0
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
echo ""
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export -f resolve_config
|
|
87
|
+
|
|
88
|
+
# ─── COLORS ───────────────────────────────────────────────────────────────────
|
|
89
|
+
export RED='\033[0;31m'
|
|
90
|
+
export GREEN='\033[0;32m'
|
|
91
|
+
export YELLOW='\033[1;33m'
|
|
92
|
+
export BLUE='\033[0;34m'
|
|
93
|
+
export CYAN='\033[0;36m'
|
|
94
|
+
export MAGENTA='\033[0;35m'
|
|
95
|
+
export NC='\033[0m'
|
|
96
|
+
|
|
97
|
+
# ─── LOGGING ──────────────────────────────────────────────────────────────────
|
|
98
|
+
log_info() { echo -e "${CYAN}ℹ ${NC}$*"; }
|
|
99
|
+
log_success() { echo -e "${GREEN}✅ ${NC}$*"; }
|
|
100
|
+
log_warning() { echo -e "${YELLOW}⚠️ ${NC}$*"; }
|
|
101
|
+
log_error() { echo -e "${RED}❌ ${NC}$*" >&2; }
|
|
102
|
+
log_step() { echo -e "${BLUE}→${NC} $*"; }
|
|
103
|
+
log_header() { echo -e "\n${MAGENTA} $*${NC}\n${MAGENTA}════════════════${NC}\n"; }
|
|
104
|
+
|
|
105
|
+
export -f log_info
|
|
106
|
+
export -f log_success
|
|
107
|
+
export -f log_warning
|
|
108
|
+
export -f log_error
|
|
109
|
+
export -f log_step
|
|
110
|
+
export -f log_header
|
|
111
|
+
|
|
112
|
+
# ─── BINARY CHECKS ────────────────────────────────────────────────────────────
|
|
113
|
+
ensure_bin() {
|
|
114
|
+
local bin="$1"
|
|
115
|
+
local name="${2:-$(basename "$bin")}"
|
|
116
|
+
if [[ ! -f "$bin" ]]; then
|
|
117
|
+
log_error "${name} not found in node_modules/.bin/"
|
|
118
|
+
log_error "Run: ${PM} install"
|
|
119
|
+
return 1
|
|
120
|
+
fi
|
|
121
|
+
}
|
|
122
|
+
export -f ensure_bin
|
|
123
|
+
|
|
124
|
+
ensure_bin_optional() {
|
|
125
|
+
local bin="$1"
|
|
126
|
+
local name="${2:-$(basename "$bin")}"
|
|
127
|
+
if [[ ! -f "$bin" ]]; then
|
|
128
|
+
log_warning "${name} not installed — skipping (optional)"
|
|
129
|
+
return 1
|
|
130
|
+
fi
|
|
131
|
+
return 0
|
|
132
|
+
}
|
|
133
|
+
export -f ensure_bin_optional
|
|
134
|
+
|
|
135
|
+
# Check if files matching pattern exist
|
|
136
|
+
has_files() {
|
|
137
|
+
local pattern="$1"
|
|
138
|
+
# SC2086: unquoted intentionally — we need word splitting + glob expansion via nullglob
|
|
139
|
+
# shellcheck disable=SC2086
|
|
140
|
+
( shopt -s nullglob; set -- $pattern; [ $# -gt 0 ] )
|
|
141
|
+
}
|
|
142
|
+
export -f has_files
|
|
143
|
+
|
|
144
|
+
# ─── ERROR COUNTER ────────────────────────────────────────────────────────────
|
|
145
|
+
ERROR_COUNT=0
|
|
146
|
+
export ERROR_COUNT
|
|
147
|
+
init_error_counter() { ERROR_COUNT=0; }
|
|
148
|
+
increment_error_counter() { ERROR_COUNT=$((ERROR_COUNT + 1)); }
|
|
149
|
+
get_error_count() { echo "$ERROR_COUNT"; }
|
|
150
|
+
|
|
151
|
+
exit_with_error_count() {
|
|
152
|
+
local name="${1:-Checks}"
|
|
153
|
+
if [[ $ERROR_COUNT -eq 0 ]]; then
|
|
154
|
+
log_header "✅ All ${name} Passed"
|
|
155
|
+
return 0
|
|
156
|
+
else
|
|
157
|
+
log_header "❌ ${ERROR_COUNT} ${name} Failed"
|
|
158
|
+
return 1
|
|
159
|
+
fi
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export -f init_error_counter
|
|
163
|
+
export -f increment_error_counter
|
|
164
|
+
export -f get_error_count
|
|
165
|
+
export -f exit_with_error_count
|
|
166
|
+
|
|
167
|
+
run_check() {
|
|
168
|
+
local name="$1"
|
|
169
|
+
local cmd="$2"
|
|
170
|
+
log_info "Running: ${name}"
|
|
171
|
+
if eval "$cmd"; then
|
|
172
|
+
log_success "${name} passed"
|
|
173
|
+
else
|
|
174
|
+
log_error "${name} failed"
|
|
175
|
+
increment_error_counter
|
|
176
|
+
return 1
|
|
177
|
+
fi
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
# ─── BACKUP ──────────────────────────────────────────────────────────────────
|
|
181
|
+
BACKUP_DIR=""
|
|
182
|
+
backup_file() {
|
|
183
|
+
local file="$1"
|
|
184
|
+
local base="${2:-${PROJECT_ROOT}/.dev-tools-backup}"
|
|
185
|
+
[[ ! -f "$file" || -L "$file" ]] && return 1
|
|
186
|
+
if [[ -z "$BACKUP_DIR" ]]; then
|
|
187
|
+
BACKUP_DIR="${base}/$(date +%Y%m%d-%H%M%S)"
|
|
188
|
+
mkdir -p "$BACKUP_DIR"
|
|
189
|
+
fi
|
|
190
|
+
local rel="${file#"${PROJECT_ROOT}"/}"
|
|
191
|
+
local dest="${BACKUP_DIR}/${rel}"
|
|
192
|
+
mkdir -p "$(dirname "$dest")"
|
|
193
|
+
cp "$file" "$dest" 2>/dev/null
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
# ─── HELPERS ──────────────────────────────────────────────────────────────────
|
|
197
|
+
command_exists() { command -v "$1" >/dev/null 2>&1; }
|
|
198
|
+
ensure_dir() {
|
|
199
|
+
if [[ ! -d "$1" ]]; then
|
|
200
|
+
mkdir -p "$1"
|
|
201
|
+
log_step "Created directory: $1"
|
|
202
|
+
fi
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
# ─── FILE PROTECTION (SHA-256) ────────────────────────────────────────────────
|
|
206
|
+
file_hash() {
|
|
207
|
+
local file="$1"
|
|
208
|
+
if command_exists sha256sum; then
|
|
209
|
+
sha256sum "$file" | cut -d' ' -f1
|
|
210
|
+
elif command_exists shasum; then
|
|
211
|
+
shasum -a 256 "$file" | cut -d' ' -f1
|
|
212
|
+
else
|
|
213
|
+
echo ""
|
|
214
|
+
fi
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
# ─── ENVIRONMENT DETECTION ────────────────────────────────────────────────────
|
|
218
|
+
export IS_CI="${CI:-false}"
|
|
219
|
+
export IS_GITLAB_CI="${GITLAB_CI:-false}"
|
|
220
|
+
export IS_GITHUB_ACTIONS="${GITHUB_ACTIONS:-false}"
|
|
221
|
+
|
|
222
|
+
# ─── TOOL CONFIG RESOLUTION ───────────────────────────────────────────────────
|
|
223
|
+
# Pre-resolved at startup so individual scripts don't call resolve_config themselves.
|
|
224
|
+
ESLINT_CONFIG="$(resolve_config "eslint.config.js")"
|
|
225
|
+
export ESLINT_CONFIG
|
|
226
|
+
|
|
227
|
+
PRETTIER_CONFIG="$(resolve_config "prettier.config.js")"
|
|
228
|
+
PRETTIER_IGNORE="$(resolve_config ".prettierignore")"
|
|
229
|
+
export PRETTIER_CONFIG PRETTIER_IGNORE
|
|
230
|
+
|
|
231
|
+
STYLELINT_CONFIG="$(resolve_config "stylelint.config.js")"
|
|
232
|
+
STYLELINT_IGNORE="$(resolve_config ".stylelintignore")"
|
|
233
|
+
export STYLELINT_CONFIG STYLELINT_IGNORE
|
|
234
|
+
|
|
235
|
+
MARKDOWNLINT_CONFIG="$(resolve_config ".markdownlint.json")"
|
|
236
|
+
MARKDOWNLINT_IGNORE="$(resolve_config ".markdownlintignore")"
|
|
237
|
+
export MARKDOWNLINT_CONFIG MARKDOWNLINT_IGNORE
|
|
238
|
+
|
|
239
|
+
VITEST_CONFIG="$(resolve_config "vitest.config.js")"
|
|
240
|
+
export VITEST_CONFIG
|
|
241
|
+
|
|
242
|
+
KNIP_CONFIG="$(resolve_config "knip.config.js")"
|
|
243
|
+
export KNIP_CONFIG
|
|
244
|
+
|
|
245
|
+
TSUP_CONFIG="$(resolve_config "tsup.config.js")"
|
|
246
|
+
export TSUP_CONFIG
|
|
247
|
+
|
|
248
|
+
# ─── VALIDATION ───────────────────────────────────────────────────────────────
|
|
249
|
+
cd "$PROJECT_ROOT"
|
|
250
|
+
|
|
251
|
+
if [[ ! -d "${PROJECT_ROOT}/node_modules" ]]; then
|
|
252
|
+
log_error "Dependencies not installed. Run: ${PM} install"
|
|
253
|
+
exit 1
|
|
254
|
+
fi
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
+
# shellcheck disable=SC1091
|
|
6
|
+
source "$SCRIPT_DIR/config.sh"
|
|
7
|
+
|
|
8
|
+
log_header "Environment Diagnostics"
|
|
9
|
+
|
|
10
|
+
echo -e "${CYAN}Node.js Version:${NC}"
|
|
11
|
+
node --version
|
|
12
|
+
|
|
13
|
+
echo ""
|
|
14
|
+
echo -e "${CYAN}Package Manager:${NC}"
|
|
15
|
+
echo " → ${PM} $(${PM} --version)"
|
|
16
|
+
|
|
17
|
+
echo ""
|
|
18
|
+
echo -e "${CYAN}Project Type:${NC}"
|
|
19
|
+
echo " → ${PROJECT_TYPE}"
|
|
20
|
+
|
|
21
|
+
echo ""
|
|
22
|
+
echo -e "${CYAN}Available Tools:${NC}"
|
|
23
|
+
[[ -f "$ESLINT_BIN" ]] && echo " ✅ ESLint: $("$ESLINT_BIN" --version 2>/dev/null)" || echo " ❌ ESLint not found"
|
|
24
|
+
[[ -f "$PRETTIER_BIN" ]] && echo " ✅ Prettier: $("$PRETTIER_BIN" --version 2>/dev/null)" || echo " ❌ Prettier not found"
|
|
25
|
+
[[ -f "$STYLELINT_BIN" ]] && echo " ✅ Stylelint: $("$STYLELINT_BIN" --version 2>/dev/null)" || echo " ℹ️ Stylelint not installed (optional)"
|
|
26
|
+
[[ -f "$VITEST_BIN" ]] && echo " ✅ Vitest: $("$VITEST_BIN" --version 2>/dev/null)" || echo " ℹ️ Vitest not installed"
|
|
27
|
+
[[ -f "$MARKDOWNLINT_BIN" ]] && echo " ✅ Markdownlint: installed" || echo " ❌ Markdownlint not found"
|
|
28
|
+
[[ -f "${BIN_DIR}/knip" ]] && echo " ✅ Knip: installed" || echo " ℹ️ Knip not installed (optional)"
|
|
29
|
+
[[ -f "${BIN_DIR}/tsc" ]] && echo " ✅ TypeScript: $("${BIN_DIR}/tsc" --version 2>/dev/null)" || echo " ℹ️ TypeScript not installed (optional)"
|
|
30
|
+
[[ -f "${BIN_DIR}/tsup" ]] && echo " ✅ tsup: installed" || echo " ℹ️ tsup not installed (optional)"
|
|
31
|
+
|
|
32
|
+
echo ""
|
|
33
|
+
echo -e "${CYAN}CI/CD Detection:${NC}"
|
|
34
|
+
if [[ "$IS_CI" == "true" ]]; then
|
|
35
|
+
echo " ✅ Running in CI environment"
|
|
36
|
+
[[ "$IS_GITLAB_CI" == "true" ]] && echo " → Platform: GitLab CI"
|
|
37
|
+
[[ "$IS_GITHUB_ACTIONS" == "true" ]] && echo " → Platform: GitHub Actions"
|
|
38
|
+
else
|
|
39
|
+
echo " ℹ️ Local development environment"
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
echo ""
|
|
43
|
+
echo -e "${CYAN}Configuration Files (resolved):${NC}"
|
|
44
|
+
|
|
45
|
+
show_config() {
|
|
46
|
+
local label="$1"
|
|
47
|
+
local value="$2"
|
|
48
|
+
if [[ -n "$value" ]] && [[ -f "$value" ]]; then
|
|
49
|
+
echo " ✅ ${label}: ${value#"$PROJECT_ROOT"/}"
|
|
50
|
+
else
|
|
51
|
+
echo " ℹ️ ${label}: Using defaults (no config file)"
|
|
52
|
+
fi
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
show_config "ESLint" "$ESLINT_CONFIG"
|
|
56
|
+
show_config "Prettier" "$PRETTIER_CONFIG"
|
|
57
|
+
show_config ".prettierignore" "$PRETTIER_IGNORE"
|
|
58
|
+
show_config "Stylelint" "$STYLELINT_CONFIG"
|
|
59
|
+
show_config ".stylelintignore" "$STYLELINT_IGNORE"
|
|
60
|
+
show_config "Markdownlint" "$MARKDOWNLINT_CONFIG"
|
|
61
|
+
show_config ".markdownlintignore" "$MARKDOWNLINT_IGNORE"
|
|
62
|
+
show_config "Vitest" "$VITEST_CONFIG"
|
|
63
|
+
show_config "Knip" "$KNIP_CONFIG"
|
|
64
|
+
show_config "tsup" "$TSUP_CONFIG"
|
|
65
|
+
|
|
66
|
+
echo ""
|
|
67
|
+
echo -e "${CYAN}Configuration Fallback Order (all tools):${NC}"
|
|
68
|
+
echo " 1. {file} (project root override)"
|
|
69
|
+
echo " 2. config/dev-tools/{file} (published — can extend bundled default)"
|
|
70
|
+
echo " 3. config/{file} (legacy or intermediate)"
|
|
71
|
+
echo " 4. node_modules/@zairakai/js-dev-tools/config/{file} (bundled default)"
|
|
72
|
+
|
|
73
|
+
echo ""
|
|
74
|
+
log_success "Diagnostics complete"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
+
# shellcheck disable=SC1091
|
|
6
|
+
source "$SCRIPT_DIR/config.sh"
|
|
7
|
+
|
|
8
|
+
log_header "ESLint Fix"
|
|
9
|
+
|
|
10
|
+
ensure_bin "$ESLINT_BIN" "eslint" || exit 1
|
|
11
|
+
|
|
12
|
+
if [[ -n "$ESLINT_CONFIG" ]]; then
|
|
13
|
+
log_step "Using configuration: ${ESLINT_CONFIG#"$PROJECT_ROOT"/}"
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
if [[ "$PROJECT_TYPE" == "laravel-app" ]]; then
|
|
17
|
+
LINT_TARGET="${LINT_TARGET:-resources/js/}"
|
|
18
|
+
else
|
|
19
|
+
LINT_TARGET="${LINT_TARGET:-src/}"
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
log_step "Fixing: $LINT_TARGET"
|
|
23
|
+
|
|
24
|
+
# Skip gracefully if no matching files exist
|
|
25
|
+
if ! has_files "${PROJECT_ROOT}/${LINT_TARGET}**/*.{js,ts,vue,jsx,tsx}"; then
|
|
26
|
+
log_info "No JS/TS files found in ${LINT_TARGET} — skipping"
|
|
27
|
+
exit 0
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
ESLINT_ARGS=(--fix)
|
|
31
|
+
|
|
32
|
+
if [[ -n "$ESLINT_CONFIG" ]] && [[ "$ESLINT_CONFIG" != "${PROJECT_ROOT}/eslint.config.js" ]]; then
|
|
33
|
+
ESLINT_ARGS+=(--config "$ESLINT_CONFIG")
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
"$ESLINT_BIN" "${ESLINT_ARGS[@]}" "$LINT_TARGET"
|
|
37
|
+
|
|
38
|
+
log_success "ESLint fix applied"
|