@venizia/dev-configs 0.4.8-1 → 0.4.8-2
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/README.md +60 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ it as a dev dependency in an application that wants the same rules.
|
|
|
9
9
|
bun add -d @venizia/dev-configs oxlint oxlint-tsgolint eslint typescript
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
`oxlint` (>=1.
|
|
12
|
+
`oxlint` (>=1.89.0), `oxlint-tsgolint` (>=7.0.2004), `eslint` (9 or 10),
|
|
13
13
|
`typescript` (5 or 6) are optional peers. Install only the tools you use. Formatting is `bun fmt` (Bun 1.4.4 or newer), set in `bunfig.toml`: see [Formatting](#formatting). Keep the
|
|
14
14
|
ESLint config `.mjs`: a TypeScript one (`.mts`) makes ESLint require `jiti`, one more dependency. A
|
|
15
15
|
project that only wants the full ESLint preset installs `eslint` and skips the oxc tools.
|
|
@@ -95,19 +95,21 @@ Every IGNIS package and example does.
|
|
|
95
95
|
| Flag | Base value | Why |
|
|
96
96
|
| :--- | :--- | :--- |
|
|
97
97
|
| `experimentalDecorators` | `true` | `@inject`, `@controller`, `@repository` and the other decorators need it |
|
|
98
|
-
| `emitDecoratorMetadata` | `true` | Optional - restate it only if your code reads `design:*` metadata. IGNIS reads `design:paramtypes` once, to validate a `@repository` constructor, and skips the check when the metadata is absent. Under Bun it turns an interface-typed constructor parameter into a runtime import (`Export named 'X' not found`), so import such names with `import type`; `
|
|
98
|
+
| `emitDecoratorMetadata` | `true` | Optional - restate it only if your code reads `design:*` metadata. IGNIS reads `design:paramtypes` once, to validate a `@repository` constructor, and skips the check when the metadata is absent. Under Bun it turns an interface-typed constructor parameter into a runtime import (`Export named 'X' not found`), so import such names with `import type`; `bun check` (TS1272; the base tsconfig sets `isolatedModules`) finds most of them, loading `src/index.ts` under Bun the rest |
|
|
99
99
|
| `useDefineForClassFields` | `false` | Class fields are assigned, not defined, so a subclass field initializer does not shadow a value the base constructor set |
|
|
100
100
|
|
|
101
101
|
## Entry points
|
|
102
102
|
|
|
103
103
|
| Entry point | What it gives |
|
|
104
104
|
| :--- | :--- |
|
|
105
|
-
| `@venizia/dev-configs` |
|
|
105
|
+
| `@venizia/dev-configs` | `/compilers` and `/linters`, re-exported. Not `/checks` or `/testing` |
|
|
106
106
|
| `@venizia/dev-configs/compilers` | `BunCompiler` |
|
|
107
107
|
| `@venizia/dev-configs/testing` | `RejectionHelper` (`rejectionOf`, `expectRejection`), `SpawnHelper` (`spawnSyncBounded`), `RepoTmp` (`findRoot`, `apply`) - test helpers (imports `bun:test`; tests only) |
|
|
108
|
-
| `@venizia/dev-configs/
|
|
108
|
+
| `@venizia/dev-configs/testing/tmpdir-preload` | A bunfig test preload: a bare `bun test` keeps its temp folders in the repository (calls `RepoTmp.apply()`) |
|
|
109
|
+
| `@venizia/dev-configs/checks` | The engines behind `devz check <name>`: catalog, module cycles, purity, split report and the test-trimming checks. Bun-only tooling, never import it from browser code |
|
|
110
|
+
| `@venizia/dev-configs/linters` | `oxlintConfigs`, `OxlintConfigs`, `BrowserOxlintConfigs`, `ReactOxlintConfigs`, `LintIgnore`, `namingConventionConfigs`, `reactNamingConventionConfigs`, `houseConfigs`, `reactHouseConfigs`, `eslintConfigs`, `paddingConfigs`, the rule classes and their types |
|
|
109
111
|
| `@venizia/dev-configs/linters/oxlint` | `oxlintConfigs`, `OxlintConfigs`, `IOxlintPresetOptions`, `BrowserOxlintConfigs`, `ReactOxlintConfigs`, `LintIgnore`, the rule classes and their types: everything an oxlint config needs, and nothing that loads ESLint. Loads in milliseconds: `/linters` also loads ESLint and its plugins, which an oxlint config never uses |
|
|
110
|
-
| `@venizia/dev-configs/tsconfig.base.json` | Target and lib ES2025, `module`
|
|
112
|
+
| `@venizia/dev-configs/tsconfig.base.json` | Target and lib ES2025, `module` esnext with `moduleResolution` bundler, strict mode (`noImplicitAny` and `useUnknownInCatchVariables` on) with `strictPropertyInitialization` off (DI-injected properties have no initializer), `noEmitOnError`, tests excluded |
|
|
111
113
|
| `@venizia/dev-configs/tsconfig.common.json` | Extends the base and restates `module` as `esnext` and `moduleResolution` as `bundler` |
|
|
112
114
|
| `@venizia/dev-configs/tsconfig.browser.json` | Extends the base for a browser library built with a bundler: `module` ESNext, `moduleResolution` bundler, lib ES2025 + `DOM` + `DOM.Iterable`, `types: []` so no Bun types reach `dist` |
|
|
113
115
|
| `@venizia/dev-configs/tsconfig.react.json` | Extends `tsconfig.browser.json` and sets `jsx: react-jsx` |
|
|
@@ -123,7 +125,7 @@ Every IGNIS package and example does.
|
|
|
123
125
|
becomes a runtime import when Bun runs a decorated class's source, and loading fails with
|
|
124
126
|
`Export named 'X' not found`. `oxlint --fix` rewrites them.
|
|
125
127
|
|
|
126
|
-
oxlint
|
|
128
|
+
oxlint does not read decorator metadata, so it also rewrites the import of a decorated
|
|
127
129
|
constructor parameter's class to `import { type X }`. tsc then emits `Function` (or `Object` under Bun)
|
|
128
130
|
as that parameter's `design:paramtypes` entry. IGNIS never injects by that entry - `@inject` names its
|
|
129
131
|
key, and `@repository` skips `Object` and `Function` - so nothing breaks. Code that does read
|
|
@@ -160,8 +162,9 @@ booleans. `BrowserOxlintConfigs.create()` and `ReactOxlintConfigs.create()` take
|
|
|
160
162
|
|
|
161
163
|
### houseConfigs and the house rules
|
|
162
164
|
|
|
163
|
-
`houseConfigs` is `namingConventionConfigs` plus the house rules oxlint cannot express
|
|
164
|
-
|
|
165
|
+
`houseConfigs` is `namingConventionConfigs` plus the house rules oxlint cannot express, the four async style rules
|
|
166
|
+
and the blank-line padding rules (`paddingConfigs`, below); `reactHouseConfigs` is the same over
|
|
167
|
+
`reactNamingConventionConfigs`, plus the React rules. The house rules ship as the ESLint plugin
|
|
165
168
|
`houseEslintPlugin`, registered as `venizia`:
|
|
166
169
|
|
|
167
170
|
| Class | Rule | Default | What it enforces |
|
|
@@ -176,10 +179,25 @@ booleans. `BrowserOxlintConfigs.create()` and `ReactOxlintConfigs.create()` take
|
|
|
176
179
|
with `[ConstClassValuesRule.NAME]: ConstClassValuesRule.build({ severity: 'error' })`. The 5-parameter
|
|
177
180
|
limit (V-C-02) is `venizia/max-params-own`, an error.
|
|
178
181
|
|
|
182
|
+
#### Blank-line padding
|
|
183
|
+
|
|
184
|
+
`paddingConfigs` holds two `@stylistic` rules, both `error`, on `.ts`, `.tsx`, `.mts` and `.cts` files.
|
|
185
|
+
`houseConfigs`, `reactHouseConfigs` and `eslintConfigs` carry it. It has no parser of its own: it rides on the
|
|
186
|
+
TypeScript parser of `namingConventionConfigs` or `eslintConfigs`. oxlint has none of these rules, so a
|
|
187
|
+
project that lints with oxlint alone gets no padding check. `devz lint --fix` writes the blank lines.
|
|
188
|
+
|
|
189
|
+
| Rule | What it enforces |
|
|
190
|
+
| :--- | :--- |
|
|
191
|
+
| `@stylistic/padding-line-between-statements` | A blank line after the imports (none needed between two imports), before a `return`, and around a block-like statement (a statement that ends in a block, such as `if`, `for`, `while`, `switch`, `try`, a function declaration or a bare block). Stacked `case` and `default` labels stay together |
|
|
192
|
+
| `@stylistic/lines-between-class-members` | A blank line between class members, except after a one-line member, so a run of one-line properties stays together |
|
|
193
|
+
|
|
194
|
+
Turn one off after the preset with `'off'`. See the
|
|
195
|
+
[changelog](https://ignis.venizia.ai/changelogs/2026-11-04-blank-line-padding-rules).
|
|
196
|
+
|
|
179
197
|
### namingConventionConfigs
|
|
180
198
|
|
|
181
199
|
`namingConventionConfigs` (type `Linter.Config[]`) sets only `@typescript-eslint/naming-convention`, with
|
|
182
|
-
its
|
|
200
|
+
its 16 selectors. It targets `.ts`, `.tsx`, `.mts` and `.cts`, and ignores `dist`, `build`,
|
|
183
201
|
`coverage`, `*.d.ts` and plain JavaScript. ESLint does not report unused disable comments in this
|
|
184
202
|
config, because oxlint owns the other rules.
|
|
185
203
|
|
|
@@ -239,9 +257,8 @@ flavor = "oxfmt"
|
|
|
239
257
|
|
|
240
258
|
### eslintConfigs
|
|
241
259
|
|
|
242
|
-
`eslintConfigs`
|
|
243
|
-
|
|
244
|
-
conventions, `curly`, plus these IGNIS rules (the node-protocol check runs in `oxlintConfigs` only):
|
|
260
|
+
`eslintConfigs` is the full ESLint preset: ESLint recommended, typescript-eslint, naming
|
|
261
|
+
conventions, `curly`, the padding rules, plus these IGNIS rules (the node-protocol check runs in `oxlintConfigs` only):
|
|
245
262
|
|
|
246
263
|
| Rule | Setting |
|
|
247
264
|
| :--- | :--- |
|
|
@@ -289,7 +306,13 @@ table above, as strict as the base. `react/no-deprecated` is left out: oxlint ha
|
|
|
289
306
|
Both React presets run the same fifteen `jsx-a11y` rules, including the six that need a human
|
|
290
307
|
decision (`click-events-have-key-events`, `no-static-element-interactions`,
|
|
291
308
|
`no-noninteractive-element-interactions`, `label-has-associated-control`, `heading-has-content`,
|
|
292
|
-
`anchor-is-valid`). `reactHouseConfigs` adds
|
|
309
|
+
`anchor-is-valid`). `reactHouseConfigs` adds three house rules oxlint has no port of:
|
|
310
|
+
|
|
311
|
+
| Rule | What it enforces |
|
|
312
|
+
| :--- | :--- |
|
|
313
|
+
| `venizia/no-leaked-render` | See the table above. On JSX files |
|
|
314
|
+
| `venizia/no-async-hook-callback` | A hook never gets an async function. On all source files |
|
|
315
|
+
| `venizia/effect-cleanup-consistency` | An effect callback returns a cleanup on every path or on none. On all source files |
|
|
293
316
|
|
|
294
317
|
The presets start strict. An application that wants less overrides the rule after the preset:
|
|
295
318
|
|
|
@@ -360,6 +383,30 @@ await BunCompiler.compile({
|
|
|
360
383
|
});
|
|
361
384
|
```
|
|
362
385
|
|
|
386
|
+
## The devz command
|
|
387
|
+
|
|
388
|
+
The package installs a `devz` binary. Run `devz --help` for the list, and `devz clean --help`,
|
|
389
|
+
`devz check --help` or `devz codemod --help` for the options of one command. A usage error in a command exits 2.
|
|
390
|
+
|
|
391
|
+
| Command | What it does |
|
|
392
|
+
| :--- | :--- |
|
|
393
|
+
| `devz lint [--fix] [files]` | Runs oxlint, ESLint and `bun fmt` from `.configs/lints/` and `.configs/formatters/.ignore`, and stops at the first tool that fails. With no file it checks the project; with files it handles only those, as a pre-commit hook passes them. `--fix` writes |
|
|
394
|
+
| `devz check purity --claims <file> [package] [--json]` | Probes every entry claimed browser-pure. Needs a build |
|
|
395
|
+
| `devz check module-cycles <dir> [--max <n>]` | Lists the import cycles of a built ESM folder; exits 1 when there are more than `--max` |
|
|
396
|
+
| `devz check split-report [--dist <dir>] [folder...]` | Reports hub files, stray types, missing barrels, long files and cycles. Never a gate |
|
|
397
|
+
| `devz check catalog [--glob <pattern>]... [--pinned <file>]... [--preset-prefix <prefix>]` | Guards dependency ranges against the root `workspaces.catalog` |
|
|
398
|
+
| `devz clean` | Removes `dist`, `node_modules/.cache` and the `*.tsbuildinfo` files next to the tsconfig. It takes no argument |
|
|
399
|
+
| `devz codemod <name> [paths...]` | Rewrites source files. A dry run unless `--write`; `--check` exits 1 while a rewrite remains |
|
|
400
|
+
|
|
401
|
+
`devz check` also runs the four tools of the test-trimming method: `test-weight`, `test-dead-code`,
|
|
402
|
+
`test-mutate` and `test-controls`.
|
|
403
|
+
|
|
404
|
+
The codemods are `drop-redundant-casts` (removes `as X` casts the compiler no longer needs),
|
|
405
|
+
`const-classes` (turns a string-literal union into a const class), `async-style` (applies the async style
|
|
406
|
+
fixers and lists the rest), `namespace-functions` (moves calls of a function that moved into a class to the
|
|
407
|
+
class form) and `connector-imports` (moves `@venizia/ignis/<connector sub-path>` imports to
|
|
408
|
+
`@venizia/ignis-connectors`).
|
|
409
|
+
|
|
363
410
|
## Where it sits
|
|
364
411
|
|
|
365
412
|
The root of the chain, with no IGNIS dependency: **dev-configs** -> inversion -> {filter, helpers}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@venizia/dev-configs",
|
|
3
|
-
"version": "0.4.8-
|
|
3
|
+
"version": "0.4.8-2",
|
|
4
4
|
"description": "Shareable development configurations for TypeScript projects: oxlint presets with per-rule builders, the ESLint naming-convention rule, the legacy ESLint flat config, and TypeScript compiler options with critical decorator support (experimentalDecorators, emitDecoratorMetadata, useDefineForClassFields). Single source of truth for consistent code style, type checking, and build settings across monorepo packages.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"build-tools",
|