Files
start-os/sdk/base/lib/actions/input/builder/variants.ts
Aiden McClelland 7750e33f82 misc sdk changes (#2934)
* misc sdk changes

* delete the store ☠️

* port comments

* fix build

* fix removing

* fix tests

* beta.20

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
2025-05-09 15:10:51 -06:00

126 lines
3.3 KiB
TypeScript

import { DeepPartial } from "../../../types"
import { ValueSpec, ValueSpecUnion } from "../inputSpecTypes"
import {
LazyBuild,
InputSpec,
ExtractInputSpecType,
ExtractPartialInputSpecType,
} from "./inputSpec"
import { Parser, anyOf, literal, object } from "ts-matches"
export type UnionRes<
VariantValues extends {
[K in string]: {
name: string
spec: InputSpec<any>
}
},
K extends keyof VariantValues & string = keyof VariantValues & string,
> = {
[key in keyof VariantValues]: {
selection: key
value: ExtractInputSpecType<VariantValues[key]["spec"]>
other?: {
[key2 in Exclude<keyof VariantValues & string, key>]?: DeepPartial<
ExtractInputSpecType<VariantValues[key2]["spec"]>
>
}
}
}[K]
/**
* Used in the the Value.select { @link './value.ts' }
* to indicate the type of select variants that are available. The key for the record passed in will be the
* key to the tag.id in the Value.select
```ts
export const disabled = InputSpec.of({});
export const size = Value.number({
name: "Max Chain Size",
default: 550,
description: "Limit of blockchain size on disk.",
warning: "Increasing this value will require re-syncing your node.",
required: true,
range: "[550,1000000)",
integral: true,
units: "MiB",
placeholder: null,
});
export const automatic = InputSpec.of({ size: size });
export const size1 = Value.number({
name: "Failsafe Chain Size",
default: 65536,
description: "Prune blockchain if size expands beyond this.",
warning: null,
required: true,
range: "[550,1000000)",
integral: true,
units: "MiB",
placeholder: null,
});
export const manual = InputSpec.of({ size: size1 });
export const pruningSettingsVariants = Variants.of({
disabled: { name: "Disabled", spec: disabled },
automatic: { name: "Automatic", spec: automatic },
manual: { name: "Manual", spec: manual },
});
export const pruning = Value.union(
{
name: "Pruning Settings",
description:
'- Disabled: Disable pruning\n- Automatic: Limit blockchain size on disk to a certain number of megabytes\n- Manual: Prune blockchain with the "pruneblockchain" RPC\n',
warning: null,
default: "disabled",
},
pruningSettingsVariants
);
```
*/
export class Variants<
VariantValues extends {
[K in string]: {
name: string
spec: InputSpec<any>
}
},
> {
private constructor(
public build: LazyBuild<ValueSpecUnion["variants"]>,
public validator: Parser<unknown, UnionRes<VariantValues>>,
) {}
static of<
VariantValues extends {
[K in string]: {
name: string
spec: InputSpec<any>
}
},
>(a: VariantValues) {
const validator = anyOf(
...Object.entries(a).map(([id, { spec }]) =>
object({
selection: literal(id),
value: spec.validator,
}),
),
) as Parser<unknown, any>
return new Variants<VariantValues>(async (options) => {
const variants = {} as {
[K in keyof VariantValues]: {
name: string
spec: Record<string, ValueSpec>
}
}
for (const key in a) {
const value = a[key]
variants[key] = {
name: value.name,
spec: await value.spec.build(options as any),
}
}
return variants
}, validator)
}
}