diff --git a/core/locks.ts b/core/locks.ts index c1b798d4..d9d11465 100644 --- a/core/locks.ts +++ b/core/locks.ts @@ -35,23 +35,30 @@ export const empty: LockfileJson = { * * @param dependency The dependency to create the lock for. * @param target The target version to update the dependency to. + * @param original The original lockfile to create the partial lock from. + * + * @returns The `LockfileJson` object representing the partial lock. + * @throws If the version of the original lockfile is not supported. */ export function create( dependency: DependencySpec, target: string, - extracted: LockfileJson, + original: LockfileJson, ): Promise { + if (original.version !== VERSION) { + throw new Error(`Unsupported lockfile version: ${original.version}`); + } return isRemote(dependency) - ? createRemoteLock(dependency, extracted) + ? createRemoteLock(dependency, original) : createPackageLock(dependency as DependencySpec<"jsr" | "npm">, target); } async function createRemoteLock( dep: DependencySpec<"http" | "https">, - extracted: LockfileJson, + original: LockfileJson, ): Promise { const { kind, name, constraint, path } = dep; - const reqs = Object.keys(extracted.remote).filter((req) => + const reqs = Object.keys(original.remote).filter((req) => [kind, name, path ?? ""].every((part) => req.includes(part)) ); const lockfile = parseFromJson("", empty); @@ -238,6 +245,7 @@ async function getJsrDependencies( * @param lockfile The `Lockfile` object to extract the partial lock for the dependency from. * @param dependency The dependency to extract the partial lock for. * @returns The `LockfileJson` object representing the partial lock. + * @throws If the lockfile version is not supported. * * @example * ```ts @@ -249,6 +257,9 @@ export async function extract( lockfile: LockfileJson, dependency: DependencySpec, ): Promise { + if (lockfile.version !== VERSION) { + throw new Error(`Unsupported lockfile version: ${lockfile.version}`); + } return isRemote(dependency) ? await extractRemote(lockfile, dependency) : extractPackage(lockfile, dependency as DependencySpec<"jsr" | "npm">); diff --git a/core/locks_test.ts b/core/locks_test.ts index b7a83b49..dfa6512e 100644 --- a/core/locks_test.ts +++ b/core/locks_test.ts @@ -1,5 +1,5 @@ import * as fs from "@chiezo/amber/fs"; -import { assertEquals } from "@std/assert"; +import { assertEquals, assertRejects } from "@std/assert"; import { afterEach, beforeEach, describe, it } from "@std/testing/bdd"; import { parse } from "./specs.ts"; import { create, extract, type LockfileJson, query } from "./locks.ts"; @@ -50,11 +50,23 @@ describe("create", () => { beforeEach(() => fs.mock()); afterEach(() => fs.dispose()); + it("should throw an error for an unsupported lockfile version", async () => { + await assertRejects( + async () => { + await create(parse("jsr:@std/testing@^0.222.0"), "0.222.0", { + version: "4", + } as LockfileJson); + }, + Error, + "Unsupported lockfile version: 4", + ); + }); + it("should create a partial lock for a package with a patch update", async () => { const lock = await create( parse("jsr:@std/assert@^0.222.0"), "0.222.1", - {} as LockfileJson, + { version: "3" } as LockfileJson, ); assertEquals(lock, { version: "3", @@ -86,7 +98,7 @@ describe("create", () => { const lock = await create( parse("jsr:@std/assert@^0.226.0"), "0.226.0", - {} as LockfileJson, + { version: "3" } as LockfileJson, ); assertEquals(lock, { version: "3", @@ -116,7 +128,7 @@ describe("create", () => { const lock = await create( parse("jsr:@core/match@^0.2.0"), "0.2.5", - {} as LockfileJson, + { version: "3" } as LockfileJson, ); assertEquals(lock, { version: "3", @@ -149,7 +161,7 @@ describe("create", () => { const lock = await create( parse("npm:@conventional-commits/parser@^0.4.0"), "0.4.1", - {} as LockfileJson, + { version: "3" } as LockfileJson, ); assertEquals(lock, { version: "3", @@ -246,6 +258,19 @@ describe("extract", () => { beforeEach(() => fs.mock()); afterEach(() => fs.dispose()); + it("should throw an error for an unsupported lockfile version", async () => { + await assertRejects( + async () => { + await extract( + { version: "4" } as LockfileJson, + parse("jsr:@std/testing@^0.222.0"), + ); + }, + Error, + "Unsupported lockfile version: 4", + ); + }); + it("should return undefined for an unlocked package", async () => { const dep = parse("jsr:@std/testing@^0.222.0"); const lock = await extract(LOCKFILE, dep);