@alint-js/plugin-js 0.7.1 → 0.7.3
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 +4 -0
- package/dist/index.d.mts +5 -1
- package/dist/index.mjs +99 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ The package default export is the plugin definition. Individual rule definitions
|
|
|
9
9
|
The bundled `recommended` config enables these rules under the `js` plugin name:
|
|
10
10
|
|
|
11
11
|
- `js/inline-miniature-normalizer` reports clusters of local helpers that form a private reader or narrowing toolkit.
|
|
12
|
+
- `js/no-config-file-tests` reports standalone tests that restate repository configuration instead of verifying behavior. It skips non-test files before calling the model, but the `files:` glob must include tests and ignored files remain excluded.
|
|
12
13
|
- `js/no-mixed-layers-without-abstraction` reports consuming features that own independently reusable external-integration responsibilities without a stable interface.
|
|
13
14
|
- `js/no-private-schema-toolkit` reports clusters of local helpers that form an ad hoc schema or payload-normalization toolkit.
|
|
14
15
|
- `js/no-redundant-binding` reports local bindings that only rename an unchanged value or reference without adding a useful boundary.
|
|
@@ -30,6 +31,8 @@ Five repository-aware rules are registered but intentionally not enabled by `rec
|
|
|
30
31
|
|
|
31
32
|
The five opt-in rules require both a configured model and an agent adapter capable of tool calls. They reuse the standard `@alint-js/tools-fs` list, search, and read tools, and ask the agent to include repository evidence with each finding.
|
|
32
33
|
|
|
34
|
+
`js/no-config-file-tests` is not repository-aware and needs no agent adapter: it judges the test file it is handed, so a configured model is enough.
|
|
35
|
+
|
|
33
36
|
## How to use
|
|
34
37
|
|
|
35
38
|
Use the default export with the `js` plugin name because the bundled preset refers to `js/*` rule IDs.
|
|
@@ -88,6 +91,7 @@ export default defineConfig([
|
|
|
88
91
|
|
|
89
92
|
- Do not use model-backed rules as a deterministic replacement for syntax-aware lint.
|
|
90
93
|
- Do not enable repository-aware rules with a generation-only model or without an agent adapter.
|
|
94
|
+
- Do not use `js/no-config-file-tests` when the configuration module owns logic the repository must verify, such as a custom lint rule, a custom bundler plugin, or a merge or normalization helper. Move that logic into its own module and test the module instead.
|
|
91
95
|
- Do not use `js/no-duplicated-knowledge` for coincidental literals or clones that do not encode one shared decision.
|
|
92
96
|
- Do not use `js/no-overlapping-entrypoints` for documented compatibility aliases or conditional/type-only exports.
|
|
93
97
|
- Do not use `js/no-redundant-catch` when the outer catch changes cleanup, observability, error metadata, cause, identity, or cancellation behavior.
|
package/dist/index.d.mts
CHANGED
|
@@ -2605,6 +2605,9 @@ declare function createReportFindingsToolParameters(): JsonSchema;
|
|
|
2605
2605
|
//#region src/rules/inline-miniature-normalizer/rule.d.ts
|
|
2606
2606
|
declare const inlineMiniatureNormalizerRule: RuleDefinition<[]>;
|
|
2607
2607
|
//#endregion
|
|
2608
|
+
//#region src/rules/no-config-file-tests/rule.d.ts
|
|
2609
|
+
declare const configFileTestsRule: RuleDefinition<[]>;
|
|
2610
|
+
//#endregion
|
|
2608
2611
|
//#region src/rules/no-duplicated-knowledge/rule.d.ts
|
|
2609
2612
|
declare const duplicatedKnowledgeRule: RuleDefinition<[]>;
|
|
2610
2613
|
//#endregion
|
|
@@ -2641,6 +2644,7 @@ declare const vacuousFunctionRule: RuleDefinition<[]>;
|
|
|
2641
2644
|
//#region src/index.d.ts
|
|
2642
2645
|
declare const _default: PluginDefinition<{
|
|
2643
2646
|
readonly 'inline-miniature-normalizer': RuleDefinition<[]>;
|
|
2647
|
+
readonly 'no-config-file-tests': RuleDefinition<[]>;
|
|
2644
2648
|
readonly 'no-duplicated-knowledge': RuleDefinition<[]>;
|
|
2645
2649
|
readonly 'no-mixed-layers-without-abstraction': RuleDefinition<[]>;
|
|
2646
2650
|
readonly 'no-overlapping-entrypoints': RuleDefinition<[]>;
|
|
@@ -2654,4 +2658,4 @@ declare const _default: PluginDefinition<{
|
|
|
2654
2658
|
readonly 'no-vacuous-function': RuleDefinition<[]>;
|
|
2655
2659
|
}>;
|
|
2656
2660
|
//#endregion
|
|
2657
|
-
export { createJudgeMessages, createReportFindingsToolParameters, _default as default, duplicatedKnowledgeRule, inlineMiniatureNormalizerRule, judgeFindingSchema, judgeResponseSchema, mixedLayersWithoutAbstractionRule, overlappingEntrypointsRule, privateSchemaToolkitRule, redundantBindingRule, redundantCatchRule, redundantJsdocRule, singleUseMaterializationRule, testOnlyProductionWrapperRule, trivialWrapperStackRule, vacuousFunctionRule };
|
|
2661
|
+
export { configFileTestsRule, createJudgeMessages, createReportFindingsToolParameters, _default as default, duplicatedKnowledgeRule, inlineMiniatureNormalizerRule, judgeFindingSchema, judgeResponseSchema, mixedLayersWithoutAbstractionRule, overlappingEntrypointsRule, privateSchemaToolkitRule, redundantBindingRule, redundantCatchRule, redundantJsdocRule, singleUseMaterializationRule, testOnlyProductionWrapperRule, trivialWrapperStackRule, vacuousFunctionRule };
|
package/dist/index.mjs
CHANGED
|
@@ -2048,6 +2048,102 @@ async onTargetFile(target) {
|
|
|
2048
2048
|
} })
|
|
2049
2049
|
});
|
|
2050
2050
|
//#endregion
|
|
2051
|
+
//#region src/rules/no-config-file-tests/prompt.ts
|
|
2052
|
+
const configFileTestsPrompt = `
|
|
2053
|
+
You are reviewing one JavaScript or TypeScript test file.
|
|
2054
|
+
|
|
2055
|
+
Task:
|
|
2056
|
+
Warn about a standalone test file whose subject is repository configuration rather than production behavior.
|
|
2057
|
+
|
|
2058
|
+
This is a warning-level design smell, not a correctness error.
|
|
2059
|
+
|
|
2060
|
+
The issue:
|
|
2061
|
+
Configuration is declarative, so a test that restates it keeps a second copy of values the configuration already states. Every intentional configuration change then fails the test without proving any behavior, and the same decision has to be updated in two places. A failing copy is also easy to misread: it looks like evidence that the configuration change is wrong.
|
|
2062
|
+
|
|
2063
|
+
Report test files whose subject is configuration, such as:
|
|
2064
|
+
- importing a configuration module like eslint.config.ts, vite.config.ts, vitest.config.ts, tsdown.config.ts, or alint.config.ts and asserting its exported object, arrays, globs, plugin lists, or rule severities
|
|
2065
|
+
- reading a configuration file as text or structured data, like tsconfig.json, package.json, or cspell.config.yaml, and asserting its keys, values, ordering, or a snapshot of it
|
|
2066
|
+
- asserting that a configuration entry contains an expected string, path, dependency, or file name, where the expectation is the configuration itself
|
|
2067
|
+
|
|
2068
|
+
Do not report:
|
|
2069
|
+
- tests for logic the repository owns: custom lint rule implementations, custom bundler or transformer plugins, configuration helper, merge, or normalization functions, schema validation, or environment-dependent branch selection
|
|
2070
|
+
- tests that run the configured tool over a fixture and assert the behavior or diagnostics it produces
|
|
2071
|
+
- tests that verify a generator produces configuration, when the generator is the unit under test
|
|
2072
|
+
- configuration that owns policy the repository must verify, such as permission or access lists, ignore lists that must stay in sync with another file, or a cross-file invariant the test proves
|
|
2073
|
+
- fixtures, snapshots, or helpers rather than tests that run
|
|
2074
|
+
- test files whose subject also includes production behavior
|
|
2075
|
+
- files that are not test files
|
|
2076
|
+
|
|
2077
|
+
Use an aggressive but fair standard:
|
|
2078
|
+
- if the assertions repeat values the configuration already declares, report it
|
|
2079
|
+
- if the test can only fail when a value it copied changes, report it
|
|
2080
|
+
- if deleting the test would lose no verified behavior, report it
|
|
2081
|
+
- if the subject is production code, or the configuration carries behavior that needs coverage, return no finding
|
|
2082
|
+
|
|
2083
|
+
Report the line that shows the configuration under test, usually the import of the configuration module or the assertion that restates it. Report each test file once, name the configuration under test or the values being restated, and keep the message short.
|
|
2084
|
+
|
|
2085
|
+
Suggest deleting the standalone test and covering the configuration through the behavior it produces. When the configuration carries logic that needs coverage, suggest moving that logic into its own module and testing the module instead.
|
|
2086
|
+
|
|
2087
|
+
Return warnings only.
|
|
2088
|
+
`.trim();
|
|
2089
|
+
//#endregion
|
|
2090
|
+
//#region src/rules/no-config-file-tests/rule.ts
|
|
2091
|
+
const TEST_FILE_SUFFIX = /\.(?:test|spec)\.[cm]?[jt]sx?$/;
|
|
2092
|
+
const TEST_DIRECTORY = /(?:^|\/)(?:__tests__|__test__)\//;
|
|
2093
|
+
const configFileTestsRule = defineRule({
|
|
2094
|
+
cacheKey: configFileTestsPrompt,
|
|
2095
|
+
create: (ctx) => ({
|
|
2096
|
+
/**
|
|
2097
|
+
* Reviews one test file target for a standalone test of configuration content.
|
|
2098
|
+
*
|
|
2099
|
+
* Triggering workflow:
|
|
2100
|
+
*
|
|
2101
|
+
* {@link defineRule}
|
|
2102
|
+
* -> `PlannedSourceTarget.kind === "file"`
|
|
2103
|
+
* -> `onTargetFile`
|
|
2104
|
+
* -> {@link judgeSource}
|
|
2105
|
+
*
|
|
2106
|
+
* Upstream:
|
|
2107
|
+
* - {@link defineRule}
|
|
2108
|
+
*
|
|
2109
|
+
* Downstream:
|
|
2110
|
+
* - {@link judgeSource}
|
|
2111
|
+
* - `ctx.report`
|
|
2112
|
+
*/
|
|
2113
|
+
async onTargetFile(target) {
|
|
2114
|
+
if (!isTestFile(target.file.path)) return;
|
|
2115
|
+
const model = await ctx.model();
|
|
2116
|
+
const file = await ctx.src.readFile(target.file);
|
|
2117
|
+
const findings = await judgeSource({
|
|
2118
|
+
logger: ctx.logger,
|
|
2119
|
+
metering: ctx.metering,
|
|
2120
|
+
model,
|
|
2121
|
+
operation: "config-file-tests-judge",
|
|
2122
|
+
outputLanguage: ctx.outputLanguage,
|
|
2123
|
+
prompt: configFileTestsPrompt,
|
|
2124
|
+
signal: ctx.signal,
|
|
2125
|
+
source: file.text
|
|
2126
|
+
});
|
|
2127
|
+
for (const finding of findings) ctx.report({
|
|
2128
|
+
evidence: {
|
|
2129
|
+
confidence: finding.confidence,
|
|
2130
|
+
suggestion: finding.suggestion
|
|
2131
|
+
},
|
|
2132
|
+
filePath: target.file.path,
|
|
2133
|
+
loc: { start: {
|
|
2134
|
+
column: 0,
|
|
2135
|
+
line: finding.line
|
|
2136
|
+
} },
|
|
2137
|
+
message: finding.message
|
|
2138
|
+
});
|
|
2139
|
+
} }),
|
|
2140
|
+
languages: ["javascript", "typescript"]
|
|
2141
|
+
});
|
|
2142
|
+
function isTestFile(filePath) {
|
|
2143
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
2144
|
+
return TEST_FILE_SUFFIX.test(normalized) || TEST_DIRECTORY.test(normalized);
|
|
2145
|
+
}
|
|
2146
|
+
//#endregion
|
|
2051
2147
|
//#region src/rules/no-duplicated-knowledge/prompt.ts
|
|
2052
2148
|
const duplicatedKnowledgeInstructions = `
|
|
2053
2149
|
Investigate whether the target independently maintains knowledge that the repository already owns elsewhere.
|
|
@@ -6232,6 +6328,7 @@ async onTargetFile(target) {
|
|
|
6232
6328
|
var src_default = definePlugin({
|
|
6233
6329
|
configs: { recommended: [{ rules: {
|
|
6234
6330
|
"js/inline-miniature-normalizer": "warn",
|
|
6331
|
+
"js/no-config-file-tests": "warn",
|
|
6235
6332
|
"js/no-mixed-layers-without-abstraction": "warn",
|
|
6236
6333
|
"js/no-private-schema-toolkit": "warn",
|
|
6237
6334
|
"js/no-redundant-binding": "warn",
|
|
@@ -6241,6 +6338,7 @@ var src_default = definePlugin({
|
|
|
6241
6338
|
} }] },
|
|
6242
6339
|
rules: {
|
|
6243
6340
|
"inline-miniature-normalizer": inlineMiniatureNormalizerRule,
|
|
6341
|
+
"no-config-file-tests": configFileTestsRule,
|
|
6244
6342
|
"no-duplicated-knowledge": duplicatedKnowledgeRule,
|
|
6245
6343
|
"no-mixed-layers-without-abstraction": mixedLayersWithoutAbstractionRule,
|
|
6246
6344
|
"no-overlapping-entrypoints": overlappingEntrypointsRule,
|
|
@@ -6255,4 +6353,4 @@ var src_default = definePlugin({
|
|
|
6255
6353
|
}
|
|
6256
6354
|
});
|
|
6257
6355
|
//#endregion
|
|
6258
|
-
export { createJudgeMessages, createReportFindingsToolParameters, src_default as default, duplicatedKnowledgeRule, inlineMiniatureNormalizerRule, judgeFindingSchema, judgeResponseSchema, mixedLayersWithoutAbstractionRule, overlappingEntrypointsRule, privateSchemaToolkitRule, redundantBindingRule, redundantCatchRule, redundantJsdocRule, singleUseMaterializationRule, dist_exports as t, testOnlyProductionWrapperRule, trivialWrapperStackRule, vacuousFunctionRule };
|
|
6356
|
+
export { configFileTestsRule, createJudgeMessages, createReportFindingsToolParameters, src_default as default, duplicatedKnowledgeRule, inlineMiniatureNormalizerRule, judgeFindingSchema, judgeResponseSchema, mixedLayersWithoutAbstractionRule, overlappingEntrypointsRule, privateSchemaToolkitRule, redundantBindingRule, redundantCatchRule, redundantJsdocRule, singleUseMaterializationRule, dist_exports as t, testOnlyProductionWrapperRule, trivialWrapperStackRule, vacuousFunctionRule };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alint-js/plugin-js",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.3",
|
|
5
5
|
"description": "Model-backed JavaScript and TypeScript review rules for alint",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
"@valibot/to-json-schema": "^1.7.1",
|
|
33
33
|
"apeira": "^0.0.7",
|
|
34
34
|
"valibot": "^1.4.2",
|
|
35
|
-
"@alint-js/
|
|
36
|
-
"@alint-js/
|
|
37
|
-
"@alint-js/tools-fs": "0.7.
|
|
35
|
+
"@alint-js/core": "0.7.3",
|
|
36
|
+
"@alint-js/plugin": "0.7.3",
|
|
37
|
+
"@alint-js/tools-fs": "0.7.3"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"build": "tsdown",
|