scan-json-toggleschanged
Asserts — What output.* toggles do to –format json: today, nothing (#91). The payload below is emitted with every section switched off, yet still carries packages, components, versus and ruleViolations in full. Pair it with scan-human-minimal to see the two formats diverge; when #91 lands, this baseline shrinking is the proof.
Ran hermex scan --format json --config configs/minimal.config.ts in fixtures/ → exit 0, as asserted
Config fixtures/configs/minimal.config.ts · Fixture fixtures (overview) · Case scan-json-toggles (dossier)
Reproduce locally: pnpm run test:output -- --filter scan-json-toggles
fixtures/configs/minimal.config.ts
import type { HermexConfigInput } from '../../src/config/types.ts';
import base from '../hermex.config.ts';
/**
* Every output section off except the summary. Regression cover for #63:
* a section that is switched off must actually be absent, not rendered
* empty or rendered anyway. Used twice — once as human output, once as
* `--format json`, since the JSON payload has to honour the same toggles.
*/
export default {
...base,
output: {
summary: 'log',
packages: false,
components: false,
patterns: false,
details: false,
versus: false,
rules: false,
},
} satisfies HermexConfigInput;
Diffs are unified format: - is the target branch, + is this run. @@ -12,7 +12,9 @@ is a hunk header — unchanged lines were skipped, and the hunk below covers 7 lines from line 12 of the target branch and 9 lines from line 12 of this run.
--- target/stdout.json
+++ current/stdout.json
@@ -4,499 +4,8 @@
"filesAnalyzed": 17,
"totalImports": 80,
"totalComponents": 35,
- "totalUsagePatterns": 284,
- "patternCounts": [
- {
- "patternType": "usage.jsx",
- "displayName": "JSX Usage",
- "count": 64
- },
- {
- "patternType": "imports.default",
- "displayName": "Default Imports",
- "count": 39
- },
- {
- "patternType": "imports.named",
- "displayName": "Named Imports",
- "count": 37
- },
- {
- "patternType": "usage.objects",
- "displayName": "Object Mappings",
- "count": 19
- },
- {
- "patternType": "advanced.dynamic",
- "displayName": "Dynamic Imports",
- "count": 19
- },
- {
- "patternType": "usage.variables",
- "displayName": "Variable Assignments",
- "count": 9
- },
- {
- "patternType": "usage.conditional",
- "displayName": "Conditional Usage",
- "count": 7
- },
- {
- "patternType": "imports.aliased",
- "displayName": "Aliased Imports",
- "count": 6
- },
- {
- "patternType": "advanced.lazy",
- "displayName": "Lazy Loading",
- "count": 6
- },
- {
- "patternType": "advanced.hoc",
- "displayName": "Higher-Order Components",
- "count": 5
- },
- {
- "patternType": "imports.namespace",
- "displayName": "Namespace Imports",
- "count": 4
- },
- {
- "patternType": "usage.destructuring",
- "displayName": "Destructuring",
- "count": 2
- },
- {
- "patternType": "usage.arrays",
- "displayName": "Array Mappings",
- "count": 2
- },
- {
- "patternType": "advanced.portal",
- "displayName": "Portal Usage",
- "count": 1
- },
- {
- "patternType": "advanced.memo",
- "displayName": "Memoized Components",
- "count": 0
- },
- {
- "patternType": "advanced.forwardRef",
- "displayName": "Forward Refs",
- "count": 0
- }
- ]
+ "totalUsagePatterns": 284
},
- "packages": [
- {
- "packageName": "@design-system/foundation",
- "version": "2.5.3",
- "rootVersion": "2.5.3",
- "declaredIn": [
- "dependencies"
- ],
- "componentCount": 18,
- "usageCount": 33,
- "percentage": 91.66666666666666,
- "internal": true,
- "hasVersionConflict": false,
- "allVersions": [
- "2.5.3"
- ]
- },
- {
- "packageName": "react",
- "version": "18.3.1",
- "rootVersion": "18.3.1",
- "declaredIn": [
- "dependencies"
- ],
- "componentCount": 1,
- "usageCount": 3,
- "percentage": 8.333333333333332,
- "internal": false,
- "hasVersionConflict": false,
- "allVersions": [
- "18.3.1"
- ]
- },
- {
- "packageName": "eslint",
- "version": null,
- "rootVersion": null,
- "declaredIn": [
- "devDependencies"
- ],
- "componentCount": 0,
- "usageCount": 0,
- "percentage": 0,
- "internal": false,
- "hasVersionConflict": false,
- "allVersions": []
- },
- {
- "packageName": "moment",
- "version": "2.29.4",
- "rootVersion": "2.29.4",
- "declaredIn": [
- "devDependencies"
- ],
- "componentCount": 0,
- "usageCount": 0,
- "percentage": 0,
- "internal": false,
- "hasVersionConflict": false,
- "allVersions": [
- "2.29.4"
- ]
- },
- {
- "packageName": "react-dom",
- "version": "18.3.1",
- "rootVersion": "18.3.1",
- "declaredIn": [],
- "componentCount": 0,
- "usageCount": 0,
- "percentage": 0,
- "internal": false,
- "hasVersionConflict": false,
- "allVersions": [
- "18.3.1"
- ]
- }
- ],
- "components": [
- {
- "name": "Button",
- "source": "@design-system/foundation",
- "count": 6,
- "files": [
- "patterns/01-direct-usage.tsx",
- "patterns/03-object-mapping.tsx",
- "patterns/04-lazy-loading.tsx",
- "patterns/06-common-patterns.tsx",
- "patterns/07-comprehensive-usage.tsx"
- ]
- },
- {
- "name": "Card",
- "source": "unknown",
- "count": 5,
- "files": [
- "aliasing/01-plain.tsx",
- "aliasing/02-alias.tsx",
- "aliasing/03-alias-again.tsx",
- "aliasing/04-plain-again.tsx",
- "patterns/05-namespace-imports.tsx"
- ]
- },
- {
- "name": "Input",
- "source": "@design-system/foundation",
- "count": 5,
- "files": [
- "patterns/01-direct-usage.tsx",
- "patterns/03-object-mapping.tsx",
- "patterns/06-common-patterns.tsx",
- "patterns/07-comprehensive-usage.tsx"
- ]
- },
- {
- "name": "Card",
- "source": "@design-system/foundation",
- "count": 4,
- "files": [
- "patterns/01-direct-usage.tsx",
- "patterns/03-object-mapping.tsx",
- "patterns/06-common-patterns.tsx",
- "patterns/07-comprehensive-usage.tsx"
- ]
- },
- {
- "name": "Typography",
- "source": "@design-system/foundation",
- "count": 4,
- "files": [
- "patterns/01-direct-usage.tsx",
- "patterns/04-lazy-loading.tsx",
- "patterns/06-common-patterns.tsx",
- "patterns/07-comprehensive-usage.tsx"
- ]
- },
- {
- "name": "Suspense",
- "source": "react",
- "count": 3,
- "files": [
- "patterns/04-lazy-loading.tsx",
- "patterns/06-common-patterns.tsx",
- "patterns/07-comprehensive-usage.tsx"
- ]
- },
- {
- "name": "Foundation.Button",
- "source": "unknown",
- "count": 3,
- "files": [
- "patterns/05-namespace-imports.tsx",
- "patterns/06-common-patterns.tsx",
- "patterns/07-comprehensive-usage.tsx"
- ]
- },
- {
- "name": "Foundation.Input",
- "source": "unknown",
- "count": 3,
- "files": [
- "patterns/05-namespace-imports.tsx",
- "patterns/06-common-patterns.tsx",
- "patterns/07-comprehensive-usage.tsx"
- ]
- },
- {
- "name": "Foundation.Card",
- "source": "unknown",
- "count": 3,
- "files": [
- "patterns/05-namespace-imports.tsx",
- "patterns/06-common-patterns.tsx",
- "patterns/07-comprehensive-usage.tsx"
- ]
- },
- {
- "name": "Foundation.Typography",
- "source": "unknown",
- "count": 2,
- "files": [
- "patterns/05-namespace-imports.tsx",
- "patterns/06-common-patterns.tsx"
- ]
- },
- {
- "name": "Button",
- "source": "unknown",
- "count": 2,
- "files": [
- "versus/01-collision-classic-button.tsx",
- "versus/02-collision-pulse-button.tsx"
- ]
- },
- {
- "name": "Doc",
- "source": "local",
- "count": 1,
- "files": [
- "declarations/consumer.tsx"
- ]
- },
- {
- "name": "PrimaryButton",
- "source": "unknown",
- "count": 1,
- "files": [
- "patterns/02-variable-assignment.tsx"
- ]
- },
- {
- "name": "UserInput",
- "source": "unknown",
- "count": 1,
- "files": [
- "patterns/02-variable-assignment.tsx"
- ]
- },
- {
- "name": "InfoCard",
- "source": "unknown",
- "count": 1,
- "files": [
- "patterns/02-variable-assignment.tsx"
- ]
- },
- {
- "name": "Typography",
- "source": "unknown",
- "count": 1,
- "files": [
- "patterns/05-namespace-imports.tsx"
- ]
- },
- {
- "name": "FoundationComponents.Button",
- "source": "unknown",
- "count": 1,
- "files": [
- "patterns/05-namespace-imports.tsx"
- ]
- },
- {
- "name": "Icon",
- "source": "@design-system/foundation",
- "count": 1,
- "files": [
- "patterns/06-common-patterns.tsx"
- ]
- },
- {
- "name": "SaveButton",
- "source": "unknown",
- "count": 1,
- "files": [
- "patterns/06-common-patterns.tsx"
- ]
- },
- {
- "name": "UserCard",
- "source": "unknown",
- "count": 1,
- "files": [
- "patterns/06-common-patterns.tsx"
- ]
- },
- {
- "name": "MyButton",
- "source": "unknown",
- "count": 1,
- "files": [
- "patterns/07-comprehensive-usage.tsx"
- ]
- },
- {
- "name": "MyInput",
- "source": "unknown",
- "count": 1,
- "files": [
- "patterns/07-comprehensive-usage.tsx"
- ]
- },
- {
- "name": "Modal",
- "source": "@design-system/foundation",
- "count": 1,
- "files": [
- "patterns/07-comprehensive-usage.tsx"
- ]
- },
- {
- "name": "CaseChild",
- "source": "@design-system/foundation",
- "count": 1,
- "files": [
- "patterns/09-jsx-in-attributes.tsx"
- ]
- },
- {
- "name": "CaseCond",
- "source": "@design-system/foundation",
- "count": 1,
- "files": [
- "patterns/09-jsx-in-attributes.tsx"
- ]
- },
- {
- "name": "CaseMap",
- "source": "@design-system/foundation",
- "count": 1,
- "files": [
- "patterns/09-jsx-in-attributes.tsx"
- ]
- },
- {
- "name": "CaseVar",
- "source": "@design-system/foundation",
- "count": 1,
- "files": [
- "patterns/09-jsx-in-attributes.tsx"
- ]
- },
- {
- "name": "CaseReturn",
- "source": "@design-system/foundation",
- "count": 1,
- "files": [
- "patterns/09-jsx-in-attributes.tsx"
- ]
- },
- {
- "name": "Child",
- "source": "@design-system/foundation",
- "count": 1,
- "files": [
- "patterns/09-jsx-in-attributes.tsx"
- ]
- },
- {
- "name": "CaseAttr",
- "source": "@design-system/foundation",
- "count": 1,
- "files": [
- "patterns/09-jsx-in-attributes.tsx"
- ]
- },
- {
- "name": "CaseAttrSelfClosing",
- "source": "@design-system/foundation",
- "count": 1,
- "files": [
- "patterns/09-jsx-in-attributes.tsx"
- ]
- },
- {
- "name": "CaseAttrCond",
- "source": "@design-system/foundation",
- "count": 1,
- "files": [
- "patterns/09-jsx-in-attributes.tsx"
- ]
- },
- {
- "name": "CaseAttrHost",
- "source": "@design-system/foundation",
- "count": 1,
- "files": [
- "patterns/09-jsx-in-attributes.tsx"
- ]
- },
- {
- "name": "CaseAttrFragment",
- "source": "@design-system/foundation",
- "count": 1,
- "files": [
- "patterns/09-jsx-in-attributes.tsx"
- ]
- },
- {
- "name": "CaseBoth",
- "source": "@design-system/foundation",
- "count": 1,
- "files": [
- "patterns/09-jsx-in-attributes.tsx"
- ]
- }
- ],
- "versus": [
- {
- "name": "Design System Migration",
- "packages": [
- "@design-system/foundation",
- "@new-system/arc"
- ],
- "entries": [
- {
- "packageName": "@design-system/foundation",
- "count": 33,
- "percentage": 100
- },
- {
- "packageName": "@new-system/arc",
- "count": 0,
- "percentage": 0
- }
- ],
- "totalCount": 33
- }
- ],
"ruleViolations": [
{
"ruleId": "no-packages",
stdout.json{
"version": "<version>",
"summary": {
"filesAnalyzed": 17,
"totalImports": 80,
"totalComponents": 35,
"totalUsagePatterns": 284
},
"ruleViolations": [
{
"ruleId": "no-packages",
"severity": "error",
"patterns": [
"moment"
],
"message": "Use date-fns or dayjs",
"matchedFiles": [],
"packageName": "moment"
},
{
"ruleId": "require-packages",
"severity": "error",
"patterns": [
"typescript"
],
"message": "TypeScript is required",
"matchedFiles": []
},
{
"ruleId": "require-files",
"severity": "error",
"patterns": [
".nvmrc"
],
"matchedFiles": []
},
{
"ruleId": "require-files",
"severity": "warn",
"patterns": [
".editorconfig"
],
"matchedFiles": []
}
],
"compliance": {
"status": "non-compliant",
"compliant": false,
"counts": {
"errorRuleViolations": 3,
"releaseAgeViolations": 0,
"warningRuleViolations": 1
}
}
}
stderr.txthermex v<version>
- Parsing lockfile...
✔ Found pnpm lockfile (supports: v5, v6, v9) - 5 packages
✔ Found 18 files
✔ Analysis complete! Analyzed 17/18 files
⚠ 1 file(s) failed to parse:
broken/unparseable.tsx
x Expression expected
,----
1 | export const Broken = ( : : :;
: ^
`----
Caused by:
Syntax Error