API: Standardize "nextCompletion" promise in tasks (#2687)

This commit is contained in:
catloversg
2026-04-28 13:49:53 +07:00
committed by GitHub
parent ee3014b029
commit 36e1adf2d2
72 changed files with 1750 additions and 364 deletions
+35
View File
@@ -639,5 +639,40 @@ export const breakingChanges300: VersionBreakingChange = {
"The function was renamed because it returns information about all gangs, including the player's own gang.",
showWarning: false,
},
{
brokenAPIs: [
{
name: "ns.singularity.getCurrentWork",
migration: {
searchValue: "completion",
/**
* "completion" is a common word, so we cannot replace all its instances.
* This migrator focuses on the most popular use cases of the "completion" promise. It intentionally does
* not support complex cases and `completion.then()`.
*/
migrator: (line: string) => {
// Direct chaining from API
// Use \b:
// - The leading \b applies to getCurrentWork, preventing prefixes like foo_getCurrentWork
// - The trailing \b applies to completion, preventing suffixes like completionFoo.
// Use \s* to match `getCurrentWork ( ) .completion`
line = line.replace(/\b(getCurrentWork\s*\(\s*\))\s*\.completion\b/g, "$1.nextCompletion");
// Awaited property access (`await task.completion`). This is a bit risky, but it's still a common usage.
// [a-zA-Z0-9_$.[\]()?]+ is enough to catch common usages.
line = line.replace(/(\bawait\s+[a-zA-Z0-9_$.[\]()?]+)\s*\.completion\b/g, "$1.nextCompletion");
return line;
},
},
},
{ name: "ns.sleeve.getTask" },
],
info:
"Task objects returned from ns.singularity.getCurrentWork() and ns.sleeve.getTask() previously had an optional\n" +
`promise property named either "completion" or "nextCompletion", depending on the task.\n` +
`Now, these task objects always include this property, and it is consistently named "nextCompletion".`,
showWarning: false,
},
],
};
+8 -8
View File
@@ -634,14 +634,14 @@ Error: ${e}`,
person.overrideIntelligence();
}
}
if (ver < 48) {
if (ver < 49) {
if (Player.sourceFileLvl(5) === 0 && Player.bitNodeN !== 5) {
for (const person of [Player, ...Player.sleeves]) {
person.persistentIntelligenceData.exp = 0;
person.exp.intelligence = 0;
person.skills.intelligence = 0;
}
}
showAPIBreaks("3.0.0", breakingChanges300);
}
if (ver < 49 && Player.sourceFileLvl(5) === 0 && Player.bitNodeN !== 5) {
for (const person of [Player, ...Player.sleeves]) {
person.persistentIntelligenceData.exp = 0;
person.exp.intelligence = 0;
person.skills.intelligence = 0;
}
}
}