@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.
Files changed (69) hide show
  1. package/.editorconfig +86 -0
  2. package/.gitlab/ci/pipeline-js-app.yml +75 -0
  3. package/.gitlab/ci/pipeline-js-package.yml +360 -0
  4. package/LICENSE +21 -0
  5. package/README.md +206 -0
  6. package/config/.markdownlint.json +7 -0
  7. package/config/.markdownlintignore +5 -0
  8. package/config/.prettierignore +11 -0
  9. package/config/.stylelintignore +7 -0
  10. package/config/eslint.config.js +198 -0
  11. package/config/knip.config.js +40 -0
  12. package/config/prettier.config.js +121 -0
  13. package/config/stylelint.config.js +56 -0
  14. package/config/tsconfig.base.json +20 -0
  15. package/config/vitest.config.js +25 -0
  16. package/index.js +24 -0
  17. package/package.json +148 -0
  18. package/scripts/build.sh +58 -0
  19. package/scripts/ci-quality.sh +51 -0
  20. package/scripts/config.sh +254 -0
  21. package/scripts/doctor.sh +74 -0
  22. package/scripts/eslint-fix.sh +38 -0
  23. package/scripts/eslint.sh +49 -0
  24. package/scripts/install-bats.sh +227 -0
  25. package/scripts/install-hooks.sh +167 -0
  26. package/scripts/install-markdownlint.sh +31 -0
  27. package/scripts/install-shellcheck.sh +232 -0
  28. package/scripts/knip.sh +40 -0
  29. package/scripts/markdownlint-fix.sh +8 -0
  30. package/scripts/markdownlint.sh +84 -0
  31. package/scripts/outdated.sh +70 -0
  32. package/scripts/prettier-fix.sh +52 -0
  33. package/scripts/prettier.sh +53 -0
  34. package/scripts/setup-project.sh +816 -0
  35. package/scripts/stylelint-fix.sh +64 -0
  36. package/scripts/stylelint.sh +66 -0
  37. package/scripts/test.sh +40 -0
  38. package/scripts/typecheck.sh +41 -0
  39. package/scripts/validate-shellcheck.sh +70 -0
  40. package/stubs/githooks/commit-msg +34 -0
  41. package/stubs/githooks/pre-commit +58 -0
  42. package/stubs/githooks/pre-push +57 -0
  43. package/stubs/githooks/prepare-commit-msg +39 -0
  44. package/stubs/gitlab-ci/gitlab-ci.yml.stub +18 -0
  45. package/stubs/gitlab-ci/gitlab-pipeline-js-app.yml.stub +16 -0
  46. package/stubs/governance/CODE_OF_CONDUCT.md.stub +8 -0
  47. package/stubs/governance/CONTRIBUTING.md.stub +39 -0
  48. package/stubs/governance/SECURITY.md.stub +41 -0
  49. package/stubs/quality/eslint.config.js.stub +18 -0
  50. package/stubs/quality/knip.config.js.stub +14 -0
  51. package/stubs/style/prettier.config.js.stub +16 -0
  52. package/stubs/style/stylelint.config.js.stub +17 -0
  53. package/stubs/testing/vitest.config.js.stub +18 -0
  54. package/stubs/typescript/tsconfig.json.stub +10 -0
  55. package/tools/make/bats.mk +49 -0
  56. package/tools/make/code-style.mk +20 -0
  57. package/tools/make/core.mk +56 -0
  58. package/tools/make/help.mk +32 -0
  59. package/tools/make/knip.mk +7 -0
  60. package/tools/make/markdownlint.mk +17 -0
  61. package/tools/make/quality.mk +19 -0
  62. package/tools/make/shellcheck.mk +14 -0
  63. package/tools/make/stylelint.mk +11 -0
  64. package/tools/make/test.mk +19 -0
  65. package/tools/make/typescript.mk +10 -0
  66. package/tools/make/utils.mk +44 -0
  67. package/tools/make/variables.mk +42 -0
  68. package/tools/scripts/git-cleanup.sh +53 -0
  69. 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"
@@ -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 }