port 040 config (#2657)

* port 040 config, WIP

* update fixtures

* use taiga modal for backups too

* fix: update Taiga UI and refactor everything to work

* chore: package-lock

* fix interfaces and mocks for interfaces

* better mocks

* function to transform old spec to new

* delete unused fns

* delete unused FE config utils

* fix exports from sdk

* reorganize exports

* functions to translate config

* rename unionSelectKey and unionValueKey

* Adding in the transformation of the getConfig to the new types.

* chore: add Taiga UI to preloader

---------

Co-authored-by: waterplea <alexander@inkin.ru>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: J H <dragondef@gmail.com>
This commit is contained in:
Matt Hill
2024-07-10 11:58:02 -06:00
committed by GitHub
parent 822dd5e100
commit f76e822381
173 changed files with 9761 additions and 9200 deletions

View File

@@ -125,96 +125,6 @@ export class List<Type, Store> {
return built
}, arrayOf(string))
}
static number(
a: {
name: string
description?: string | null
warning?: string | null
/** Default = [] */
default?: string[]
minLength?: number | null
maxLength?: number | null
},
aSpec: {
integer: boolean
min?: number | null
max?: number | null
step?: number | null
units?: string | null
placeholder?: string | null
},
) {
return new List<number[], never>(() => {
const spec = {
type: "number" as const,
placeholder: null,
min: null,
max: null,
step: null,
units: null,
...aSpec,
}
const built: ValueSpecListOf<"number"> = {
description: null,
warning: null,
minLength: null,
maxLength: null,
default: [],
type: "list" as const,
disabled: false,
...a,
spec,
}
return built
}, arrayOf(number))
}
static dynamicNumber<Store = never>(
getA: LazyBuild<
Store,
{
name: string
description?: string | null
warning?: string | null
/** Default = [] */
default?: string[]
minLength?: number | null
maxLength?: number | null
disabled?: false | string
spec: {
integer: boolean
min?: number | null
max?: number | null
step?: number | null
units?: string | null
placeholder?: string | null
}
}
>,
) {
return new List<number[], Store>(async (options) => {
const { spec: aSpec, ...a } = await getA(options)
const spec = {
type: "number" as const,
placeholder: null,
min: null,
max: null,
step: null,
units: null,
...aSpec,
}
return {
description: null,
warning: null,
minLength: null,
maxLength: null,
default: [],
type: "list" as const,
disabled: false,
...a,
spec,
}
}, arrayOf(number))
}
static obj<Type extends Record<string, any>, Store>(
a: {
name: string

View File

@@ -69,8 +69,8 @@ export class Variants<Type, Store> {
const validator = anyOf(
...Object.entries(a).map(([name, { spec }]) =>
object({
unionSelectKey: literals(name),
unionValueKey: spec.validator,
selection: literals(name),
value: spec.validator,
}),
),
) as Parser<unknown, any>
@@ -78,9 +78,9 @@ export class Variants<Type, Store> {
return new Variants<
{
[K in keyof VariantValues]: {
unionSelectKey: K
selection: K
// prettier-ignore
unionValueKey:
value:
VariantValues[K]["spec"] extends (Config<infer B, Store> | Config<infer B, never>) ? B :
never
}

View File

@@ -15,70 +15,93 @@ export type ValueType =
export type ValueSpec = ValueSpecOf<ValueType>
/** core spec types. These types provide the metadata for performing validations */
// prettier-ignore
export type ValueSpecOf<T extends ValueType> = T extends "text"
? ValueSpecText
: T extends "textarea"
? ValueSpecTextarea
: T extends "number"
? ValueSpecNumber
: T extends "color"
? ValueSpecColor
: T extends "datetime"
? ValueSpecDatetime
: T extends "toggle"
? ValueSpecToggle
: T extends "select"
? ValueSpecSelect
: T extends "multiselect"
? ValueSpecMultiselect
: T extends "list"
? ValueSpecList
: T extends "object"
? ValueSpecObject
: T extends "file"
? ValueSpecFile
: T extends "union"
? ValueSpecUnion
: never
export type ValueSpecOf<T extends ValueType> =
T extends "text" ? ValueSpecText :
T extends "textarea" ? ValueSpecTextarea :
T extends "number" ? ValueSpecNumber :
T extends "color" ? ValueSpecColor :
T extends "datetime" ? ValueSpecDatetime :
T extends "toggle" ? ValueSpecToggle :
T extends "select" ? ValueSpecSelect :
T extends "multiselect" ? ValueSpecMultiselect :
T extends "list" ? ValueSpecList :
T extends "object" ? ValueSpecObject :
T extends "file" ? ValueSpecFile :
T extends "union" ? ValueSpecUnion :
never
export type ValueSpecText = {
name: string
description: string | null
warning: string | null
type: "text"
patterns: Pattern[]
minLength: number | null
maxLength: number | null
masked: boolean
inputmode: "text" | "email" | "tel" | "url"
placeholder: string | null
export interface ValueSpecText extends ListValueSpecText, WithStandalone {
required: boolean
default: DefaultString | null
disabled: false | string
generate: null | RandomString
/** Immutable means it can only be configed at the first config then never again */
/** Immutable means it can only be configured at the first config then never again */
immutable: boolean
}
export interface ValueSpecTextarea extends WithStandalone {
export type ValueSpecTextarea = {
name: string
description: string | null
warning: string | null
type: "textarea"
placeholder: string | null
minLength: number | null
maxLength: number | null
required: boolean
disabled: false | string
/** Immutable means it can only be configed at the first config then never again */
/** Immutable means it can only be configured at the first config then never again */
immutable: boolean
}
export type FilePath = {
filePath: string
}
export interface ValueSpecNumber extends ListValueSpecNumber, WithStandalone {
export type ValueSpecNumber = {
type: "number"
min: number | null
max: number | null
integer: boolean
step: number | null
units: string | null
placeholder: string | null
name: string
description: string | null
warning: string | null
required: boolean
default: number | null
disabled: false | string
/** Immutable means it can only be configed at the first config then never again */
/** Immutable means it can only be configured at the first config then never again */
immutable: boolean
}
export interface ValueSpecColor extends WithStandalone {
export type ValueSpecColor = {
name: string
description: string | null
warning: string | null
type: "color"
required: boolean
default: string | null
disabled: false | string
/** Immutable means it can only be configed at the first config then never again */
/** Immutable means it can only be configured at the first config then never again */
immutable: boolean
}
export interface ValueSpecDatetime extends WithStandalone {
export type ValueSpecDatetime = {
name: string
description: string | null
warning: string | null
type: "datetime"
required: boolean
inputmode: "date" | "time" | "datetime-local"
@@ -86,10 +109,14 @@ export interface ValueSpecDatetime extends WithStandalone {
max: string | null
default: string | null
disabled: false | string
/** Immutable means it can only be configed at the first config then never again */
/** Immutable means it can only be configured at the first config then never again */
immutable: boolean
}
export interface ValueSpecSelect extends SelectBase, WithStandalone {
export type ValueSpecSelect = {
values: Record<string, string>
name: string
description: string | null
warning: string | null
type: "select"
required: boolean
default: string | null
@@ -99,10 +126,16 @@ export interface ValueSpecSelect extends SelectBase, WithStandalone {
* string[] means that the options are disabled
*/
disabled: false | string | string[]
/** Immutable means it can only be configed at the first config then never again */
/** Immutable means it can only be configured at the first config then never again */
immutable: boolean
}
export interface ValueSpecMultiselect extends SelectBase, WithStandalone {
export type ValueSpecMultiselect = {
values: Record<string, string>
name: string
description: string | null
warning: string | null
type: "multiselect"
minLength: number | null
maxLength: number | null
@@ -113,17 +146,25 @@ export interface ValueSpecMultiselect extends SelectBase, WithStandalone {
*/
disabled: false | string | string[]
default: string[]
/** Immutable means it can only be configed at the first config then never again */
/** Immutable means it can only be configured at the first config then never again */
immutable: boolean
}
export interface ValueSpecToggle extends WithStandalone {
export type ValueSpecToggle = {
name: string
description: string | null
warning: string | null
type: "toggle"
default: boolean | null
disabled: false | string
/** Immutable means it can only be configed at the first config then never again */
/** Immutable means it can only be configured at the first config then never again */
immutable: boolean
}
export interface ValueSpecUnion extends WithStandalone {
export type ValueSpecUnion = {
name: string
description: string | null
warning: string | null
type: "union"
variants: Record<
string,
@@ -140,39 +181,37 @@ export interface ValueSpecUnion extends WithStandalone {
disabled: false | string | string[]
required: boolean
default: string | null
/** Immutable means it can only be configed at the first config then never again */
/** Immutable means it can only be configured at the first config then never again */
immutable: boolean
}
export interface ValueSpecFile extends WithStandalone {
export type ValueSpecFile = {
name: string
description: string | null
warning: string | null
type: "file"
extensions: string[]
required: boolean
}
export interface ValueSpecObject extends WithStandalone {
type: "object"
spec: InputSpec
}
export interface WithStandalone {
export type ValueSpecObject = {
name: string
description: string | null
warning: string | null
type: "object"
spec: InputSpec
}
export interface SelectBase {
values: Record<string, string>
}
export type ListValueSpecType = "text" | "number" | "object"
export type ListValueSpecType = "text" | "object"
/** represents a spec for the values of a list */
export type ListValueSpecOf<T extends ListValueSpecType> = T extends "text"
? ListValueSpecText
: T extends "number"
? ListValueSpecNumber
: T extends "object"
? ListValueSpecObject
: never
// prettier-ignore
export type ListValueSpecOf<T extends ListValueSpecType> =
T extends "text" ? ListValueSpecText :
T extends "object" ? ListValueSpecObject :
never
/** represents a spec for a list */
export type ValueSpecList = ValueSpecListOf<ListValueSpecType>
export interface ValueSpecListOf<T extends ListValueSpecType>
extends WithStandalone {
export type ValueSpecListOf<T extends ListValueSpecType> = {
name: string
description: string | null
warning: string | null
type: "list"
spec: ListValueSpecOf<T>
minLength: number | null
@@ -180,19 +219,17 @@ export interface ValueSpecListOf<T extends ListValueSpecType>
disabled: false | string
default:
| string[]
| number[]
| DefaultString[]
| Record<string, unknown>[]
| readonly string[]
| readonly number[]
| readonly DefaultString[]
| readonly Record<string, unknown>[]
}
export interface Pattern {
export type Pattern = {
regex: string
description: string
}
export interface ListValueSpecText {
export type ListValueSpecText = {
type: "text"
patterns: Pattern[]
minLength: number | null
@@ -203,16 +240,8 @@ export interface ListValueSpecText {
inputmode: "text" | "email" | "tel" | "url"
placeholder: string | null
}
export interface ListValueSpecNumber {
type: "number"
min: number | null
max: number | null
integer: boolean
step: number | null
units: string | null
placeholder: string | null
}
export interface ListValueSpecObject {
export type ListValueSpecObject = {
type: "object"
/** this is a mapped type of the config object at this level, replacing the object's values with specs on those values */
spec: InputSpec
@@ -242,8 +271,3 @@ export function isValueSpecListOf<S extends ListValueSpecType>(
): t is ValueSpecListOf<S> & { spec: ListValueSpecOf<S> } {
return "spec" in t && t.spec.type === s
}
export const unionSelectKey = "unionSelectKey" as const
export type UnionSelectKey = typeof unionSelectKey
export const unionValueKey = "unionValueKey" as const
export type UnionValueKey = typeof unionValueKey