@zairakai/dev-tools 1.0.11

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.
Files changed (52) hide show
  1. package/.editorconfig +86 -0
  2. package/.gitlab/ci/pipeline-js.yml +189 -0
  3. package/.gitlab/ci/pipeline-npm-package.yml +353 -0
  4. package/LICENSE +21 -0
  5. package/README.md +162 -0
  6. package/config/.markdownlint.json +7 -0
  7. package/config/.markdownlintignore +5 -0
  8. package/config/.prettierignore +10 -0
  9. package/config/.stylelintignore +7 -0
  10. package/config/eslint.config.js +191 -0
  11. package/config/prettier.config.js +121 -0
  12. package/config/stylelint.config.js +56 -0
  13. package/config/tsconfig.base.json +20 -0
  14. package/config/vitest.config.js +25 -0
  15. package/index.js +22 -0
  16. package/package.json +137 -0
  17. package/scripts/build.sh +54 -0
  18. package/scripts/ci-quality.sh +47 -0
  19. package/scripts/config.sh +193 -0
  20. package/scripts/eslint-fix.sh +34 -0
  21. package/scripts/eslint.sh +46 -0
  22. package/scripts/install-bats.sh +227 -0
  23. package/scripts/install-shellcheck.sh +232 -0
  24. package/scripts/knip.sh +33 -0
  25. package/scripts/markdownlint-fix.sh +8 -0
  26. package/scripts/markdownlint.sh +43 -0
  27. package/scripts/prettier-fix.sh +33 -0
  28. package/scripts/prettier.sh +34 -0
  29. package/scripts/setup-project.sh +702 -0
  30. package/scripts/stylelint-fix.sh +39 -0
  31. package/scripts/stylelint.sh +47 -0
  32. package/scripts/test.sh +43 -0
  33. package/scripts/typecheck.sh +35 -0
  34. package/scripts/validate-shellcheck.sh +70 -0
  35. package/stubs/eslint.config.js.stub +18 -0
  36. package/stubs/gitlab-ci.yml.stub +18 -0
  37. package/stubs/gitlab-pipeline-js.yml.stub +16 -0
  38. package/stubs/prettier.config.js.stub +16 -0
  39. package/stubs/stylelint.config.js.stub +17 -0
  40. package/stubs/tsconfig.json.stub +10 -0
  41. package/stubs/vitest.config.js.stub +18 -0
  42. package/tools/make/bats.mk +49 -0
  43. package/tools/make/code-style.mk +29 -0
  44. package/tools/make/core.mk +50 -0
  45. package/tools/make/help.mk +32 -0
  46. package/tools/make/markdownlint.mk +17 -0
  47. package/tools/make/quality.mk +20 -0
  48. package/tools/make/shellcheck.mk +14 -0
  49. package/tools/make/stylelint.mk +0 -0
  50. package/tools/make/test.mk +19 -0
  51. package/tools/make/typescript.mk +14 -0
  52. package/tools/make/variables.mk +35 -0
package/package.json ADDED
@@ -0,0 +1,137 @@
1
+ {
2
+ "name": "@zairakai/dev-tools",
3
+ "version": "1.0.11",
4
+ "description": "Development tools umbrella for Zairakai projects - ESLint, Prettier, Stylelint all-in-one",
5
+ "keywords": [
6
+ "zairakai",
7
+ "dev-tools",
8
+ "umbrella",
9
+ "eslint",
10
+ "prettier",
11
+ "stylelint",
12
+ "vue",
13
+ "typescript",
14
+ "javascript",
15
+ "scss"
16
+ ],
17
+ "homepage": "https://gitlab.com/zairakai/npm/dev-tools",
18
+ "bugs": {
19
+ "url": "https://gitlab.com/zairakai/npm/dev-tools/-/issues",
20
+ "email": "contact-project+zairakai-npm-dev-tools-73530803-issue-@incoming.gitlab.com"
21
+ },
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://gitlab.com/zairakai/npm/dev-tools.git"
25
+ },
26
+ "funding": [
27
+ {
28
+ "type": "patreon",
29
+ "url": "https://www.patreon.com/c/zairakai"
30
+ },
31
+ {
32
+ "type": "twitch",
33
+ "url": "https://www.twitch.tv/zairakai"
34
+ }
35
+ ],
36
+ "license": "MIT",
37
+ "author": "Stanislas Poisson <stanislas.p@the-white-rabbits.fr> (https://the-white-rabbits.fr)",
38
+ "contributors": [
39
+ {
40
+ "name": "Stanislas Poisson",
41
+ "url": "https://gitlab.com/zairakai",
42
+ "role": "Maintainer"
43
+ }
44
+ ],
45
+ "type": "module",
46
+ "exports": {
47
+ ".": {
48
+ "import": "./index.js"
49
+ },
50
+ "./prettier": "./config/prettier.config.js",
51
+ "./eslint": "./config/eslint.config.js",
52
+ "./stylelint": "./config/stylelint.config.js",
53
+ "./vitest": "./config/vitest.config.js",
54
+ "./tsconfig": "./config/tsconfig.base.json",
55
+ "./config/*": "./config/*"
56
+ },
57
+ "main": "index.js",
58
+ "files": [
59
+ ".gitlab/",
60
+ "config/",
61
+ "scripts/",
62
+ "stubs/",
63
+ "tools/",
64
+ "index.js",
65
+ ".editorconfig",
66
+ "LICENSE",
67
+ "README.md"
68
+ ],
69
+ "scripts": {
70
+ "eslint": "eslint --config config/eslint.config.js config/*.{js,ts}",
71
+ "eslint:fix": "eslint --config config/eslint.config.js config/*.{js,ts} --fix",
72
+ "postinstall": "bash ./scripts/setup-project.sh --silent || true",
73
+ "markdownlint": "markdownlint '**/*.md' --config config/.markdownlint.json --ignore-path config/.markdownlintignore --ignore node_modules",
74
+ "markdownlint:fix": "markdownlint '**/*.md' --config config/.markdownlint.json --ignore-path config/.markdownlintignore --ignore node_modules --fix",
75
+ "package:normalize": "sort-package-json",
76
+ "prettier": "prettier . --check --config ./config/prettier.config.js --ignore-path ./config/.prettierignore",
77
+ "prettier:fix": "prettier . --write --config ./config/prettier.config.js --ignore-path ./config/.prettierignore",
78
+ "setup": "bash ./scripts/setup-project.sh",
79
+ "stylelint": "stylelint --config config/stylelint.config.js --ignore-path config/.stylelintignore '**/*.scss'",
80
+ "stylelint:fix": "stylelint --config config/stylelint.config.js --ignore-path config/.stylelintignore '**/*.scss' --fix",
81
+ "test": "bash ./scripts/test.sh",
82
+ "validate": "node --input-type=module < /dev/null"
83
+ },
84
+ "dependencies": {
85
+ "@eslint/js": "^9.34.0",
86
+ "@prettier/plugin-php": "^0.22.0",
87
+ "@typescript-eslint/eslint-plugin": "^8.40.0",
88
+ "@typescript-eslint/parser": "^8.40.0",
89
+ "eslint": "^9.0.0",
90
+ "eslint-config-prettier": "^9.1.0",
91
+ "eslint-plugin-vue": "^9.30.0",
92
+ "globals": "^16.3.0",
93
+ "markdownlint-cli": "^0.47.0",
94
+ "prettier": "^3.0.0",
95
+ "prettier-plugin-blade": "^2.1.0",
96
+ "prettier-plugin-organize-imports": "^3.2.4",
97
+ "sort-package-json": "^3.6.1",
98
+ "stylelint": "^16.0.0",
99
+ "stylelint-config-html": "^1.1.0",
100
+ "stylelint-config-recommended-vue": "^1.5.0",
101
+ "stylelint-config-standard": "^36.0.0",
102
+ "stylelint-config-standard-scss": "^13.0.0",
103
+ "stylelint-order": "^6.0.4",
104
+ "stylelint-scss": "^6.0.0",
105
+ "zod": "^3.0.0"
106
+ },
107
+ "devDependencies": {
108
+ "@vitest/coverage-v8": "^3.0.0",
109
+ "knip": "^5.85.0",
110
+ "typescript": "^5.9.3",
111
+ "vitest": "^3.0.0"
112
+ },
113
+ "peerDependencies": {
114
+ "eslint": "^9.0.0",
115
+ "prettier": "^3.0.0",
116
+ "stylelint": "^16.0.0",
117
+ "typedoc": "^0.28.0",
118
+ "zod": "^3.0.0"
119
+ },
120
+ "peerDependenciesMeta": {
121
+ "stylelint": {
122
+ "optional": true
123
+ },
124
+ "typedoc": {
125
+ "optional": true
126
+ },
127
+ "zod": {
128
+ "optional": true
129
+ }
130
+ },
131
+ "engines": {
132
+ "node": ">=22.0.0"
133
+ },
134
+ "publishConfig": {
135
+ "access": "public"
136
+ }
137
+ }
@@ -0,0 +1,54 @@
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
+ "$TSUP_BIN"
32
+ log_success "Build complete — output in dist/"
33
+
34
+ elif [[ -f "$TSC_BIN" ]]; then
35
+ log_info "Builder: tsc (official TypeScript compiler)"
36
+
37
+ if [[ ! -f "${PROJECT_ROOT}/tsconfig.json" ]]; then
38
+ log_error "No tsconfig.json found at project root"
39
+ log_info "Publish one with:"
40
+ log_info " bash node_modules/@zairakai/dev-tools/scripts/setup-project.sh --publish=tsconfig"
41
+ exit 1
42
+ fi
43
+
44
+ log_info "Config: tsconfig.json"
45
+ "$TSC_BIN"
46
+ log_success "Build complete"
47
+
48
+ else
49
+ log_error "No TypeScript builder found in node_modules/.bin/"
50
+ log_info "Install one of:"
51
+ log_info " npm install --save-dev tsup (recommended for npm packages)"
52
+ log_info " npm install --save-dev typescript (for apps or when you need full tsc control)"
53
+ exit 1
54
+ fi
@@ -0,0 +1,47 @@
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
+ run_check "Code Style (ESLint)" "bash '${SCRIPT_DIR}/eslint.sh'" || true
22
+ echo ""
23
+
24
+ run_check "Formatting (Prettier)" "bash '${SCRIPT_DIR}/prettier.sh'" || true
25
+ echo ""
26
+
27
+ run_check "CSS/SCSS (Stylelint)" "bash '${SCRIPT_DIR}/stylelint.sh'" || true
28
+ echo ""
29
+
30
+ # Markdown linting
31
+ run_check "Documentation (Markdownlint)" "bash '${SCRIPT_DIR}/markdownlint.sh'" || true
32
+ echo ""
33
+
34
+ # TypeScript type checking (optional — only if tsc + tsconfig.json are present)
35
+ if [[ -f "${PROJECT_ROOT}/tsconfig.json" ]] && [[ -f "${BIN_DIR}/tsc" ]]; then
36
+ run_check "TypeScript (tsc --noEmit)" "bash '${SCRIPT_DIR}/typecheck.sh'" || true
37
+ echo ""
38
+ else
39
+ log_info "TypeScript: no tsconfig.json or tsc — skipping"
40
+ echo ""
41
+ fi
42
+
43
+ if exit_with_error_count "Quality Checks"; then
44
+ exit 0
45
+ else
46
+ exit 1
47
+ fi
@@ -0,0 +1,193 @@
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/dev-tools/scripts/
10
+ # Dev context: npm/dev-tools/scripts/
11
+ if [[ "$SCRIPT_DIR" =~ /node_modules/@zairakai/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"
53
+
54
+ # ─── CONFIG RESOLUTION ────────────────────────────────────────────────────────
55
+ # Cascade: project root → config/dev-tools/ → 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. Bundled default in dev-tools package
72
+ if [[ -f "${DEV_TOOLS_ROOT}/config/${filename}" ]]; then
73
+ echo "${DEV_TOOLS_ROOT}/config/${filename}"
74
+ return 0
75
+ fi
76
+
77
+ echo ""
78
+ }
79
+
80
+ export -f resolve_config
81
+
82
+ # ─── COLORS ───────────────────────────────────────────────────────────────────
83
+ export RED='\033[0;31m'
84
+ export GREEN='\033[0;32m'
85
+ export YELLOW='\033[1;33m'
86
+ export BLUE='\033[0;34m'
87
+ export CYAN='\033[0;36m'
88
+ export MAGENTA='\033[0;35m'
89
+ export NC='\033[0m'
90
+
91
+ # ─── LOGGING ──────────────────────────────────────────────────────────────────
92
+ log_info() { echo -e "${CYAN}ℹ ${NC}$*"; }
93
+ log_success() { echo -e "${GREEN}✅ ${NC}$*"; }
94
+ log_warning() { echo -e "${YELLOW}⚠️ ${NC}$*"; }
95
+ log_error() { echo -e "${RED}❌ ${NC}$*" >&2; }
96
+ log_step() { echo -e "${BLUE}→${NC} $*"; }
97
+ log_header() { echo -e "\n${MAGENTA} $*${NC}\n${MAGENTA}════════════════${NC}\n"; }
98
+
99
+ # ─── BINARY CHECKS ────────────────────────────────────────────────────────────
100
+ ensure_bin() {
101
+ local bin="$1"
102
+ local name="${2:-$(basename "$bin")}"
103
+ if [[ ! -f "$bin" ]]; then
104
+ log_error "${name} not found in node_modules/.bin/"
105
+ log_error "Run: ${PM} install"
106
+ return 1
107
+ fi
108
+ }
109
+
110
+ ensure_bin_optional() {
111
+ local bin="$1"
112
+ local name="${2:-$(basename "$bin")}"
113
+ if [[ ! -f "$bin" ]]; then
114
+ log_warning "${name} not installed — skipping (optional)"
115
+ return 1
116
+ fi
117
+ return 0
118
+ }
119
+
120
+ # ─── ERROR COUNTER ────────────────────────────────────────────────────────────
121
+ ERROR_COUNT=0
122
+ init_error_counter() { ERROR_COUNT=0; }
123
+ increment_error_counter() { ERROR_COUNT=$((ERROR_COUNT + 1)); }
124
+ get_error_count() { echo "$ERROR_COUNT"; }
125
+
126
+ exit_with_error_count() {
127
+ local name="${1:-Checks}"
128
+ if [[ $ERROR_COUNT -eq 0 ]]; then
129
+ log_header "✅ All ${name} Passed"
130
+ return 0
131
+ else
132
+ log_header "❌ ${ERROR_COUNT} ${name} Failed"
133
+ return 1
134
+ fi
135
+ }
136
+
137
+ run_check() {
138
+ local name="$1"
139
+ local cmd="$2"
140
+ log_info "Running: ${name}"
141
+ if eval "$cmd"; then
142
+ log_success "${name} passed"
143
+ else
144
+ log_error "${name} failed"
145
+ increment_error_counter
146
+ return 1
147
+ fi
148
+ }
149
+
150
+ # ─── BACKUP ──────────────────────────────────────────────────────────────────
151
+ BACKUP_DIR=""
152
+ backup_file() {
153
+ local file="$1"
154
+ local base="${2:-${PROJECT_ROOT}/.dev-tools-backup}"
155
+ [[ ! -f "$file" || -L "$file" ]] && return 1
156
+ if [[ -z "$BACKUP_DIR" ]]; then
157
+ BACKUP_DIR="${base}/$(date +%Y%m%d-%H%M%S)"
158
+ mkdir -p "$BACKUP_DIR"
159
+ fi
160
+ local rel="${file#"${PROJECT_ROOT}"/}"
161
+ local dest="${BACKUP_DIR}/${rel}"
162
+ mkdir -p "$(dirname "$dest")"
163
+ cp "$file" "$dest" 2>/dev/null
164
+ }
165
+
166
+ # ─── HELPERS ──────────────────────────────────────────────────────────────────
167
+ command_exists() { command -v "$1" >/dev/null 2>&1; }
168
+ ensure_dir() {
169
+ if [[ ! -d "$1" ]]; then
170
+ mkdir -p "$1"
171
+ log_step "Created directory: $1"
172
+ fi
173
+ }
174
+
175
+ # ─── FILE PROTECTION (SHA-256) ────────────────────────────────────────────────
176
+ file_hash() {
177
+ local file="$1"
178
+ if command_exists sha256sum; then
179
+ sha256sum "$file" | cut -d' ' -f1
180
+ elif command_exists shasum; then
181
+ shasum -a 256 "$file" | cut -d' ' -f1
182
+ else
183
+ echo ""
184
+ fi
185
+ }
186
+
187
+ # ─── VALIDATION ───────────────────────────────────────────────────────────────
188
+ cd "$PROJECT_ROOT"
189
+
190
+ if [[ ! -d "${PROJECT_ROOT}/node_modules" ]]; then
191
+ log_error "Dependencies not installed. Run: ${PM} install"
192
+ exit 1
193
+ fi
@@ -0,0 +1,34 @@
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
+ ESLINT_CONFIG="$(resolve_config "eslint.config.js")"
13
+
14
+ if [[ -n "$ESLINT_CONFIG" ]]; then
15
+ log_step "Using configuration: ${ESLINT_CONFIG#"$PROJECT_ROOT"/}"
16
+ fi
17
+
18
+ if [[ "$PROJECT_TYPE" == "laravel-app" ]]; then
19
+ LINT_TARGET="${LINT_TARGET:-resources/js/}"
20
+ else
21
+ LINT_TARGET="${LINT_TARGET:-src/}"
22
+ fi
23
+
24
+ log_step "Fixing: $LINT_TARGET"
25
+
26
+ ESLINT_ARGS=(--fix)
27
+
28
+ if [[ -n "$ESLINT_CONFIG" ]] && [[ "$ESLINT_CONFIG" != "${PROJECT_ROOT}/eslint.config.js" ]]; then
29
+ ESLINT_ARGS+=(--config "$ESLINT_CONFIG")
30
+ fi
31
+
32
+ "$ESLINT_BIN" "${ESLINT_ARGS[@]}" "$LINT_TARGET"
33
+
34
+ log_success "ESLint fix applied"
@@ -0,0 +1,46 @@
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 Check"
9
+
10
+ ensure_bin "$ESLINT_BIN" "eslint" || exit 1
11
+
12
+ # Resolve config (cascade: root → config/dev-tools/ → bundled)
13
+ ESLINT_CONFIG="$(resolve_config "eslint.config.js")"
14
+
15
+ if [[ -n "$ESLINT_CONFIG" ]]; then
16
+ log_step "Using configuration: ${ESLINT_CONFIG#"$PROJECT_ROOT"/}"
17
+ else
18
+ log_warning "No ESLint configuration found — using ESLint defaults"
19
+ fi
20
+
21
+ # Lint target depends on project type (overridable via env)
22
+ if [[ "$PROJECT_TYPE" == "laravel-app" ]]; then
23
+ LINT_TARGET="${LINT_TARGET:-resources/js/}"
24
+ else
25
+ # Default to src/, but fallback to . if src/ doesn't exist
26
+ if [[ -z "${LINT_TARGET:-}" ]]; then
27
+ if [[ -d "${PROJECT_ROOT}/src" ]]; then
28
+ LINT_TARGET="src/"
29
+ else
30
+ LINT_TARGET="."
31
+ fi
32
+ fi
33
+ fi
34
+
35
+ log_step "Checking: $LINT_TARGET"
36
+
37
+ ESLINT_ARGS=()
38
+
39
+ # Only pass --config when the config is not at project root (ESLint 9 auto-discovers root)
40
+ if [[ -n "$ESLINT_CONFIG" ]] && [[ "$ESLINT_CONFIG" != "${PROJECT_ROOT}/eslint.config.js" ]]; then
41
+ ESLINT_ARGS+=(--config "$ESLINT_CONFIG")
42
+ fi
43
+
44
+ "$ESLINT_BIN" "${ESLINT_ARGS[@]}" "$LINT_TARGET"
45
+
46
+ log_success "ESLint check passed"