skyltmax_config 0.0.5 → 0.0.7

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 21e29a8060c6f72c9bca8d4a60f7f148520bf0f779c0ba43d067ce2a11fca3a4
4
- data.tar.gz: c6d61948ca4a7ddad94778f4db4c57c018e225b45f443058d09f811f38bdb7f2
3
+ metadata.gz: c0635b272bd30a126daa5ea09e2aa10ce63567c109c0b606e0018083620ef898
4
+ data.tar.gz: b21dddaf0d2b757c3c87a7239d89f82772a86420ed36c57e087be2b30fb7b586
5
5
  SHA512:
6
- metadata.gz: c071f6305cdf6332c69d7e18720ba454d86f478bfef01c4c7474d7937f850da81cb76bf41af385f414471f9c510df5330e6d0cfd6f983d12d1bb0bef66058c59
7
- data.tar.gz: e755fa674c72a6793a1211c9986b3276cc998f5b40b8a82559ab33a6a634136843a6a6e7058afd67e2322c704a740c697f19488059f74a4b405a7d7f1f3d55ad
6
+ metadata.gz: 2b96358afb801106c087d22fcaa0d5206896e77aa43b74f202ff1a987231f018d338d3af4e0a53458e2d416c95a2db7e20254a11194919e3d9de7910748a595d
7
+ data.tar.gz: 324d6f181de3e97a1c09a201f1f1cd722332cbbda3a1f08dd65cdde5b265b6b925864eb4234ae75d21c89f52ffee6be9f25a884e22feebcb0a7020ec0f1730ff
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  node_modules
2
2
  .pnpm-store
3
+ .devcontainer/.bootdone
data/AGENTS.md ADDED
@@ -0,0 +1,650 @@
1
+ # AI Agent Guide for @signmax/config
2
+
3
+ This document provides comprehensive guidance for AI coding agents working with the `@signmax/config` package.
4
+
5
+ ## Table of Contents
6
+
7
+ 1. [Conventions](#conventions)
8
+ 2. [Package Overview](#package-overview)
9
+ 3. [Getting Started](#getting-started)
10
+ 4. [Development](#development)
11
+ 5. [Testing](#testing)
12
+ 6. [Configuration](#configuration)
13
+
14
+ ---
15
+
16
+ ## Conventions
17
+
18
+ - Max line length before wrapping is 120 chars.
19
+ - Don't be overly verbose, prefer brevity.
20
+ - Always put strong emphasis on idiomatic TypeScript solutions.
21
+ - Always uphold the configured linter settings - eslint, prettier.
22
+ - Avoid tautologic comments - prefer saying nothing over stating the obvious.
23
+ - Linear git history is required. Avoid cherry-picking etc.
24
+
25
+ ### Commit message
26
+
27
+ Commit messages should follow a specific format:
28
+
29
+ ```
30
+ <type>(<scope>): <subject>
31
+ <BLANK LINE>
32
+ <body>
33
+ <BLANK LINE>
34
+ <footer>
35
+ ```
36
+
37
+ For example:
38
+
39
+ ```
40
+ fix(middleware): Fix device key cookie initialization
41
+
42
+ The device key middleware was not setting the cookie header correctly.
43
+
44
+ Fixes #42
45
+ ```
46
+
47
+ Or:
48
+
49
+ ```
50
+ feat(server): Add configurable middleware options
51
+
52
+ Allow users to disable default middleware via ServeAppOptions.
53
+
54
+ Breaking change: Default middleware is now optional
55
+ ```
56
+
57
+ ---
58
+
59
+ ## Package Overview
60
+
61
+ ### Structure
62
+
63
+ This is a **dual-language configuration package** providing ESLint, Prettier, and TypeScript configs for
64
+ JavaScript/TypeScript projects, and Rubocop configs for Ruby projects:
65
+
66
+ ```
67
+ @signmax/config/
68
+ ├── lib/
69
+ │ └── skyltmax_config.rb # Ruby gem entry point
70
+ ├── eslint.js # ESLint configuration
71
+ ├── eslint.config.js # Example ESLint usage
72
+ ├── prettier.js # Prettier configuration
73
+ ├── typescript.json # TypeScript configuration
74
+ ├── reset.d.ts # TypeScript reset types
75
+ ├── rubocop.yml # Rubocop base config
76
+ ├── rubocop.rails.yml # Rubocop Rails config
77
+ ├── index.js # Package entry point
78
+ ├── package.json # npm package manifest
79
+ ├── skyltmax_config.gemspec # Ruby gem specification
80
+ ├── tsconfig.json # TypeScript config
81
+ ├── Gemfile # Ruby dependencies
82
+ ├── Rakefile # Ruby tasks
83
+ └── README.md
84
+ ```
85
+
86
+ ### Technology Stack
87
+
88
+ **JavaScript/TypeScript:**
89
+
90
+ - ESLint 9+ (flat config)
91
+ - Prettier 3+
92
+ - TypeScript 5+
93
+ - React support
94
+ - Vitest support
95
+ - Testing Library support
96
+
97
+ **Ruby:**
98
+
99
+ - Rubocop (>= 1.81.0)
100
+ - Rubocop Performance
101
+ - Rubocop Rails
102
+
103
+ **Key Dependencies:**
104
+
105
+ - `@typescript-eslint/eslint-plugin` & `@typescript-eslint/parser`
106
+ - `eslint-plugin-react`, `eslint-plugin-react-hooks`
107
+ - `eslint-plugin-jsx-a11y`
108
+ - `eslint-plugin-import-x`
109
+ - `@vitest/eslint-plugin`
110
+ - `eslint-plugin-testing-library`, `eslint-plugin-jest-dom`
111
+ - `prettier-plugin-tailwindcss`
112
+ - `@total-typescript/ts-reset`
113
+
114
+ **System Requirements:**
115
+
116
+ - Node.js >= 18.0.0
117
+ - Ruby >= 3.4 (for Rubocop configs)
118
+
119
+ ---
120
+
121
+ ## Getting Started
122
+
123
+ ### Installation
124
+
125
+ **For JavaScript/TypeScript projects:**
126
+
127
+ ```bash
128
+ npm install --save-dev @signmax/config
129
+ # or
130
+ pnpm add -D @signmax/config
131
+ ```
132
+
133
+ **That's it!** All required tools (ESLint, Prettier, TypeScript, and all plugins) are bundled as dependencies. No need
134
+ to install peer dependencies separately.
135
+
136
+ **For Ruby projects:**
137
+
138
+ ```ruby
139
+ # Gemfile
140
+ gem "skyltmax_config"
141
+ ```
142
+
143
+ ### Basic Usage
144
+
145
+ **ESLint:**
146
+
147
+ ```javascript
148
+ // eslint.config.js
149
+ import { config as defaultConfig } from "@signmax/config/eslint"
150
+
151
+ /** @type {import("eslint").Linter.Config[]} */
152
+ export default [...defaultConfig]
153
+ ```
154
+
155
+ **Prettier:**
156
+
157
+ ```json
158
+ // package.json
159
+ {
160
+ "prettier": "@signmax/config/prettier"
161
+ }
162
+ ```
163
+
164
+ **TypeScript:**
165
+
166
+ ```json
167
+ // tsconfig.json
168
+ {
169
+ "extends": ["@signmax/config/typescript"],
170
+ "include": ["**/*.ts", "**/*.tsx"],
171
+ "compilerOptions": {
172
+ "paths": {
173
+ "#app/*": ["./app/*"]
174
+ }
175
+ }
176
+ }
177
+ ```
178
+
179
+ **Rubocop:**
180
+
181
+ ```yaml
182
+ # .rubocop.yml
183
+ inherit_gem:
184
+ skyltmax_config:
185
+ - rubocop.yml
186
+ - rubocop.rails.yml
187
+ ```
188
+
189
+ ### Development Setup
190
+
191
+ ```bash
192
+ # Install dependencies
193
+ pnpm install
194
+
195
+ # Run validation
196
+ pnpm validate
197
+
198
+ # Run individual checks
199
+ pnpm format # Format with Prettier
200
+ pnpm lint # Lint with ESLint
201
+ pnpm typecheck # Type check with TypeScript
202
+ ```
203
+
204
+ ---
205
+
206
+ ## Development
207
+
208
+ ### File Structure
209
+
210
+ **JavaScript/TypeScript Files:**
211
+
212
+ - `eslint.js` - ESLint configuration export with all rules and plugins
213
+ - `prettier.js` - Prettier configuration with formatting options
214
+ - `typescript.json` - TypeScript compiler configuration
215
+ - `reset.d.ts` - TypeScript type reset declarations
216
+ - `index.js` - Package entry point
217
+ - `eslint.config.js` - Example ESLint configuration usage
218
+
219
+ **Ruby Files:**
220
+
221
+ - `lib/skyltmax_config.rb` - Ruby gem entry point
222
+ - `rubocop.yml` - Base Rubocop configuration
223
+ - `rubocop.rails.yml` - Rails-specific Rubocop rules
224
+ - `skyltmax_config.gemspec` - Gem specification
225
+ - `Gemfile` - Ruby dependencies
226
+ - `Rakefile` - Ruby build tasks
227
+
228
+ ### ESLint Configuration (`eslint.js`)
229
+
230
+ The ESLint configuration uses the flat config format (ESLint 9+) and exports an array of configuration objects:
231
+
232
+ ```javascript
233
+ export const config = [
234
+ // Ignore patterns
235
+ { ignores: ["**/node_modules/**", "**/build/**", ...] },
236
+
237
+ // Base configs
238
+ ...(await import("@eslint/js")).default.configs.recommended,
239
+ ...(await import("eslint-plugin-prettier/recommended")).default,
240
+
241
+ // Import rules for all files
242
+ { plugins: { import: ... }, rules: { "import/order": ... } },
243
+
244
+ // React/JSX specific rules
245
+ { files: ["**/*.tsx", "**/*.jsx"], plugins: { react: ... } },
246
+
247
+ // TypeScript specific rules
248
+ ...(await import("typescript-eslint")).default.config({ files: ["**/*.ts?(x)"] }),
249
+
250
+ // Test file rules (Vitest, Testing Library, Jest DOM)
251
+ { files: testFiles, plugins: { vitest: ... } },
252
+ ]
253
+ ```
254
+
255
+ **Key Features:**
256
+
257
+ - React and React Hooks support
258
+ - JSX accessibility rules
259
+ - TypeScript type-aware linting
260
+ - Import ordering and deduplication
261
+ - Vitest test file support
262
+ - Testing Library rules
263
+ - Jest DOM assertions
264
+
265
+ **Common Rules:**
266
+
267
+ - `import/order` - Alphabetized, grouped imports
268
+ - `import/no-duplicates` - Prevent duplicate imports with inline types
269
+ - `@typescript-eslint/consistent-type-imports` - Prefer `type` imports
270
+ - `react/jsx-no-leaked-render` - Prevent leaked renders in JSX
271
+ - `no-warning-comments` - Disallow FIXME comments
272
+
273
+ ### Prettier Configuration (`prettier.js`)
274
+
275
+ The Prettier config emphasizes readability and consistency:
276
+
277
+ ```javascript
278
+ export const config = {
279
+ printWidth: 120, // Max line length
280
+ semi: false, // No semicolons
281
+ singleQuote: false, // Double quotes
282
+ trailingComma: "es5", // Trailing commas where valid in ES5
283
+ arrowParens: "avoid", // Omit parens when possible
284
+ // ... other options
285
+ plugins: ["prettier-plugin-tailwindcss"],
286
+ }
287
+ ```
288
+
289
+ **Tailwind Support:**
290
+
291
+ - Automatic class sorting via `prettier-plugin-tailwindcss`
292
+ - Configurable class attributes and functions
293
+ - Default: `className`, `class`, and `clsx`/`cn` functions
294
+
295
+ ### TypeScript Configuration (`typescript.json`)
296
+
297
+ Base TypeScript configuration for strict type checking:
298
+
299
+ ```json
300
+ {
301
+ "compilerOptions": {
302
+ "strict": true,
303
+ "esModuleInterop": true,
304
+ "skipLibCheck": true,
305
+ "moduleResolution": "Bundler",
306
+ "resolveJsonModule": true,
307
+ "isolatedModules": true,
308
+ "jsx": "react-jsx"
309
+ // ... other strict options
310
+ }
311
+ }
312
+ ```
313
+
314
+ **TypeScript Reset (`reset.d.ts`):**
315
+
316
+ - Imports `@total-typescript/ts-reset`
317
+ - Provides better type definitions for common JS APIs
318
+ - Fixes issues with `Array.includes`, `JSON.parse`, `fetch`, etc.
319
+
320
+ ### Rubocop Configuration
321
+
322
+ **Base Config (`rubocop.yml`):**
323
+
324
+ - Strict Ruby style enforcement
325
+ - Performance optimizations
326
+ - Disabled cops that conflict with modern Ruby style
327
+
328
+ **Rails Config (`rubocop.rails.yml`):**
329
+
330
+ - Rails-specific linting rules
331
+ - Database conventions
332
+ - ActiveRecord best practices
333
+
334
+ ### TypeScript Conventions
335
+
336
+ **Exports:**
337
+
338
+ - Use named exports for configurations
339
+ - Provide default export for backward compatibility
340
+ - Example: `export const config = {...}; export default config;`
341
+
342
+ **Imports:**
343
+
344
+ - Use dynamic imports for ESLint plugins (required for flat config)
345
+ - Example: `(await import("eslint-plugin-react")).default`
346
+
347
+ **Code Style:**
348
+
349
+ - Follow configured Prettier settings
350
+ - Max line length: 120 characters
351
+ - No semicolons
352
+ - Double quotes for strings
353
+ - Trailing commas in ES5 contexts
354
+
355
+ ### Patterns
356
+
357
+ **Configuration Pattern:** All configuration files follow a similar pattern:
358
+
359
+ 1. Define constants (severity levels, file patterns)
360
+ 2. Export configuration object/array
361
+ 3. Provide default export for compatibility
362
+ 4. Add JSDoc type annotations for IDE support
363
+
364
+ Example:
365
+
366
+ ```javascript
367
+ /** @type {import("prettier").Options} */
368
+ export const config = {
369
+ /* ... */
370
+ }
371
+ export default config
372
+ ```
373
+
374
+ ### Making Changes
375
+
376
+ When updating configurations:
377
+
378
+ 1. **ESLint:** Update `eslint.js` with new rules/plugins
379
+ 2. **Prettier:** Update `prettier.js` formatting options
380
+ 3. **TypeScript:** Update `typescript.json` compiler options
381
+ 4. **Rubocop:** Update `rubocop.yml` or `rubocop.rails.yml`
382
+ 5. **Version:** Bump version in both `package.json` AND `skyltmax_config.gemspec`
383
+ 6. **Changelog:** Document changes in `CHANGELOG.md`
384
+ 7. **Test:** Run `pnpm validate` to ensure configs work
385
+
386
+ ---
387
+
388
+ ## Testing
389
+
390
+ This package **does not include automated tests** as it primarily provides configuration files. Testing is done by:
391
+
392
+ 1. **Using the configs in real projects** - The configurations are dogfooded
393
+ 2. **Manual validation** - `pnpm validate` checks formatting, linting, and type-checking
394
+ 3. **CI/CD validation** - GitHub Actions verify the package structure
395
+
396
+ ### Validation Process
397
+
398
+ **Run all checks:**
399
+
400
+ ```bash
401
+ pnpm validate
402
+ ```
403
+
404
+ This runs:
405
+
406
+ - `pnpm format` - Prettier formatting
407
+ - `pnpm lint` - ESLint validation
408
+ - `pnpm typecheck` - TypeScript compilation
409
+
410
+ **Individual checks:**
411
+
412
+ ```bash
413
+ pnpm format # Auto-format all files
414
+ pnpm lint # Check ESLint rules
415
+ pnpm typecheck # Verify TypeScript types
416
+ ```
417
+
418
+ ### Testing Configuration Changes
419
+
420
+ When modifying configurations:
421
+
422
+ 1. **Test in a real project:**
423
+ - Link the package locally: `pnpm link /path/to/config`
424
+ - Verify ESLint runs without errors
425
+ - Check Prettier formats correctly
426
+ - Ensure TypeScript compiles
427
+
428
+ 2. **Check backward compatibility:**
429
+ - Existing projects should not break
430
+ - New rules should be additive or opt-in
431
+ - Document breaking changes in CHANGELOG
432
+
433
+ 3. **Validate exports:**
434
+ - Ensure all exports work: `import { config } from "@signmax/config/eslint"`
435
+ - Check both named and default exports
436
+ - Verify TypeScript definitions are correct
437
+
438
+ ### Rubocop Testing
439
+
440
+ For Ruby configurations:
441
+
442
+ ```bash
443
+ # Test Rubocop configs locally
444
+ bundle exec rubocop
445
+
446
+ # Test with specific config
447
+ bundle exec rubocop --config rubocop.yml
448
+ bundle exec rubocop --config rubocop.rails.yml
449
+ ```
450
+
451
+ ### Continuous Integration
452
+
453
+ The package uses GitHub Actions for CI/CD with two workflows:
454
+
455
+ **CI Workflow (`.github/workflows/ci.yml`)** - Runs on PRs and pushes to main:
456
+
457
+ 1. **Validate JavaScript/TypeScript configs:**
458
+ - Runs `pnpm validate` (dogfooding - lints/formats/typechecks itself)
459
+ - Ensures ESLint, Prettier, and TypeScript configs work correctly
460
+
461
+ 2. **Validate Ruby configs:**
462
+ - Runs `bundle exec rubocop` (dogfooding - validates Rubocop configs)
463
+
464
+ 3. **Version sync check:**
465
+ - Verifies `package.json` and `lib/skyltmax_config/version.rb` versions match
466
+ - Prevents version drift between npm and gem
467
+
468
+ 4. **Package installation test:**
469
+ - Packs the package with `pnpm pack`
470
+ - Installs in a test project
471
+ - Verifies all exports work (ESLint, Prettier, TypeScript, reset.d.ts)
472
+
473
+ **Release Workflow (`.github/workflows/release.yml`)** - Publishes on GitHub Release:
474
+
475
+ 1. Verifies tag version matches both package.json and version.rb
476
+ 2. Publishes npm package with provenance (trusted publishing)
477
+ 3. Publishes RubyGems gem (trusted publishing)
478
+
479
+ **Key CI principle:** Dogfooding is the primary validation strategy. The package validates itself using its own
480
+ configurations, which ensures the configs are functional and catches issues early.
481
+
482
+ ---
483
+
484
+ ## Configuration
485
+
486
+ ### Package Structure
487
+
488
+ This package uses a dual-publishing approach:
489
+
490
+ **NPM Package (`@signmax/config`):**
491
+
492
+ - Main entry: `index.js`
493
+ - Exports: `./prettier`, `./typescript`, `./eslint`, `./reset.d.ts`
494
+ - Version must match gemspec version
495
+
496
+ **Ruby Gem (`skyltmax_config`):**
497
+
498
+ - Entry point: `lib/skyltmax_config.rb`
499
+ - Provides Rubocop configurations
500
+ - Version must match package.json version
501
+
502
+ ### Dependency Management
503
+
504
+ This package bundles all required tooling as direct dependencies, making it the **single source of truth** for versions:
505
+
506
+ **Dependencies (all tooling bundled):**
507
+
508
+ - **ESLint & Core:** `eslint`, `@eslint/js`, `typescript-eslint`
509
+ - **TypeScript ESLint:** `@typescript-eslint/eslint-plugin`, `@typescript-eslint/parser`, `@typescript-eslint/utils`
510
+ - **Prettier:** `prettier`, `eslint-config-prettier`, `eslint-plugin-prettier`, `prettier-plugin-tailwindcss`
511
+ - **TypeScript:** `typescript`, `@total-typescript/ts-reset`, `tslib`
512
+ - **Plugins:** `eslint-plugin-import-x`, `eslint-plugin-react`, `eslint-plugin-react-hooks`, `eslint-plugin-jsx-a11y`
513
+ - **Testing:** `@vitest/eslint-plugin`, `eslint-plugin-testing-library`, `eslint-plugin-jest-dom`
514
+ - **Utilities:** `globals`
515
+
516
+ **Why this approach?**
517
+
518
+ - ✅ **Version control:** Consuming projects get consistent, tested versions
519
+ - ✅ **Simplified setup:** Single `npm install @signmax/config` gets everything
520
+ - ✅ **No version conflicts:** This package manages compatibility between tools
521
+ - ✅ **Updates centralized:** Bump versions here, all projects benefit
522
+
523
+ **DevDependencies (development only):**
524
+
525
+ - `@types/react` - Type definitions for development
526
+ - `npm-run-all` - Script runner
527
+ - `react` - For testing React-related rules
528
+
529
+ **Files Included in Published Package:**
530
+
531
+ The `files` field specifies what gets published to npm:
532
+
533
+ - `*.js`, `*.json`, `*.d.ts`, `*.yml` - Configuration files
534
+ - `lib/**` - Ruby gem files
535
+ - `README.md`, `LICENSE` - Documentation
536
+
537
+ ### Version Management
538
+
539
+ **Critical:** Versions must be kept in sync across `package.json` and `lib/skyltmax_config/version.rb`.
540
+
541
+ The gemspec automatically reads the version from `lib/skyltmax_config/version.rb`, so you only need to update two files:
542
+
543
+ ```json
544
+ // package.json
545
+ {
546
+ "version": "0.0.5"
547
+ }
548
+ ```
549
+
550
+ ```ruby
551
+ # lib/skyltmax_config/version.rb
552
+ module SkyltmaxConfig
553
+ VERSION = "0.0.5"
554
+ end
555
+ ```
556
+
557
+ **Note:** The `skyltmax_config.gemspec` uses `SkyltmaxConfig::VERSION` and does not need manual version updates.
558
+
559
+ ### Publishing Process
560
+
561
+ Releases are automated via GitHub Actions when a release is published:
562
+
563
+ 1. **Update versions:**
564
+ - `package.json`: `"version": "x.y.z"`
565
+ - `lib/skyltmax_config/version.rb`: `VERSION = "x.y.z"`
566
+
567
+ 2. **Update changelog:**
568
+ - Add changes to `CHANGELOG.md`
569
+
570
+ 3. **Commit and push:**
571
+
572
+ ```bash
573
+ git add package.json lib/skyltmax_config/version.rb CHANGELOG.md
574
+ git commit -m "chore: bump version to x.y.z"
575
+ git push
576
+ ```
577
+
578
+ 4. **Create release:**
579
+ - Create Git tag: `vX.Y.Z`
580
+ - Create GitHub Release for that tag
581
+ - Or run "Publish release" workflow manually
582
+
583
+ **The workflow:**
584
+
585
+ - Verifies tag version matches both package.json and version.rb
586
+ - Publishes npm package with provenance
587
+ - Builds and pushes Ruby gem to RubyGems
588
+
589
+ ### Adding New Configurations
590
+
591
+ When adding new linting rules or formatting options:
592
+
593
+ 1. **Add to appropriate file:**
594
+ - ESLint rules → `eslint.js`
595
+ - Prettier options → `prettier.js`
596
+ - TypeScript options → `typescript.json`
597
+ - Rubocop rules → `rubocop.yml` or `rubocop.rails.yml`
598
+
599
+ 2. **Document in README.md:**
600
+ - Add usage examples
601
+ - List new features
602
+ - Update configuration sections
603
+
604
+ 3. **Update CHANGELOG.md:**
605
+ - Document what changed
606
+ - Note any breaking changes
607
+ - Provide migration guidance if needed
608
+
609
+ 4. **Test locally:**
610
+ - Run `pnpm validate`
611
+ - Test in a real project via `pnpm link`
612
+
613
+ 5. **Update version:**
614
+ - Bump both `package.json` and `skyltmax_config.gemspec`
615
+ - Follow semantic versioning
616
+
617
+ ### Backward Compatibility
618
+
619
+ When making changes:
620
+
621
+ - ✅ Add new optional configuration options
622
+ - ✅ Add new rules as warnings first, then errors in next major
623
+ - ✅ Provide sensible defaults for all options
624
+ - ✅ Support both old and new usage patterns
625
+ - ❌ Don't remove exports without major version bump
626
+ - ❌ Don't change default behavior without documenting
627
+ - ❌ Don't introduce breaking changes in minor/patch versions
628
+
629
+ ### Export Structure
630
+
631
+ The package exports are defined in `package.json`:
632
+
633
+ ```json
634
+ {
635
+ "exports": {
636
+ ".": "./index.js",
637
+ "./prettier": "./prettier.js",
638
+ "./typescript": "./typescript.json",
639
+ "./reset.d.ts": "./reset.d.ts",
640
+ "./eslint": "./eslint.js"
641
+ }
642
+ }
643
+ ```
644
+
645
+ All exports must:
646
+
647
+ - Have valid file paths
648
+ - Export both named and default exports (JS files)
649
+ - Include proper JSDoc type annotations
650
+ - Be documented in README.md
data/CHANGELOG.md CHANGED
@@ -2,14 +2,26 @@
2
2
 
3
3
  ### Unreleased
4
4
 
5
+ ### [0.0.7] - 2025-11-05
6
+
7
+ - feat: Make prettier tailwind plugin optional.
8
+
9
+ ### [0.0.6] - 2025-11-05
10
+
11
+ - fix: Add missing eslint-config-prettier dependency.
12
+
5
13
  ### [0.0.5] - 2025-11-04
14
+
6
15
  - Fix rubygems attestation.
7
16
 
8
17
  ### [0.0.4] - 2025-11-04
18
+
9
19
  - Fix rubygems release.
10
20
 
11
21
  ### [0.0.3] - 2025-11-04
22
+
12
23
  - Fix rubygems release.
13
24
 
14
25
  ### [0.0.2] - 2025-11-04
26
+
15
27
  - First public release.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- skyltmax_config (0.0.5)
4
+ skyltmax_config (0.0.7)
5
5
  rubocop (>= 1.81.0, < 2)
6
6
  rubocop-performance (>= 1.26.0, < 2)
7
7
  rubocop-rails (>= 2.33.0, < 3)
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Skyltmax
3
+ Copyright (c) 2025 Signmax AB
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,12 +1,25 @@
1
- # 👮 @skyltmax/config
1
+ # 👮 Skyltmax Config
2
2
 
3
- **Reasonable ESLint, Prettier, TypeScript, and Rubocop configs**
3
+ [![CI](https://github.com/skyltmax/config/actions/workflows/ci.yml/badge.svg)](https://github.com/skyltmax/config/actions/workflows/ci.yml)
4
+
5
+ **Reasonable ESLint, Prettier, TypeScript, and Rubocop configs.**
4
6
 
5
7
  Based on <a href="https://github.com/epicweb-dev/config">@epic-web/config</a>.
6
8
 
7
- ## Usage
9
+ ## Installation
8
10
 
9
- ### Rubocop
11
+ ### JavaScript/TypeScript
12
+
13
+ ```bash
14
+ npm install --save-dev @signmax/config
15
+ # or
16
+ pnpm add -D @signmax/config
17
+ ```
18
+
19
+ All required tools (ESLint, Prettier, TypeScript, and all plugins) are bundled as dependencies. This package is the
20
+ single source of truth for all tooling versions—no need to install peer dependencies separately.
21
+
22
+ ### Ruby
10
23
 
11
24
  Include the gem in your `Gemfile`:
12
25
 
@@ -14,6 +27,10 @@ Include the gem in your `Gemfile`:
14
27
  gem "skyltmax_config"
15
28
  ```
16
29
 
30
+ ## Usage
31
+
32
+ ### Rubocop
33
+
17
34
  Inherit the configs from the gem in your `.rubocop.yml`:
18
35
 
19
36
  ```yml
@@ -106,7 +123,8 @@ positives.
106
123
 
107
124
  ## Publishing
108
125
 
109
- This repo publishes a Ruby gem (skyltmax_config) and an npm package (@signmax/config) whenever a GitHub Release is published. A manual run is also available.
126
+ This repo publishes a Ruby gem (skyltmax_config) and an npm package (@signmax/config) whenever a GitHub Release is
127
+ published. A manual run is also available.
110
128
 
111
129
  Setup (one-time):
112
130
 
@@ -116,22 +134,17 @@ Setup (one-time):
116
134
  How to release:
117
135
 
118
136
  1. Update versions:
119
- - package.json: "version": x.y.z
120
- - skyltmax_config.gemspec: s.version = "x.y.z"
137
+ - `package.json`: `"version": "x.y.z"`
138
+ - `lib/skyltmax_config/version.rb`: `VERSION = "x.y.z"`
121
139
  2. Commit and push changes.
122
140
  3. Create a Git tag vX.Y.Z and a GitHub Release for that tag (or run the "Publish release" workflow with that ref).
123
141
 
124
142
  What the workflow does:
125
143
 
126
- - Verifies tag version matches package.json and gemspec
144
+ - Verifies tag version matches package.json and version.rb
127
145
  - Publishes the npm package with provenance enabled
128
146
  - Builds and pushes the gem to RubyGems
129
147
 
130
- Notes:
131
-
132
- - For first-time publish of a scoped npm package, access is set to public by the workflow.
133
- - If your npm org enforces 2FA, the token must be an automation token.
134
-
135
148
  ## License
136
149
 
137
150
  MIT
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SkyltmaxConfig
4
+ VERSION = "0.0.7"
5
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SkyltmaxConfig
4
+ end
data/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@signmax/config",
3
+ "version": "0.0.7",
3
4
  "publishConfig": {
4
5
  "access": "public"
5
6
  },
6
- "version": "0.0.5",
7
7
  "description": "Reasonable ESLint, Prettier, and TypeScript configs.",
8
8
  "license": "MIT",
9
9
  "author": "Signmax AB <team@signomatic.ee> (https://skyltmax.se/)",
@@ -32,6 +32,18 @@
32
32
  "./reset.d.ts": "./reset.d.ts",
33
33
  "./eslint": "./eslint.js"
34
34
  },
35
+ "files": [
36
+ "*.js",
37
+ "*.json",
38
+ "*.d.ts",
39
+ "*.yml",
40
+ "lib/**",
41
+ "README.md",
42
+ "LICENSE"
43
+ ],
44
+ "engines": {
45
+ "node": ">=18.0.0"
46
+ },
35
47
  "scripts": {
36
48
  "format": "prettier . --write",
37
49
  "lint": "eslint .",
@@ -39,11 +51,14 @@
39
51
  "validate": "run-p -l format lint typecheck"
40
52
  },
41
53
  "dependencies": {
54
+ "@eslint/js": "^9.33.0",
42
55
  "@total-typescript/ts-reset": "^0.6.1",
43
56
  "@typescript-eslint/eslint-plugin": "^8.39.1",
44
57
  "@typescript-eslint/parser": "^8.39.1",
45
58
  "@typescript-eslint/utils": "^8.39.1",
46
59
  "@vitest/eslint-plugin": "^1.3.4",
60
+ "eslint": "^9.33.0",
61
+ "eslint-config-prettier": "^10.1.8",
47
62
  "eslint-plugin-import-x": "^4.16.1",
48
63
  "eslint-plugin-jest-dom": "^5.5.0",
49
64
  "eslint-plugin-jsx-a11y": "^6.10.2",
@@ -52,18 +67,16 @@
52
67
  "eslint-plugin-react-hooks": "^5.2.0",
53
68
  "eslint-plugin-testing-library": "^7.6.6",
54
69
  "globals": "^16.3.0",
55
- "prettier-plugin-tailwindcss": "^0.6.14",
70
+ "prettier": "^3.6.2",
71
+ "prettier-plugin-tailwindcss": "^0.7.1",
56
72
  "tslib": "^2.8.1",
73
+ "typescript": "^5.9.2",
57
74
  "typescript-eslint": "^8.39.1"
58
75
  },
59
76
  "devDependencies": {
60
- "@eslint/js": "^9.33.0",
61
77
  "@types/react": "^18.3.0",
62
- "eslint": "^9.33.0",
63
78
  "npm-run-all": "^4.1.5",
64
- "prettier": "^3.6.2",
65
- "react": "^18.3.0",
66
- "typescript": "^5.9.2"
79
+ "react": "^18.3.0"
67
80
  },
68
81
  "prettier": "./prettier.js"
69
82
  }
data/pnpm-lock.yaml CHANGED
@@ -8,6 +8,9 @@ importers:
8
8
 
9
9
  .:
10
10
  dependencies:
11
+ '@eslint/js':
12
+ specifier: ^9.33.0
13
+ version: 9.39.1
11
14
  '@total-typescript/ts-reset':
12
15
  specifier: ^0.6.1
13
16
  version: 0.6.1
@@ -23,6 +26,12 @@ importers:
23
26
  '@vitest/eslint-plugin':
24
27
  specifier: ^1.3.4
25
28
  version: 1.4.0(eslint@9.39.1)(typescript@5.9.3)
29
+ eslint:
30
+ specifier: ^9.33.0
31
+ version: 9.39.1
32
+ eslint-config-prettier:
33
+ specifier: ^10.1.8
34
+ version: 10.1.8(eslint@9.39.1)
26
35
  eslint-plugin-import-x:
27
36
  specifier: ^4.16.1
28
37
  version: 4.16.1(@typescript-eslint/utils@8.46.3(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)
@@ -34,7 +43,7 @@ importers:
34
43
  version: 6.10.2(eslint@9.39.1)
35
44
  eslint-plugin-prettier:
36
45
  specifier: ^5.5.4
37
- version: 5.5.4(eslint@9.39.1)(prettier@3.6.2)
46
+ version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.39.1))(eslint@9.39.1)(prettier@3.6.2)
38
47
  eslint-plugin-react:
39
48
  specifier: ^7.37.5
40
49
  version: 7.37.5(eslint@9.39.1)
@@ -47,37 +56,31 @@ importers:
47
56
  globals:
48
57
  specifier: ^16.3.0
49
58
  version: 16.5.0
59
+ prettier:
60
+ specifier: ^3.6.2
61
+ version: 3.6.2
50
62
  prettier-plugin-tailwindcss:
51
- specifier: ^0.6.14
52
- version: 0.6.14(prettier@3.6.2)
63
+ specifier: ^0.7.1
64
+ version: 0.7.1(prettier@3.6.2)
53
65
  tslib:
54
66
  specifier: ^2.8.1
55
67
  version: 2.8.1
68
+ typescript:
69
+ specifier: ^5.9.2
70
+ version: 5.9.3
56
71
  typescript-eslint:
57
72
  specifier: ^8.39.1
58
73
  version: 8.46.3(eslint@9.39.1)(typescript@5.9.3)
59
74
  devDependencies:
60
- '@eslint/js':
61
- specifier: ^9.33.0
62
- version: 9.39.1
63
75
  '@types/react':
64
76
  specifier: ^18.3.0
65
77
  version: 18.3.26
66
- eslint:
67
- specifier: ^9.33.0
68
- version: 9.39.1
69
78
  npm-run-all:
70
79
  specifier: ^4.1.5
71
80
  version: 4.1.5
72
- prettier:
73
- specifier: ^3.6.2
74
- version: 3.6.2
75
81
  react:
76
82
  specifier: ^18.3.0
77
83
  version: 18.3.1
78
- typescript:
79
- specifier: ^5.9.2
80
- version: 5.9.3
81
84
 
82
85
  packages:
83
86
 
@@ -592,6 +595,12 @@ packages:
592
595
  resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
593
596
  engines: {node: '>=10'}
594
597
 
598
+ eslint-config-prettier@10.1.8:
599
+ resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==}
600
+ hasBin: true
601
+ peerDependencies:
602
+ eslint: '>=7.0.0'
603
+
595
604
  eslint-import-context@0.1.9:
596
605
  resolution: {integrity: sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==}
597
606
  engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
@@ -1169,9 +1178,9 @@ packages:
1169
1178
  resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==}
1170
1179
  engines: {node: '>=6.0.0'}
1171
1180
 
1172
- prettier-plugin-tailwindcss@0.6.14:
1173
- resolution: {integrity: sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg==}
1174
- engines: {node: '>=14.21.3'}
1181
+ prettier-plugin-tailwindcss@0.7.1:
1182
+ resolution: {integrity: sha512-Bzv1LZcuiR1Sk02iJTS1QzlFNp/o5l2p3xkopwOrbPmtMeh3fK9rVW5M3neBQzHq+kGKj/4LGQMTNcTH4NGPtQ==}
1183
+ engines: {node: '>=20.19'}
1175
1184
  peerDependencies:
1176
1185
  '@ianvs/prettier-plugin-sort-imports': '*'
1177
1186
  '@prettier/plugin-hermes': '*'
@@ -1183,14 +1192,12 @@ packages:
1183
1192
  prettier: ^3.0
1184
1193
  prettier-plugin-astro: '*'
1185
1194
  prettier-plugin-css-order: '*'
1186
- prettier-plugin-import-sort: '*'
1187
1195
  prettier-plugin-jsdoc: '*'
1188
1196
  prettier-plugin-marko: '*'
1189
1197
  prettier-plugin-multiline-arrays: '*'
1190
1198
  prettier-plugin-organize-attributes: '*'
1191
1199
  prettier-plugin-organize-imports: '*'
1192
1200
  prettier-plugin-sort-imports: '*'
1193
- prettier-plugin-style-order: '*'
1194
1201
  prettier-plugin-svelte: '*'
1195
1202
  peerDependenciesMeta:
1196
1203
  '@ianvs/prettier-plugin-sort-imports':
@@ -1211,8 +1218,6 @@ packages:
1211
1218
  optional: true
1212
1219
  prettier-plugin-css-order:
1213
1220
  optional: true
1214
- prettier-plugin-import-sort:
1215
- optional: true
1216
1221
  prettier-plugin-jsdoc:
1217
1222
  optional: true
1218
1223
  prettier-plugin-marko:
@@ -1225,8 +1230,6 @@ packages:
1225
1230
  optional: true
1226
1231
  prettier-plugin-sort-imports:
1227
1232
  optional: true
1228
- prettier-plugin-style-order:
1229
- optional: true
1230
1233
  prettier-plugin-svelte:
1231
1234
  optional: true
1232
1235
 
@@ -2140,6 +2143,10 @@ snapshots:
2140
2143
 
2141
2144
  escape-string-regexp@4.0.0: {}
2142
2145
 
2146
+ eslint-config-prettier@10.1.8(eslint@9.39.1):
2147
+ dependencies:
2148
+ eslint: 9.39.1
2149
+
2143
2150
  eslint-import-context@0.1.9(unrs-resolver@1.11.1):
2144
2151
  dependencies:
2145
2152
  get-tsconfig: 4.13.0
@@ -2189,12 +2196,14 @@ snapshots:
2189
2196
  safe-regex-test: 1.1.0
2190
2197
  string.prototype.includes: 2.0.1
2191
2198
 
2192
- eslint-plugin-prettier@5.5.4(eslint@9.39.1)(prettier@3.6.2):
2199
+ eslint-plugin-prettier@5.5.4(eslint-config-prettier@10.1.8(eslint@9.39.1))(eslint@9.39.1)(prettier@3.6.2):
2193
2200
  dependencies:
2194
2201
  eslint: 9.39.1
2195
2202
  prettier: 3.6.2
2196
2203
  prettier-linter-helpers: 1.0.0
2197
2204
  synckit: 0.11.11
2205
+ optionalDependencies:
2206
+ eslint-config-prettier: 10.1.8(eslint@9.39.1)
2198
2207
 
2199
2208
  eslint-plugin-react-hooks@5.2.0(eslint@9.39.1):
2200
2209
  dependencies:
@@ -2770,7 +2779,7 @@ snapshots:
2770
2779
  dependencies:
2771
2780
  fast-diff: 1.3.0
2772
2781
 
2773
- prettier-plugin-tailwindcss@0.6.14(prettier@3.6.2):
2782
+ prettier-plugin-tailwindcss@0.7.1(prettier@3.6.2):
2774
2783
  dependencies:
2775
2784
  prettier: 3.6.2
2776
2785
 
data/prettier.js CHANGED
@@ -1,3 +1,11 @@
1
+ // Try to load the Tailwind plugin if available
2
+ let tailwindPlugin
3
+ try {
4
+ tailwindPlugin = await import("prettier-plugin-tailwindcss")
5
+ } catch {
6
+ // Plugin not installed, that's okay
7
+ }
8
+
1
9
  /** @type {import("prettier").Options} */
2
10
  export const config = {
3
11
  arrowParens: "avoid",
@@ -39,9 +47,12 @@ export const config = {
39
47
  },
40
48
  },
41
49
  ],
42
- plugins: ["prettier-plugin-tailwindcss"],
43
- tailwindAttributes: ["class", "className", ".*[cC]lassName"],
44
- tailwindFunctions: ["clsx", "cn", "twcn"],
50
+ // Only include Tailwind plugin and config if it's available
51
+ ...(tailwindPlugin && {
52
+ plugins: ["prettier-plugin-tailwindcss"],
53
+ tailwindAttributes: ["class", "className", ".*[cC]lassName"],
54
+ tailwindFunctions: ["clsx", "cn", "twcn"],
55
+ }),
45
56
  }
46
57
 
47
58
  // this is for backward compatibility
@@ -1,8 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ $LOAD_PATH.push File.expand_path("./lib", __dir__)
4
+ require "skyltmax_config/version"
5
+
3
6
  Gem::Specification.new do |s|
4
7
  s.name = "skyltmax_config"
5
- s.version = "0.0.5"
8
+ s.version = SkyltmaxConfig::VERSION
6
9
  s.authors = ["Signmax AB"]
7
10
  s.email = ["team@signomatic.ee"]
8
11
  s.platform = Gem::Platform::RUBY
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skyltmax_config
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Signmax AB
@@ -89,12 +89,12 @@ executables: []
89
89
  extensions: []
90
90
  extra_rdoc_files: []
91
91
  files:
92
- - ".devcontainer/.bootdone"
93
92
  - ".devcontainer/boot.sh"
94
93
  - ".devcontainer/devcontainer.json"
95
94
  - ".devcontainer/docker-compose.yml"
96
95
  - ".gitignore"
97
96
  - ".rubocop.yml"
97
+ - AGENTS.md
98
98
  - CHANGELOG.md
99
99
  - Gemfile
100
100
  - Gemfile.lock
@@ -105,6 +105,7 @@ files:
105
105
  - eslint.js
106
106
  - index.js
107
107
  - lib/skyltmax_config.rb
108
+ - lib/skyltmax_config/version.rb
108
109
  - package.json
109
110
  - pnpm-lock.yaml
110
111
  - prettier.js
@@ -1,2 +0,0 @@
1
- BUNDLE_ALREADY_INSTALLED=true
2
- CHANGELOG_DISPLAYED_6=true