chore: Fix the tests and add new types for raw

This commit is contained in:
BluJ
2023-04-05 13:51:43 -06:00
parent b8d6addf28
commit 45192e0358
19 changed files with 222 additions and 376 deletions

View File

@@ -1,4 +1,4 @@
import { InputSpec, ValueSpec } from "../config-types";
import { InputSpec, ValueSpec } from "../configTypes";
import { typeFromProps } from "../../util";
import { BuilderExtract, IBuilder } from "./builder";
import { Value } from "./value";
@@ -63,16 +63,10 @@ export class Config<A extends InputSpec> extends IBuilder<A> {
static empty() {
return new Config({});
}
static withValue<K extends string, B extends ValueSpec>(
key: K,
value: Value<B>
) {
static withValue<K extends string, B extends ValueSpec>(key: K, value: Value<B>) {
return Config.empty().withValue(key, value);
}
static addValue<K extends string, B extends ValueSpec>(
key: K,
value: Value<B>
) {
static addValue<K extends string, B extends ValueSpec>(key: K, value: Value<B>) {
return Config.empty().withValue(key, value);
}

View File

@@ -1,6 +1,6 @@
import { BuilderExtract, IBuilder } from "./builder";
import { Config } from "./config";
import { InputSpec, ListValueSpecNumber, ListValueSpecString, UniqueBy, ValueSpecList } from "../config-types";
import { InputSpec, ListValueSpecNumber, ListValueSpecString, UniqueBy, ValueSpecList } from "../configTypes";
import { guardAll } from "../../util";
/**
* Used as a subtype of Value.list

View File

@@ -9,9 +9,9 @@ import {
ValueSpecList,
ValueSpecNumber,
ValueSpecTextarea,
} from "../config-types";
} from "../configTypes";
import { guardAll } from "../../util";
import { DefaultString } from "../config-types";
import { DefaultString } from "../configTypes";
/**
* A value is going to be part of the form in the FE of the OS.
* Something like a boolean, a string, a number, etc.
@@ -35,12 +35,7 @@ const username = Value.string({
```
*/
export class Value<A extends ValueSpec> extends IBuilder<A> {
static boolean(a: {
name: string;
description?: string | null;
warning?: string | null;
default?: boolean | null;
}) {
static boolean(a: { name: string; description?: string | null; warning?: string | null; default?: boolean | null }) {
return new Value({
description: null,
warning: null,
@@ -166,9 +161,7 @@ export class Value<A extends ValueSpec> extends IBuilder<A> {
spec,
});
}
static union<
V extends Variants<{ [key: string]: { name: string; spec: InputSpec } }>
>(
static union<V extends Variants<{ [key: string]: { name: string; spec: InputSpec } }>>(
a: {
name: string;
description?: string | null;

View File

@@ -1,4 +1,4 @@
import { InputSpec } from "../config-types";
import { InputSpec } from "../configTypes";
import { BuilderExtract, IBuilder } from "./builder";
import { Config } from ".";
@@ -80,10 +80,7 @@ export class Variants<
static empty() {
return Variants.of({});
}
static withVariant<K extends string, B extends InputSpec>(
key: K,
value: Config<B>
) {
static withVariant<K extends string, B extends InputSpec>(key: K, value: Config<B>) {
return Variants.empty().withVariant(key, value);
}

53
lib/config/configTypes.ts Normal file
View File

@@ -0,0 +1,53 @@
import * as C from "./configTypesRaw";
export type ValueType = C.ValueType;
// prettier-ignore
export type WithOutOptionals<A> =
A extends Record<string | number, unknown> ? {[k in keyof A]: A[k]} :
A;
export type InputSpec = Record<string, WithOutOptionals<C.ValueSpec>>;
export type ValueSpec = WithOutOptionals<C.ValueSpec>;
/** core spec types. These types provide the metadata for performing validations */
export type ValueSpecOf<T extends ValueType> = WithOutOptionals<C.ValueSpecOf<T>>;
export type ValueSpecString = WithOutOptionals<C.ValueSpecString>;
export type ValueSpecTextarea = WithOutOptionals<C.ValueSpecTextarea>;
export type ValueSpecNumber = WithOutOptionals<C.ValueSpecNumber>;
export type ValueSpecSelect = WithOutOptionals<C.ValueSpecSelect>;
export type ValueSpecMultiselect = WithOutOptionals<C.ValueSpecMultiselect>;
export type ValueSpecBoolean = WithOutOptionals<C.ValueSpecBoolean>;
export type ValueSpecUnion = WithOutOptionals<C.ValueSpecUnion>;
export type ValueSpecFile = WithOutOptionals<C.ValueSpecFile>;
export type ValueSpecObject = WithOutOptionals<C.ValueSpecObject>;
export type WithStandalone = WithOutOptionals<C.WithStandalone>;
export type SelectBase = WithOutOptionals<C.SelectBase>;
export type ListValueSpecType = WithOutOptionals<C.ListValueSpecType>;
/** represents a spec for the values of a list */
export type ListValueSpecOf<T extends ListValueSpecType> = WithOutOptionals<C.ListValueSpecOf<T>>;
/** represents a spec for a list */
export type ValueSpecList = WithOutOptionals<C.ValueSpecList>;
export type ValueSpecListOf<T extends ListValueSpecType> = WithOutOptionals<C.ValueSpecListOf<T>>;
// sometimes the type checker needs just a little bit of help
export function isValueSpecListOf<S extends ListValueSpecType>(
t: ValueSpecListOf<ListValueSpecType>,
s: S
): t is ValueSpecListOf<S> & { spec: ListValueSpecOf<S> } {
return t.spec.type === s;
}
export type ListValueSpecString = WithOutOptionals<C.ListValueSpecString>;
export type ListValueSpecNumber = WithOutOptionals<C.ListValueSpecNumber>;
export type ListValueSpecObject = WithOutOptionals<C.ListValueSpecObject>;
export type UniqueBy = WithOutOptionals<C.UniqueBy>;
export type DefaultString = WithOutOptionals<C.DefaultString>;
export const unionSelectKey = "unionSelectKey" as const;
export type UnionSelectKey = typeof unionSelectKey;
export const unionValueKey = "unionValueKey" as const;
export type UnionValueKey = typeof unionValueKey;

View File

@@ -1,5 +1,4 @@
export type InputSpec = Record<string, ValueSpec>;
export type InputSpecRaw = Record<string, ValueSpec>;
export type ValueType =
| "string"
| "textarea"
@@ -12,7 +11,6 @@ export type ValueType =
| "file"
| "union";
export type ValueSpec = ValueSpecOf<ValueType>;
/** core spec types. These types provide the metadata for performing validations */
export type ValueSpecOf<T extends ValueType> = T extends "string"
? ValueSpecString
@@ -35,71 +33,64 @@ export type ValueSpecOf<T extends ValueType> = T extends "string"
: T extends "union"
? ValueSpecUnion
: never;
export interface ValueSpecString extends ListValueSpecString, WithStandalone {
required: boolean;
default: DefaultString | null;
default?: DefaultString | null;
}
export interface ValueSpecTextarea extends WithStandalone {
type: "textarea";
placeholder: string | null;
placeholder?: string | null;
required: boolean;
}
export interface ValueSpecNumber extends ListValueSpecNumber, WithStandalone {
required: boolean;
default: number | null;
default?: number | null;
}
export interface ValueSpecSelect extends SelectBase, WithStandalone {
type: "select";
required: boolean;
default: string | null;
default?: string | null;
}
export interface ValueSpecMultiselect extends SelectBase, WithStandalone {
type: "multiselect";
/**'[0,1]' (inclusive) OR '[0,*)' (right unbounded), normal math rules */
range: string;
default: string[];
range?: string;
default?: string[];
}
export interface ValueSpecBoolean extends WithStandalone {
type: "boolean";
default: boolean | null;
default?: boolean | null;
}
export interface ValueSpecUnion extends WithStandalone {
type: "union";
variants: Record<string, { name: string; spec: InputSpec }>;
variants: Record<
string,
{
name: string;
spec: InputSpecRaw;
}
>;
required: boolean;
default: string | null;
default?: string | null;
}
export interface ValueSpecFile extends WithStandalone {
type: "file";
extensions: string[];
required: boolean;
}
export interface ValueSpecObject extends WithStandalone {
type: "object";
spec: InputSpec;
spec: InputSpecRaw;
}
export interface WithStandalone {
name: string;
description: string | null;
warning: string | null;
description?: string | null;
warning?: string | null;
}
export interface SelectBase {
values: Record<string, string>;
}
export type ListValueSpecType = "string" | "number" | "object";
/** represents a spec for the values of a list */
export type ListValueSpecOf<T extends ListValueSpecType> = T extends "string"
? ListValueSpecString
@@ -108,15 +99,13 @@ export type ListValueSpecOf<T extends ListValueSpecType> = T extends "string"
: 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 interface ValueSpecListOf<T extends ListValueSpecType> extends WithStandalone {
type: "list";
spec: ListValueSpecOf<T>;
range: string; // '[0,1]' (inclusive) OR '[0,*)' (right unbounded), normal math rules
default:
range?: string;
default?:
| string[]
| number[]
| DefaultString[]
@@ -126,53 +115,48 @@ export interface ValueSpecListOf<T extends ListValueSpecType>
| readonly DefaultString[]
| readonly Record<string, unknown>[];
}
// sometimes the type checker needs just a little bit of help
export function isValueSpecListOf<S extends ListValueSpecType>(
export declare function isValueSpecListOf<S extends ListValueSpecType>(
t: ValueSpecListOf<ListValueSpecType>,
s: S
): t is ValueSpecListOf<S> & { spec: ListValueSpecOf<S> } {
return t.spec.type === s;
}
): t is ValueSpecListOf<S> & {
spec: ListValueSpecOf<S>;
};
export interface ListValueSpecString {
type: "string";
pattern: string | null;
patternDescription: string | null;
masked: boolean; // default = false
inputmode: "text" | "email" | "tel" | "url"; // default = 'text'
placeholder: string | null;
pattern?: string | null;
patternDescription?: string | null;
masked?: boolean;
inputmode?: "text" | "email" | "tel" | "url";
placeholder?: string | null;
}
export interface ListValueSpecNumber {
type: "number";
/** '[0,1]' (inclusive) OR '[0,*)' (right unbounded), normal math rules */
range: string;
integral: boolean; // default = false
units: string | null;
placeholder: string | null;
range?: string;
integral: boolean;
units?: string | null;
placeholder?: string | null;
}
export interface 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;
spec: InputSpecRaw;
/** indicates whether duplicates can be permitted in the list */
uniqueBy: UniqueBy;
/** this should be a handlebars template which can make use of the entire config which corresponds to 'spec' */
displayAs: string | null;
displayAs?: string | null;
}
export type UniqueBy =
| null
| string
| { any: readonly UniqueBy[] | UniqueBy[] }
| { all: readonly UniqueBy[] | UniqueBy[] };
export type DefaultString = string | { charset: string; len: number };
export declare const unionSelectKey: "unionSelectKey";
export type UnionSelectKey = typeof unionSelectKey;
export declare const unionValueKey: "unionValueKey";
export type UnionValueKey = typeof unionValueKey;
| {
any: readonly UniqueBy[] | UniqueBy[];
}
| {
all: readonly UniqueBy[] | UniqueBy[];
};
export type DefaultString =
| string
| {
charset: string;
len: number;
};

View File

@@ -1,3 +1,3 @@
export * as configBuilder from "./builder";
export { setupConfigExports } from "./setup_config_export";
export { setupConfigExports } from "./setupConfigExports";

View File

@@ -1,6 +1,6 @@
import { Config } from "./builder";
import { DeepPartial, DependsOn, Effects, ExpectedExports } from "../types";
import { InputSpec } from "./config-types";
import { InputSpec } from "./configTypes";
import { nullIfEmpty } from "../util";
import { TypeFromProps } from "../util/propertiesMatcher";