feat(ota): add kv helpers and policy logic
This commit is contained in:
parent
acf0ace77c
commit
c7d0fd1eeb
|
|
@ -0,0 +1,27 @@
|
|||
import { describe, expect, it } from "vitest"
|
||||
|
||||
import { evaluateStorePolicy } from "../lib/policy"
|
||||
import type { OtaRelease } from "../lib/schema"
|
||||
|
||||
describe("evaluateStorePolicy", () => {
|
||||
it("requires a store update when a store release is newer than the installed binary", () => {
|
||||
const policy = evaluateStorePolicy(
|
||||
{
|
||||
releaseVersion: "0.4.3",
|
||||
releaseKind: "store",
|
||||
runtimeVersion: "0.4.3",
|
||||
policy: {
|
||||
storeRequired: true,
|
||||
minSupportedBinaryVersion: "0.4.3",
|
||||
message: "Please update from the store.",
|
||||
},
|
||||
} satisfies Pick<OtaRelease, "releaseVersion" | "releaseKind" | "runtimeVersion" | "policy">,
|
||||
{
|
||||
installedBinaryVersion: "0.4.1",
|
||||
},
|
||||
)
|
||||
|
||||
expect(policy.action).toBe("block")
|
||||
expect(policy.targetVersion).toBe("0.4.3")
|
||||
})
|
||||
})
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import type { OtaPlatform, OtaRelease } from "./schema"
|
||||
|
||||
export const KV_KEYS = {
|
||||
release: (product: OtaRelease["product"], releaseVersion: OtaRelease["releaseVersion"]) =>
|
||||
`release:${product}:${releaseVersion}`,
|
||||
latest: (
|
||||
product: OtaRelease["product"],
|
||||
channel: OtaRelease["channel"],
|
||||
runtimeVersion: OtaRelease["runtimeVersion"],
|
||||
platform: OtaPlatform,
|
||||
) => `latest:${product}:${channel}:${runtimeVersion}:${platform}`,
|
||||
policy: (product: OtaRelease["product"], channel: OtaRelease["channel"]) =>
|
||||
`policy:${product}:${channel}`,
|
||||
githubEtag: "github:etag:releases",
|
||||
syncLastSuccessAt: "sync:last-success-at",
|
||||
} as const
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import { KV_KEYS } from "./constants"
|
||||
import type { OtaPlatform, OtaRelease } from "./schema"
|
||||
|
||||
export async function getLatestReleasePointer<T = unknown>(
|
||||
kv: KVNamespace,
|
||||
input: {
|
||||
product: OtaRelease["product"]
|
||||
channel: OtaRelease["channel"]
|
||||
runtimeVersion: OtaRelease["runtimeVersion"]
|
||||
platform: OtaPlatform
|
||||
},
|
||||
) {
|
||||
return kv.get<T>(
|
||||
KV_KEYS.latest(input.product, input.channel, input.runtimeVersion, input.platform),
|
||||
"json",
|
||||
)
|
||||
}
|
||||
|
||||
export async function putReleaseRecord<T>(
|
||||
kv: KVNamespace,
|
||||
product: OtaRelease["product"],
|
||||
releaseVersion: OtaRelease["releaseVersion"],
|
||||
value: T,
|
||||
) {
|
||||
await kv.put(KV_KEYS.release(product, releaseVersion), JSON.stringify(value))
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
import type { OtaRelease } from "./schema"
|
||||
import { compareSemver } from "./version"
|
||||
|
||||
type StoreReleasePolicyInput = Pick<
|
||||
OtaRelease,
|
||||
"releaseVersion" | "releaseKind" | "runtimeVersion" | "policy"
|
||||
>
|
||||
|
||||
type StorePolicyEvaluation =
|
||||
| {
|
||||
action: "none"
|
||||
targetVersion: null
|
||||
message: null
|
||||
}
|
||||
| {
|
||||
action: "block" | "prompt"
|
||||
targetVersion: OtaRelease["releaseVersion"]
|
||||
message: string | null
|
||||
}
|
||||
|
||||
export function evaluateStorePolicy(
|
||||
latestStoreRelease: StoreReleasePolicyInput | null,
|
||||
input: {
|
||||
installedBinaryVersion: OtaRelease["releaseVersion"]
|
||||
},
|
||||
): StorePolicyEvaluation {
|
||||
if (!latestStoreRelease || latestStoreRelease.releaseKind !== "store") {
|
||||
return { action: "none", targetVersion: null, message: null }
|
||||
}
|
||||
|
||||
if (compareSemver(latestStoreRelease.releaseVersion, input.installedBinaryVersion) <= 0) {
|
||||
return { action: "none", targetVersion: null, message: null }
|
||||
}
|
||||
|
||||
return {
|
||||
action: latestStoreRelease.policy.storeRequired ? "block" : "prompt",
|
||||
targetVersion: latestStoreRelease.releaseVersion,
|
||||
message: latestStoreRelease.policy.message,
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue