@zairakai/js-dev-tools 1.0.0 → 1.2.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.
@@ -41,6 +41,7 @@ include:
41
41
  workflow:
42
42
  rules:
43
43
  - if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
44
+ - if: $CI_PIPELINE_SOURCE == "schedule"
44
45
  - if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_MERGE_REQUEST_ID
45
46
  - if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "develop"
46
47
  - if: $CI_COMMIT_REF_NAME =~ /^feature\// || $CI_COMMIT_REF_NAME =~ /^fix\// || $CI_COMMIT_REF_NAME =~ /^hotfix\//
@@ -240,6 +241,8 @@ js:quality:bats:
240
241
  js:quality:outdated:
241
242
  <<: *job_node
242
243
  stage: quality
244
+ rules:
245
+ - if: $CI_PIPELINE_SOURCE == "schedule"
243
246
  script:
244
247
  - bash "$DEV_TOOLS_SCRIPTS/outdated.sh"
245
248
  artifacts:
@@ -16,15 +16,13 @@ const gitignoreConfig = existsSync(gitignorePath) ? [includeIgnoreFile(gitignore
16
16
 
17
17
  export default [
18
18
  ...gitignoreConfig,
19
+
19
20
  // Base JavaScript rules
20
21
  pluginJs.configs.recommended,
21
22
 
22
- // Vue configurations
23
+ // Vue flat config (sets up vue-eslint-parser as the Vue file parser)
23
24
  ...pluginVue.configs['flat/strongly-recommended'],
24
25
 
25
- // Prettier integration (must be last)
26
- eslintConfigPrettier,
27
-
28
26
  // Base configuration for all files
29
27
  {
30
28
  languageOptions: {
@@ -112,25 +110,56 @@ export default [
112
110
  },
113
111
  },
114
112
 
115
- // TypeScript specific configuration
113
+ // TypeScript configuration for .ts / .tsx files
116
114
  {
117
- files: ['**/*.ts', '**/*.tsx', '**/*.vue'],
115
+ files: ['**/*.ts', '**/*.tsx'],
118
116
  languageOptions: {
119
117
  parser: parserTypeScript,
120
118
  parserOptions: {
121
119
  project: './tsconfig.json',
122
- extraFileExtensions: ['.vue'],
123
120
  },
124
121
  },
125
122
  plugins: {
126
123
  '@typescript-eslint': pluginTypeScript,
127
124
  },
128
125
  rules: {
129
- // Disable JS rules that conflict with TS
130
126
  'no-unused-vars': 'off',
131
127
  'no-undef': 'off',
128
+ '@typescript-eslint/no-unused-vars': [
129
+ 'error',
130
+ {
131
+ argsIgnorePattern: '^_',
132
+ varsIgnorePattern: '^_',
133
+ caughtErrorsIgnorePattern: '^_',
134
+ },
135
+ ],
136
+ '@typescript-eslint/no-explicit-any': 'warn',
137
+ '@typescript-eslint/explicit-function-return-type': 'off',
138
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
139
+ '@typescript-eslint/prefer-nullish-coalescing': 'error',
140
+ '@typescript-eslint/prefer-optional-chain': 'error',
141
+ '@typescript-eslint/no-non-null-assertion': 'warn',
142
+ },
143
+ },
132
144
 
133
- // Enable TS rules
145
+ // TypeScript configuration for .vue files
146
+ // vue-eslint-parser (set by pluginVue above) must remain the primary parser.
147
+ // TypeScript parser is passed as parserOptions.parser for <script> blocks only.
148
+ {
149
+ files: ['**/*.vue'],
150
+ languageOptions: {
151
+ parserOptions: {
152
+ parser: parserTypeScript,
153
+ project: './tsconfig.json',
154
+ extraFileExtensions: ['.vue'],
155
+ },
156
+ },
157
+ plugins: {
158
+ '@typescript-eslint': pluginTypeScript,
159
+ },
160
+ rules: {
161
+ 'no-unused-vars': 'off',
162
+ 'no-undef': 'off',
134
163
  '@typescript-eslint/no-unused-vars': [
135
164
  'error',
136
165
  {
@@ -148,13 +177,12 @@ export default [
148
177
  },
149
178
  },
150
179
 
151
- // Test files configuration
180
+ // Test files
152
181
  {
153
182
  files: ['**/*.test.{js,ts}', '**/*.spec.{js,ts}', '**/tests/**/*'],
154
183
  languageOptions: {
155
184
  globals: {
156
185
  ...globals.jest,
157
- ...globals.vitest,
158
186
  describe: 'readonly',
159
187
  it: 'readonly',
160
188
  test: 'readonly',
@@ -172,7 +200,7 @@ export default [
172
200
  },
173
201
  },
174
202
 
175
- // Configuration files
203
+ // Config files
176
204
  {
177
205
  files: ['**/*.config.{js,ts}', '**/.*rc.{js,ts}'],
178
206
  rules: {
@@ -195,4 +223,7 @@ export default [
195
223
  '**/*.min.js',
196
224
  ],
197
225
  },
226
+
227
+ // Prettier — must be last to disable all formatting rules
228
+ eslintConfigPrettier,
198
229
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zairakai/js-dev-tools",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
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
5
  "keywords": [
6
6
  "dev-tools",
@@ -88,6 +88,7 @@
88
88
  "validate": "make quality"
89
89
  },
90
90
  "dependencies": {
91
+ "@eslint/compat": "^2.0.3",
91
92
  "@eslint/js": "^10.0.0",
92
93
  "@prettier/plugin-php": "^0.24.0",
93
94
  "@typescript-eslint/eslint-plugin": "^8.40.0",
@@ -110,7 +111,6 @@
110
111
  "vue-eslint-parser": "^10.0.0"
111
112
  },
112
113
  "devDependencies": {
113
- "@eslint/compat": "^2.0.3",
114
114
  "@vitest/coverage-v8": "^4.0.0",
115
115
  "knip": "^5.85.0",
116
116
  "sort-package-json": "^3.6.1",
package/scripts/config.sh CHANGED
@@ -135,9 +135,9 @@ export -f ensure_bin_optional
135
135
  # Check if files matching pattern exist
136
136
  has_files() {
137
137
  local pattern="$1"
138
- # SC2086: unquoted intentionally — we need word splitting + glob expansion via nullglob
138
+ # SC2086: unquoted intentionally — we need word splitting + glob expansion via nullglob+globstar
139
139
  # shellcheck disable=SC2086
140
- ( shopt -s nullglob; set -- $pattern; [ $# -gt 0 ] )
140
+ ( shopt -s nullglob globstar; set -- $pattern; [ $# -gt 0 ] )
141
141
  }
142
142
  export -f has_files
143
143
 
@@ -617,9 +617,86 @@ do_publish() {
617
617
  "${DEV_TOOLS_ROOT}/${source_rel}" \
618
618
  "${PROJECT_ROOT}/${target_rel}" \
619
619
  "$key"
620
+
621
+ # After publishing markdownlint config to config/dev-tools/, also create a root
622
+ # .markdownlint.json that extends it — IDEs and editor extensions look at root.
623
+ if [[ "$key" == "markdownlint" ]]; then
624
+ local root_markdownlint="${PROJECT_ROOT}/.markdownlint.json"
625
+ local root_content='{"extends":"./config/dev-tools/.markdownlint.json"}'
626
+
627
+ if [[ ! -f "$root_markdownlint" ]]; then
628
+ echo "$root_content" > "$root_markdownlint"
629
+ track_created ".markdownlint.json (root — extends config/dev-tools/)"
630
+ log_success "Created: .markdownlint.json → extends config/dev-tools/.markdownlint.json"
631
+ fi
632
+ fi
620
633
  done
621
634
  }
622
635
 
636
+ # ============================================================================
637
+ # GitLab CI — Ref Synchronizer
638
+ # Mirrors GitlabCiSynchronizer.php from laravel-dev-tools.
639
+ # Runs on every postinstall (npm install / npm update).
640
+ # Reads the installed version of @zairakai/js-dev-tools and updates the
641
+ # ref: in the project's .gitlab-ci.yml if it is out of sync.
642
+ # ============================================================================
643
+
644
+ sync_gitlab_ci_ref() {
645
+ local gitlab_ci="${PROJECT_ROOT}/.gitlab-ci.yml"
646
+ local gitlab_project="zairakai/npm-packages/js-dev-tools"
647
+
648
+ [[ -f "$gitlab_ci" ]] || return 0
649
+ grep -qF "$gitlab_project" "$gitlab_ci" || return 0
650
+
651
+ # Resolve installed version from the package's own package.json
652
+ local installed_version
653
+ installed_version="$(node -e "try{const p=require('${DEV_TOOLS_ROOT}/package.json');console.log('v'+(p.version||'').replace(/^v/,''))}catch(e){}" 2>/dev/null || echo "")"
654
+
655
+ [[ -n "$installed_version" ]] || return 0
656
+
657
+ # Extract the current ref: value inside the js-dev-tools include block
658
+ local in_block=false found_project=false current_ref=""
659
+ while IFS= read -r line; do
660
+ local trimmed="${line#"${line%%[![:space:]]*}"}" # ltrim
661
+
662
+ if [[ "$trimmed" == "include:" ]]; then
663
+ in_block=true
664
+ continue
665
+ fi
666
+
667
+ if [[ "$in_block" == true ]]; then
668
+ # Exit block on non-indented, non-list line
669
+ if [[ -n "$trimmed" ]] && [[ "$line" != " "* ]] && [[ "$line" != "-"* ]]; then
670
+ in_block=false
671
+ found_project=false
672
+ fi
673
+
674
+ if [[ "$found_project" == false ]] && [[ "$trimmed" == *"$gitlab_project"* ]]; then
675
+ found_project=true
676
+ continue
677
+ fi
678
+
679
+ if [[ "$found_project" == true ]] && [[ "$trimmed" == ref:* ]]; then
680
+ current_ref="${trimmed#ref:}"
681
+ current_ref="${current_ref#"${current_ref%%[![:space:]]*}"}" # ltrim
682
+ current_ref="${current_ref//\'/}"
683
+ current_ref="${current_ref//\"/}"
684
+ break
685
+ fi
686
+ fi
687
+ done < "$gitlab_ci"
688
+
689
+ [[ -n "$current_ref" ]] || return 0
690
+ [[ "$current_ref" != "$installed_version" ]] || return 0
691
+
692
+ # Auto-fix: replace the ref
693
+ if sed -i "s|ref: ${current_ref}|ref: ${installed_version}|" "$gitlab_ci"; then
694
+ echo " dev-tools: .gitlab-ci.yml ref ${current_ref} → ${installed_version}"
695
+ else
696
+ echo " dev-tools: WARNING — could not update .gitlab-ci.yml ref (manual fix needed)" >&2
697
+ fi
698
+ }
699
+
623
700
  # ============================================================================
624
701
  # Makefile Setup
625
702
  # ============================================================================
@@ -776,6 +853,9 @@ setup_project() {
776
853
  "config/dev-tools/eslint.config.js"
777
854
  fi
778
855
 
856
+ # ─── GitLab CI ref sync ───────────────────────────────────────────────────
857
+ sync_gitlab_ci_ref
858
+
779
859
  # ─── Summary ─────────────────────────────────────────────────────────────
780
860
  if [[ "$SILENT_MODE" == "true" ]]; then
781
861
  check_optional_deps
@@ -1,14 +1,20 @@
1
1
  /**
2
- * Knip configuration
2
+ * Knip configuration — extends the @zairakai/js-dev-tools base config.
3
3
  * @see https://knip.dev/reference/configuration
4
4
  */
5
+
6
+ import baseConfig from '@zairakai/js-dev-tools/config/knip.config.js'
7
+
5
8
  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: [],
9
+ ...baseConfig,
10
+ // Override entry points for your project structure:
11
+ // entry: ['src/index.ts!'],
12
+ // project: ['src/**/*.ts!'],
13
+ ignoreDependencies: [
14
+ ...(baseConfig.ignoreDependencies ?? []),
15
+ // Add project-specific ignored dependencies here
16
+ ],
17
+ ignoreBinaries: [
18
+ ...(baseConfig.ignoreBinaries ?? []),
19
+ ],
14
20
  }
@@ -3,14 +3,15 @@
3
3
  * Extends the @zairakai/js-dev-tools base config — customize as needed.
4
4
  *
5
5
  * Example of adding project-specific overrides:
6
- * module.exports = {
6
+ * import baseConfig from '@zairakai/js-dev-tools/config/prettier.config.js'
7
+ * export default {
7
8
  * ...baseConfig,
8
9
  * printWidth: 100,
9
10
  * }
10
11
  */
11
12
 
12
- const baseConfig = require('@zairakai/js-dev-tools/config/prettier.config.js')
13
+ import baseConfig from '@zairakai/js-dev-tools/config/prettier.config.js'
13
14
 
14
- module.exports = {
15
+ export default {
15
16
  ...baseConfig,
16
17
  }