feat(mod_update): add self-update flow, package name parser, dynamic CLI version, and tests

This commit is contained in:
2026-02-06 00:19:17 +00:00
parent 57e4d1c043
commit 65906f7e5f
7 changed files with 172 additions and 9 deletions

View File

@@ -191,12 +191,11 @@ export class PackageManagerUtil {
const data = JSON.parse(line);
if (data.type === 'tree' && data.data && data.data.trees) {
for (const tree of data.data.trees) {
const name = tree.name?.split('@')[0] || '';
if (name.startsWith('@git.zone/')) {
const version = tree.name?.split('@').pop() || 'unknown';
const parsed = PackageManagerUtil.parseYarnPackageName(tree.name || '');
if (parsed.name.startsWith('@git.zone/')) {
packages.push({
name,
version,
name: parsed.name,
version: parsed.version,
packageManager: pm,
});
}
@@ -277,6 +276,26 @@ export class PackageManagerUtil {
}
}
/**
* Parse a yarn package name string like "@git.zone/cli@1.0.0" into name and version.
* Handles scoped packages correctly by splitting on the last '@' (version separator).
*/
public static parseYarnPackageName(fullName: string): { name: string; version: string } {
if (!fullName) {
return { name: '', version: 'unknown' };
}
const lastAtIndex = fullName.lastIndexOf('@');
// If lastAtIndex is 0, the string is just "@something" with no version
// If lastAtIndex is -1, there's no '@' at all
if (lastAtIndex <= 0) {
return { name: fullName, version: 'unknown' };
}
return {
name: fullName.substring(0, lastAtIndex),
version: fullName.substring(lastAtIndex + 1) || 'unknown',
};
}
/**
* Compare two semver versions
* Returns true if latest > current