mirror of
https://github.com/Start9Labs/start-sdk.git
synced 2026-03-30 12:21:57 +00:00
feat: creating the rest of the sdk
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
import { ValueSpec } from "../configTypes"
|
||||
import { Utils } from "../../util"
|
||||
import { Utils } from "../../util/utils"
|
||||
import { Value } from "./value"
|
||||
import { _ } from "../../util"
|
||||
import { Effects } from "../../types"
|
||||
import { Parser, object } from "ts-matches"
|
||||
|
||||
export type LazyBuildOptions<WD> = {
|
||||
export type LazyBuildOptions<Store> = {
|
||||
effects: Effects
|
||||
utils: Utils<WD>
|
||||
utils: Utils<Store>
|
||||
}
|
||||
export type LazyBuild<WD, ExpectedOut> = (
|
||||
options: LazyBuildOptions<WD>,
|
||||
export type LazyBuild<Store, ExpectedOut> = (
|
||||
options: LazyBuildOptions<Store>,
|
||||
) => Promise<ExpectedOut> | ExpectedOut
|
||||
|
||||
// prettier-ignore
|
||||
@@ -18,8 +18,8 @@ export type ExtractConfigType<A extends Record<string, any> | Config<Record<stri
|
||||
A extends Config<infer B, any> | Config<infer B, never> ? B :
|
||||
A
|
||||
|
||||
export type ConfigSpecOf<A extends Record<string, any>, WD = never> = {
|
||||
[K in keyof A]: Value<A[K], WD>
|
||||
export type ConfigSpecOf<A extends Record<string, any>, Store = never> = {
|
||||
[K in keyof A]: Value<A[K], Store>
|
||||
}
|
||||
|
||||
export type MaybeLazyValues<A> = LazyBuild<any, A> | A
|
||||
@@ -79,14 +79,14 @@ export const addNodesSpec = Config.of({ hostname: hostname, port: port });
|
||||
|
||||
```
|
||||
*/
|
||||
export class Config<Type extends Record<string, any>, WD> {
|
||||
export class Config<Type extends Record<string, any>, Store> {
|
||||
private constructor(
|
||||
private readonly spec: {
|
||||
[K in keyof Type]: Value<Type[K], WD> | Value<Type[K], never>
|
||||
[K in keyof Type]: Value<Type[K], Store> | Value<Type[K], never>
|
||||
},
|
||||
public validator: Parser<unknown, Type>,
|
||||
) {}
|
||||
async build(options: LazyBuildOptions<WD>) {
|
||||
async build(options: LazyBuildOptions<Store>) {
|
||||
const answer = {} as {
|
||||
[K in keyof Type]: ValueSpec
|
||||
}
|
||||
@@ -96,9 +96,10 @@ export class Config<Type extends Record<string, any>, WD> {
|
||||
return answer
|
||||
}
|
||||
|
||||
static of<Spec extends Record<string, Value<any, any> | Value<any, never>>>(
|
||||
spec: Spec,
|
||||
) {
|
||||
static of<
|
||||
Spec extends Record<string, Value<any, Store> | Value<any, never>>,
|
||||
Store,
|
||||
>(spec: Spec) {
|
||||
const validatorObj = {} as {
|
||||
[K in keyof Spec]: Parser<unknown, any>
|
||||
}
|
||||
@@ -109,14 +110,12 @@ export class Config<Type extends Record<string, any>, WD> {
|
||||
return new Config<
|
||||
{
|
||||
[K in keyof Spec]: Spec[K] extends
|
||||
| Value<infer T, any>
|
||||
| Value<infer T, Store>
|
||||
| Value<infer T, never>
|
||||
? T
|
||||
: never
|
||||
},
|
||||
{
|
||||
[K in keyof Spec]: Spec[K] extends Value<any, infer WD> ? WD : never
|
||||
}[keyof Spec]
|
||||
Store
|
||||
>(spec, validator as any)
|
||||
}
|
||||
|
||||
@@ -129,12 +128,12 @@ export class Config<Type extends Record<string, any>, WD> {
|
||||
required: false,
|
||||
})
|
||||
|
||||
return Config.of<WrapperData>()({
|
||||
myValue: a.withWrapperData(),
|
||||
return Config.of<Store>()({
|
||||
myValue: a.withStore(),
|
||||
})
|
||||
```
|
||||
*/
|
||||
withWrapperData<NewWrapperData extends WD extends never ? any : WD>() {
|
||||
return this as any as Config<Type, NewWrapperData>
|
||||
withStore<NewStore extends Store extends never ? any : Store>() {
|
||||
return this as any as Config<Type, NewStore>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
ValueSpecText,
|
||||
} from "../configTypes"
|
||||
import { Parser, arrayOf, number, string } from "ts-matches"
|
||||
import { WrapperDataContract } from "../../wrapperData/wrapperDataContract"
|
||||
/**
|
||||
* Used as a subtype of Value.list
|
||||
```ts
|
||||
@@ -23,9 +22,9 @@ export const authorizationList = List.string({
|
||||
export const auth = Value.list(authorizationList);
|
||||
```
|
||||
*/
|
||||
export class List<Type, WD> {
|
||||
export class List<Type, Store> {
|
||||
private constructor(
|
||||
public build: LazyBuild<WD, ValueSpecList>,
|
||||
public build: LazyBuild<Store, ValueSpecList>,
|
||||
public validator: Parser<unknown, Type>,
|
||||
) {}
|
||||
static text(
|
||||
@@ -74,10 +73,9 @@ export class List<Type, WD> {
|
||||
} satisfies ValueSpecListOf<"text">
|
||||
}, arrayOf(string))
|
||||
}
|
||||
static dynamicText<WD = never>(
|
||||
_wrapperDataContract: WrapperDataContract<WD>,
|
||||
static dynamicText<Store = never>(
|
||||
getA: LazyBuild<
|
||||
WD,
|
||||
Store,
|
||||
{
|
||||
name: string
|
||||
description?: string | null
|
||||
@@ -101,7 +99,7 @@ export class List<Type, WD> {
|
||||
}
|
||||
>,
|
||||
) {
|
||||
return new List<string[], WD>(async (options) => {
|
||||
return new List<string[], Store>(async (options) => {
|
||||
const { spec: aSpec, ...a } = await getA(options)
|
||||
const spec = {
|
||||
type: "text" as const,
|
||||
@@ -168,10 +166,9 @@ export class List<Type, WD> {
|
||||
} satisfies ValueSpecListOf<"number">
|
||||
}, arrayOf(number))
|
||||
}
|
||||
static dynamicNumber<WD = never>(
|
||||
_wrapperDataContract: WrapperDataContract<WD>,
|
||||
static dynamicNumber<Store = never>(
|
||||
getA: LazyBuild<
|
||||
WD,
|
||||
Store,
|
||||
{
|
||||
name: string
|
||||
description?: string | null
|
||||
@@ -192,7 +189,7 @@ export class List<Type, WD> {
|
||||
}
|
||||
>,
|
||||
) {
|
||||
return new List<number[], WD>(async (options) => {
|
||||
return new List<number[], Store>(async (options) => {
|
||||
const { spec: aSpec, ...a } = await getA(options)
|
||||
const spec = {
|
||||
type: "number" as const,
|
||||
@@ -216,7 +213,7 @@ export class List<Type, WD> {
|
||||
}
|
||||
}, arrayOf(number))
|
||||
}
|
||||
static obj<Type extends Record<string, any>, WrapperData>(
|
||||
static obj<Type extends Record<string, any>, Store>(
|
||||
a: {
|
||||
name: string
|
||||
description?: string | null
|
||||
@@ -227,12 +224,12 @@ export class List<Type, WD> {
|
||||
maxLength?: number | null
|
||||
},
|
||||
aSpec: {
|
||||
spec: Config<Type, WrapperData>
|
||||
spec: Config<Type, Store>
|
||||
displayAs?: null | string
|
||||
uniqueBy?: null | UniqueBy
|
||||
},
|
||||
) {
|
||||
return new List<Type[], WrapperData>(async (options) => {
|
||||
return new List<Type[], Store>(async (options) => {
|
||||
const { spec: previousSpecSpec, ...restSpec } = aSpec
|
||||
const specSpec = await previousSpecSpec.build(options)
|
||||
const spec = {
|
||||
@@ -268,12 +265,12 @@ export class List<Type, WD> {
|
||||
required: false,
|
||||
})
|
||||
|
||||
return Config.of<WrapperData>()({
|
||||
myValue: a.withWrapperData(),
|
||||
return Config.of<Store>()({
|
||||
myValue: a.withStore(),
|
||||
})
|
||||
```
|
||||
*/
|
||||
withWrapperData<NewWrapperData extends WD extends never ? any : WD>() {
|
||||
return this as any as List<Type, NewWrapperData>
|
||||
withStore<NewStore extends Store extends never ? any : Store>() {
|
||||
return this as any as List<Type, NewStore>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,9 +94,9 @@ const username = Value.string({
|
||||
});
|
||||
```
|
||||
*/
|
||||
export class Value<Type, WD> {
|
||||
export class Value<Type, Store> {
|
||||
protected constructor(
|
||||
public build: LazyBuild<WD, ValueSpec>,
|
||||
public build: LazyBuild<Store, ValueSpec>,
|
||||
public validator: Parser<unknown, Type>,
|
||||
) {}
|
||||
static toggle(a: {
|
||||
@@ -120,9 +120,9 @@ export class Value<Type, WD> {
|
||||
boolean,
|
||||
)
|
||||
}
|
||||
static dynamicToggle<WD = never>(
|
||||
static dynamicToggle<Store = never>(
|
||||
a: LazyBuild<
|
||||
WD,
|
||||
Store,
|
||||
{
|
||||
name: string
|
||||
description?: string | null
|
||||
@@ -132,7 +132,7 @@ export class Value<Type, WD> {
|
||||
}
|
||||
>,
|
||||
) {
|
||||
return new Value<boolean, WD>(
|
||||
return new Value<boolean, Store>(
|
||||
async (options) => ({
|
||||
description: null,
|
||||
warning: null,
|
||||
@@ -183,9 +183,9 @@ export class Value<Type, WD> {
|
||||
asRequiredParser(string, a),
|
||||
)
|
||||
}
|
||||
static dynamicText<WD = never>(
|
||||
static dynamicText<Store = never>(
|
||||
getA: LazyBuild<
|
||||
WD,
|
||||
Store,
|
||||
{
|
||||
name: string
|
||||
description?: string | null
|
||||
@@ -204,7 +204,7 @@ export class Value<Type, WD> {
|
||||
}
|
||||
>,
|
||||
) {
|
||||
return new Value<string | null | undefined, WD>(async (options) => {
|
||||
return new Value<string | null | undefined, Store>(async (options) => {
|
||||
const a = await getA(options)
|
||||
return {
|
||||
type: "text" as const,
|
||||
@@ -254,9 +254,9 @@ export class Value<Type, WD> {
|
||||
string,
|
||||
)
|
||||
}
|
||||
static dynamicTextarea<WD = never>(
|
||||
static dynamicTextarea<Store = never>(
|
||||
getA: LazyBuild<
|
||||
WD,
|
||||
Store,
|
||||
{
|
||||
name: string
|
||||
description?: string | null
|
||||
@@ -270,7 +270,7 @@ export class Value<Type, WD> {
|
||||
}
|
||||
>,
|
||||
) {
|
||||
return new Value<string, WD>(async (options) => {
|
||||
return new Value<string, Store>(async (options) => {
|
||||
const a = await getA(options)
|
||||
return {
|
||||
description: null,
|
||||
@@ -320,9 +320,9 @@ export class Value<Type, WD> {
|
||||
asRequiredParser(number, a),
|
||||
)
|
||||
}
|
||||
static dynamicNumber<WD = never>(
|
||||
static dynamicNumber<Store = never>(
|
||||
getA: LazyBuild<
|
||||
WD,
|
||||
Store,
|
||||
{
|
||||
name: string
|
||||
description?: string | null
|
||||
@@ -339,7 +339,7 @@ export class Value<Type, WD> {
|
||||
}
|
||||
>,
|
||||
) {
|
||||
return new Value<number | null | undefined, WD>(async (options) => {
|
||||
return new Value<number | null | undefined, Store>(async (options) => {
|
||||
const a = await getA(options)
|
||||
return {
|
||||
type: "number" as const,
|
||||
@@ -381,9 +381,9 @@ export class Value<Type, WD> {
|
||||
)
|
||||
}
|
||||
|
||||
static dynamicColor<WD = never>(
|
||||
static dynamicColor<Store = never>(
|
||||
getA: LazyBuild<
|
||||
WD,
|
||||
Store,
|
||||
{
|
||||
name: string
|
||||
description?: string | null
|
||||
@@ -394,7 +394,7 @@ export class Value<Type, WD> {
|
||||
}
|
||||
>,
|
||||
) {
|
||||
return new Value<string | null | undefined, WD>(async (options) => {
|
||||
return new Value<string | null | undefined, Store>(async (options) => {
|
||||
const a = await getA(options)
|
||||
return {
|
||||
type: "color" as const,
|
||||
@@ -438,9 +438,9 @@ export class Value<Type, WD> {
|
||||
asRequiredParser(string, a),
|
||||
)
|
||||
}
|
||||
static dynamicDatetime<WD = never>(
|
||||
static dynamicDatetime<Store = never>(
|
||||
getA: LazyBuild<
|
||||
WD,
|
||||
Store,
|
||||
{
|
||||
name: string
|
||||
description?: string | null
|
||||
@@ -455,7 +455,7 @@ export class Value<Type, WD> {
|
||||
}
|
||||
>,
|
||||
) {
|
||||
return new Value<string | null | undefined, WD>(async (options) => {
|
||||
return new Value<string | null | undefined, Store>(async (options) => {
|
||||
const a = await getA(options)
|
||||
return {
|
||||
type: "datetime" as const,
|
||||
@@ -503,9 +503,9 @@ export class Value<Type, WD> {
|
||||
) as any,
|
||||
)
|
||||
}
|
||||
static dynamicSelect<WD = never>(
|
||||
static dynamicSelect<Store = never>(
|
||||
getA: LazyBuild<
|
||||
WD,
|
||||
Store,
|
||||
{
|
||||
name: string
|
||||
description?: string | null
|
||||
@@ -516,7 +516,7 @@ export class Value<Type, WD> {
|
||||
}
|
||||
>,
|
||||
) {
|
||||
return new Value<string | null | undefined, WD>(async (options) => {
|
||||
return new Value<string | null | undefined, Store>(async (options) => {
|
||||
const a = await getA(options)
|
||||
return {
|
||||
description: null,
|
||||
@@ -557,9 +557,9 @@ export class Value<Type, WD> {
|
||||
),
|
||||
)
|
||||
}
|
||||
static dynamicMultiselect<WD = never>(
|
||||
static dynamicMultiselect<Store = never>(
|
||||
getA: LazyBuild<
|
||||
WD,
|
||||
Store,
|
||||
{
|
||||
name: string
|
||||
description?: string | null
|
||||
@@ -572,7 +572,7 @@ export class Value<Type, WD> {
|
||||
}
|
||||
>,
|
||||
) {
|
||||
return new Value<string[], WD>(async (options) => {
|
||||
return new Value<string[], Store>(async (options) => {
|
||||
const a = await getA(options)
|
||||
return {
|
||||
type: "multiselect" as const,
|
||||
@@ -586,15 +586,15 @@ export class Value<Type, WD> {
|
||||
}
|
||||
}, arrayOf(string))
|
||||
}
|
||||
static object<Type extends Record<string, any>, WrapperData>(
|
||||
static object<Type extends Record<string, any>, Store>(
|
||||
a: {
|
||||
name: string
|
||||
description?: string | null
|
||||
warning?: string | null
|
||||
},
|
||||
previousSpec: Config<Type, WrapperData>,
|
||||
previousSpec: Config<Type, Store>,
|
||||
) {
|
||||
return new Value<Type, WrapperData>(async (options) => {
|
||||
return new Value<Type, Store>(async (options) => {
|
||||
const spec = await previousSpec.build(options as any)
|
||||
return {
|
||||
type: "object" as const,
|
||||
@@ -605,7 +605,7 @@ export class Value<Type, WD> {
|
||||
}
|
||||
}, previousSpec.validator)
|
||||
}
|
||||
static union<Required extends RequiredDefault<string>, Type, WrapperData>(
|
||||
static union<Required extends RequiredDefault<string>, Type, Store>(
|
||||
a: {
|
||||
name: string
|
||||
description?: string | null
|
||||
@@ -615,9 +615,9 @@ export class Value<Type, WD> {
|
||||
Default is false */
|
||||
immutable?: boolean
|
||||
},
|
||||
aVariants: Variants<Type, WrapperData>,
|
||||
aVariants: Variants<Type, Store>,
|
||||
) {
|
||||
return new Value<AsRequired<Type, Required>, WrapperData>(
|
||||
return new Value<AsRequired<Type, Required>, Store>(
|
||||
async (options) => ({
|
||||
type: "union" as const,
|
||||
description: null,
|
||||
@@ -633,18 +633,18 @@ export class Value<Type, WD> {
|
||||
static filteredUnion<
|
||||
Required extends RequiredDefault<string>,
|
||||
Type extends Record<string, any>,
|
||||
WD = never,
|
||||
Store = never,
|
||||
>(
|
||||
getDisabledFn: LazyBuild<WD, string[]>,
|
||||
getDisabledFn: LazyBuild<Store, string[]>,
|
||||
a: {
|
||||
name: string
|
||||
description?: string | null
|
||||
warning?: string | null
|
||||
required: Required
|
||||
},
|
||||
aVariants: Variants<Type, WD> | Variants<Type, never>,
|
||||
aVariants: Variants<Type, Store> | Variants<Type, never>,
|
||||
) {
|
||||
return new Value<AsRequired<Type, Required>, WD>(
|
||||
return new Value<AsRequired<Type, Required>, Store>(
|
||||
async (options) => ({
|
||||
type: "union" as const,
|
||||
description: null,
|
||||
@@ -659,11 +659,8 @@ export class Value<Type, WD> {
|
||||
)
|
||||
}
|
||||
|
||||
static list<Type, WrapperData>(a: List<Type, WrapperData>) {
|
||||
return new Value<Type, WrapperData>(
|
||||
(options) => a.build(options),
|
||||
a.validator,
|
||||
)
|
||||
static list<Type, Store>(a: List<Type, Store>) {
|
||||
return new Value<Type, Store>((options) => a.build(options), a.validator)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -675,12 +672,12 @@ export class Value<Type, WD> {
|
||||
required: false,
|
||||
})
|
||||
|
||||
return Config.of<WrapperData>()({
|
||||
myValue: a.withWrapperData(),
|
||||
return Config.of<Store>()({
|
||||
myValue: a.withStore(),
|
||||
})
|
||||
```
|
||||
*/
|
||||
withWrapperData<NewWrapperData extends WD extends never ? any : WD>() {
|
||||
return this as any as Value<Type, NewWrapperData>
|
||||
withStore<NewStore extends Store extends never ? any : Store>() {
|
||||
return this as any as Value<Type, NewStore>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,24 +51,20 @@ export const pruning = Value.union(
|
||||
);
|
||||
```
|
||||
*/
|
||||
export class Variants<Type, WD> {
|
||||
export class Variants<Type, Store> {
|
||||
static text: any
|
||||
private constructor(
|
||||
public build: LazyBuild<WD, ValueSpecUnion["variants"]>,
|
||||
public build: LazyBuild<Store, ValueSpecUnion["variants"]>,
|
||||
public validator: Parser<unknown, Type>,
|
||||
) {}
|
||||
// A extends {
|
||||
// [key: string]: {
|
||||
// name: string
|
||||
// spec: InputSpec
|
||||
// }
|
||||
// },
|
||||
static of<
|
||||
VariantValues extends {
|
||||
[K in string]: {
|
||||
name: string
|
||||
spec: Config<any, any> | Config<any, never>
|
||||
spec: Config<any, Store> | Config<any, never>
|
||||
}
|
||||
},
|
||||
Store,
|
||||
>(a: VariantValues) {
|
||||
const validator = anyOf(
|
||||
...Object.entries(a).map(([name, { spec }]) =>
|
||||
@@ -83,21 +79,13 @@ export class Variants<Type, WD> {
|
||||
{
|
||||
[K in keyof VariantValues]: {
|
||||
unionSelectKey: K
|
||||
unionValueKey: VariantValues[K]["spec"] extends
|
||||
| Config<infer B, any>
|
||||
| Config<infer B, never>
|
||||
? B
|
||||
: never
|
||||
// prettier-ignore
|
||||
unionValueKey:
|
||||
VariantValues[K]["spec"] extends (Config<infer B, Store> | Config<infer B, never>) ? B :
|
||||
never
|
||||
}
|
||||
}[keyof VariantValues],
|
||||
{
|
||||
[K in keyof VariantValues]: VariantValues[K] extends Config<
|
||||
any,
|
||||
infer C
|
||||
>
|
||||
? C
|
||||
: never
|
||||
}[keyof VariantValues]
|
||||
Store
|
||||
>(async (options) => {
|
||||
const variants = {} as {
|
||||
[K in keyof VariantValues]: { name: string; spec: InputSpec }
|
||||
@@ -121,12 +109,12 @@ export class Variants<Type, WD> {
|
||||
required: false,
|
||||
})
|
||||
|
||||
return Config.of<WrapperData>()({
|
||||
myValue: a.withWrapperData(),
|
||||
return Config.of<Store>()({
|
||||
myValue: a.withStore(),
|
||||
})
|
||||
```
|
||||
*/
|
||||
withWrapperData<NewWrapperData extends WD extends never ? any : WD>() {
|
||||
return this as any as Variants<Type, NewWrapperData>
|
||||
withStore<NewStore extends Store extends never ? any : Store>() {
|
||||
return this as any as Variants<Type, NewStore>
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user