@rettangoli/check 0.0.1
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 +295 -0
- package/ROADMAP.md +175 -0
- package/package.json +46 -0
- package/src/cli/bin.js +325 -0
- package/src/cli/check.js +232 -0
- package/src/cli/index.js +1 -0
- package/src/core/analyze.js +227 -0
- package/src/core/discovery.js +83 -0
- package/src/core/exportedFunctions.js +235 -0
- package/src/core/model.js +898 -0
- package/src/core/parsers.js +2726 -0
- package/src/core/registry.js +779 -0
- package/src/core/schema.js +161 -0
- package/src/core/scopeGraph.js +1400 -0
- package/src/core/semantic.js +329 -0
- package/src/diagnostics/autofix.js +191 -0
- package/src/diagnostics/catalog.js +89 -0
- package/src/index.js +2 -0
- package/src/reporters/index.js +13 -0
- package/src/reporters/json.js +42 -0
- package/src/reporters/sarif.js +213 -0
- package/src/reporters/text.js +145 -0
- package/src/rules/compatibility.js +318 -0
- package/src/rules/constants.js +22 -0
- package/src/rules/crossFileSymbols.js +108 -0
- package/src/rules/expression.js +338 -0
- package/src/rules/feParity.js +65 -0
- package/src/rules/index.js +39 -0
- package/src/rules/jempl.js +80 -0
- package/src/rules/lifecycle.js +4 -0
- package/src/rules/listenerConfig.js +556 -0
- package/src/rules/listenerSymbols.js +49 -0
- package/src/rules/methods.js +117 -0
- package/src/rules/refs.js +20 -0
- package/src/rules/schema.js +118 -0
- package/src/rules/shared.js +20 -0
- package/src/rules/yahtmlAttrs.js +238 -0
- package/src/semantic/engine.js +778 -0
- package/src/semantic/index.js +9 -0
- package/src/types/lattice.js +281 -0
- package/src/utils/case.js +9 -0
- package/src/utils/fs.js +30 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { toCamelCase, toKebabCase } from "../utils/case.js";
|
|
2
|
+
|
|
3
|
+
const isObjectRecord = (value) => {
|
|
4
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const isCanonicalKey = (value) => {
|
|
8
|
+
return typeof value === "string" && value.length > 0 && value.trim() === value;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const toSortedObjectFromMap = (valueByKey) => {
|
|
12
|
+
const result = {};
|
|
13
|
+
if (!(valueByKey instanceof Map)) {
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
[...valueByKey.entries()]
|
|
18
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
19
|
+
.forEach(([key, value]) => {
|
|
20
|
+
result[key] = value;
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const collectCanonicalNameMap = (value) => {
|
|
27
|
+
const byName = new Map();
|
|
28
|
+
if (!isObjectRecord(value)) {
|
|
29
|
+
return byName;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
Object.keys(value).forEach((rawName) => {
|
|
33
|
+
if (!isCanonicalKey(rawName)) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (byName.has(rawName)) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
byName.set(rawName, value[rawName]);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return byName;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const collectCanonicalStringListFromArray = (value) => {
|
|
46
|
+
if (!Array.isArray(value)) {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return [...new Set(value.filter(isCanonicalKey))].sort();
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const collectCanonicalStringListFromObjectKeys = (value) => {
|
|
54
|
+
if (!isObjectRecord(value)) {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return [...new Set(Object.keys(value).filter(isCanonicalKey))].sort();
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const createPropAliasMap = (propByName = new Map()) => {
|
|
62
|
+
const aliasToCanonical = new Map();
|
|
63
|
+
[...propByName.keys()]
|
|
64
|
+
.sort((left, right) => left.localeCompare(right))
|
|
65
|
+
.forEach((canonicalName) => {
|
|
66
|
+
[canonicalName, toCamelCase(canonicalName), toKebabCase(canonicalName)].forEach((alias) => {
|
|
67
|
+
if (!alias || aliasToCanonical.has(alias)) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
aliasToCanonical.set(alias, canonicalName);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
return aliasToCanonical;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export const normalizeSchemaYaml = (schemaYaml) => {
|
|
77
|
+
const empty = {
|
|
78
|
+
componentName: "",
|
|
79
|
+
props: {
|
|
80
|
+
names: [],
|
|
81
|
+
requiredNames: [],
|
|
82
|
+
byName: new Map(),
|
|
83
|
+
aliasToCanonical: new Map(),
|
|
84
|
+
},
|
|
85
|
+
events: {
|
|
86
|
+
names: [],
|
|
87
|
+
byName: new Map(),
|
|
88
|
+
},
|
|
89
|
+
methods: {
|
|
90
|
+
names: [],
|
|
91
|
+
byName: new Map(),
|
|
92
|
+
},
|
|
93
|
+
canonicalSchema: {
|
|
94
|
+
componentName: "",
|
|
95
|
+
propsSchema: {
|
|
96
|
+
type: "object",
|
|
97
|
+
properties: {},
|
|
98
|
+
required: [],
|
|
99
|
+
},
|
|
100
|
+
events: [],
|
|
101
|
+
methods: {
|
|
102
|
+
type: "object",
|
|
103
|
+
properties: {},
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
if (!isObjectRecord(schemaYaml)) {
|
|
109
|
+
return empty;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const componentName = typeof schemaYaml.componentName === "string"
|
|
113
|
+
? schemaYaml.componentName.trim()
|
|
114
|
+
: "";
|
|
115
|
+
const propByName = collectCanonicalNameMap(schemaYaml?.propsSchema?.properties);
|
|
116
|
+
const propAliasToCanonical = createPropAliasMap(propByName);
|
|
117
|
+
const requiredNames = collectCanonicalStringListFromArray(schemaYaml?.propsSchema?.required);
|
|
118
|
+
const methodByName = collectCanonicalNameMap(schemaYaml?.methods?.properties);
|
|
119
|
+
const eventByName = (() => {
|
|
120
|
+
if (Array.isArray(schemaYaml?.events)) {
|
|
121
|
+
const byName = new Map();
|
|
122
|
+
collectCanonicalStringListFromArray(schemaYaml.events).forEach((eventName) => {
|
|
123
|
+
byName.set(eventName, {});
|
|
124
|
+
});
|
|
125
|
+
return byName;
|
|
126
|
+
}
|
|
127
|
+
return collectCanonicalNameMap(schemaYaml?.events);
|
|
128
|
+
})();
|
|
129
|
+
const eventNames = [...eventByName.keys()].sort((left, right) => left.localeCompare(right));
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
componentName,
|
|
133
|
+
props: {
|
|
134
|
+
names: [...propByName.keys()].sort((left, right) => left.localeCompare(right)),
|
|
135
|
+
requiredNames,
|
|
136
|
+
byName: propByName,
|
|
137
|
+
aliasToCanonical: propAliasToCanonical,
|
|
138
|
+
},
|
|
139
|
+
events: {
|
|
140
|
+
names: eventNames,
|
|
141
|
+
byName: eventByName,
|
|
142
|
+
},
|
|
143
|
+
methods: {
|
|
144
|
+
names: [...methodByName.keys()].sort((left, right) => left.localeCompare(right)),
|
|
145
|
+
byName: methodByName,
|
|
146
|
+
},
|
|
147
|
+
canonicalSchema: {
|
|
148
|
+
componentName,
|
|
149
|
+
propsSchema: {
|
|
150
|
+
type: "object",
|
|
151
|
+
properties: toSortedObjectFromMap(propByName),
|
|
152
|
+
required: requiredNames,
|
|
153
|
+
},
|
|
154
|
+
events: eventNames,
|
|
155
|
+
methods: {
|
|
156
|
+
type: "object",
|
|
157
|
+
properties: toSortedObjectFromMap(methodByName),
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
};
|