@decantr/verifier 3.5.5 → 3.6.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/README.md +1 -1
- package/dist/index.js +19 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ npm install @decantr/verifier
|
|
|
37
37
|
- Next.js static/document outputs are treated as framework-rendered documents instead of requiring a Vite-style `id="root"` mount element
|
|
38
38
|
- project source audits ignore test, spec, story, fixture, and mock files for production drift warnings such as localhost endpoints and unsafe rendering patterns
|
|
39
39
|
- project audits emit `COMP001` / `import-existing-component` findings when a production source file locally redeclares a primitive such as `Button`, `Card`, or `Dialog` while an exported reusable primitive already exists under common component paths
|
|
40
|
-
- project audits emit `COMP010` / `replace-raw-control-with-local-component` findings when production JSX renders raw controls such as `<button>` or `<input>` while a project-owned primitive already exists
|
|
40
|
+
- project audits emit `COMP010` / `replace-raw-control-with-local-component` findings when production JSX renders generic raw controls such as `<button>` or text-like `<input>` while a project-owned primitive already exists; specialized inputs such as file, hidden, checkbox, radio, color, range, and Dropzone `getInputProps()` controls are not treated as generic `Input` drift
|
|
41
41
|
- project audits emit behavior-obligation findings when accepted `.decantr/local-patterns.json` patterns declare `behavior_obligations` and production source strongly violates statically checkable dialog/form obligations:
|
|
42
42
|
- `A11Y010` / `restore-dialog-accessible-name`
|
|
43
43
|
- `A11Y011` / `restore-label-association`
|
package/dist/index.js
CHANGED
|
@@ -69,6 +69,18 @@ var RAW_CONTROL_COMPONENT_BY_ELEMENT = {
|
|
|
69
69
|
table: "Table",
|
|
70
70
|
textarea: "Textarea"
|
|
71
71
|
};
|
|
72
|
+
var NON_GENERIC_INPUT_TYPES = /* @__PURE__ */ new Set([
|
|
73
|
+
"button",
|
|
74
|
+
"checkbox",
|
|
75
|
+
"color",
|
|
76
|
+
"file",
|
|
77
|
+
"hidden",
|
|
78
|
+
"image",
|
|
79
|
+
"radio",
|
|
80
|
+
"range",
|
|
81
|
+
"reset",
|
|
82
|
+
"submit"
|
|
83
|
+
]);
|
|
72
84
|
function normalizePath(path) {
|
|
73
85
|
return path.replace(/\\/g, "/");
|
|
74
86
|
}
|
|
@@ -120,10 +132,14 @@ function jsxAttributeStringValue(node, attributeName) {
|
|
|
120
132
|
}
|
|
121
133
|
return null;
|
|
122
134
|
}
|
|
123
|
-
function
|
|
135
|
+
function isSpecializedInput(node) {
|
|
124
136
|
const tagName = jsxIdentifierName(node.tagName);
|
|
125
137
|
if (tagName !== "input") return false;
|
|
126
|
-
|
|
138
|
+
const type = jsxAttributeStringValue(node, "type")?.toLowerCase();
|
|
139
|
+
if (type && NON_GENERIC_INPUT_TYPES.has(type)) return true;
|
|
140
|
+
return node.attributes.properties.some(
|
|
141
|
+
(property) => ts.isJsxSpreadAttribute(property) && /\bgetInputProps\s*\(/.test(property.expression.getText())
|
|
142
|
+
);
|
|
127
143
|
}
|
|
128
144
|
function isReusableComponentPath(file, name) {
|
|
129
145
|
const normalized = normalizePath(file);
|
|
@@ -222,7 +238,7 @@ function collectRawControls(sourceFile, file) {
|
|
|
222
238
|
if (ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) {
|
|
223
239
|
const tagName = jsxIdentifierName(node.tagName);
|
|
224
240
|
const component = tagName && Object.hasOwn(RAW_CONTROL_COMPONENT_BY_ELEMENT, tagName) ? RAW_CONTROL_COMPONENT_BY_ELEMENT[tagName] : null;
|
|
225
|
-
if (component && !
|
|
241
|
+
if (component && !isSpecializedInput(node)) {
|
|
226
242
|
rawControls.push({
|
|
227
243
|
element: tagName,
|
|
228
244
|
component,
|