nativekeel 0.1.18 → 0.1.19
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/package.json +1 -1
- package/src/plan.js +9 -3
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Health check for React Native and Expo apps. One command, no install, no account
|
|
|
6
6
|
npx nativekeel
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
**What's new in 0.1.18:** the upgrade plan only suggests library versions your current React Native supports, moves React Navigation and RN Firebase packages together, and says plainly when a vulnerable package has no fixed release.
|
|
9
|
+
**What's new in 0.1.19:** better plans for apps that are far behind: library targets that fit the React Native you have, not the latest. **0.1.18:** the upgrade plan only suggests library versions your current React Native supports, moves React Navigation and RN Firebase packages together, and says plainly when a vulnerable package has no fixed release. Recent releases added a *Start here* list in every report, hacking risks mapped to OWASP MASVS, crash and performance checks. Every check is tuned on 450+ open-source React Native and Expo apps to keep false alarms out. [All releases →](https://nativekeel.com/changelog)
|
|
10
10
|
|
|
11
11
|
```
|
|
12
12
|
Summary 4 critical · 5 high · 4 medium · 6 low
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nativekeel",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
4
4
|
"description": "Health check for React Native and Expo apps: upgrade blockers, store deadlines, crash risks, vulnerable dependencies and leaked secrets, with a step-by-step upgrade plan.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/plan.js
CHANGED
|
@@ -177,6 +177,8 @@ export function buildPlan(result) {
|
|
|
177
177
|
const pm = isExpo ? { ...basePm, add: 'npx expo install' } : basePm;
|
|
178
178
|
const pinned = isExpo ? expoPinnedNames(result.project.root) : new Set();
|
|
179
179
|
const movesWithExpo = (name) => isExpo && movesWithExpoSdk(name, pinned);
|
|
180
|
+
// Packages the React Native upgrade steps move (React Native itself and the compatibility tables).
|
|
181
|
+
const movesWithRn = (name) => !isExpo && !!byKind('upgrade-rn').length && (name === 'react-native' || !!COMPAT[name]);
|
|
180
182
|
const installed = new Set(result.deps.map((d) => d.name));
|
|
181
183
|
const byKind = (kind) => result.findings.filter((f) => f.fix && f.fix.kind === kind).map((f) => f.fix);
|
|
182
184
|
const phases = [];
|
|
@@ -290,7 +292,7 @@ export function buildPlan(result) {
|
|
|
290
292
|
} else if (f.fix.kind === 'vuln-dep' && (f.fix.severity === 'critical' || f.fix.severity === 'high')) {
|
|
291
293
|
const v = f.fix;
|
|
292
294
|
if (v.noFix) sec.push({ sev, step: `\`${v.name}\` ${v.from} has ${v.severity} known vulnerabilities and no fixed release (the latest is ${v.latest}): replace it, or make sure it never handles untrusted input.` });
|
|
293
|
-
else sec.push({ sev, step: `Update \`${v.name}\` ${v.from}${v.to ? ` to ${v.to}${v.to.startsWith('a release') ? '' : ' or later'}` : ''}: it has ${v.severity} known vulnerabilities. ${movesWithExpo(v.name) ? 'Expo pins it: the SDK upgrade below moves it.' : 'Check its changelog for breaking changes.'}` });
|
|
295
|
+
else sec.push({ sev, step: `Update \`${v.name}\` ${v.from}${v.to ? ` to ${v.to}${v.to.startsWith('a release') ? '' : ' or later'}` : ''}: it has ${v.severity} known vulnerabilities. ${movesWithExpo(v.name) ? 'Expo pins it: the SDK upgrade below moves it.' : movesWithRn(v.name) ? 'The React Native steps below move it past this version; if you ship before them, update it now.' : 'Check its changelog for breaking changes.'}` });
|
|
294
296
|
}
|
|
295
297
|
}
|
|
296
298
|
const securitySteps = sec.sort((a, b) => a.sev - b.sev).map((x) => x.step);
|
|
@@ -369,17 +371,21 @@ export function buildPlan(result) {
|
|
|
369
371
|
// The React Native steps move them further.
|
|
370
372
|
const curMinor = result.project.reactNative ? Number(result.project.reactNative.split('.')[1]) : null;
|
|
371
373
|
const archNow = !byKind('enable-new-arch').length;
|
|
374
|
+
const rnTarget = byKind('upgrade-rn')[0];
|
|
375
|
+
const rnBehind = !!(rnTarget && curMinor !== null && Number(rnTarget.to.split('.')[1]) - curMinor >= 3);
|
|
372
376
|
const nativeBumps = byKind('bump-dep')
|
|
373
377
|
.filter((d) => d.native && !movesWithExpo(d.name))
|
|
374
378
|
.map((d) => {
|
|
375
379
|
if (!COMPAT[d.name] || curMinor === null) return d;
|
|
376
380
|
const best = bestRange(d.name, curMinor, archNow);
|
|
377
|
-
if (!best) return
|
|
381
|
+
if (!best) return null; // the table starts later: the React Native steps move it
|
|
378
382
|
if (compareVersions(d.from, best.from) >= 0 && (!best.to || compareVersions(d.from, best.to) <= 0)) return null;
|
|
379
383
|
if (compareVersions(d.from, best.from) > 0) return null;
|
|
380
384
|
return { ...d, to: best.range, capped: `0.${curMinor}` };
|
|
381
385
|
})
|
|
382
|
-
.filter(Boolean)
|
|
386
|
+
.filter(Boolean)
|
|
387
|
+
// Far behind: the latest release usually needs a newer React Native than the app has.
|
|
388
|
+
.map((d) => (rnBehind && !d.capped ? { ...d, to: `the newest release that supports React Native 0.${curMinor} (latest is ${d.to})` } : d));
|
|
383
389
|
if (nativeBumps.length) {
|
|
384
390
|
phases.push({
|
|
385
391
|
title: 'Update native modules on the current React Native version',
|