1import * as Schema from "effect/Schema";
2
3const ForkVersion = Schema.String.check(Schema.isPattern(/^0\.0\.[0-9]+$/));
4
5export const ForkReleaseListing = Schema.Struct({
6 files: Schema.Array(Schema.Struct({ href: Schema.String })),
7});
8
9export function latestForkRelease(listing: typeof ForkReleaseListing.Type): string | undefined {
10 let latest: string | undefined;
11 for (const { href } of listing.files) {
12 const version = /^(0\.0\.[0-9]+)\.json$/.exec(href)?.[1];
13 if (version && (!latest || BigInt(version.slice(4)) > BigInt(latest.slice(4))))
14 latest = version;
15 }
16 return latest;
17}
18
19export const FORK_RUNTIME_MANIFEST_FILE = "knife-runtime.json";
20export const ForkRuntimeManifest = Schema.Struct({
21 version: ForkVersion,
22 sha256: Schema.String.check(Schema.isPattern(/^[a-f0-9]{64}$/)),
23 shell: Schema.String.check(Schema.isPattern(/^[a-f0-9]{64}$/)),
24});
25
26export const ForkArtifact = Schema.Struct({
27 file: Schema.String.check(Schema.isPattern(/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/)),
28 sha256: Schema.String.check(Schema.isPattern(/^[a-f0-9]{64}$/)),
29 size: Schema.Number.check(Schema.isInt(), Schema.isGreaterThan(0)),
30});
31
32export const ForkReleaseManifest = Schema.Struct({
33 version: ForkVersion,
34 ui: ForkArtifact,
35 assets: ForkArtifact,
36 server: Schema.Struct({
37 ...ForkArtifact.fields,
38 version: ForkVersion,
39 runtime: Schema.String.check(Schema.isPattern(/^[a-f0-9]{64}$/)),
40 }),
41 desktop: Schema.Record(
42 Schema.String,
43 Schema.Struct({
44 version: ForkVersion,
45 ui: ForkArtifact,
46 assets: ForkArtifact,
47 shell: Schema.String.check(Schema.isPattern(/^[a-f0-9]{64}$/)),
48 runtime: Schema.String.check(Schema.isPattern(/^[a-f0-9]{64}$/)),
49 code: ForkArtifact,
50 app: Schema.Struct({ ...ForkArtifact.fields, version: ForkVersion }),
51 }),
52 ),
53});