@waynestate/pinstripe 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +264 -2
- package/eslint/javascript.js +37 -0
- package/eslint/typescript.js +50 -0
- package/package.json +49 -5
- package/prettier/index.json +6 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Wayne State University
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,265 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<a href="site/index.html"><img src="docs/readme/hero.jpg" width="100%" alt="Pinstripe's front page: the headline Pinstripe, 'Sharp code. Every line.', and a swatch of green pinstripe cloth with the necktie mark sewn on and a hang tag reading Cut PER, Size level 8, Lining Larastan, Fit a11y."></a>
|
|
3
|
+
</div>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
# Pinstripe
|
|
6
|
+
|
|
7
|
+
<p>
|
|
8
|
+
<img src="docs/readme/badges/php.svg" alt="php ^8.3">
|
|
9
|
+
<img src="docs/readme/badges/phpstan.svg" alt="phpstan level 8">
|
|
10
|
+
<img src="docs/readme/badges/license.svg" alt="licence MIT">
|
|
11
|
+
<a href="https://github.com/waynestate/pinstripe/actions/workflows/ci.yml"><img src="https://github.com/waynestate/pinstripe/actions/workflows/ci.yml/badge.svg" alt="GitHub CI"></a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
**Sharp code. Every line.**
|
|
15
|
+
|
|
16
|
+
The coding standard for the Wayne State app stack: shared presets for Pint, PHPStan (with Larastan for Laravel), Rector,
|
|
17
|
+
and ESLint with Prettier. Your app points at them and adds only its own exceptions. Pinstripe is to code what a good
|
|
18
|
+
suit is to a job interview: nobody notices it, everybody notices when it's missing.
|
|
19
|
+
|
|
20
|
+
Checks: `composer ci` (the same command runs on GitLab and GitHub).
|
|
21
|
+
|
|
22
|
+
Development happens on Wayne State's GitLab; this repository is a release mirror. Changes land there first.
|
|
23
|
+
|
|
24
|
+
Front page: [`site/index.html`](site/index.html), a static tailor's shop you can open in a browser or serve from `site/`.
|
|
25
|
+
On Citadel it is served by the raw-PHP deploy layer in [`deploy/`](deploy/): a SQUIRE kit whose front controller serves `site/` behind HELMET's security headers. For local development, keep serving `site/` directly.
|
|
26
|
+
|
|
27
|
+
<div align="center">
|
|
28
|
+
<img src="docs/readme/tape.svg" width="100%" alt="A yellow tape measure unrolls across a green card with seven marks, one per preset: The cut, Pint, presets per and laravel; The inseam, PHPStan, level 8; The lining, Larastan; The press, Rector, with dead code, code quality, type declarations and early return; The buttonholes, ESLint, javascript and typescript with vue and accessibility; The hem, Prettier, 100 columns, single quotes, semicolons, trailing commas; The chalk line, baseline.">
|
|
29
|
+
</div>
|
|
30
|
+
<div align="center"><sub>Seven pieces, one tape. Every mark is read from the preset files in this repo; with reduced motion on, the tape stays unrolled.</sub></div>
|
|
31
|
+
|
|
32
|
+
<details>
|
|
33
|
+
<summary><b>Try it on</b>: three cuts from <code>site/</code> at phone width</summary>
|
|
34
|
+
<br>
|
|
35
|
+
<div align="center"><img src="docs/readme/gallery.jpg" width="100%" alt="Three phone-width crops of Pinstripe's front page: the hero with the pinstripe swatch and hang tag, the fitting where messy PHP is chalked, and the pieces with the pincushion."></div>
|
|
36
|
+
</details>
|
|
37
|
+
|
|
38
|
+
<details>
|
|
39
|
+
<summary><b>The pattern book</b>: the brand board</summary>
|
|
40
|
+
<br>
|
|
41
|
+
<div align="center"><img src="docs/readme/board.jpg" width="100%" alt="Pinstripe's brand board: the necktie mark in its green and gold, the pinstripe cloth, and the type and colours it is cut from."></div>
|
|
42
|
+
</details>
|
|
43
|
+
|
|
44
|
+
## Use it in a raw PHP app
|
|
45
|
+
|
|
46
|
+
Add Pinstripe as a dev dependency:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
composer require --dev waynestate/pinstripe:^0.1
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Pinstripe 0.1.0 is on Packagist, and the npm package, `@waynestate/pinstripe`, is at 0.1.0 too.
|
|
53
|
+
|
|
54
|
+
Point PHPStan at the raw config. `phpstan.neon`:
|
|
55
|
+
|
|
56
|
+
```neon
|
|
57
|
+
includes:
|
|
58
|
+
- vendor/waynestate/pinstripe/phpstan/raw.neon
|
|
59
|
+
|
|
60
|
+
parameters:
|
|
61
|
+
paths:
|
|
62
|
+
- app
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Add Composer scripts that run on every OS:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"scripts": {
|
|
70
|
+
"lint": "pint --test --config vendor/waynestate/pinstripe/pint/per.json",
|
|
71
|
+
"fix": "pint --config vendor/waynestate/pinstripe/pint/per.json",
|
|
72
|
+
"analyse": "phpstan analyse"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`composer lint` fails on style. `composer fix` fixes it. Pint's `per` preset is the PER Coding Style, and `tests/fixtures/per` keeps a clean and a messy proof.
|
|
78
|
+
`composer analyse` runs PHPStan at level 8, with deprecation checks too.
|
|
79
|
+
Pinstripe ships `phpstan/phpstan-deprecation-rules`, loaded automatically by
|
|
80
|
+
`phpstan/extension-installer`. Calling a `@deprecated` method fails the build.
|
|
81
|
+
The tailor flags the old cut before the fabric is retired.
|
|
82
|
+
|
|
83
|
+
## Use it in a Laravel app
|
|
84
|
+
|
|
85
|
+
Same, with the Laravel parts:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
composer require --dev waynestate/pinstripe:^0.1 larastan/larastan
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Pinstripe pulls in `phpstan/extension-installer`, which registers Larastan for you. When Composer asks, allow the
|
|
92
|
+
plugin (`config.allow-plugins` in your `composer.json`). Your `phpstan.neon` includes
|
|
93
|
+
`vendor/waynestate/pinstripe/phpstan/laravel.neon` and nothing else: there is no Larastan line to add, and the
|
|
94
|
+
scripts point at `vendor/waynestate/pinstripe/pint/laravel.json`.
|
|
95
|
+
|
|
96
|
+
Proven on Laravel: `composer ci` lints a minimal Laravel 13 app (`tests/fixtures/laravel-app`) with
|
|
97
|
+
`pint/laravel.json` and analyses it with `phpstan/laravel.neon` on every run, and fails if the app stops
|
|
98
|
+
passing. A smaller fixture (`tests/fixtures/laravel`) proves the preset really loads Larastan: it plants an
|
|
99
|
+
undefined Eloquent property that only Larastan reports, and a clean twin it leaves alone.
|
|
100
|
+
|
|
101
|
+
## Use it for Vue
|
|
102
|
+
|
|
103
|
+
Add Pinstripe as a dev dependency:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
npm install --save-dev @waynestate/pinstripe eslint prettier
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Create `eslint.config.js` and spread the preset. For TypeScript:
|
|
110
|
+
|
|
111
|
+
```js
|
|
112
|
+
import pinstripe from '@waynestate/pinstripe/eslint/typescript'
|
|
113
|
+
|
|
114
|
+
export default [...pinstripe]
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
For plain JavaScript, import `@waynestate/pinstripe/eslint/javascript` instead.
|
|
118
|
+
|
|
119
|
+
Point Prettier at the preset in `package.json`:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"prettier": "@waynestate/pinstripe/prettier"
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Add scripts that run on every OS:
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"scripts": {
|
|
132
|
+
"lint": "eslint .",
|
|
133
|
+
"format": "prettier --write ."
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`npm run lint` fails on style and accessibility. `npm run format` fixes the layout. The preset is the off-the-rack
|
|
139
|
+
suit: it fits every app, and you only add your own cufflinks.
|
|
140
|
+
|
|
141
|
+
## Use it for Rector
|
|
142
|
+
|
|
143
|
+
Rector modernises code for the PHP version your app already supports. Add it as a dev dependency:
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
composer require --dev rector/rector
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Create `rector.php` and use the Pinstripe preset, adding only your own paths:
|
|
150
|
+
|
|
151
|
+
```php
|
|
152
|
+
<?php
|
|
153
|
+
|
|
154
|
+
$base = require __DIR__ . '/vendor/waynestate/pinstripe/rector/base.php';
|
|
155
|
+
|
|
156
|
+
return $base->withPaths([__DIR__ . '/src']);
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
The preset reads the PHP floor from your app's own `composer.json`, so it cannot drift out of step with the version
|
|
160
|
+
the app actually runs on. Check with `vendor/bin/rector process --dry-run` and apply with `vendor/bin/rector process`.
|
|
161
|
+
|
|
162
|
+
Proven on fixtures: `composer ci` runs the preset against a modern app (`tests/fixtures/rector-clean`) and an
|
|
163
|
+
old-style one (`tests/fixtures/rector-old`) on every run, and fails if the clean one changes or the old one is left
|
|
164
|
+
alone. Rector is the tailor's press: it smooths old code to the standard without changing the cut.
|
|
165
|
+
|
|
166
|
+
## The strict cut
|
|
167
|
+
|
|
168
|
+
New apps can include `vendor/waynestate/pinstripe/phpstan/strict.neon` instead of `raw.neon` or `laravel.neon`. It keeps the base cut and turns on `phpstan/phpstan-strict-rules`, so loose comparisons like `==` fail the build. Existing apps stay on the base cut and baseline their way over.
|
|
169
|
+
|
|
170
|
+
PHPStan checks phpdoc method signatures from level 3 up, and `phpstan/phpstan-strict-rules` forces the two switches behind them on for every run it is installed for. The base cut pins `reportMaybesInMethodSignatures` and `reportStaticMethodSignatures` off so it stays exactly as documented; the strict cut keeps them on, so it also reports maybe-mismatched overrides and static method overrides.
|
|
171
|
+
|
|
172
|
+
`phpstan/phpstan-strict-rules` forces eight more switches on for every run as well. Each one is decided below: low noise and real bugs stay on in every cut, noisy ones are pinned off in the base cut and turned on only in `strict.neon`.
|
|
173
|
+
|
|
174
|
+
| Parameter | Raw and Laravel cuts | Strict cut | Why |
|
|
175
|
+
|---|---|---|---|
|
|
176
|
+
| `checkExplicitMixedMissingReturn` | on | on | A function declared to return `mixed` that can fall off the end is a real bug, and rare in practice. |
|
|
177
|
+
| `checkFunctionNameCase` | on | on | A wrongly cased function name works on Windows and macOS and breaks on Linux. |
|
|
178
|
+
| `checkInternalClassCaseSensitivity` | on | on | The same case bug for PHP's own classes. |
|
|
179
|
+
| `checkStrictPrintfPlaceholderTypes` | on | on | `%d` fed a string is a real formatting bug, and rare. |
|
|
180
|
+
| `checkDynamicProperties` | off | on | Floods legacy code with undeclared properties. |
|
|
181
|
+
| `reportMaybesInPropertyPhpDocTypes` | off | on | Reports "maybe" phpdoc mismatches that legacy docblocks trip constantly. |
|
|
182
|
+
| `reportWrongPhpDocTypeInVarTag` | off | on | Old `@var` tags are often loose; fixing them is cleanup, not bug hunting. |
|
|
183
|
+
| `reportNonIntStringArrayKey` | off | on | Bleeding-edge check that is noisy on loosely keyed arrays. |
|
|
184
|
+
|
|
185
|
+
Strict is the tailor's chalk line drawn before the first stitch.
|
|
186
|
+
|
|
187
|
+
## Adopting on an existing app
|
|
188
|
+
|
|
189
|
+
Generate a baseline with `phpstan analyse --generate-baseline`, include it in your `phpstan.neon`, and only ever
|
|
190
|
+
shrink it. New code gets no baseline. A baseline is a tailor's chalk line: it marks the fabric as it is, and every
|
|
191
|
+
release you take it in, never let it out.
|
|
192
|
+
|
|
193
|
+
## Baselines only shrink
|
|
194
|
+
|
|
195
|
+
Pinstripe ships `pinstripe-baseline`, one PHP command that runs on every OS, to keep that promise. It reads both
|
|
196
|
+
the NEON baseline and the PHP format (`phpstan-baseline.php`).
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
vendor/bin/pinstripe-baseline count phpstan-baseline.neon
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
prints how many errors the baseline ignores: the sum of each entry's `count`, 1 when `count` is absent.
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
vendor/bin/pinstripe-baseline check --max=42 phpstan-baseline.neon
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
exits 1 with `baseline grew: N errors, the most allowed is M` when the count is above the limit, 0 otherwise. To
|
|
209
|
+
compare with the target branch instead of a fixed number, pass a git ref:
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
vendor/bin/pinstripe-baseline check --against=origin/main phpstan-baseline.neon
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
In GitLab CI the merge request's base SHA is already in the environment:
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
vendor/bin/pinstripe-baseline check --against=$CI_MERGE_REQUEST_DIFF_BASE_SHA phpstan-baseline.neon
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
A baseline is a tailor's chalk line, and this command is the tape measure: it fails the build the moment the line
|
|
222
|
+
gets longer.
|
|
223
|
+
|
|
224
|
+
## Tested with
|
|
225
|
+
|
|
226
|
+
Maintainers: how to build, test and release this project, and where its data comes from, is in [MAINTAINING.md](MAINTAINING.md).
|
|
227
|
+
|
|
228
|
+
- Pint 1.32.1
|
|
229
|
+
- PHPStan 2.3.3
|
|
230
|
+
- PHPStan extension-installer 1.4.3
|
|
231
|
+
- PHPStan strict-rules 2.1.0
|
|
232
|
+
- Larastan 3.13.2
|
|
233
|
+
- Rector 2.8.1
|
|
234
|
+
- ESLint 10.13.0
|
|
235
|
+
- Prettier 3.9.10
|
|
236
|
+
- eslint-plugin-vue 10.12.0
|
|
237
|
+
- eslint-plugin-vuejs-accessibility 2.6.3
|
|
238
|
+
- typescript-eslint 8.72.1
|
|
239
|
+
- Node 22.13 or newer
|
|
240
|
+
|
|
241
|
+
## Coming next
|
|
242
|
+
|
|
243
|
+
PREFLIGHT jobs, and reading the PHP floor from CREED.
|
|
244
|
+
|
|
245
|
+
## The cast
|
|
246
|
+
|
|
247
|
+
<div align="center">
|
|
248
|
+
<a href="https://github.com/waynestate/wayne-ui" title="WayneUI"><img src="docs/readme/cast/wayneui.png" width="48" alt="WayneUI"></a>
|
|
249
|
+
<a href="https://github.com/waynestate/creed" title="CREED"><img src="docs/readme/cast/creed.png" width="48" alt="CREED"></a>
|
|
250
|
+
<a href="https://github.com/waynestate/proctor" title="PROCTOR"><img src="docs/readme/cast/proctor.png" width="48" alt="PROCTOR"></a>
|
|
251
|
+
<a href="https://github.com/waynestate/sesame" title="SESAME"><img src="docs/readme/cast/sesame.png" width="48" alt="SESAME"></a>
|
|
252
|
+
<a href="https://github.com/waynestate/helmet" title="HELMET"><img src="docs/readme/cast/helmet.png" width="48" alt="HELMET"></a>
|
|
253
|
+
<a href="https://github.com/waynestate/sourdough" title="Sourdough"><img src="docs/readme/cast/sourdough.png" width="48" alt="Sourdough"></a>
|
|
254
|
+
<a href="https://github.com/waynestate/squire" title="SQUIRE"><img src="docs/readme/cast/squire.png" width="48" alt="SQUIRE"></a>
|
|
255
|
+
<a href="https://github.com/waynestate/preflight" title="PREFLIGHT"><img src="docs/readme/cast/preflight.png" width="48" alt="PREFLIGHT"></a>
|
|
256
|
+
<a href="https://github.com/waynestate/pinstripe" title="Pinstripe"><img src="docs/readme/cast/pinstripe.png" width="48" alt="Pinstripe"></a>
|
|
257
|
+
<a href="https://github.com/waynestate/booster" title="BOOSTER"><img src="docs/readme/cast/booster.png" width="48" alt="BOOSTER"></a>
|
|
258
|
+
<a href="https://github.com/waynestate/rollcall" title="ROLLCALL"><img src="docs/readme/cast/rollcall.png" width="48" alt="ROLLCALL"></a>
|
|
259
|
+
<a href="https://github.com/waynestate/drawbridge" title="DRAWBRIDGE"><img src="docs/readme/cast/drawbridge.png" width="48" alt="DRAWBRIDGE"></a>
|
|
260
|
+
<a href="https://github.com/waynestate/advisor" title="ADVISOR"><img src="docs/readme/cast/advisor.png" width="48" alt="ADVISOR"></a>
|
|
261
|
+
<a href="https://github.com/waynestate/weld" title="WELD"><img src="docs/readme/cast/weld.png" width="48" alt="WELD"></a>
|
|
262
|
+
</div>
|
|
263
|
+
|
|
264
|
+
<div align="center"><sub>Fourteen parts, one fitting room. The README art is cut from the front page by
|
|
265
|
+
<a href="scripts/readme-art/README.md"><code>scripts/readme-art</code></a>; no suit was harmed, and every hem was pinned first.</sub></div>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import js from '@eslint/js'
|
|
2
|
+
import pluginVue from 'eslint-plugin-vue'
|
|
3
|
+
import pluginVueA11y from 'eslint-plugin-vuejs-accessibility'
|
|
4
|
+
import prettierConfig from 'eslint-config-prettier'
|
|
5
|
+
import globals from 'globals'
|
|
6
|
+
|
|
7
|
+
// Pinstripe's JavaScript preset for Vue.
|
|
8
|
+
//
|
|
9
|
+
// Spread this into your eslint.config.js:
|
|
10
|
+
//
|
|
11
|
+
// import pinstripe from '@waynestate/pinstripe/eslint/javascript'
|
|
12
|
+
// export default [...pinstripe]
|
|
13
|
+
//
|
|
14
|
+
// It lints plain JavaScript and .vue files with <script> (no lang="ts").
|
|
15
|
+
// For TypeScript, use @waynestate/pinstripe/eslint/typescript instead.
|
|
16
|
+
export default [
|
|
17
|
+
// Built assets and generated directories are never linted.
|
|
18
|
+
{
|
|
19
|
+
ignores: ['vendor/', 'node_modules/', 'public/build/', 'bootstrap/cache/', 'storage/'],
|
|
20
|
+
},
|
|
21
|
+
// Core JavaScript rules.
|
|
22
|
+
js.configs.recommended,
|
|
23
|
+
// Vue 3 rules, flat/recommended. vue-eslint-parser stays the top-level parser.
|
|
24
|
+
...pluginVue.configs['flat/recommended'],
|
|
25
|
+
// Accessibility rules for .vue templates.
|
|
26
|
+
...pluginVueA11y.configs['flat/recommended'],
|
|
27
|
+
{
|
|
28
|
+
languageOptions: {
|
|
29
|
+
globals: {
|
|
30
|
+
...globals.browser,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
// Prettier owns layout. This must stay last so it turns off the rules that
|
|
35
|
+
// would argue with it.
|
|
36
|
+
prettierConfig,
|
|
37
|
+
]
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import js from '@eslint/js'
|
|
2
|
+
import pluginVue from 'eslint-plugin-vue'
|
|
3
|
+
import pluginVueA11y from 'eslint-plugin-vuejs-accessibility'
|
|
4
|
+
import prettierConfig from 'eslint-config-prettier'
|
|
5
|
+
import globals from 'globals'
|
|
6
|
+
import { withVueTs, vueTsConfigs } from '@vue/eslint-config-typescript'
|
|
7
|
+
|
|
8
|
+
// Pinstripe's TypeScript preset for Vue.
|
|
9
|
+
//
|
|
10
|
+
// Spread this into your eslint.config.js:
|
|
11
|
+
//
|
|
12
|
+
// import pinstripe from '@waynestate/pinstripe/eslint/typescript'
|
|
13
|
+
// export default [...pinstripe]
|
|
14
|
+
//
|
|
15
|
+
// It lints .ts files and .vue files with <script lang="ts">, with typed
|
|
16
|
+
// linting (typescript-eslint recommendedTypeChecked, projectService). Typed
|
|
17
|
+
// linting is slower than syntax linting, so run it in CI, not on every save.
|
|
18
|
+
//
|
|
19
|
+
// Every <script> block in a .vue file must be TypeScript. For plain
|
|
20
|
+
// JavaScript, use @waynestate/pinstripe/eslint/javascript instead.
|
|
21
|
+
//
|
|
22
|
+
// withVueTs is async (it resolves the .vue files in your project), so the
|
|
23
|
+
// preset awaits it and exports the resulting flat config array.
|
|
24
|
+
const pinstripe = await withVueTs(
|
|
25
|
+
// Built assets and generated directories are never linted.
|
|
26
|
+
{
|
|
27
|
+
ignores: ['vendor/', 'node_modules/', 'public/build/', 'bootstrap/cache/', 'storage/'],
|
|
28
|
+
},
|
|
29
|
+
// Core JavaScript rules.
|
|
30
|
+
js.configs.recommended,
|
|
31
|
+
// Vue 3 rules, flat/recommended. vue-eslint-parser stays the top-level parser.
|
|
32
|
+
...pluginVue.configs['flat/recommended'],
|
|
33
|
+
// Accessibility rules for .vue templates.
|
|
34
|
+
...pluginVueA11y.configs['flat/recommended'],
|
|
35
|
+
// typescript-eslint recommendedTypeChecked, adapted for .vue files.
|
|
36
|
+
// This turns on typed linting (projectService) for .ts and .vue.
|
|
37
|
+
vueTsConfigs.recommendedTypeChecked,
|
|
38
|
+
{
|
|
39
|
+
languageOptions: {
|
|
40
|
+
globals: {
|
|
41
|
+
...globals.browser,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
// Prettier owns layout. This must stay last so it turns off the rules
|
|
46
|
+
// that would argue with it.
|
|
47
|
+
prettierConfig,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
export default pinstripe
|
package/package.json
CHANGED
|
@@ -1,6 +1,50 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@waynestate/pinstripe",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "The coding standard for the Wayne State app stack: shared ESLint and Prettier presets for Vue.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://pinstripe.apps.wayne.edu/",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/waynestate/pinstripe.git"
|
|
10
|
+
},
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"type": "module",
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=22.13"
|
|
17
|
+
},
|
|
18
|
+
"exports": {
|
|
19
|
+
"./eslint/javascript": "./eslint/javascript.js",
|
|
20
|
+
"./eslint/typescript": "./eslint/typescript.js",
|
|
21
|
+
"./prettier": "./prettier/index.json"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"eslint/",
|
|
25
|
+
"prettier/",
|
|
26
|
+
"README.md"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"test": "node --test \"tests/js/*.test.mjs\""
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"eslint": "^10.0.0",
|
|
33
|
+
"prettier": "^3.0.0"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@eslint/js": "^10.0.1",
|
|
37
|
+
"@vue/eslint-config-typescript": "^14.9.0",
|
|
38
|
+
"eslint-config-prettier": "^10.1.8",
|
|
39
|
+
"eslint-plugin-vue": "^10.12.0",
|
|
40
|
+
"eslint-plugin-vuejs-accessibility": "^2.6.3",
|
|
41
|
+
"globals": "^17.13.0",
|
|
42
|
+
"typescript-eslint": "^8.72.1",
|
|
43
|
+
"vue-eslint-parser": "^10.4.1"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"eslint": "^10.13.0",
|
|
47
|
+
"prettier": "^3.9.10",
|
|
48
|
+
"typescript": "~6.0.3"
|
|
49
|
+
}
|
|
50
|
+
}
|