@jterrazz/test 15.3.0 → 16.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.
package/dist/oxlint.d.cts CHANGED
@@ -7069,6 +7069,7 @@ interface OxlintConfig extends Oxlintrc {
7069
7069
  */
7070
7070
  /** A source comment, as exposed by oxlint's ESTree-compatible `sourceCode`. */
7071
7071
  type Comment = {
7072
+ end?: number;
7072
7073
  range?: [number, number];
7073
7074
  start?: number;
7074
7075
  type: 'Block' | 'Line' | 'Shebang';
@@ -7112,24 +7113,52 @@ type Visitor = Record<string, (node: AstNode) => void>;
7112
7113
  * The normative documentation a rule carries — the code is the source of truth
7113
7114
  * for the mechanized catalogue (docs-as-code inversion). Every plugin rule sets
7114
7115
  * `meta.docs` to its {@link RuleDoc} entry from `manifest.ts`; the catalogue
7115
- * generator reads these to (re)write `docs/13-linting.md` and the annex.
7116
+ * generator reads these to (re)write `docs/19-linting.md` and the annex.
7116
7117
  */
7117
7118
  type RuleDoc = {
7118
- /** Enforcement channel — the four faces the manifest assembles. */
7119
- channel: 'checker' | 'process' | 'runtime' | 'statique';
7120
- /** The French normative sentence (the constitution's per-rule text, moved here). */
7119
+ /**
7120
+ * Enforcement channel — ONE per row, and the row says which.
7121
+ *
7122
+ * A convention enforced two ways is two rows, because the two answer
7123
+ * different questions: what `statique` sees in one file is not what
7124
+ * `checker` sees across a tree, and neither is what `runtime` refuses.
7125
+ * Writing a single row with two channels made the catalogue unable to say
7126
+ * which pass a reader should expect a finding from.
7127
+ *
7128
+ * - `statique` — a `jterrazz/*` oxlint rule;
7129
+ * - `upstream` — an option this vocabulary sets on an oxlint plugin rule
7130
+ * someone else owns (ADR-005);
7131
+ * - `checker` — a pass of `dist/checker.js`, over a tree or a member;
7132
+ * - `runtime` — a refusal the framework raises while a spec runs;
7133
+ * - `type` — what the compiler refuses, proven by a `test-d` assertion;
7134
+ * - `meta` — what one of the package's own meta-tests holds;
7135
+ * - `process` — a review judgement no channel can decide.
7136
+ */
7137
+ channel: 'checker' | 'meta' | 'process' | 'runtime' | 'statique' | 'type' | 'upstream';
7138
+ /** The normative sentence — the constitution's per-rule text, moved here. */
7121
7139
  convention: string;
7122
7140
  /**
7123
7141
  * One imperative line: what to DO about it. A ban with no destination is an
7124
7142
  * argument rather than a rule, so the catalogue and the message carry the
7125
- * same fix. A row that states none renders `—`.
7143
+ * same fix.
7126
7144
  */
7127
- fix?: string;
7145
+ fix: string;
7128
7146
  /**
7129
- * The specification facet the rule guards — segments the catalogue like
7130
- * the constructors segment the API. `'shared'` for cross-facet rules.
7147
+ * Which tree of the source the rule belongs to, and therefore where its
7148
+ * implementation sits: `src/lint/rules/model/` for a rule that reaches every
7149
+ * facet, `src/lint/rules/<facet>/` for one that guards a single
7150
+ * constructor's vocabulary. The catalogue is grouped on it — model first,
7151
+ * then one section per facet — so a reader adopting one facet sees the
7152
+ * rules that reach them and nothing else.
7153
+ *
7154
+ * Required, like `fix` and `reach`: a rule with no tree is a rule nobody
7155
+ * placed, and `model` is a statement (this reaches every facet), not a
7156
+ * default to fall into. The checker's passes carry the field too, although
7157
+ * their implementations do not split by folder — several passes share one
7158
+ * module because they share one walk of the tree, so the field alone says
7159
+ * which facet a pass speaks for.
7131
7160
  */
7132
- facet?: 'api' | 'cli' | 'component' | 'integration' | 'jobs' | 'mobile' | 'shared' | 'website';
7161
+ facet: 'api' | 'cli' | 'component' | 'integration' | 'jobs' | 'mobile' | 'model' | 'website';
7133
7162
  /** Convention family letter, e.g. `'A'`. */
7134
7163
  family: string;
7135
7164
  /** Convention code, e.g. `'A1'`. */
@@ -7137,11 +7166,26 @@ type RuleDoc = {
7137
7166
  /** One line: why the rule exists. */
7138
7167
  rationale: string;
7139
7168
  /**
7140
- * Which files the rule looks at — the vocabulary of `roleOf` plus the two
7141
- * shapes that are not a role (`tests`, everything the conventions bind, and
7142
- * `all`). A row that states none renders `—`.
7169
+ * For an `upstream` row: the rule whose OPTION carries the convention
7170
+ * (`vitest/no-restricted-matchers`). It is what the completeness meta-test
7171
+ * reads, so a row of that channel names the option it rests on.
7172
+ */
7173
+ upstream?: string;
7174
+ /**
7175
+ * Which files the rule looks at — the vocabulary of `roleOf` plus the
7176
+ * shapes that are not a role: `tests` (every file that declares tests),
7177
+ * `specs` (a tree), `member` (a package), and `all`.
7178
+ *
7179
+ * `module` is the COLOCATED unit test — a `.test.ts` beside the module it
7180
+ * covers, outside every specs tree. A `module`-role file under `specs/` is
7181
+ * a repository suite: it covers a tree rather than a unit, and the passes
7182
+ * that judge a tree are the ones that reach it.
7183
+ *
7184
+ * Required, like `fix`: a reader deciding whether a rule applies to the
7185
+ * file in front of them should not have to read its implementation, and a
7186
+ * row that left it blank was answering "somewhere".
7143
7187
  */
7144
- reach?: 'all' | 'component' | 'config' | 'document' | 'ground' | 'module' | 'specification' | 'specs' | 'tests';
7188
+ reach: 'all' | 'component' | 'config' | 'contract' | 'document' | 'ground' | 'member' | 'module' | 'spec' | 'specification' | 'specs' | 'tests';
7145
7189
  };
7146
7190
  /** Rule metadata (the subset we set). */
7147
7191
  type RuleMeta = {
@@ -7168,21 +7212,7 @@ type LintPlugin = {
7168
7212
  };
7169
7213
  //#endregion
7170
7214
  //#region src/lint/plugin.d.ts
7171
- /**
7172
- * The `@jterrazz/test` oxlint plugin — the tool-facing lint layer that enforces
7173
- * the statically-checkable CONVENTIONS rules (the `Lint(statique)` catalogue).
7174
- *
7175
- * Registered in a consumer's (or this repo's own) `oxlint.config.ts` via
7176
- * `jsPlugins: ['@jterrazz/test/oxlint']` and referenced as `jterrazz/<rule>` in
7177
- * the `rules` map, e.g. `'jterrazz/j2-no-sleep-in-specs': 'error'` — or enabled
7178
- * wholesale by spreading {@link recommendedRules}.
7179
- *
7180
- * This entry is bundled by tsdown (`dist/oxlint.js`); rules import nothing from
7181
- * the framework runtime (only pure core helpers: the token list, the case
7182
- * conversions, the fixture-marker list), so the bundle stays free of the heavy
7183
- * adapters (msw, pg, testcontainers, …) that the main entry pulls in.
7184
- */
7185
- declare const plugin: LintPlugin;
7215
+ declare const routedPlugin: LintPlugin;
7186
7216
  /**
7187
7217
  * The full catalogue at its intended severities — spread into an oxlint
7188
7218
  * `rules` map to enable everything in one line:
@@ -7190,27 +7220,9 @@ declare const plugin: LintPlugin;
7190
7220
  * rules: { ...recommendedRules }
7191
7221
  *
7192
7222
  * Hard conventions are errors; redundancy heuristics (`<id>w-*` rule ids) are
7193
- * warnings. `b5-await-using` is enabled but inert until re-declared with the
7194
- * project's docker-aware runner names:
7195
- *
7196
- * 'jterrazz/b5-await-using': ['error', { runners: ['dockerCli'] }]
7223
+ * warnings.
7197
7224
  */
7198
7225
  declare const recommendedRules: Record<string, 'error' | 'warn'>;
7199
- /**
7200
- * The composable testing fragment — wire the plugin, enable the whole
7201
- * catalogue, and ship the one override every strict consumer needs. Designed
7202
- * to be composed with a base preset (e.g. `@jterrazz/typescript/oxlint`):
7203
- *
7204
- * import { compose, node } from '@jterrazz/typescript/oxlint';
7205
- * import { testing } from '@jterrazz/test/oxlint';
7206
- * export default compose(node, testing);
7207
- *
7208
- * `jsPlugins` registers the tool-facing entry; `rules` is {@link recommendedRules};
7209
- * `overrides` relaxes `import/exports-last` for `*.specification.ts` — the A4 idiom
7210
- * (`export const { cli, cleanup } … ; afterAll(cleanup)`) legitimately ends a spec
7211
- * file on a non-export statement, so the relaxation ships here rather than being
7212
- * hand-rolled in every consumer.
7213
- */
7214
7226
  declare const testing: OxlintConfig;
7215
7227
  //#endregion
7216
- export { plugin as default, recommendedRules, testing };
7228
+ export { routedPlugin as default, recommendedRules, testing };
package/dist/oxlint.d.ts CHANGED
@@ -7069,6 +7069,7 @@ interface OxlintConfig extends Oxlintrc {
7069
7069
  */
7070
7070
  /** A source comment, as exposed by oxlint's ESTree-compatible `sourceCode`. */
7071
7071
  type Comment = {
7072
+ end?: number;
7072
7073
  range?: [number, number];
7073
7074
  start?: number;
7074
7075
  type: 'Block' | 'Line' | 'Shebang';
@@ -7112,24 +7113,52 @@ type Visitor = Record<string, (node: AstNode) => void>;
7112
7113
  * The normative documentation a rule carries — the code is the source of truth
7113
7114
  * for the mechanized catalogue (docs-as-code inversion). Every plugin rule sets
7114
7115
  * `meta.docs` to its {@link RuleDoc} entry from `manifest.ts`; the catalogue
7115
- * generator reads these to (re)write `docs/13-linting.md` and the annex.
7116
+ * generator reads these to (re)write `docs/19-linting.md` and the annex.
7116
7117
  */
7117
7118
  type RuleDoc = {
7118
- /** Enforcement channel — the four faces the manifest assembles. */
7119
- channel: 'checker' | 'process' | 'runtime' | 'statique';
7120
- /** The French normative sentence (the constitution's per-rule text, moved here). */
7119
+ /**
7120
+ * Enforcement channel — ONE per row, and the row says which.
7121
+ *
7122
+ * A convention enforced two ways is two rows, because the two answer
7123
+ * different questions: what `statique` sees in one file is not what
7124
+ * `checker` sees across a tree, and neither is what `runtime` refuses.
7125
+ * Writing a single row with two channels made the catalogue unable to say
7126
+ * which pass a reader should expect a finding from.
7127
+ *
7128
+ * - `statique` — a `jterrazz/*` oxlint rule;
7129
+ * - `upstream` — an option this vocabulary sets on an oxlint plugin rule
7130
+ * someone else owns (ADR-005);
7131
+ * - `checker` — a pass of `dist/checker.js`, over a tree or a member;
7132
+ * - `runtime` — a refusal the framework raises while a spec runs;
7133
+ * - `type` — what the compiler refuses, proven by a `test-d` assertion;
7134
+ * - `meta` — what one of the package's own meta-tests holds;
7135
+ * - `process` — a review judgement no channel can decide.
7136
+ */
7137
+ channel: 'checker' | 'meta' | 'process' | 'runtime' | 'statique' | 'type' | 'upstream';
7138
+ /** The normative sentence — the constitution's per-rule text, moved here. */
7121
7139
  convention: string;
7122
7140
  /**
7123
7141
  * One imperative line: what to DO about it. A ban with no destination is an
7124
7142
  * argument rather than a rule, so the catalogue and the message carry the
7125
- * same fix. A row that states none renders `—`.
7143
+ * same fix.
7126
7144
  */
7127
- fix?: string;
7145
+ fix: string;
7128
7146
  /**
7129
- * The specification facet the rule guards — segments the catalogue like
7130
- * the constructors segment the API. `'shared'` for cross-facet rules.
7147
+ * Which tree of the source the rule belongs to, and therefore where its
7148
+ * implementation sits: `src/lint/rules/model/` for a rule that reaches every
7149
+ * facet, `src/lint/rules/<facet>/` for one that guards a single
7150
+ * constructor's vocabulary. The catalogue is grouped on it — model first,
7151
+ * then one section per facet — so a reader adopting one facet sees the
7152
+ * rules that reach them and nothing else.
7153
+ *
7154
+ * Required, like `fix` and `reach`: a rule with no tree is a rule nobody
7155
+ * placed, and `model` is a statement (this reaches every facet), not a
7156
+ * default to fall into. The checker's passes carry the field too, although
7157
+ * their implementations do not split by folder — several passes share one
7158
+ * module because they share one walk of the tree, so the field alone says
7159
+ * which facet a pass speaks for.
7131
7160
  */
7132
- facet?: 'api' | 'cli' | 'component' | 'integration' | 'jobs' | 'mobile' | 'shared' | 'website';
7161
+ facet: 'api' | 'cli' | 'component' | 'integration' | 'jobs' | 'mobile' | 'model' | 'website';
7133
7162
  /** Convention family letter, e.g. `'A'`. */
7134
7163
  family: string;
7135
7164
  /** Convention code, e.g. `'A1'`. */
@@ -7137,11 +7166,26 @@ type RuleDoc = {
7137
7166
  /** One line: why the rule exists. */
7138
7167
  rationale: string;
7139
7168
  /**
7140
- * Which files the rule looks at — the vocabulary of `roleOf` plus the two
7141
- * shapes that are not a role (`tests`, everything the conventions bind, and
7142
- * `all`). A row that states none renders `—`.
7169
+ * For an `upstream` row: the rule whose OPTION carries the convention
7170
+ * (`vitest/no-restricted-matchers`). It is what the completeness meta-test
7171
+ * reads, so a row of that channel names the option it rests on.
7172
+ */
7173
+ upstream?: string;
7174
+ /**
7175
+ * Which files the rule looks at — the vocabulary of `roleOf` plus the
7176
+ * shapes that are not a role: `tests` (every file that declares tests),
7177
+ * `specs` (a tree), `member` (a package), and `all`.
7178
+ *
7179
+ * `module` is the COLOCATED unit test — a `.test.ts` beside the module it
7180
+ * covers, outside every specs tree. A `module`-role file under `specs/` is
7181
+ * a repository suite: it covers a tree rather than a unit, and the passes
7182
+ * that judge a tree are the ones that reach it.
7183
+ *
7184
+ * Required, like `fix`: a reader deciding whether a rule applies to the
7185
+ * file in front of them should not have to read its implementation, and a
7186
+ * row that left it blank was answering "somewhere".
7143
7187
  */
7144
- reach?: 'all' | 'component' | 'config' | 'document' | 'ground' | 'module' | 'specification' | 'specs' | 'tests';
7188
+ reach: 'all' | 'component' | 'config' | 'contract' | 'document' | 'ground' | 'member' | 'module' | 'spec' | 'specification' | 'specs' | 'tests';
7145
7189
  };
7146
7190
  /** Rule metadata (the subset we set). */
7147
7191
  type RuleMeta = {
@@ -7168,21 +7212,7 @@ type LintPlugin = {
7168
7212
  };
7169
7213
  //#endregion
7170
7214
  //#region src/lint/plugin.d.ts
7171
- /**
7172
- * The `@jterrazz/test` oxlint plugin — the tool-facing lint layer that enforces
7173
- * the statically-checkable CONVENTIONS rules (the `Lint(statique)` catalogue).
7174
- *
7175
- * Registered in a consumer's (or this repo's own) `oxlint.config.ts` via
7176
- * `jsPlugins: ['@jterrazz/test/oxlint']` and referenced as `jterrazz/<rule>` in
7177
- * the `rules` map, e.g. `'jterrazz/j2-no-sleep-in-specs': 'error'` — or enabled
7178
- * wholesale by spreading {@link recommendedRules}.
7179
- *
7180
- * This entry is bundled by tsdown (`dist/oxlint.js`); rules import nothing from
7181
- * the framework runtime (only pure core helpers: the token list, the case
7182
- * conversions, the fixture-marker list), so the bundle stays free of the heavy
7183
- * adapters (msw, pg, testcontainers, …) that the main entry pulls in.
7184
- */
7185
- declare const plugin: LintPlugin;
7215
+ declare const routedPlugin: LintPlugin;
7186
7216
  /**
7187
7217
  * The full catalogue at its intended severities — spread into an oxlint
7188
7218
  * `rules` map to enable everything in one line:
@@ -7190,27 +7220,9 @@ declare const plugin: LintPlugin;
7190
7220
  * rules: { ...recommendedRules }
7191
7221
  *
7192
7222
  * Hard conventions are errors; redundancy heuristics (`<id>w-*` rule ids) are
7193
- * warnings. `b5-await-using` is enabled but inert until re-declared with the
7194
- * project's docker-aware runner names:
7195
- *
7196
- * 'jterrazz/b5-await-using': ['error', { runners: ['dockerCli'] }]
7223
+ * warnings.
7197
7224
  */
7198
7225
  declare const recommendedRules: Record<string, 'error' | 'warn'>;
7199
- /**
7200
- * The composable testing fragment — wire the plugin, enable the whole
7201
- * catalogue, and ship the one override every strict consumer needs. Designed
7202
- * to be composed with a base preset (e.g. `@jterrazz/typescript/oxlint`):
7203
- *
7204
- * import { compose, node } from '@jterrazz/typescript/oxlint';
7205
- * import { testing } from '@jterrazz/test/oxlint';
7206
- * export default compose(node, testing);
7207
- *
7208
- * `jsPlugins` registers the tool-facing entry; `rules` is {@link recommendedRules};
7209
- * `overrides` relaxes `import/exports-last` for `*.specification.ts` — the A4 idiom
7210
- * (`export const { cli, cleanup } … ; afterAll(cleanup)`) legitimately ends a spec
7211
- * file on a non-export statement, so the relaxation ships here rather than being
7212
- * hand-rolled in every consumer.
7213
- */
7214
7226
  declare const testing: OxlintConfig;
7215
7227
  //#endregion
7216
- export { plugin as default, recommendedRules, testing };
7228
+ export { routedPlugin as default, recommendedRules, testing };