Skip to content

Commit 0aaf258

Browse files
Copilothotlong
andcommitted
fix: address code review - preserve installedAt in rollback, fix semver parsing, remove duplicate hash
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent bd2085c commit 0aaf258

3 files changed

Lines changed: 68 additions & 13 deletions

File tree

packages/cli/src/commands/plugin/build.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ export default class PluginBuild extends Command {
7777

7878
// 5. Compute checksums
7979
if (!flags.json) printStep('Computing checksums...');
80-
const fileHash = crypto.createHash(flags.checksumAlgorithm).update(configBuffer).digest('hex');
8180
const manifestChecksum = crypto.createHash(flags.checksumAlgorithm).update(configBuffer).digest('hex');
8281

8382
// 6. Write output
@@ -136,7 +135,7 @@ export default class PluginBuild extends Command {
136135
checksums: {
137136
algorithm: flags.checksumAlgorithm,
138137
manifest: manifestChecksum,
139-
files: { 'manifest.json': fileHash },
138+
files: { 'manifest.json': manifestChecksum },
140139
},
141140
signature: signatureInfo,
142141
files: fileEntries,

packages/cli/src/commands/plugin/validate.ts

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -135,15 +135,68 @@ export default class PluginValidate extends Command {
135135
const engine = (manifest as any).manifest?.engine || (manifest as any).engine;
136136
const required = engine?.objectstack as string | undefined;
137137
if (required) {
138-
// Simple semver range check (>=X.Y.Z)
139-
const rangeMatch = required.match(/>=?\s*([\d.]+)/);
140-
if (rangeMatch) {
141-
const [rMajor, rMinor = '0', rPatch = '0'] = rangeMatch[1].split('.');
142-
const [pMajor, pMinor = '0', pPatch = '0'] = flags.platformVersion.split('.');
143-
const compatible =
144-
parseInt(pMajor) > parseInt(rMajor) ||
145-
(parseInt(pMajor) === parseInt(rMajor) && parseInt(pMinor) > parseInt(rMinor)) ||
146-
(parseInt(pMajor) === parseInt(rMajor) && parseInt(pMinor) === parseInt(rMinor) && parseInt(pPatch) >= parseInt(rPatch));
138+
// Semver range check supporting >=, >, ^, ~, and exact versions
139+
const parseSemver = (v: string) => {
140+
const parts = v.replace(/^v/, '').split('.').map(p => parseInt(p, 10));
141+
return { major: parts[0] || 0, minor: parts[1] || 0, patch: parts[2] || 0 };
142+
};
143+
144+
const target = parseSemver(flags.platformVersion);
145+
let compatible = false;
146+
let matched = false;
147+
148+
// >=X.Y.Z — greater than or equal
149+
const gteMatch = required.match(/^>=\s*([\d.]+)/);
150+
if (gteMatch) {
151+
const req = parseSemver(gteMatch[1]);
152+
compatible = (target.major > req.major) ||
153+
(target.major === req.major && target.minor > req.minor) ||
154+
(target.major === req.major && target.minor === req.minor && target.patch >= req.patch);
155+
matched = true;
156+
}
157+
158+
// >X.Y.Z — strictly greater than
159+
if (!matched) {
160+
const gtMatch = required.match(/^>\s*([\d.]+)/);
161+
if (gtMatch) {
162+
const req = parseSemver(gtMatch[1]);
163+
compatible = (target.major > req.major) ||
164+
(target.major === req.major && target.minor > req.minor) ||
165+
(target.major === req.major && target.minor === req.minor && target.patch > req.patch);
166+
matched = true;
167+
}
168+
}
169+
170+
// ^X.Y.Z — caret range (same major, >= minor.patch)
171+
if (!matched) {
172+
const caretMatch = required.match(/^\^\s*([\d.]+)/);
173+
if (caretMatch) {
174+
const req = parseSemver(caretMatch[1]);
175+
compatible = target.major === req.major &&
176+
((target.minor > req.minor) ||
177+
(target.minor === req.minor && target.patch >= req.patch));
178+
matched = true;
179+
}
180+
}
181+
182+
// ~X.Y.Z — tilde range (same major.minor, >= patch)
183+
if (!matched) {
184+
const tildeMatch = required.match(/^~\s*([\d.]+)/);
185+
if (tildeMatch) {
186+
const req = parseSemver(tildeMatch[1]);
187+
compatible = target.major === req.major && target.minor === req.minor && target.patch >= req.patch;
188+
matched = true;
189+
}
190+
}
191+
192+
// Exact version match
193+
if (!matched && /^\d+\.\d+\.\d+$/.test(required)) {
194+
const req = parseSemver(required);
195+
compatible = target.major === req.major && target.minor === req.minor && target.patch === req.patch;
196+
matched = true;
197+
}
198+
199+
if (matched) {
147200
platformResult = { compatible, requiredRange: required, targetVersion: flags.platformVersion };
148201
findings.push({
149202
severity: compatible ? 'info' : 'error',

packages/core/src/package-manager.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ export interface PackageSnapshot {
3636
previousManifest: Record<string, unknown>;
3737
/** Namespaces before upgrade */
3838
previousNamespaces: string[];
39+
/** Original installation timestamp */
40+
installedAt: string;
3941
/** Snapshot timestamp */
4042
createdAt: string;
4143
}
@@ -254,7 +256,7 @@ export class PackageManager {
254256
packageId,
255257
fromVersion: '',
256258
toVersion: newVersion,
257-
snapshot: { packageId, previousVersion: '', previousManifest: {}, previousNamespaces: [], createdAt: new Date().toISOString() },
259+
snapshot: { packageId, previousVersion: '', previousManifest: {}, previousNamespaces: [], installedAt: '', createdAt: new Date().toISOString() },
258260
errorMessage: `Package ${packageId} is not installed`,
259261
};
260262
}
@@ -265,6 +267,7 @@ export class PackageManager {
265267
previousVersion: existing.version,
266268
previousManifest: existing.manifest,
267269
previousNamespaces: [...existing.namespaces],
270+
installedAt: existing.installedAt,
268271
createdAt: new Date().toISOString(),
269272
};
270273
this.snapshots.set(packageId, snapshot);
@@ -351,7 +354,7 @@ export class PackageManager {
351354
packageId,
352355
version: snapshot.previousVersion,
353356
manifest: snapshot.previousManifest,
354-
installedAt: new Date().toISOString(),
357+
installedAt: snapshot.installedAt,
355358
status: 'installed',
356359
namespaces: snapshot.previousNamespaces,
357360
dependencies: deps ? Object.keys(deps) : [],

0 commit comments

Comments
 (0)