@valbuild/cli 0.70.0 → 0.72.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.
@@ -51,6 +51,38 @@ async function validate({
|
|
51
51
|
ignore: false
|
52
52
|
});
|
53
53
|
const service = await server.createService(projectRoot, {});
|
54
|
+
const checkKeyIsValid = async (key, sourcePath) => {
|
55
|
+
const [moduleFilePath, modulePath] = core.Internal.splitModuleFilePathAndModulePath(sourcePath);
|
56
|
+
const keyOfModule = await service.get(moduleFilePath, modulePath, {
|
57
|
+
source: true,
|
58
|
+
schema: false,
|
59
|
+
validate: false
|
60
|
+
});
|
61
|
+
const keyOfModuleSource = keyOfModule.source;
|
62
|
+
const keyOfModuleSchema = keyOfModule.schema;
|
63
|
+
if (keyOfModuleSchema && keyOfModuleSchema.type !== "record") {
|
64
|
+
return {
|
65
|
+
error: true,
|
66
|
+
message: `Expected key at ${sourcePath} to be of type 'record'`
|
67
|
+
};
|
68
|
+
}
|
69
|
+
if (keyOfModuleSource && typeof keyOfModuleSource === "object" && key in keyOfModuleSource) {
|
70
|
+
return {
|
71
|
+
error: false
|
72
|
+
};
|
73
|
+
}
|
74
|
+
if (!keyOfModuleSource || typeof keyOfModuleSource !== "object") {
|
75
|
+
return {
|
76
|
+
error: true,
|
77
|
+
message: `Expected ${sourcePath} to be a truthy object`
|
78
|
+
};
|
79
|
+
}
|
80
|
+
const alternatives = findSimilar(key, Object.keys(keyOfModuleSource));
|
81
|
+
return {
|
82
|
+
error: true,
|
83
|
+
message: `Key '${key}' does not exist in ${sourcePath}. Closest match: '${alternatives[0].target}'. Other similar: ${alternatives.slice(1, 4).map(a => `'${a.target}'`).join(", ")}${alternatives.length > 4 ? ", ..." : ""}`
|
84
|
+
};
|
85
|
+
};
|
54
86
|
let prettier;
|
55
87
|
try {
|
56
88
|
prettier = (await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('prettier')); })).default;
|
@@ -130,6 +162,36 @@ async function validate({
|
|
130
162
|
continue;
|
131
163
|
}
|
132
164
|
}
|
165
|
+
} else if (v.fixes.includes("keyof:check-keys")) {
|
166
|
+
const prevErrors = errors;
|
167
|
+
if (v.value && typeof v.value === "object" && "key" in v.value && "sourcePath" in v.value) {
|
168
|
+
const {
|
169
|
+
key,
|
170
|
+
sourcePath
|
171
|
+
} = v.value;
|
172
|
+
if (typeof key !== "string") {
|
173
|
+
console.log(picocolors__default["default"].red("✘"), "Unexpected error in", `${sourcePath}:`, v.message, " (Expected value property 'key' to be a string - this is likely a bug in Val)");
|
174
|
+
errors += 1;
|
175
|
+
} else if (typeof sourcePath !== "string") {
|
176
|
+
console.log(picocolors__default["default"].red("✘"), "Unexpected error in", `${sourcePath}:`, v.message, " (Expected value property 'sourcePath' to be a string - this is likely a bug in Val)");
|
177
|
+
errors += 1;
|
178
|
+
} else {
|
179
|
+
const res = await checkKeyIsValid(key, sourcePath);
|
180
|
+
if (res.error) {
|
181
|
+
console.log(picocolors__default["default"].red("✘"), res.message);
|
182
|
+
errors += 1;
|
183
|
+
}
|
184
|
+
}
|
185
|
+
} else {
|
186
|
+
console.log(picocolors__default["default"].red("✘"), "Unexpected error in", `${sourcePath}:`, v.message, " (Expected value to be an object with 'key' and 'sourcePath' properties - this is likely a bug in Val)");
|
187
|
+
errors += 1;
|
188
|
+
}
|
189
|
+
if (prevErrors < errors) {
|
190
|
+
console.log(picocolors__default["default"].red("✘"), "Found error in", `${sourcePath}`);
|
191
|
+
}
|
192
|
+
} else {
|
193
|
+
console.log(picocolors__default["default"].red("✘"), "Found error in", `${sourcePath}:`, v.message);
|
194
|
+
errors += 1;
|
133
195
|
}
|
134
196
|
const fixPatch = await server.createFixPatch({
|
135
197
|
projectRoot
|
@@ -160,7 +222,7 @@ async function validate({
|
|
160
222
|
return errors;
|
161
223
|
}
|
162
224
|
}
|
163
|
-
for (const file of valFiles) {
|
225
|
+
for (const file of valFiles.sort()) {
|
164
226
|
didFix = false;
|
165
227
|
errors += await validateFile(file);
|
166
228
|
if (prettier && didFix) {
|
@@ -205,6 +267,31 @@ function logEslintMessage(fileContent, filePath, eslintMessage) {
|
|
205
267
|
}
|
206
268
|
}
|
207
269
|
|
270
|
+
// GPT generated levenshtein distance algorithm:
|
271
|
+
const levenshtein = (a, b) => {
|
272
|
+
const [m, n] = [a.length, b.length];
|
273
|
+
if (!m || !n) return Math.max(m, n);
|
274
|
+
const dp = Array.from({
|
275
|
+
length: m + 1
|
276
|
+
}, (_, i) => i);
|
277
|
+
for (let j = 1; j <= n; j++) {
|
278
|
+
let prev = dp[0];
|
279
|
+
dp[0] = j;
|
280
|
+
for (let i = 1; i <= m; i++) {
|
281
|
+
const temp = dp[i];
|
282
|
+
dp[i] = a[i - 1] === b[j - 1] ? prev : Math.min(prev + 1, dp[i - 1] + 1, dp[i] + 1);
|
283
|
+
prev = temp;
|
284
|
+
}
|
285
|
+
}
|
286
|
+
return dp[m];
|
287
|
+
};
|
288
|
+
function findSimilar(key, targets) {
|
289
|
+
return targets.map(target => ({
|
290
|
+
target,
|
291
|
+
distance: levenshtein(key, target)
|
292
|
+
})).sort((a, b) => a.distance - b.distance);
|
293
|
+
}
|
294
|
+
|
208
295
|
async function files({
|
209
296
|
root,
|
210
297
|
managedDir
|
@@ -51,6 +51,38 @@ async function validate({
|
|
51
51
|
ignore: false
|
52
52
|
});
|
53
53
|
const service = await server.createService(projectRoot, {});
|
54
|
+
const checkKeyIsValid = async (key, sourcePath) => {
|
55
|
+
const [moduleFilePath, modulePath] = core.Internal.splitModuleFilePathAndModulePath(sourcePath);
|
56
|
+
const keyOfModule = await service.get(moduleFilePath, modulePath, {
|
57
|
+
source: true,
|
58
|
+
schema: false,
|
59
|
+
validate: false
|
60
|
+
});
|
61
|
+
const keyOfModuleSource = keyOfModule.source;
|
62
|
+
const keyOfModuleSchema = keyOfModule.schema;
|
63
|
+
if (keyOfModuleSchema && keyOfModuleSchema.type !== "record") {
|
64
|
+
return {
|
65
|
+
error: true,
|
66
|
+
message: `Expected key at ${sourcePath} to be of type 'record'`
|
67
|
+
};
|
68
|
+
}
|
69
|
+
if (keyOfModuleSource && typeof keyOfModuleSource === "object" && key in keyOfModuleSource) {
|
70
|
+
return {
|
71
|
+
error: false
|
72
|
+
};
|
73
|
+
}
|
74
|
+
if (!keyOfModuleSource || typeof keyOfModuleSource !== "object") {
|
75
|
+
return {
|
76
|
+
error: true,
|
77
|
+
message: `Expected ${sourcePath} to be a truthy object`
|
78
|
+
};
|
79
|
+
}
|
80
|
+
const alternatives = findSimilar(key, Object.keys(keyOfModuleSource));
|
81
|
+
return {
|
82
|
+
error: true,
|
83
|
+
message: `Key '${key}' does not exist in ${sourcePath}. Closest match: '${alternatives[0].target}'. Other similar: ${alternatives.slice(1, 4).map(a => `'${a.target}'`).join(", ")}${alternatives.length > 4 ? ", ..." : ""}`
|
84
|
+
};
|
85
|
+
};
|
54
86
|
let prettier;
|
55
87
|
try {
|
56
88
|
prettier = (await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('prettier')); })).default;
|
@@ -130,6 +162,36 @@ async function validate({
|
|
130
162
|
continue;
|
131
163
|
}
|
132
164
|
}
|
165
|
+
} else if (v.fixes.includes("keyof:check-keys")) {
|
166
|
+
const prevErrors = errors;
|
167
|
+
if (v.value && typeof v.value === "object" && "key" in v.value && "sourcePath" in v.value) {
|
168
|
+
const {
|
169
|
+
key,
|
170
|
+
sourcePath
|
171
|
+
} = v.value;
|
172
|
+
if (typeof key !== "string") {
|
173
|
+
console.log(picocolors__default["default"].red("✘"), "Unexpected error in", `${sourcePath}:`, v.message, " (Expected value property 'key' to be a string - this is likely a bug in Val)");
|
174
|
+
errors += 1;
|
175
|
+
} else if (typeof sourcePath !== "string") {
|
176
|
+
console.log(picocolors__default["default"].red("✘"), "Unexpected error in", `${sourcePath}:`, v.message, " (Expected value property 'sourcePath' to be a string - this is likely a bug in Val)");
|
177
|
+
errors += 1;
|
178
|
+
} else {
|
179
|
+
const res = await checkKeyIsValid(key, sourcePath);
|
180
|
+
if (res.error) {
|
181
|
+
console.log(picocolors__default["default"].red("✘"), res.message);
|
182
|
+
errors += 1;
|
183
|
+
}
|
184
|
+
}
|
185
|
+
} else {
|
186
|
+
console.log(picocolors__default["default"].red("✘"), "Unexpected error in", `${sourcePath}:`, v.message, " (Expected value to be an object with 'key' and 'sourcePath' properties - this is likely a bug in Val)");
|
187
|
+
errors += 1;
|
188
|
+
}
|
189
|
+
if (prevErrors < errors) {
|
190
|
+
console.log(picocolors__default["default"].red("✘"), "Found error in", `${sourcePath}`);
|
191
|
+
}
|
192
|
+
} else {
|
193
|
+
console.log(picocolors__default["default"].red("✘"), "Found error in", `${sourcePath}:`, v.message);
|
194
|
+
errors += 1;
|
133
195
|
}
|
134
196
|
const fixPatch = await server.createFixPatch({
|
135
197
|
projectRoot
|
@@ -160,7 +222,7 @@ async function validate({
|
|
160
222
|
return errors;
|
161
223
|
}
|
162
224
|
}
|
163
|
-
for (const file of valFiles) {
|
225
|
+
for (const file of valFiles.sort()) {
|
164
226
|
didFix = false;
|
165
227
|
errors += await validateFile(file);
|
166
228
|
if (prettier && didFix) {
|
@@ -205,6 +267,31 @@ function logEslintMessage(fileContent, filePath, eslintMessage) {
|
|
205
267
|
}
|
206
268
|
}
|
207
269
|
|
270
|
+
// GPT generated levenshtein distance algorithm:
|
271
|
+
const levenshtein = (a, b) => {
|
272
|
+
const [m, n] = [a.length, b.length];
|
273
|
+
if (!m || !n) return Math.max(m, n);
|
274
|
+
const dp = Array.from({
|
275
|
+
length: m + 1
|
276
|
+
}, (_, i) => i);
|
277
|
+
for (let j = 1; j <= n; j++) {
|
278
|
+
let prev = dp[0];
|
279
|
+
dp[0] = j;
|
280
|
+
for (let i = 1; i <= m; i++) {
|
281
|
+
const temp = dp[i];
|
282
|
+
dp[i] = a[i - 1] === b[j - 1] ? prev : Math.min(prev + 1, dp[i - 1] + 1, dp[i] + 1);
|
283
|
+
prev = temp;
|
284
|
+
}
|
285
|
+
}
|
286
|
+
return dp[m];
|
287
|
+
};
|
288
|
+
function findSimilar(key, targets) {
|
289
|
+
return targets.map(target => ({
|
290
|
+
target,
|
291
|
+
distance: levenshtein(key, target)
|
292
|
+
})).sort((a, b) => a.distance - b.distance);
|
293
|
+
}
|
294
|
+
|
208
295
|
async function files({
|
209
296
|
root,
|
210
297
|
managedDir
|
@@ -23,6 +23,38 @@ async function validate({
|
|
23
23
|
ignore: false
|
24
24
|
});
|
25
25
|
const service = await createService(projectRoot, {});
|
26
|
+
const checkKeyIsValid = async (key, sourcePath) => {
|
27
|
+
const [moduleFilePath, modulePath] = Internal.splitModuleFilePathAndModulePath(sourcePath);
|
28
|
+
const keyOfModule = await service.get(moduleFilePath, modulePath, {
|
29
|
+
source: true,
|
30
|
+
schema: false,
|
31
|
+
validate: false
|
32
|
+
});
|
33
|
+
const keyOfModuleSource = keyOfModule.source;
|
34
|
+
const keyOfModuleSchema = keyOfModule.schema;
|
35
|
+
if (keyOfModuleSchema && keyOfModuleSchema.type !== "record") {
|
36
|
+
return {
|
37
|
+
error: true,
|
38
|
+
message: `Expected key at ${sourcePath} to be of type 'record'`
|
39
|
+
};
|
40
|
+
}
|
41
|
+
if (keyOfModuleSource && typeof keyOfModuleSource === "object" && key in keyOfModuleSource) {
|
42
|
+
return {
|
43
|
+
error: false
|
44
|
+
};
|
45
|
+
}
|
46
|
+
if (!keyOfModuleSource || typeof keyOfModuleSource !== "object") {
|
47
|
+
return {
|
48
|
+
error: true,
|
49
|
+
message: `Expected ${sourcePath} to be a truthy object`
|
50
|
+
};
|
51
|
+
}
|
52
|
+
const alternatives = findSimilar(key, Object.keys(keyOfModuleSource));
|
53
|
+
return {
|
54
|
+
error: true,
|
55
|
+
message: `Key '${key}' does not exist in ${sourcePath}. Closest match: '${alternatives[0].target}'. Other similar: ${alternatives.slice(1, 4).map(a => `'${a.target}'`).join(", ")}${alternatives.length > 4 ? ", ..." : ""}`
|
56
|
+
};
|
57
|
+
};
|
26
58
|
let prettier;
|
27
59
|
try {
|
28
60
|
prettier = (await import('prettier')).default;
|
@@ -102,6 +134,36 @@ async function validate({
|
|
102
134
|
continue;
|
103
135
|
}
|
104
136
|
}
|
137
|
+
} else if (v.fixes.includes("keyof:check-keys")) {
|
138
|
+
const prevErrors = errors;
|
139
|
+
if (v.value && typeof v.value === "object" && "key" in v.value && "sourcePath" in v.value) {
|
140
|
+
const {
|
141
|
+
key,
|
142
|
+
sourcePath
|
143
|
+
} = v.value;
|
144
|
+
if (typeof key !== "string") {
|
145
|
+
console.log(picocolors.red("✘"), "Unexpected error in", `${sourcePath}:`, v.message, " (Expected value property 'key' to be a string - this is likely a bug in Val)");
|
146
|
+
errors += 1;
|
147
|
+
} else if (typeof sourcePath !== "string") {
|
148
|
+
console.log(picocolors.red("✘"), "Unexpected error in", `${sourcePath}:`, v.message, " (Expected value property 'sourcePath' to be a string - this is likely a bug in Val)");
|
149
|
+
errors += 1;
|
150
|
+
} else {
|
151
|
+
const res = await checkKeyIsValid(key, sourcePath);
|
152
|
+
if (res.error) {
|
153
|
+
console.log(picocolors.red("✘"), res.message);
|
154
|
+
errors += 1;
|
155
|
+
}
|
156
|
+
}
|
157
|
+
} else {
|
158
|
+
console.log(picocolors.red("✘"), "Unexpected error in", `${sourcePath}:`, v.message, " (Expected value to be an object with 'key' and 'sourcePath' properties - this is likely a bug in Val)");
|
159
|
+
errors += 1;
|
160
|
+
}
|
161
|
+
if (prevErrors < errors) {
|
162
|
+
console.log(picocolors.red("✘"), "Found error in", `${sourcePath}`);
|
163
|
+
}
|
164
|
+
} else {
|
165
|
+
console.log(picocolors.red("✘"), "Found error in", `${sourcePath}:`, v.message);
|
166
|
+
errors += 1;
|
105
167
|
}
|
106
168
|
const fixPatch = await createFixPatch({
|
107
169
|
projectRoot
|
@@ -132,7 +194,7 @@ async function validate({
|
|
132
194
|
return errors;
|
133
195
|
}
|
134
196
|
}
|
135
|
-
for (const file of valFiles) {
|
197
|
+
for (const file of valFiles.sort()) {
|
136
198
|
didFix = false;
|
137
199
|
errors += await validateFile(file);
|
138
200
|
if (prettier && didFix) {
|
@@ -177,6 +239,31 @@ function logEslintMessage(fileContent, filePath, eslintMessage) {
|
|
177
239
|
}
|
178
240
|
}
|
179
241
|
|
242
|
+
// GPT generated levenshtein distance algorithm:
|
243
|
+
const levenshtein = (a, b) => {
|
244
|
+
const [m, n] = [a.length, b.length];
|
245
|
+
if (!m || !n) return Math.max(m, n);
|
246
|
+
const dp = Array.from({
|
247
|
+
length: m + 1
|
248
|
+
}, (_, i) => i);
|
249
|
+
for (let j = 1; j <= n; j++) {
|
250
|
+
let prev = dp[0];
|
251
|
+
dp[0] = j;
|
252
|
+
for (let i = 1; i <= m; i++) {
|
253
|
+
const temp = dp[i];
|
254
|
+
dp[i] = a[i - 1] === b[j - 1] ? prev : Math.min(prev + 1, dp[i - 1] + 1, dp[i] + 1);
|
255
|
+
prev = temp;
|
256
|
+
}
|
257
|
+
}
|
258
|
+
return dp[m];
|
259
|
+
};
|
260
|
+
function findSimilar(key, targets) {
|
261
|
+
return targets.map(target => ({
|
262
|
+
target,
|
263
|
+
distance: levenshtein(key, target)
|
264
|
+
})).sort((a, b) => a.distance - b.distance);
|
265
|
+
}
|
266
|
+
|
180
267
|
async function files({
|
181
268
|
root,
|
182
269
|
managedDir
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@valbuild/cli",
|
3
3
|
"private": false,
|
4
|
-
"version": "0.
|
4
|
+
"version": "0.72.1",
|
5
5
|
"description": "Val CLI tools",
|
6
6
|
"bin": {
|
7
7
|
"val": "./bin.js"
|
@@ -18,9 +18,9 @@
|
|
18
18
|
"typecheck": "tsc --noEmit"
|
19
19
|
},
|
20
20
|
"dependencies": {
|
21
|
-
"@valbuild/core": "~0.
|
22
|
-
"@valbuild/server": "~0.
|
23
|
-
"@valbuild/eslint-plugin": "~0.
|
21
|
+
"@valbuild/core": "~0.72.1",
|
22
|
+
"@valbuild/server": "~0.72.1",
|
23
|
+
"@valbuild/eslint-plugin": "~0.72.1",
|
24
24
|
"eslint": "^8.31.0",
|
25
25
|
"@inquirer/confirm": "^2.0.15",
|
26
26
|
"@inquirer/prompts": "^3.0.2",
|
package/src/validate.ts
CHANGED
@@ -28,6 +28,48 @@ export async function validate({
|
|
28
28
|
ignore: false,
|
29
29
|
});
|
30
30
|
const service = await createService(projectRoot, {});
|
31
|
+
const checkKeyIsValid = async (
|
32
|
+
key: string,
|
33
|
+
sourcePath: string,
|
34
|
+
): Promise<{ error: false } | { error: true; message: string }> => {
|
35
|
+
const [moduleFilePath, modulePath] =
|
36
|
+
Internal.splitModuleFilePathAndModulePath(sourcePath as SourcePath);
|
37
|
+
const keyOfModule = await service.get(moduleFilePath, modulePath, {
|
38
|
+
source: true,
|
39
|
+
schema: false,
|
40
|
+
validate: false,
|
41
|
+
});
|
42
|
+
|
43
|
+
const keyOfModuleSource = keyOfModule.source;
|
44
|
+
const keyOfModuleSchema = keyOfModule.schema;
|
45
|
+
if (keyOfModuleSchema && keyOfModuleSchema.type !== "record") {
|
46
|
+
return {
|
47
|
+
error: true,
|
48
|
+
message: `Expected key at ${sourcePath} to be of type 'record'`,
|
49
|
+
};
|
50
|
+
}
|
51
|
+
if (
|
52
|
+
keyOfModuleSource &&
|
53
|
+
typeof keyOfModuleSource === "object" &&
|
54
|
+
key in keyOfModuleSource
|
55
|
+
) {
|
56
|
+
return { error: false };
|
57
|
+
}
|
58
|
+
if (!keyOfModuleSource || typeof keyOfModuleSource !== "object") {
|
59
|
+
return {
|
60
|
+
error: true,
|
61
|
+
message: `Expected ${sourcePath} to be a truthy object`,
|
62
|
+
};
|
63
|
+
}
|
64
|
+
const alternatives = findSimilar(key, Object.keys(keyOfModuleSource));
|
65
|
+
return {
|
66
|
+
error: true,
|
67
|
+
message: `Key '${key}' does not exist in ${sourcePath}. Closest match: '${alternatives[0].target}'. Other similar: ${alternatives
|
68
|
+
.slice(1, 4)
|
69
|
+
.map((a) => `'${a.target}'`)
|
70
|
+
.join(", ")}${alternatives.length > 4 ? ", ..." : ""}`,
|
71
|
+
};
|
72
|
+
};
|
31
73
|
let prettier;
|
32
74
|
try {
|
33
75
|
prettier = (await import("prettier")).default;
|
@@ -152,6 +194,65 @@ export async function validate({
|
|
152
194
|
continue;
|
153
195
|
}
|
154
196
|
}
|
197
|
+
} else if (v.fixes.includes("keyof:check-keys")) {
|
198
|
+
const prevErrors = errors;
|
199
|
+
if (
|
200
|
+
v.value &&
|
201
|
+
typeof v.value === "object" &&
|
202
|
+
"key" in v.value &&
|
203
|
+
"sourcePath" in v.value
|
204
|
+
) {
|
205
|
+
const { key, sourcePath } = v.value;
|
206
|
+
if (typeof key !== "string") {
|
207
|
+
console.log(
|
208
|
+
picocolors.red("✘"),
|
209
|
+
"Unexpected error in",
|
210
|
+
`${sourcePath}:`,
|
211
|
+
v.message,
|
212
|
+
" (Expected value property 'key' to be a string - this is likely a bug in Val)",
|
213
|
+
);
|
214
|
+
errors += 1;
|
215
|
+
} else if (typeof sourcePath !== "string") {
|
216
|
+
console.log(
|
217
|
+
picocolors.red("✘"),
|
218
|
+
"Unexpected error in",
|
219
|
+
`${sourcePath}:`,
|
220
|
+
v.message,
|
221
|
+
" (Expected value property 'sourcePath' to be a string - this is likely a bug in Val)",
|
222
|
+
);
|
223
|
+
errors += 1;
|
224
|
+
} else {
|
225
|
+
const res = await checkKeyIsValid(key, sourcePath);
|
226
|
+
if (res.error) {
|
227
|
+
console.log(picocolors.red("✘"), res.message);
|
228
|
+
errors += 1;
|
229
|
+
}
|
230
|
+
}
|
231
|
+
} else {
|
232
|
+
console.log(
|
233
|
+
picocolors.red("✘"),
|
234
|
+
"Unexpected error in",
|
235
|
+
`${sourcePath}:`,
|
236
|
+
v.message,
|
237
|
+
" (Expected value to be an object with 'key' and 'sourcePath' properties - this is likely a bug in Val)",
|
238
|
+
);
|
239
|
+
errors += 1;
|
240
|
+
}
|
241
|
+
if (prevErrors < errors) {
|
242
|
+
console.log(
|
243
|
+
picocolors.red("✘"),
|
244
|
+
"Found error in",
|
245
|
+
`${sourcePath}`,
|
246
|
+
);
|
247
|
+
}
|
248
|
+
} else {
|
249
|
+
console.log(
|
250
|
+
picocolors.red("✘"),
|
251
|
+
"Found error in",
|
252
|
+
`${sourcePath}:`,
|
253
|
+
v.message,
|
254
|
+
);
|
255
|
+
errors += 1;
|
155
256
|
}
|
156
257
|
const fixPatch = await createFixPatch(
|
157
258
|
{ projectRoot },
|
@@ -209,7 +310,7 @@ export async function validate({
|
|
209
310
|
}
|
210
311
|
}
|
211
312
|
|
212
|
-
for (const file of valFiles) {
|
313
|
+
for (const file of valFiles.sort()) {
|
213
314
|
didFix = false;
|
214
315
|
errors += await validateFile(file);
|
215
316
|
if (prettier && didFix) {
|
@@ -289,3 +390,33 @@ function logEslintMessage(
|
|
289
390
|
);
|
290
391
|
}
|
291
392
|
}
|
393
|
+
|
394
|
+
// GPT generated levenshtein distance algorithm:
|
395
|
+
const levenshtein = (a: string, b: string): number => {
|
396
|
+
const [m, n] = [a.length, b.length];
|
397
|
+
if (!m || !n) return Math.max(m, n);
|
398
|
+
|
399
|
+
const dp = Array.from({ length: m + 1 }, (_, i) => i);
|
400
|
+
|
401
|
+
for (let j = 1; j <= n; j++) {
|
402
|
+
let prev = dp[0];
|
403
|
+
dp[0] = j;
|
404
|
+
|
405
|
+
for (let i = 1; i <= m; i++) {
|
406
|
+
const temp = dp[i];
|
407
|
+
dp[i] =
|
408
|
+
a[i - 1] === b[j - 1]
|
409
|
+
? prev
|
410
|
+
: Math.min(prev + 1, dp[i - 1] + 1, dp[i] + 1);
|
411
|
+
prev = temp;
|
412
|
+
}
|
413
|
+
}
|
414
|
+
|
415
|
+
return dp[m];
|
416
|
+
};
|
417
|
+
|
418
|
+
function findSimilar(key: string, targets: string[]) {
|
419
|
+
return targets
|
420
|
+
.map((target) => ({ target, distance: levenshtein(key, target) }))
|
421
|
+
.sort((a, b) => a.distance - b.distance);
|
422
|
+
}
|