@nordcraft/search 1.0.81 → 1.0.82
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/dist/findProblems.js +52 -0
- package/dist/findProblems.js.map +1 -0
- package/dist/fixProblems.js +29 -0
- package/dist/fixProblems.js.map +1 -0
- package/dist/problems.worker.js +4 -80
- package/dist/problems.worker.js.map +1 -1
- package/dist/rules/issues/apis/unknownApiRule.js +2 -1
- package/dist/rules/issues/apis/unknownApiRule.js.map +1 -1
- package/dist/rules/issues/apis/unknownApiRule.test.js +7 -1
- package/dist/rules/issues/apis/unknownApiRule.test.js.map +1 -1
- package/package.json +3 -3
- package/src/findProblems.ts +64 -0
- package/src/fixProblems.ts +34 -0
- package/src/problems.worker.ts +8 -157
- package/src/rules/issues/apis/unknownApiRule.test.ts +7 -1
- package/src/rules/issues/apis/unknownApiRule.ts +3 -1
- package/src/types.d.ts +63 -5
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ISSUE_RULES } from './rules/issues/issueRules.index';
|
|
2
|
+
import { searchProject } from './searchProject';
|
|
3
|
+
export const findProblems = (data, reportResults) => {
|
|
4
|
+
const { files, options = {} } = data;
|
|
5
|
+
const idRespond = (results) => reportResults({
|
|
6
|
+
id: data.id,
|
|
7
|
+
results,
|
|
8
|
+
});
|
|
9
|
+
const rules = ISSUE_RULES.filter((rule) => (!options.categories || options.categories.includes(rule.category)) &&
|
|
10
|
+
(!options.levels || options.levels.includes(rule.level)) &&
|
|
11
|
+
!options.rulesToExclude?.includes(rule.code));
|
|
12
|
+
let batch = [];
|
|
13
|
+
let fileType;
|
|
14
|
+
let fileName;
|
|
15
|
+
for (const problem of searchProject({
|
|
16
|
+
files,
|
|
17
|
+
rules,
|
|
18
|
+
pathsToVisit: options.pathsToVisit,
|
|
19
|
+
useExactPaths: options.useExactPaths,
|
|
20
|
+
state: options.state,
|
|
21
|
+
})) {
|
|
22
|
+
switch (options.batchSize) {
|
|
23
|
+
case 'all': {
|
|
24
|
+
batch.push(problem);
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
case 'per-file': {
|
|
28
|
+
if (fileType !== problem.path[0] || fileName !== problem.path[1]) {
|
|
29
|
+
if (batch.length > 0) {
|
|
30
|
+
idRespond(batch);
|
|
31
|
+
}
|
|
32
|
+
batch = [];
|
|
33
|
+
fileType = problem.path[0];
|
|
34
|
+
fileName = problem.path[1];
|
|
35
|
+
}
|
|
36
|
+
batch.push(problem);
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
default: {
|
|
40
|
+
batch.push(problem);
|
|
41
|
+
if (batch.length >= (options.batchSize ?? 1)) {
|
|
42
|
+
idRespond(batch);
|
|
43
|
+
batch = [];
|
|
44
|
+
}
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Send the remaining results
|
|
50
|
+
idRespond(batch);
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=findProblems.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findProblems.js","sourceRoot":"","sources":["../src/findProblems.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAA;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAG/C,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,IAAsB,EACtB,aAAsD,EACtD,EAAE,CAAC;IACH,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,EAAE,EAAE,GAAG,IAAI,CAAA;IACpC,MAAM,SAAS,GAAG,CAAC,OAAiB,EAAE,EAAE,CACtC,aAAa,CAAC;QACZ,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,OAAO;KACR,CAAC,CAAA;IACJ,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAC9B,CAAC,IAAI,EAAE,EAAE,CACP,CAAC,CAAC,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnE,CAAC,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxD,CAAC,OAAO,CAAC,cAAc,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAC/C,CAAA;IAED,IAAI,KAAK,GAAa,EAAE,CAAA;IACxB,IAAI,QAAqC,CAAA;IACzC,IAAI,QAAqC,CAAA;IACzC,KAAK,MAAM,OAAO,IAAI,aAAa,CAAC;QAClC,KAAK;QACL,KAAK;QACL,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC,EAAE,CAAC;QACH,QAAQ,OAAO,CAAC,SAAS,EAAE,CAAC;YAC1B,KAAK,KAAK,EAAE,CAAC;gBACX,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBACnB,MAAK;YACP,CAAC;YACD,KAAK,UAAU,EAAE,CAAC;gBAChB,IAAI,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;oBACjE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACrB,SAAS,CAAC,KAAK,CAAC,CAAA;oBAClB,CAAC;oBACD,KAAK,GAAG,EAAE,CAAA;oBACV,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;oBAC1B,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBAC5B,CAAC;gBAED,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBACnB,MAAK;YACP,CAAC;YAED,SAAS,CAAC;gBACR,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBACnB,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC;oBAC7C,SAAS,CAAC,KAAK,CAAC,CAAA;oBAChB,KAAK,GAAG,EAAE,CAAA;gBACZ,CAAC;gBACD,MAAK;YACP,CAAC;QACH,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,SAAS,CAAC,KAAK,CAAC,CAAA;AAAA,CACjB,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { create } from 'jsondiffpatch';
|
|
2
|
+
import { fixProject } from './fixProject';
|
|
3
|
+
import { ISSUE_RULES } from './rules/issues/issueRules.index';
|
|
4
|
+
export const fixProblems = (data, reportResults) => {
|
|
5
|
+
const { files, options = {}, fixRule } = data;
|
|
6
|
+
const rule = ISSUE_RULES.find((r) => r.code === fixRule);
|
|
7
|
+
if (!rule) {
|
|
8
|
+
throw new Error(`Unknown fix rule: ${data.fixRule}`);
|
|
9
|
+
}
|
|
10
|
+
const updatedFiles = fixProject({
|
|
11
|
+
files,
|
|
12
|
+
rule,
|
|
13
|
+
fixType: data.fixType,
|
|
14
|
+
pathsToVisit: options.pathsToVisit,
|
|
15
|
+
useExactPaths: options.useExactPaths,
|
|
16
|
+
state: options.state,
|
|
17
|
+
});
|
|
18
|
+
// Calculate diff
|
|
19
|
+
const jsonDiffPatch = create({ omitRemovedValues: true });
|
|
20
|
+
const diff = jsonDiffPatch.diff(files, updatedFiles);
|
|
21
|
+
// Send diff + metadata to main thread
|
|
22
|
+
reportResults({
|
|
23
|
+
id: data.id,
|
|
24
|
+
patch: diff,
|
|
25
|
+
fixRule: data.fixRule,
|
|
26
|
+
fixType: data.fixType,
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=fixProblems.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixProblems.js","sourceRoot":"","sources":["../src/fixProblems.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAA;AAG7D,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,IAAqB,EACrB,aAAqD,EACrD,EAAE,CAAC;IACH,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,EAAE,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAC7C,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAA;IACxD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;IACtD,CAAC;IAED,MAAM,YAAY,GAAG,UAAU,CAAC;QAC9B,KAAK;QACL,IAAI;QACJ,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC,CAAA;IACF,iBAAiB;IACjB,MAAM,aAAa,GAAG,MAAM,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAA;IACzD,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,YAAY,CAAC,CAAA;IACpD,sCAAsC;IACtC,aAAa,CAAC;QACZ,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAA;AAAA,CACH,CAAA"}
|
package/dist/problems.worker.js
CHANGED
|
@@ -1,91 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { ISSUE_RULES } from './rules/issues/issueRules.index';
|
|
4
|
-
import { searchProject } from './searchProject';
|
|
1
|
+
import { findProblems } from './findProblems';
|
|
2
|
+
import { fixProblems } from './fixProblems';
|
|
5
3
|
const respond = (data) => postMessage(data);
|
|
6
|
-
const findProblems = (data) => {
|
|
7
|
-
const { files, options = {} } = data;
|
|
8
|
-
const idRespond = (results) => respond({
|
|
9
|
-
id: data.id,
|
|
10
|
-
results,
|
|
11
|
-
});
|
|
12
|
-
const rules = ISSUE_RULES.filter((rule) => (!options.categories || options.categories.includes(rule.category)) &&
|
|
13
|
-
(!options.levels || options.levels.includes(rule.level)) &&
|
|
14
|
-
!options.rulesToExclude?.includes(rule.code));
|
|
15
|
-
let batch = [];
|
|
16
|
-
let fileType;
|
|
17
|
-
let fileName;
|
|
18
|
-
for (const problem of searchProject({
|
|
19
|
-
files,
|
|
20
|
-
rules,
|
|
21
|
-
pathsToVisit: options.pathsToVisit,
|
|
22
|
-
useExactPaths: options.useExactPaths,
|
|
23
|
-
state: options.state,
|
|
24
|
-
})) {
|
|
25
|
-
switch (options.batchSize) {
|
|
26
|
-
case 'all': {
|
|
27
|
-
batch.push(problem);
|
|
28
|
-
break;
|
|
29
|
-
}
|
|
30
|
-
case 'per-file': {
|
|
31
|
-
if (fileType !== problem.path[0] || fileName !== problem.path[1]) {
|
|
32
|
-
if (batch.length > 0) {
|
|
33
|
-
idRespond(batch);
|
|
34
|
-
}
|
|
35
|
-
batch = [];
|
|
36
|
-
fileType = problem.path[0];
|
|
37
|
-
fileName = problem.path[1];
|
|
38
|
-
}
|
|
39
|
-
batch.push(problem);
|
|
40
|
-
break;
|
|
41
|
-
}
|
|
42
|
-
default: {
|
|
43
|
-
batch.push(problem);
|
|
44
|
-
if (batch.length >= (options.batchSize ?? 1)) {
|
|
45
|
-
idRespond(batch);
|
|
46
|
-
batch = [];
|
|
47
|
-
}
|
|
48
|
-
break;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
// Send the remaining results
|
|
53
|
-
idRespond(batch);
|
|
54
|
-
};
|
|
55
|
-
const fixProblems = (data) => {
|
|
56
|
-
const { files, options = {}, fixRule } = data;
|
|
57
|
-
const rule = ISSUE_RULES.find((r) => r.code === fixRule);
|
|
58
|
-
if (!rule) {
|
|
59
|
-
throw new Error(`Unknown fix rule: ${data.fixRule}`);
|
|
60
|
-
}
|
|
61
|
-
const updatedFiles = fixProject({
|
|
62
|
-
files,
|
|
63
|
-
rule,
|
|
64
|
-
fixType: data.fixType,
|
|
65
|
-
pathsToVisit: options.pathsToVisit,
|
|
66
|
-
useExactPaths: options.useExactPaths,
|
|
67
|
-
state: options.state,
|
|
68
|
-
});
|
|
69
|
-
// Calculate diff
|
|
70
|
-
const jsonDiffPatch = create({ omitRemovedValues: true });
|
|
71
|
-
const diff = jsonDiffPatch.diff(files, updatedFiles);
|
|
72
|
-
// Send diff + metadata to main thread
|
|
73
|
-
respond({
|
|
74
|
-
id: data.id,
|
|
75
|
-
patch: diff,
|
|
76
|
-
fixRule: data.fixRule,
|
|
77
|
-
fixType: data.fixType,
|
|
78
|
-
});
|
|
79
|
-
};
|
|
80
4
|
/**
|
|
81
5
|
* This function is a web worker that checks for problems in the files.
|
|
82
6
|
*/
|
|
83
7
|
onmessage = (event) => {
|
|
84
8
|
if ('fixRule' in event.data) {
|
|
85
|
-
fixProblems(event.data);
|
|
9
|
+
fixProblems(event.data, respond);
|
|
86
10
|
}
|
|
87
11
|
else {
|
|
88
|
-
findProblems(event.data);
|
|
12
|
+
findProblems(event.data, respond);
|
|
89
13
|
}
|
|
90
14
|
};
|
|
91
15
|
//# sourceMappingURL=problems.worker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"problems.worker.js","sourceRoot":"","sources":["../src/problems.worker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"problems.worker.js","sourceRoot":"","sources":["../src/problems.worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAY3C,MAAM,OAAO,GAAG,CAAC,IAAc,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;AAErD;;GAEG;AACH,SAAS,GAAG,CAAC,KAA4B,EAAE,EAAE,CAAC;IAC5C,IAAI,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QAC5B,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAClC,CAAC;SAAM,CAAC;QACN,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACnC,CAAC;AAAA,CACF,CAAA"}
|
|
@@ -6,7 +6,8 @@ export const unknownApiRule = {
|
|
|
6
6
|
const isApiFormula = nodeType === 'formula' &&
|
|
7
7
|
value.type === 'path' &&
|
|
8
8
|
value.path[0] === 'Apis';
|
|
9
|
-
const isApiAction = nodeType === 'action-model' &&
|
|
9
|
+
const isApiAction = nodeType === 'action-model' &&
|
|
10
|
+
(value.type === 'Fetch' || value.type === 'AbortFetch');
|
|
10
11
|
if (!isApiFormula && !isApiAction) {
|
|
11
12
|
return;
|
|
12
13
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unknownApiRule.js","sourceRoot":"","sources":["../../../../src/rules/issues/apis/unknownApiRule.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAEtB;IACH,IAAI,EAAE,aAAa;IACnB,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,mBAAmB;IAC7B,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QACnD,MAAM,YAAY,GAChB,QAAQ,KAAK,SAAS;YACtB,KAAK,CAAC,IAAI,KAAK,MAAM;YACrB,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,CAAA;QAC1B,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"unknownApiRule.js","sourceRoot":"","sources":["../../../../src/rules/issues/apis/unknownApiRule.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAEtB;IACH,IAAI,EAAE,aAAa;IACnB,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,mBAAmB;IAC7B,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QACnD,MAAM,YAAY,GAChB,QAAQ,KAAK,SAAS;YACtB,KAAK,CAAC,IAAI,KAAK,MAAM;YACrB,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,CAAA;QAC1B,MAAM,WAAW,GACf,QAAQ,KAAK,cAAc;YAC3B,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,CAAA;QACzD,IAAI,CAAC,YAAY,IAAI,CAAC,WAAW,EAAE,CAAC;YAClC,OAAM;QACR,CAAC;QACD,MAAM,CAAC,EAAE,aAAa,CAAC,GAAG,IAAI,CAAA;QAC9B,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,CAAA;QACjD,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,CAAC,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAA;YAC7B,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC/B,MAAM,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;YAChC,CAAC;QACH,CAAC;aAAM,IAAI,WAAW,EAAE,CAAC;YACvB,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClC,MAAM,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAA;YACnC,CAAC;QACH,CAAC;IAAA,CACF;CACF,CAAA"}
|
|
@@ -66,6 +66,10 @@ describe('unknownApi', () => {
|
|
|
66
66
|
onSuccess: { actions: [] },
|
|
67
67
|
onError: { actions: [] },
|
|
68
68
|
},
|
|
69
|
+
{
|
|
70
|
+
type: 'AbortFetch',
|
|
71
|
+
api: 'unknown-abort-api',
|
|
72
|
+
},
|
|
69
73
|
],
|
|
70
74
|
},
|
|
71
75
|
},
|
|
@@ -91,9 +95,11 @@ describe('unknownApi', () => {
|
|
|
91
95
|
},
|
|
92
96
|
rules: [unknownApiRule],
|
|
93
97
|
}));
|
|
94
|
-
expect(problems).toHaveLength(
|
|
98
|
+
expect(problems).toHaveLength(2);
|
|
95
99
|
expect(problems[0].code).toBe('unknown api');
|
|
96
100
|
expect(problems[0].details).toEqual({ name: 'unknown-api' });
|
|
101
|
+
expect(problems[1].code).toBe('unknown api');
|
|
102
|
+
expect(problems[1].details).toEqual({ name: 'unknown-abort-api' });
|
|
97
103
|
});
|
|
98
104
|
test('should not report APIs that exist', () => {
|
|
99
105
|
const problems = Array.from(searchProject({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unknownApiRule.test.js","sourceRoot":"","sources":["../../../../src/rules/issues/apis/unknownApiRule.test.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"unknownApiRule.test.js","sourceRoot":"","sources":["../../../../src/rules/issues/apis/unknownApiRule.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"directory": "packages/search"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@nordcraft/ssr": "1.0.
|
|
14
|
-
"@nordcraft/core": "1.0.
|
|
13
|
+
"@nordcraft/ssr": "1.0.82",
|
|
14
|
+
"@nordcraft/core": "1.0.82",
|
|
15
15
|
"jsondiffpatch": "0.7.3",
|
|
16
16
|
"postcss": "8.5.6",
|
|
17
17
|
"zod": "4.2.1"
|
|
@@ -26,5 +26,5 @@
|
|
|
26
26
|
"test:watch:only": "bun test --watch --only"
|
|
27
27
|
},
|
|
28
28
|
"files": ["dist", "src"],
|
|
29
|
-
"version": "1.0.
|
|
29
|
+
"version": "1.0.82"
|
|
30
30
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { ISSUE_RULES } from './rules/issues/issueRules.index'
|
|
2
|
+
import { searchProject } from './searchProject'
|
|
3
|
+
import type { FindProblemsArgs, FindProblemsResponse, Result } from './types'
|
|
4
|
+
|
|
5
|
+
export const findProblems = (
|
|
6
|
+
data: FindProblemsArgs,
|
|
7
|
+
reportResults: (results: FindProblemsResponse) => void,
|
|
8
|
+
) => {
|
|
9
|
+
const { files, options = {} } = data
|
|
10
|
+
const idRespond = (results: Result[]) =>
|
|
11
|
+
reportResults({
|
|
12
|
+
id: data.id,
|
|
13
|
+
results,
|
|
14
|
+
})
|
|
15
|
+
const rules = ISSUE_RULES.filter(
|
|
16
|
+
(rule) =>
|
|
17
|
+
(!options.categories || options.categories.includes(rule.category)) &&
|
|
18
|
+
(!options.levels || options.levels.includes(rule.level)) &&
|
|
19
|
+
!options.rulesToExclude?.includes(rule.code),
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
let batch: Result[] = []
|
|
23
|
+
let fileType: string | number | undefined
|
|
24
|
+
let fileName: string | number | undefined
|
|
25
|
+
for (const problem of searchProject({
|
|
26
|
+
files,
|
|
27
|
+
rules,
|
|
28
|
+
pathsToVisit: options.pathsToVisit,
|
|
29
|
+
useExactPaths: options.useExactPaths,
|
|
30
|
+
state: options.state,
|
|
31
|
+
})) {
|
|
32
|
+
switch (options.batchSize) {
|
|
33
|
+
case 'all': {
|
|
34
|
+
batch.push(problem)
|
|
35
|
+
break
|
|
36
|
+
}
|
|
37
|
+
case 'per-file': {
|
|
38
|
+
if (fileType !== problem.path[0] || fileName !== problem.path[1]) {
|
|
39
|
+
if (batch.length > 0) {
|
|
40
|
+
idRespond(batch)
|
|
41
|
+
}
|
|
42
|
+
batch = []
|
|
43
|
+
fileType = problem.path[0]
|
|
44
|
+
fileName = problem.path[1]
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
batch.push(problem)
|
|
48
|
+
break
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
default: {
|
|
52
|
+
batch.push(problem)
|
|
53
|
+
if (batch.length >= (options.batchSize ?? 1)) {
|
|
54
|
+
idRespond(batch)
|
|
55
|
+
batch = []
|
|
56
|
+
}
|
|
57
|
+
break
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Send the remaining results
|
|
63
|
+
idRespond(batch)
|
|
64
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { create } from 'jsondiffpatch'
|
|
2
|
+
import { fixProject } from './fixProject'
|
|
3
|
+
import { ISSUE_RULES } from './rules/issues/issueRules.index'
|
|
4
|
+
import type { FixProblemsArgs, FixProblemsResponse } from './types'
|
|
5
|
+
|
|
6
|
+
export const fixProblems = (
|
|
7
|
+
data: FixProblemsArgs,
|
|
8
|
+
reportResults: (results: FixProblemsResponse) => void,
|
|
9
|
+
) => {
|
|
10
|
+
const { files, options = {}, fixRule } = data
|
|
11
|
+
const rule = ISSUE_RULES.find((r) => r.code === fixRule)
|
|
12
|
+
if (!rule) {
|
|
13
|
+
throw new Error(`Unknown fix rule: ${data.fixRule}`)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const updatedFiles = fixProject({
|
|
17
|
+
files,
|
|
18
|
+
rule,
|
|
19
|
+
fixType: data.fixType,
|
|
20
|
+
pathsToVisit: options.pathsToVisit,
|
|
21
|
+
useExactPaths: options.useExactPaths,
|
|
22
|
+
state: options.state,
|
|
23
|
+
})
|
|
24
|
+
// Calculate diff
|
|
25
|
+
const jsonDiffPatch = create({ omitRemovedValues: true })
|
|
26
|
+
const diff = jsonDiffPatch.diff(files, updatedFiles)
|
|
27
|
+
// Send diff + metadata to main thread
|
|
28
|
+
reportResults({
|
|
29
|
+
id: data.id,
|
|
30
|
+
patch: diff,
|
|
31
|
+
fixRule: data.fixRule,
|
|
32
|
+
fixType: data.fixType,
|
|
33
|
+
})
|
|
34
|
+
}
|
package/src/problems.worker.ts
CHANGED
|
@@ -1,174 +1,25 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { create } from 'jsondiffpatch'
|
|
4
|
-
import { fixProject } from './fixProject'
|
|
5
|
-
import { ISSUE_RULES } from './rules/issues/issueRules.index'
|
|
6
|
-
import { searchProject } from './searchProject'
|
|
1
|
+
import { findProblems } from './findProblems'
|
|
2
|
+
import { fixProblems } from './fixProblems'
|
|
7
3
|
import type {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
Level,
|
|
13
|
-
Result,
|
|
4
|
+
FindProblemsArgs,
|
|
5
|
+
FindProblemsResponse,
|
|
6
|
+
FixProblemsArgs,
|
|
7
|
+
FixProblemsResponse,
|
|
14
8
|
} from './types'
|
|
15
9
|
|
|
16
|
-
export type Options = {
|
|
17
|
-
/**
|
|
18
|
-
* Useful for running search on a subset or a single file.
|
|
19
|
-
*/
|
|
20
|
-
pathsToVisit?: string[][]
|
|
21
|
-
/**
|
|
22
|
-
* Whether to match the paths exactly (including length) or just the beginning.
|
|
23
|
-
*/
|
|
24
|
-
useExactPaths?: boolean
|
|
25
|
-
/**
|
|
26
|
-
* Search only rules with these specific categories. If empty, all categories are shown.
|
|
27
|
-
*/
|
|
28
|
-
categories?: Category[]
|
|
29
|
-
/**
|
|
30
|
-
* Search only rules with the specific levels. If empty, all levels are shown.
|
|
31
|
-
*/
|
|
32
|
-
levels?: Level[]
|
|
33
|
-
/**
|
|
34
|
-
* The number of reports to send per message.
|
|
35
|
-
* @default 1
|
|
36
|
-
*/
|
|
37
|
-
batchSize?: number | 'all' | 'per-file'
|
|
38
|
-
/**
|
|
39
|
-
* Dynamic data that is used by some rules.
|
|
40
|
-
*/
|
|
41
|
-
state?: ApplicationState
|
|
42
|
-
/**
|
|
43
|
-
* Do not run rules with these codes. Useful for feature flagged rules
|
|
44
|
-
*/
|
|
45
|
-
rulesToExclude?: Code[]
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
interface FindProblemsArgs {
|
|
49
|
-
id: string
|
|
50
|
-
files: ProjectFiles
|
|
51
|
-
options?: Options
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
interface FixProblemsArgs {
|
|
55
|
-
id: string
|
|
56
|
-
files: ProjectFiles
|
|
57
|
-
options?: Options
|
|
58
|
-
fixRule: Code
|
|
59
|
-
fixType: FixType
|
|
60
|
-
}
|
|
61
|
-
|
|
62
10
|
type Message = FindProblemsArgs | FixProblemsArgs
|
|
63
11
|
|
|
64
|
-
interface FindProblemsResponse {
|
|
65
|
-
id: string
|
|
66
|
-
results: Result[]
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
interface FixProblemsResponse {
|
|
70
|
-
id: string
|
|
71
|
-
patch: Delta
|
|
72
|
-
fixRule: Code
|
|
73
|
-
fixType: FixType
|
|
74
|
-
}
|
|
75
|
-
|
|
76
12
|
type Response = FindProblemsResponse | FixProblemsResponse
|
|
77
13
|
|
|
78
14
|
const respond = (data: Response) => postMessage(data)
|
|
79
15
|
|
|
80
|
-
const findProblems = (data: FindProblemsArgs) => {
|
|
81
|
-
const { files, options = {} } = data
|
|
82
|
-
const idRespond = (results: Result[]) =>
|
|
83
|
-
respond({
|
|
84
|
-
id: data.id,
|
|
85
|
-
results,
|
|
86
|
-
})
|
|
87
|
-
const rules = ISSUE_RULES.filter(
|
|
88
|
-
(rule) =>
|
|
89
|
-
(!options.categories || options.categories.includes(rule.category)) &&
|
|
90
|
-
(!options.levels || options.levels.includes(rule.level)) &&
|
|
91
|
-
!options.rulesToExclude?.includes(rule.code),
|
|
92
|
-
)
|
|
93
|
-
|
|
94
|
-
let batch: Result[] = []
|
|
95
|
-
let fileType: string | number | undefined
|
|
96
|
-
let fileName: string | number | undefined
|
|
97
|
-
for (const problem of searchProject({
|
|
98
|
-
files,
|
|
99
|
-
rules,
|
|
100
|
-
pathsToVisit: options.pathsToVisit,
|
|
101
|
-
useExactPaths: options.useExactPaths,
|
|
102
|
-
state: options.state,
|
|
103
|
-
})) {
|
|
104
|
-
switch (options.batchSize) {
|
|
105
|
-
case 'all': {
|
|
106
|
-
batch.push(problem)
|
|
107
|
-
break
|
|
108
|
-
}
|
|
109
|
-
case 'per-file': {
|
|
110
|
-
if (fileType !== problem.path[0] || fileName !== problem.path[1]) {
|
|
111
|
-
if (batch.length > 0) {
|
|
112
|
-
idRespond(batch)
|
|
113
|
-
}
|
|
114
|
-
batch = []
|
|
115
|
-
fileType = problem.path[0]
|
|
116
|
-
fileName = problem.path[1]
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
batch.push(problem)
|
|
120
|
-
break
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
default: {
|
|
124
|
-
batch.push(problem)
|
|
125
|
-
if (batch.length >= (options.batchSize ?? 1)) {
|
|
126
|
-
idRespond(batch)
|
|
127
|
-
batch = []
|
|
128
|
-
}
|
|
129
|
-
break
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Send the remaining results
|
|
135
|
-
idRespond(batch)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const fixProblems = (data: FixProblemsArgs) => {
|
|
139
|
-
const { files, options = {}, fixRule } = data
|
|
140
|
-
const rule = ISSUE_RULES.find((r) => r.code === fixRule)
|
|
141
|
-
if (!rule) {
|
|
142
|
-
throw new Error(`Unknown fix rule: ${data.fixRule}`)
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const updatedFiles = fixProject({
|
|
146
|
-
files,
|
|
147
|
-
rule,
|
|
148
|
-
fixType: data.fixType,
|
|
149
|
-
pathsToVisit: options.pathsToVisit,
|
|
150
|
-
useExactPaths: options.useExactPaths,
|
|
151
|
-
state: options.state,
|
|
152
|
-
})
|
|
153
|
-
// Calculate diff
|
|
154
|
-
const jsonDiffPatch = create({ omitRemovedValues: true })
|
|
155
|
-
const diff = jsonDiffPatch.diff(files, updatedFiles)
|
|
156
|
-
// Send diff + metadata to main thread
|
|
157
|
-
respond({
|
|
158
|
-
id: data.id,
|
|
159
|
-
patch: diff,
|
|
160
|
-
fixRule: data.fixRule,
|
|
161
|
-
fixType: data.fixType,
|
|
162
|
-
})
|
|
163
|
-
}
|
|
164
|
-
|
|
165
16
|
/**
|
|
166
17
|
* This function is a web worker that checks for problems in the files.
|
|
167
18
|
*/
|
|
168
19
|
onmessage = (event: MessageEvent<Message>) => {
|
|
169
20
|
if ('fixRule' in event.data) {
|
|
170
|
-
fixProblems(event.data)
|
|
21
|
+
fixProblems(event.data, respond)
|
|
171
22
|
} else {
|
|
172
|
-
findProblems(event.data)
|
|
23
|
+
findProblems(event.data, respond)
|
|
173
24
|
}
|
|
174
25
|
}
|
|
@@ -72,6 +72,10 @@ describe('unknownApi', () => {
|
|
|
72
72
|
onSuccess: { actions: [] },
|
|
73
73
|
onError: { actions: [] },
|
|
74
74
|
},
|
|
75
|
+
{
|
|
76
|
+
type: 'AbortFetch',
|
|
77
|
+
api: 'unknown-abort-api',
|
|
78
|
+
},
|
|
75
79
|
],
|
|
76
80
|
},
|
|
77
81
|
},
|
|
@@ -99,9 +103,11 @@ describe('unknownApi', () => {
|
|
|
99
103
|
}),
|
|
100
104
|
)
|
|
101
105
|
|
|
102
|
-
expect(problems).toHaveLength(
|
|
106
|
+
expect(problems).toHaveLength(2)
|
|
103
107
|
expect(problems[0].code).toBe('unknown api')
|
|
104
108
|
expect(problems[0].details).toEqual({ name: 'unknown-api' })
|
|
109
|
+
expect(problems[1].code).toBe('unknown api')
|
|
110
|
+
expect(problems[1].details).toEqual({ name: 'unknown-abort-api' })
|
|
105
111
|
})
|
|
106
112
|
|
|
107
113
|
test('should not report APIs that exist', () => {
|
|
@@ -11,7 +11,9 @@ export const unknownApiRule: Rule<{
|
|
|
11
11
|
nodeType === 'formula' &&
|
|
12
12
|
value.type === 'path' &&
|
|
13
13
|
value.path[0] === 'Apis'
|
|
14
|
-
const isApiAction =
|
|
14
|
+
const isApiAction =
|
|
15
|
+
nodeType === 'action-model' &&
|
|
16
|
+
(value.type === 'Fetch' || value.type === 'AbortFetch')
|
|
15
17
|
if (!isApiFormula && !isApiAction) {
|
|
16
18
|
return
|
|
17
19
|
}
|
package/src/types.d.ts
CHANGED
|
@@ -137,7 +137,7 @@ type Category =
|
|
|
137
137
|
|
|
138
138
|
type Level = 'error' | 'warning' | 'info'
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
type Result = {
|
|
141
141
|
path: (string | number)[]
|
|
142
142
|
code: Code
|
|
143
143
|
category: Category
|
|
@@ -168,7 +168,7 @@ type NonHttpOnlyCookie = ApplicationCookie & {
|
|
|
168
168
|
value: string
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
|
|
171
|
+
interface ApplicationState {
|
|
172
172
|
cookiesAvailable?: Array<HttpOnlyCookie | NonHttpOnlyCookie>
|
|
173
173
|
isBrowserExtensionAvailable?: boolean
|
|
174
174
|
projectDetails?: ToddleProject
|
|
@@ -377,7 +377,7 @@ type StyleNode = {
|
|
|
377
377
|
}
|
|
378
378
|
} & Base
|
|
379
379
|
|
|
380
|
-
|
|
380
|
+
type NodeType =
|
|
381
381
|
| ActionModelNode
|
|
382
382
|
| ComponentAPIInputNode
|
|
383
383
|
| ComponentAPINode
|
|
@@ -425,7 +425,7 @@ type FixType =
|
|
|
425
425
|
| UnknownApiServiceRuleFix
|
|
426
426
|
| UnknownComponentAttributeRuleFix
|
|
427
427
|
|
|
428
|
-
|
|
428
|
+
interface Rule<T = unknown, V = NodeType> {
|
|
429
429
|
category: Category
|
|
430
430
|
code: Code
|
|
431
431
|
level: Level
|
|
@@ -443,6 +443,64 @@ interface FixFunctionArgs<Data extends NodeType, Details = unknown> {
|
|
|
443
443
|
state?: ApplicationState
|
|
444
444
|
}
|
|
445
445
|
|
|
446
|
-
|
|
446
|
+
type FixFunction<Data extends NodeType, Details = unknown> = (
|
|
447
447
|
args: FixFunctionArgs<Data, Details>,
|
|
448
448
|
) => ProjectFiles | void
|
|
449
|
+
|
|
450
|
+
type Options = {
|
|
451
|
+
/**
|
|
452
|
+
* Useful for running search on a subset or a single file.
|
|
453
|
+
*/
|
|
454
|
+
pathsToVisit?: string[][]
|
|
455
|
+
/**
|
|
456
|
+
* Whether to match the paths exactly (including length) or just the beginning.
|
|
457
|
+
*/
|
|
458
|
+
useExactPaths?: boolean
|
|
459
|
+
/**
|
|
460
|
+
* Search only rules with these specific categories. If empty, all categories are shown.
|
|
461
|
+
*/
|
|
462
|
+
categories?: Category[]
|
|
463
|
+
/**
|
|
464
|
+
* Search only rules with the specific levels. If empty, all levels are shown.
|
|
465
|
+
*/
|
|
466
|
+
levels?: Level[]
|
|
467
|
+
/**
|
|
468
|
+
* The number of reports to send per message.
|
|
469
|
+
* @default 1
|
|
470
|
+
*/
|
|
471
|
+
batchSize?: number | 'all' | 'per-file'
|
|
472
|
+
/**
|
|
473
|
+
* Dynamic data that is used by some rules.
|
|
474
|
+
*/
|
|
475
|
+
state?: ApplicationState
|
|
476
|
+
/**
|
|
477
|
+
* Do not run rules with these codes. Useful for feature flagged rules
|
|
478
|
+
*/
|
|
479
|
+
rulesToExclude?: Code[]
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
interface FindProblemsArgs {
|
|
483
|
+
id: string
|
|
484
|
+
files: ProjectFiles
|
|
485
|
+
options?: Options
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
interface FindProblemsResponse {
|
|
489
|
+
id: string
|
|
490
|
+
results: Result[]
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
interface FixProblemsArgs {
|
|
494
|
+
id: string
|
|
495
|
+
files: ProjectFiles
|
|
496
|
+
options?: Options
|
|
497
|
+
fixRule: Code
|
|
498
|
+
fixType: FixType
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
interface FixProblemsResponse {
|
|
502
|
+
id: string
|
|
503
|
+
patch: Delta
|
|
504
|
+
fixRule: Code
|
|
505
|
+
fixType: FixType
|
|
506
|
+
}
|