mirror of
https://github.com/Start9Labs/start-sdk.git
synced 2026-03-26 10:21:55 +00:00
feat: Dynamic Union
This commit is contained in:
@@ -487,6 +487,26 @@ export class StartSdk<Manifest extends SDKManifest, Store, Vault> {
|
||||
a,
|
||||
aVariants,
|
||||
),
|
||||
|
||||
dynamicUnion: <
|
||||
Required extends RequiredDefault<string>,
|
||||
Type extends Record<string, any>,
|
||||
>(
|
||||
getA: LazyBuild<
|
||||
Store,
|
||||
Vault,
|
||||
{
|
||||
disabled: string[] | false | string
|
||||
name: string
|
||||
description?: string | null
|
||||
warning?: string | null
|
||||
required: Required
|
||||
}
|
||||
>,
|
||||
aVariants:
|
||||
| Variants<Type, Store, Vault>
|
||||
| Variants<Type, never, never>,
|
||||
) => Value.dynamicUnion<Required, Type, Store, Vault>(getA, aVariants),
|
||||
},
|
||||
Variants: {
|
||||
of: <
|
||||
|
||||
@@ -751,6 +751,38 @@ export class Value<Type, Store, Vault> {
|
||||
asRequiredParser(aVariants.validator, a),
|
||||
)
|
||||
}
|
||||
static dynamicUnion<
|
||||
Required extends RequiredDefault<string>,
|
||||
Type extends Record<string, any>,
|
||||
Store = never,
|
||||
Vault = never,
|
||||
>(
|
||||
getA: LazyBuild<
|
||||
Store,
|
||||
Vault,
|
||||
{
|
||||
disabled: string[] | false | string
|
||||
name: string
|
||||
description?: string | null
|
||||
warning?: string | null
|
||||
required: Required
|
||||
}
|
||||
>,
|
||||
aVariants: Variants<Type, Store, Vault> | Variants<Type, never, never>,
|
||||
) {
|
||||
return new Value<Type | null | undefined, Store, Vault>(async (options) => {
|
||||
const newValues = await getA(options)
|
||||
return {
|
||||
type: "union" as const,
|
||||
description: null,
|
||||
warning: null,
|
||||
...newValues,
|
||||
variants: await aVariants.build(options as any),
|
||||
...requiredLikeToAbove(newValues.required),
|
||||
immutable: false,
|
||||
}
|
||||
}, aVariants.validator.optional())
|
||||
}
|
||||
|
||||
static list<Type, Store, Vault>(a: List<Type, Store, Vault>) {
|
||||
return new Value<Type, Store, Vault>(
|
||||
|
||||
@@ -562,6 +562,74 @@ describe("values", () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
test("dynamic union", async () => {
|
||||
const value = Value.dynamicUnion(
|
||||
() => ({
|
||||
disabled: ["a", "c"],
|
||||
name: "Testing",
|
||||
required: { default: null },
|
||||
description: null,
|
||||
warning: null,
|
||||
}),
|
||||
Variants.of({
|
||||
a: {
|
||||
name: "a",
|
||||
spec: Config.of({
|
||||
b: Value.toggle({
|
||||
name: "b",
|
||||
description: null,
|
||||
warning: null,
|
||||
default: false,
|
||||
}),
|
||||
}),
|
||||
},
|
||||
b: {
|
||||
name: "b",
|
||||
spec: Config.of({
|
||||
b: Value.toggle({
|
||||
name: "b",
|
||||
description: null,
|
||||
warning: null,
|
||||
default: false,
|
||||
}),
|
||||
}),
|
||||
},
|
||||
}),
|
||||
)
|
||||
const validator = value.validator
|
||||
validator.unsafeCast({ unionSelectKey: "a", unionValueKey: { b: false } })
|
||||
type Test = typeof validator._TYPE
|
||||
testOutput<
|
||||
Test,
|
||||
| { unionSelectKey: "a"; unionValueKey: { b: boolean } }
|
||||
| { unionSelectKey: "b"; unionValueKey: { b: boolean } }
|
||||
| null
|
||||
| undefined
|
||||
>()(null)
|
||||
|
||||
const built = await value.build({} as any)
|
||||
expect(built).toMatchObject({
|
||||
name: "Testing",
|
||||
variants: {
|
||||
b: {},
|
||||
},
|
||||
})
|
||||
expect(built).toMatchObject({
|
||||
name: "Testing",
|
||||
variants: {
|
||||
a: {},
|
||||
b: {},
|
||||
},
|
||||
})
|
||||
expect(built).toMatchObject({
|
||||
name: "Testing",
|
||||
variants: {
|
||||
a: {},
|
||||
b: {},
|
||||
},
|
||||
disabled: ["a", "c"],
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("Builder List", () => {
|
||||
|
||||
Reference in New Issue
Block a user