@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,64 @@
|
|
|
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
|
+
EXTRA_IGNORES=()
|
|
9
|
+
while [[ $# -gt 0 ]]; do
|
|
10
|
+
case "$1" in
|
|
11
|
+
--ignore) EXTRA_IGNORES+=("$2"); shift 2 ;;
|
|
12
|
+
--ignore=*) EXTRA_IGNORES+=("${1#--ignore=}"); shift ;;
|
|
13
|
+
*) shift ;;
|
|
14
|
+
esac
|
|
15
|
+
done
|
|
16
|
+
|
|
17
|
+
log_header "Stylelint Fix"
|
|
18
|
+
|
|
19
|
+
ensure_bin_optional "$STYLELINT_BIN" "stylelint" || exit 0
|
|
20
|
+
|
|
21
|
+
if [[ -n "$STYLELINT_CONFIG" ]]; then
|
|
22
|
+
log_step "Using configuration: ${STYLELINT_CONFIG#"$PROJECT_ROOT"/}"
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
if [[ "$PROJECT_TYPE" == "laravel-app" ]]; then
|
|
26
|
+
STYLELINT_TARGET="${STYLELINT_TARGET:-resources/**/*.scss}"
|
|
27
|
+
else
|
|
28
|
+
STYLELINT_TARGET="${STYLELINT_TARGET:-src/**/*.scss}"
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
log_step "Fixing: $STYLELINT_TARGET"
|
|
32
|
+
|
|
33
|
+
# Skip gracefully if no matching files exist
|
|
34
|
+
if ! has_files "${PROJECT_ROOT}/${STYLELINT_TARGET}"; then
|
|
35
|
+
log_info "No SCSS/CSS files found matching ${STYLELINT_TARGET} — skipping"
|
|
36
|
+
exit 0
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
STYLELINT_ARGS=(--fix)
|
|
40
|
+
|
|
41
|
+
if [[ -n "$STYLELINT_CONFIG" ]] && [[ "$STYLELINT_CONFIG" != "${PROJECT_ROOT}/stylelint.config.js" ]]; then
|
|
42
|
+
STYLELINT_ARGS+=(--config "$STYLELINT_CONFIG")
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
if [[ -n "$STYLELINT_IGNORE" ]]; then
|
|
46
|
+
STYLELINT_ARGS+=(--ignore-path "$STYLELINT_IGNORE")
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# Also respect .gitignore if present
|
|
50
|
+
if [[ -f "${PROJECT_ROOT}/.gitignore" ]]; then
|
|
51
|
+
STYLELINT_ARGS+=(--ignore-path "${PROJECT_ROOT}/.gitignore")
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# Extra ignores passed via --ignore → temp file (gitignore format)
|
|
55
|
+
if [[ ${#EXTRA_IGNORES[@]} -gt 0 ]]; then
|
|
56
|
+
_TMP_IGNORE=$(mktemp)
|
|
57
|
+
trap 'rm -f "$_TMP_IGNORE"' EXIT
|
|
58
|
+
printf '%s\n' "${EXTRA_IGNORES[@]}" > "$_TMP_IGNORE"
|
|
59
|
+
STYLELINT_ARGS+=(--ignore-path "$_TMP_IGNORE")
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
"$STYLELINT_BIN" "${STYLELINT_ARGS[@]}" "$STYLELINT_TARGET"
|
|
63
|
+
|
|
64
|
+
log_success "Stylelint fix applied"
|
|
@@ -0,0 +1,66 @@
|
|
|
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
|
+
EXTRA_IGNORES=()
|
|
9
|
+
while [[ $# -gt 0 ]]; do
|
|
10
|
+
case "$1" in
|
|
11
|
+
--ignore) EXTRA_IGNORES+=("$2"); shift 2 ;;
|
|
12
|
+
--ignore=*) EXTRA_IGNORES+=("${1#--ignore=}"); shift ;;
|
|
13
|
+
*) shift ;;
|
|
14
|
+
esac
|
|
15
|
+
done
|
|
16
|
+
|
|
17
|
+
log_header "Stylelint Check"
|
|
18
|
+
|
|
19
|
+
# Stylelint is optional — skip gracefully if not installed
|
|
20
|
+
ensure_bin_optional "$STYLELINT_BIN" "stylelint" || exit 0
|
|
21
|
+
|
|
22
|
+
if [[ -n "$STYLELINT_CONFIG" ]]; then
|
|
23
|
+
log_step "Using configuration: ${STYLELINT_CONFIG#"$PROJECT_ROOT"/}"
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
# Lint target depends on project type (overridable via env)
|
|
27
|
+
if [[ "$PROJECT_TYPE" == "laravel-app" ]]; then
|
|
28
|
+
STYLELINT_TARGET="${STYLELINT_TARGET:-resources/**/*.scss}"
|
|
29
|
+
else
|
|
30
|
+
STYLELINT_TARGET="${STYLELINT_TARGET:-src/**/*.scss}"
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
log_step "Checking: $STYLELINT_TARGET"
|
|
34
|
+
|
|
35
|
+
# Skip gracefully if no matching files exist (stylelint v16 errors on empty glob)
|
|
36
|
+
if ! has_files "${PROJECT_ROOT}/${STYLELINT_TARGET}"; then
|
|
37
|
+
log_info "No SCSS/CSS files found matching ${STYLELINT_TARGET} — skipping"
|
|
38
|
+
exit 0
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
STYLELINT_ARGS=()
|
|
42
|
+
|
|
43
|
+
if [[ -n "$STYLELINT_CONFIG" ]] && [[ "$STYLELINT_CONFIG" != "${PROJECT_ROOT}/stylelint.config.js" ]]; then
|
|
44
|
+
STYLELINT_ARGS+=(--config "$STYLELINT_CONFIG")
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
if [[ -n "$STYLELINT_IGNORE" ]]; then
|
|
48
|
+
STYLELINT_ARGS+=(--ignore-path "$STYLELINT_IGNORE")
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# Also respect .gitignore if present
|
|
52
|
+
if [[ -f "${PROJECT_ROOT}/.gitignore" ]]; then
|
|
53
|
+
STYLELINT_ARGS+=(--ignore-path "${PROJECT_ROOT}/.gitignore")
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# Extra ignores passed via --ignore → temp file (gitignore format)
|
|
57
|
+
if [[ ${#EXTRA_IGNORES[@]} -gt 0 ]]; then
|
|
58
|
+
_TMP_IGNORE=$(mktemp)
|
|
59
|
+
trap 'rm -f "$_TMP_IGNORE"' EXIT
|
|
60
|
+
printf '%s\n' "${EXTRA_IGNORES[@]}" > "$_TMP_IGNORE"
|
|
61
|
+
STYLELINT_ARGS+=(--ignore-path "$_TMP_IGNORE")
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
"$STYLELINT_BIN" "${STYLELINT_ARGS[@]}" "$STYLELINT_TARGET"
|
|
65
|
+
|
|
66
|
+
log_success "Stylelint check passed"
|
package/scripts/test.sh
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
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 "Vitest Tests"
|
|
9
|
+
|
|
10
|
+
if ! ensure_bin_optional "$VITEST_BIN" "vitest"; then
|
|
11
|
+
log_warning "vitest not installed — add it to devDependencies to run tests"
|
|
12
|
+
exit 0
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
COVERAGE="${COVERAGE:-false}"
|
|
16
|
+
CI="${CI:-false}"
|
|
17
|
+
|
|
18
|
+
# CI mode: always run with coverage
|
|
19
|
+
if [[ "$CI" == "true" ]]; then
|
|
20
|
+
log_info "Running in CI mode (strict + coverage)"
|
|
21
|
+
COVERAGE="true"
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
VITEST_ARGS=()
|
|
25
|
+
|
|
26
|
+
if [[ -n "$VITEST_CONFIG" ]]; then
|
|
27
|
+
log_step "Using configuration: ${VITEST_CONFIG#"$PROJECT_ROOT"/}"
|
|
28
|
+
VITEST_ARGS+=(--config "$VITEST_CONFIG")
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
if [[ "$COVERAGE" == "true" ]]; then
|
|
32
|
+
log_info "Running with coverage report"
|
|
33
|
+
ensure_dir "build/coverage"
|
|
34
|
+
ensure_dir "build/logs"
|
|
35
|
+
"$VITEST_BIN" run --coverage --passWithNoTests "${VITEST_ARGS[@]}"
|
|
36
|
+
else
|
|
37
|
+
"$VITEST_BIN" run --passWithNoTests "${VITEST_ARGS[@]}"
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
log_success "Tests passed"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# TypeScript Type Checking (tsc --noEmit)
|
|
4
|
+
# Validates types without emitting output files.
|
|
5
|
+
# Equivalent to PHPStan for TypeScript.
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# bash scripts/typecheck.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
|
+
TSC_BIN="${BIN_DIR}/tsc"
|
|
18
|
+
|
|
19
|
+
log_header "TypeScript Type Checking"
|
|
20
|
+
|
|
21
|
+
ensure_bin "$TSC_BIN" "tsc (typescript)"
|
|
22
|
+
|
|
23
|
+
if [[ ! -f "${PROJECT_ROOT}/tsconfig.json" ]]; then
|
|
24
|
+
log_error "No tsconfig.json found at project root"
|
|
25
|
+
log_info "Publish one with:"
|
|
26
|
+
log_info " bash node_modules/@zairakai/js-dev-tools/scripts/setup-project.sh --publish=tsconfig"
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
log_info "Config: tsconfig.json"
|
|
31
|
+
log_info "Mode: --noEmit (type validation only)"
|
|
32
|
+
|
|
33
|
+
# Skip gracefully if no .ts files are found
|
|
34
|
+
if ! has_files "${PROJECT_ROOT}/**/*.ts" && ! has_files "${PROJECT_ROOT}/**/*.tsx"; then
|
|
35
|
+
log_info "No TypeScript files found — skipping"
|
|
36
|
+
exit 0
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
"$TSC_BIN" --noEmit
|
|
40
|
+
|
|
41
|
+
log_success "TypeScript type checking passed"
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# scripts/validate-shellcheck.sh
|
|
3
|
+
# Runs ShellCheck validation on all shell scripts (100% compliance required)
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# bash scripts/validate-shellcheck.sh
|
|
7
|
+
#
|
|
8
|
+
# Environment Variables:
|
|
9
|
+
# SHELLCHECK_SEVERITY - Severity level (default: warning)
|
|
10
|
+
# SHELLCHECK_FORMAT - Output format (default: gcc)
|
|
11
|
+
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
|
|
14
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
15
|
+
# shellcheck disable=SC1091
|
|
16
|
+
source "${SCRIPT_DIR}/config.sh"
|
|
17
|
+
|
|
18
|
+
SEVERITY="${SHELLCHECK_SEVERITY:-warning}"
|
|
19
|
+
FORMAT="${SHELLCHECK_FORMAT:-gcc}"
|
|
20
|
+
|
|
21
|
+
log_header "Running ShellCheck Validation"
|
|
22
|
+
log_info "Severity: ${SEVERITY}"
|
|
23
|
+
log_info "Format: ${FORMAT}"
|
|
24
|
+
|
|
25
|
+
if ! command_exists shellcheck; then
|
|
26
|
+
log_error "ShellCheck not found. Please install shellcheck."
|
|
27
|
+
log_info " Alpine: apk add shellcheck"
|
|
28
|
+
log_info " Debian/Ubuntu: apt-get install shellcheck"
|
|
29
|
+
log_info " macOS: brew install shellcheck"
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
SHELLCHECK_VERSION="$(shellcheck --version | grep "version:" | awk '{print $2}')"
|
|
34
|
+
log_info "ShellCheck version: ${SHELLCHECK_VERSION}"
|
|
35
|
+
|
|
36
|
+
log_info "→ Finding shell scripts…"
|
|
37
|
+
|
|
38
|
+
mapfile -t SHELL_SCRIPTS < <(find . \( -name "*.sh" -o -name "*.bats" \) -type f ! -path "*/node_modules/*" ! -path "*/dist/*" ! -path "*/build/*")
|
|
39
|
+
|
|
40
|
+
SCRIPT_COUNT=${#SHELL_SCRIPTS[@]}
|
|
41
|
+
log_info "Found ${SCRIPT_COUNT} shell scripts"
|
|
42
|
+
|
|
43
|
+
if [[ ${SCRIPT_COUNT} -eq 0 ]]; then
|
|
44
|
+
log_warning "No shell scripts found"
|
|
45
|
+
exit 0
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
log_info "→ Running ShellCheck validation…"
|
|
49
|
+
|
|
50
|
+
FAILED=0
|
|
51
|
+
TOTAL=0
|
|
52
|
+
|
|
53
|
+
for script in "${SHELL_SCRIPTS[@]}"; do
|
|
54
|
+
TOTAL=$((TOTAL + 1))
|
|
55
|
+
|
|
56
|
+
if shellcheck --severity="${SEVERITY}" --format="${FORMAT}" "${script}"; then
|
|
57
|
+
:
|
|
58
|
+
else
|
|
59
|
+
log_error " ✗ ${script} — ShellCheck failed"
|
|
60
|
+
FAILED=$((FAILED + 1))
|
|
61
|
+
fi
|
|
62
|
+
done
|
|
63
|
+
|
|
64
|
+
if [[ ${FAILED} -eq 0 ]]; then
|
|
65
|
+
log_success "All ${TOTAL} scripts passed ShellCheck"
|
|
66
|
+
exit 0
|
|
67
|
+
else
|
|
68
|
+
log_error "${FAILED}/${TOTAL} scripts failed ShellCheck"
|
|
69
|
+
exit 1
|
|
70
|
+
fi
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Zairakai Git Hooks - Commit Message Validator
|
|
4
|
+
# Ensures commit messages follow Conventional Commits format
|
|
5
|
+
#
|
|
6
|
+
# To bypass (emergency only):
|
|
7
|
+
# git commit --no-verify
|
|
8
|
+
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
# ANSI Colors
|
|
12
|
+
RED='\033[0;31m'
|
|
13
|
+
NC='\033[0m'
|
|
14
|
+
|
|
15
|
+
COMMIT_MSG_FILE=$1
|
|
16
|
+
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
|
|
17
|
+
|
|
18
|
+
# Conventional Commits regex
|
|
19
|
+
# Format: <type>(<scope>): <subject>
|
|
20
|
+
CONVENTIONAL_RE='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert|init)(\(.+\))?!?: .+$'
|
|
21
|
+
|
|
22
|
+
if [[ ! $COMMIT_MSG =~ $CONVENTIONAL_RE ]]; then
|
|
23
|
+
echo ""
|
|
24
|
+
echo -e "${RED}❌ Invalid commit message format!${NC}"
|
|
25
|
+
echo ""
|
|
26
|
+
echo "Commit messages must follow Conventional Commits:"
|
|
27
|
+
echo " feat: add new feature"
|
|
28
|
+
echo " fix: resolve a bug"
|
|
29
|
+
echo " chore(deps): update dependencies"
|
|
30
|
+
echo ""
|
|
31
|
+
echo "See: https://www.conventionalcommits.org/"
|
|
32
|
+
echo ""
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Zairakai Git Hooks - Pre-Commit Quality Checks
|
|
4
|
+
# Runs quick quality checks before allowing commit
|
|
5
|
+
#
|
|
6
|
+
# To bypass (emergency only):
|
|
7
|
+
# git commit --no-verify
|
|
8
|
+
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
# ANSI Colors
|
|
12
|
+
RED='\033[0;31m'
|
|
13
|
+
GREEN='\033[0;32m'
|
|
14
|
+
YELLOW='\033[1;33m'
|
|
15
|
+
BLUE='\033[0;34m'
|
|
16
|
+
CYAN='\033[0;36m'
|
|
17
|
+
NC='\033[0m'
|
|
18
|
+
|
|
19
|
+
echo ""
|
|
20
|
+
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
21
|
+
echo -e "${CYAN} Pre-Commit Quality Checks${NC}"
|
|
22
|
+
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
23
|
+
echo ""
|
|
24
|
+
|
|
25
|
+
# Navigate to project root
|
|
26
|
+
PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
|
|
27
|
+
cd "$PROJECT_ROOT"
|
|
28
|
+
|
|
29
|
+
# Check if make is available
|
|
30
|
+
if ! command -v make &>/dev/null; then
|
|
31
|
+
echo -e "${RED}❌ make not found - skipping quality checks${NC}"
|
|
32
|
+
echo ""
|
|
33
|
+
exit 0
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Run fast quality checks (eslint + prettier + markdown)
|
|
37
|
+
echo -e "${BLUE}→${NC} Running: ${CYAN}make quality-fast${NC}"
|
|
38
|
+
echo ""
|
|
39
|
+
|
|
40
|
+
if make quality-fast; then
|
|
41
|
+
echo ""
|
|
42
|
+
echo -e "${GREEN}✅ Quality checks passed - commit allowed${NC}"
|
|
43
|
+
echo ""
|
|
44
|
+
exit 0
|
|
45
|
+
else
|
|
46
|
+
echo ""
|
|
47
|
+
echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
48
|
+
echo -e "${RED} ❌ Quality checks failed!${NC}"
|
|
49
|
+
echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
50
|
+
echo ""
|
|
51
|
+
echo -e "${YELLOW}Fix issues with:${NC}"
|
|
52
|
+
echo -e " ${CYAN}make quality-fix${NC} ${YELLOW}# Auto-fix what can be fixed${NC}"
|
|
53
|
+
echo ""
|
|
54
|
+
echo -e "${YELLOW}Or bypass (NOT recommended):${NC}"
|
|
55
|
+
echo -e " ${CYAN}git commit --no-verify${NC}"
|
|
56
|
+
echo ""
|
|
57
|
+
exit 1
|
|
58
|
+
fi
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Zairakai Git Hooks - Pre-Push Quality Gate
|
|
4
|
+
# Runs full quality checks and tests before allowing push
|
|
5
|
+
#
|
|
6
|
+
# To bypass (emergency only):
|
|
7
|
+
# git push --no-verify
|
|
8
|
+
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
# ANSI Colors
|
|
12
|
+
RED='\033[0;31m'
|
|
13
|
+
GREEN='\033[0;32m'
|
|
14
|
+
YELLOW='\033[1;33m'
|
|
15
|
+
BLUE='\033[0;34m'
|
|
16
|
+
CYAN='\033[0;36m'
|
|
17
|
+
NC='\033[0m'
|
|
18
|
+
|
|
19
|
+
echo ""
|
|
20
|
+
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
21
|
+
echo -e "${CYAN} Pre-Push Quality Gate${NC}"
|
|
22
|
+
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
23
|
+
echo ""
|
|
24
|
+
|
|
25
|
+
# Navigate to project root
|
|
26
|
+
PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
|
|
27
|
+
cd "$PROJECT_ROOT"
|
|
28
|
+
|
|
29
|
+
# Check if make is available
|
|
30
|
+
if ! command -v make &>/dev/null; then
|
|
31
|
+
echo -e "${RED}❌ make not found - skipping quality checks${NC}"
|
|
32
|
+
echo ""
|
|
33
|
+
exit 0
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Run full quality gate (quality + tests)
|
|
37
|
+
echo -e "${BLUE}→${NC} Running: ${CYAN}make ci${NC}"
|
|
38
|
+
echo ""
|
|
39
|
+
|
|
40
|
+
if make ci; then
|
|
41
|
+
echo ""
|
|
42
|
+
echo -e "${GREEN}✅ All quality gates passed - push allowed${NC}"
|
|
43
|
+
echo ""
|
|
44
|
+
exit 0
|
|
45
|
+
else
|
|
46
|
+
echo ""
|
|
47
|
+
echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
48
|
+
echo -e "${RED} ❌ Quality gate failed!${NC}"
|
|
49
|
+
echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
50
|
+
echo ""
|
|
51
|
+
echo -e "${YELLOW}Fix issues or run local tests before pushing.${NC}"
|
|
52
|
+
echo ""
|
|
53
|
+
echo -e "${YELLOW}Or bypass (NOT recommended):${NC}"
|
|
54
|
+
echo -e " ${CYAN}git push --no-verify${NC}"
|
|
55
|
+
echo ""
|
|
56
|
+
exit 1
|
|
57
|
+
fi
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Zairakai Git Hooks - Commit Message Preparer
|
|
4
|
+
# Auto-prefixes the ticket number from branch name (e.g. feature/ABC-123 -> ABC-123: )
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
|
|
9
|
+
COMMIT_MSG_FILE=$1
|
|
10
|
+
BRANCH_NAME=$(git symbolic-ref --short HEAD 2>/dev/null || true)
|
|
11
|
+
|
|
12
|
+
# Skip for special commits
|
|
13
|
+
COMMIT_SOURCE=${2:-}
|
|
14
|
+
if [[ "$COMMIT_SOURCE" == "merge" || "$COMMIT_SOURCE" == "squash" || "$COMMIT_SOURCE" == "message" ]]; then
|
|
15
|
+
exit 0
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
# Extract ticket number (Jira/GitLab style: PROJECT-123)
|
|
19
|
+
TICKET_RE='[A-Z]+-[0-9]+'
|
|
20
|
+
if [[ $BRANCH_NAME =~ $TICKET_RE ]]; then
|
|
21
|
+
TICKET="${BASH_REMATCH[0]}"
|
|
22
|
+
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
|
|
23
|
+
|
|
24
|
+
# Only prefix if not already present
|
|
25
|
+
if [[ ! $COMMIT_MSG =~ $TICKET ]]; then
|
|
26
|
+
# If it's a conventional commit type: subject format, inject after type:
|
|
27
|
+
# Before: feat: my change
|
|
28
|
+
# After: feat(ABC-123): my change
|
|
29
|
+
CONVENTIONAL_RE='^([a-z]+)(\(.*\))?!?: (.+)$'
|
|
30
|
+
if [[ $COMMIT_MSG =~ $CONVENTIONAL_RE ]]; then
|
|
31
|
+
TYPE="${BASH_REMATCH[1]}"
|
|
32
|
+
REMAINDER="${BASH_REMATCH[3]}"
|
|
33
|
+
echo "${TYPE}(${TICKET}): ${REMAINDER}" > "$COMMIT_MSG_FILE"
|
|
34
|
+
else
|
|
35
|
+
# Fallback: simple prefix
|
|
36
|
+
echo "${TICKET}: ${COMMIT_MSG}" > "$COMMIT_MSG_FILE"
|
|
37
|
+
fi
|
|
38
|
+
fi
|
|
39
|
+
fi
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# .gitlab-ci.yml
|
|
2
|
+
# Generated by @zairakai/js-dev-tools setup-project.sh
|
|
3
|
+
# Inherits the full shared template — only project-specific variables are defined here.
|
|
4
|
+
#
|
|
5
|
+
# To regenerate:
|
|
6
|
+
# bash node_modules/@zairakai/js-dev-tools/scripts/setup-project.sh --publish=gitlab-ci --force
|
|
7
|
+
|
|
8
|
+
include:
|
|
9
|
+
- project: 'zairakai/npm-packages/js-dev-tools'
|
|
10
|
+
ref: v0.0.0
|
|
11
|
+
file: '.gitlab/ci/pipeline-js-package.yml'
|
|
12
|
+
|
|
13
|
+
variables:
|
|
14
|
+
# Unique cache key for this project (update suffix when changing dependencies)
|
|
15
|
+
CACHE_KEY: "PACKAGE_CACHE_KEY"
|
|
16
|
+
|
|
17
|
+
# Full package name on npm (used in the GitLab release link)
|
|
18
|
+
NPM_PACKAGE_NAME: "PACKAGE_NPM_NAME"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# .gitlab/pipeline-js-app.yml
|
|
2
|
+
# JavaScript/Frontend CI jobs for this Laravel application.
|
|
3
|
+
# Generated by @zairakai/js-dev-tools setup-project.sh
|
|
4
|
+
# Included from .gitlab-ci.yml via: include: - local: '.gitlab/pipeline-js-app.yml'
|
|
5
|
+
#
|
|
6
|
+
# To regenerate:
|
|
7
|
+
# bash node_modules/@zairakai/js-dev-tools/scripts/setup-project.sh --publish=gitlab-ci --force
|
|
8
|
+
|
|
9
|
+
include:
|
|
10
|
+
- project: 'zairakai/npm-packages/js-dev-tools'
|
|
11
|
+
ref: v0.0.0
|
|
12
|
+
file: '.gitlab/ci/pipeline-js-app.yml'
|
|
13
|
+
|
|
14
|
+
variables:
|
|
15
|
+
# Unique JS cache key for this project
|
|
16
|
+
CACHE_KEY: "PACKAGE_CACHE_KEY"
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
> This project adheres to the [Zairakai Code of Conduct][handbook-coc].
|
|
4
|
+
>
|
|
5
|
+
> Instances of abusive, harassing, or otherwise unacceptable behavior may be reported
|
|
6
|
+
> by contacting the project team at `contact@the-white-rabbits.fr`.
|
|
7
|
+
|
|
8
|
+
[handbook-coc]: https://gitlab.com/zairakai/handbook/-/blob/main/CODE_OF_CONDUCT.md
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
> This project follows the [Zairakai Global Contributing Guide][handbook-contributing].
|
|
4
|
+
> Please read it before contributing. The sections below document project-specific workflow.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Development Workflow
|
|
9
|
+
|
|
10
|
+
| Step | Command / Action | Description |
|
|
11
|
+
| :--- | :--- | :--- |
|
|
12
|
+
| **1. Install** | `npm install && bash scripts/install-hooks.sh` | Install dependencies and set up git hooks. |
|
|
13
|
+
| **2. Branch** | `git checkout -b feature/#TICKET-name` | Create a feature branch from `main`. |
|
|
14
|
+
| **3. Code** | *(your IDE)* | Implement your changes following quality standards. |
|
|
15
|
+
| **4. Quality** | `make quality` | Run the full quality gate. |
|
|
16
|
+
| **5. Test** | `make test-all` | Ensure all tests (Vitest + BATS) are passing. |
|
|
17
|
+
| **6. Commit** | `git commit -m "type(scope): #TICKET subject"` | Use [Conventional Commits][git-rules] format. |
|
|
18
|
+
| **7. Push** | `git push origin feature/#TICKET-name` | Push and open a Merge Request to `main`. |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Quality Targets
|
|
23
|
+
|
|
24
|
+
| Command | Tool | Description |
|
|
25
|
+
| :--- | :--- | :--- |
|
|
26
|
+
| `make quality` | All | Full static analysis and formatting gate. |
|
|
27
|
+
| `make eslint` | ESLint | Run JS/TS static analysis. |
|
|
28
|
+
| `make prettier` | Prettier | Check code formatting. |
|
|
29
|
+
| `make stylelint` | Stylelint | Run SCSS/CSS static analysis. |
|
|
30
|
+
| `make typecheck` | TSC | Run TypeScript type checking. |
|
|
31
|
+
| `make markdownlint` | Markdownlint | Validate Markdown documentation. |
|
|
32
|
+
| `make test` | Vitest | Run unit tests with coverage. |
|
|
33
|
+
| `make bats` | BATS | Run shell script integration tests. |
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
[handbook-contributing]: https://gitlab.com/zairakai/handbook/-/blob/main/CONTRIBUTING.md
|
|
38
|
+
[git-rules]: https://gitlab.com/zairakai/handbook/-/blob/main/policies/git-rules.md
|
|
39
|
+
[issues]: PACKAGE_GITLAB_ISSUES
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
> This project follows the [Zairakai Global Security Policy][handbook-security].
|
|
4
|
+
> Please refer to it for standard protections, response timeline, and contact information.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 🔒 Reporting Vulnerabilities
|
|
9
|
+
|
|
10
|
+
| Channel | Description | Contact / Link |
|
|
11
|
+
| :--- | :--- | :--- |
|
|
12
|
+
| **GitLab Issues** | For non-sensitive issues (bugs, public vulnerabilities). | [Open Issue][issues] |
|
|
13
|
+
| **Service Desk** | Preferred channel for sensitive reports. | `TODO: add your project service desk email` |
|
|
14
|
+
| **Email** | Alternative secure contact. | `security@the-white-rabbits.fr` |
|
|
15
|
+
|
|
16
|
+
Please **do not disclose vulnerabilities publicly** until they have been reviewed.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 🛡️ Security Features
|
|
21
|
+
|
|
22
|
+
### Protection Layers
|
|
23
|
+
|
|
24
|
+
| Layer | Security Protection |
|
|
25
|
+
| :--- | :--- |
|
|
26
|
+
| **Static Analysis** | Strict TypeScript configs and ESLint security rules. |
|
|
27
|
+
| **Execution** | Controlled shell execution via `config.sh` and `scripts/`. |
|
|
28
|
+
| **Filesystem** | Non-destructive defaults for file generation and publishing. |
|
|
29
|
+
| **Git Hooks** | Isolated quality enforcement in project scope (`.githooks`). |
|
|
30
|
+
| **CI Pipeline** | Automated secret detection and ShellCheck validation. |
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 🔍 Security Scope
|
|
35
|
+
|
|
36
|
+
<!-- TODO: describe what this package interacts with (filesystem, network, shell, etc.) -->
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
[handbook-security]: https://gitlab.com/zairakai/handbook/-/blob/main/SECURITY.md
|
|
41
|
+
[issues]: PACKAGE_GITLAB_ISSUES
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project ESLint configuration.
|
|
3
|
+
* Extends the @zairakai/js-dev-tools base config — customize as needed.
|
|
4
|
+
*
|
|
5
|
+
* Example of adding project-specific rules:
|
|
6
|
+
* export default [
|
|
7
|
+
* ...baseConfig,
|
|
8
|
+
* {
|
|
9
|
+
* rules: {
|
|
10
|
+
* 'no-console': 'warn',
|
|
11
|
+
* },
|
|
12
|
+
* },
|
|
13
|
+
* ]
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import baseConfig from '@zairakai/js-dev-tools/config/eslint.config.js'
|
|
17
|
+
|
|
18
|
+
export default [...baseConfig]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knip configuration
|
|
3
|
+
* @see https://knip.dev/reference/configuration
|
|
4
|
+
*/
|
|
5
|
+
export default {
|
|
6
|
+
// Extend the base configuration from @zairakai/js-dev-tools
|
|
7
|
+
// (Assuming the base config is compatible or you want to start fresh)
|
|
8
|
+
// For now, we point to the project structure
|
|
9
|
+
entry: ['src/index.ts!', 'src/index.js!'],
|
|
10
|
+
project: ['src/**/*.ts!', 'src/**/*.js!'],
|
|
11
|
+
ignore: ['**/*.d.ts'],
|
|
12
|
+
ignoreDependencies: [],
|
|
13
|
+
ignoreBinaries: [],
|
|
14
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Prettier configuration.
|
|
3
|
+
* Extends the @zairakai/js-dev-tools base config — customize as needed.
|
|
4
|
+
*
|
|
5
|
+
* Example of adding project-specific overrides:
|
|
6
|
+
* module.exports = {
|
|
7
|
+
* ...baseConfig,
|
|
8
|
+
* printWidth: 100,
|
|
9
|
+
* }
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const baseConfig = require('@zairakai/js-dev-tools/config/prettier.config.js')
|
|
13
|
+
|
|
14
|
+
module.exports = {
|
|
15
|
+
...baseConfig,
|
|
16
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Stylelint configuration.
|
|
3
|
+
* Extends the @zairakai/js-dev-tools base config — customize as needed.
|
|
4
|
+
*
|
|
5
|
+
* Example of adding project-specific rules:
|
|
6
|
+
* export default {
|
|
7
|
+
* ...baseConfig,
|
|
8
|
+
* rules: {
|
|
9
|
+
* ...baseConfig.rules,
|
|
10
|
+
* 'color-no-invalid-hex': true,
|
|
11
|
+
* },
|
|
12
|
+
* }
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import baseConfig from '@zairakai/js-dev-tools/config/stylelint.config.js'
|
|
16
|
+
|
|
17
|
+
export default { ...baseConfig }
|