wip: Convert all the requireds needed :fingers-crossed:

This commit is contained in:
BluJ
2023-04-27 08:33:41 -06:00
parent 333bddf345
commit d55cc40b33
3 changed files with 154 additions and 102 deletions

View File

@@ -66,16 +66,18 @@ const username = Value.string({
export class Value<A extends ValueSpec> extends IBuilder<A> {
static toggle(a: {
name: string;
description: string | null;
warning: string | null;
default: boolean | null;
description?: string | null;
warning?: string | null;
default?: boolean | null;
}) {
return new Value({
description: null,
warning: null,
default: null,
type: "toggle" as const,
...a,
});
}
static text<Required extends RequiredLike<DefaultString>>(a: {
name: string;
description?: string | null;
@@ -106,134 +108,160 @@ export class Value<A extends ValueSpec> extends IBuilder<A> {
}
static textarea(a: {
name: string;
description: string | null;
warning: string | null;
description?: string | null;
warning?: string | null;
required: boolean;
minLength: number | null;
maxLength: number | null;
placeholder: string | null;
minLength?: number | null;
maxLength?: number | null;
placeholder?: string | null;
}) {
return new Value({
description: null,
warning: null,
minLength: null,
maxLength: null,
placeholder: null,
type: "textarea" as const,
...a,
} as ValueSpecTextarea);
}
static number<
A extends {
name: string;
description: string | null;
warning: string | null;
required: boolean;
default: number | null;
min: number | null;
max: number | null;
/** Default = '1' */
step: string | null;
integer: boolean;
units: string | null;
placeholder: string | null;
},
>(a: A) {
static number<Required extends RequiredLike<number>>(a: {
name: string;
description?: string | null;
warning?: string | null;
required: Required;
min?: number | null;
max?: number | null;
/** Default = '1' */
step?: string | null;
integer: boolean;
units?: string | null;
placeholder?: string | null;
}) {
return new Value({
type: "number" as const,
description: null,
warning: null,
min: null,
max: null,
step: null,
units: null,
placeholder: null,
...a,
...requiredLikeToAbove(a.required),
});
}
static color<
A extends {
name: string;
description: string | null;
warning: string | null;
required: boolean;
default: string | null;
},
>(a: A) {
static color<Required extends RequiredLike<string>>(a: {
name: string;
description?: string | null;
warning?: string | null;
required: Required;
}) {
return new Value({
type: "color" as const,
description: null,
warning: null,
...a,
...requiredLikeToAbove(a.required),
});
}
static datetime(a: {
static datetime<Required extends RequiredLike<string>>(a: {
name: string;
description: string | null;
warning: string | null;
required: boolean;
description?: string | null;
warning?: string | null;
required: Required;
/** Default = 'datetime-local' */
inputmode: ValueSpecDatetime["inputmode"];
min: string | null;
max: string | null;
step: string | null;
default: string | null;
inputmode?: ValueSpecDatetime["inputmode"];
min?: string | null;
max?: string | null;
step?: string | null;
}) {
return new Value({
type: "datetime" as const,
description: null,
warning: null,
inputmode: "datetime-local",
min: null,
max: null,
step: null,
...a,
...requiredLikeToAbove(a.required),
});
}
static select<
A extends {
name: string;
description: string | null;
warning: string | null;
required: boolean;
default: string | null;
values: { [key: string]: string };
},
>(a: A) {
Required extends RequiredLike<string>,
B extends Record<string, string>,
>(a: {
name: string;
description?: string | null;
warning?: string | null;
required: Required;
values: B;
}) {
return new Value({
description: null,
warning: null,
type: "select" as const,
...a,
...requiredLikeToAbove(a.required),
});
}
static multiselect<
A extends {
name: string;
description: string | null;
warning: string | null;
default: string[];
values: Values;
minLength: number | null;
maxLength: number | null;
},
Values extends Record<string, string>,
>(a: A) {
static multiselect<Values extends Record<string, string>>(a: {
name: string;
description?: string | null;
warning?: string | null;
default: string[];
values: Values;
minLength?: number | null;
maxLength?: number | null;
}) {
return new Value({
type: "multiselect" as const,
minLength: null,
maxLength: null,
warning: null,
description: null,
...a,
});
}
static object<Spec extends Config<InputSpec>>(
a: {
name: string;
description: string | null;
warning: string | null;
description?: string | null;
warning?: string | null;
},
previousSpec: Spec,
) {
const spec = previousSpec.build() as BuilderExtract<Spec>;
return new Value({
type: "object" as const,
description: null,
warning: null,
...a,
spec,
});
}
static union<
Required extends RequiredLike<string>,
V extends Variants<{ [key: string]: { name: string; spec: InputSpec } }>,
>(
a: {
name: string;
description: string | null;
warning: string | null;
required: boolean;
default: string | null;
description?: string | null;
warning?: string | null;
required: Required;
default?: string | null;
},
aVariants: V,
) {
const variants = aVariants.build() as BuilderExtract<V>;
return new Value({
type: "union" as const,
description: null,
warning: null,
...a,
variants,
...requiredLikeToAbove(a.required),
});
}

View File

@@ -16,14 +16,7 @@ describe("builder tests", () => {
"peer-tor-address": Value.text({
name: "Peer tor address",
description: "The Tor address of the peer interface",
warning: null,
required: true,
masked: true,
placeholder: null,
minLength: null,
maxLength: null,
patterns: [],
inputmode: "text",
}),
}).build();
expect(JSON.stringify(bitcoinPropertiesBuilt)).toEqual(
@@ -32,7 +25,7 @@ describe("builder tests", () => {
"type": "text",
"description": "The Tor address of the peer interface",
"warning": null,
"masked": true,
"masked": false,
"placeholder": null,
"minLength": null,
"maxLength": null,
@@ -101,13 +94,27 @@ describe("values", () => {
required: false,
description: null,
warning: null,
default: null,
});
const validator = value.validator();
validator.unsafeCast("#000000");
testOutput<typeof validator._TYPE, string | null | undefined>()(null);
});
test("datetime", () => {
const value = Value.datetime({
name: "Testing",
required: true,
description: null,
warning: null,
inputmode: "date",
min: null,
max: null,
step: null,
});
const validator = value.validator();
validator.unsafeCast("2021-01-01");
testOutput<typeof validator._TYPE, string>()(null);
});
test("optional datetime", () => {
const value = Value.datetime({
name: "Testing",
required: false,
@@ -117,11 +124,10 @@ describe("values", () => {
min: null,
max: null,
step: null,
default: null,
});
const validator = value.validator();
validator.unsafeCast("2021-01-01");
testOutput<typeof validator._TYPE, string>()(null);
testOutput<typeof validator._TYPE, string | null | undefined>()(null);
});
test("textarea", () => {
const value = Value.textarea({
@@ -138,13 +144,29 @@ describe("values", () => {
testOutput<typeof validator._TYPE, string>()(null);
});
test("number", () => {
const value = Value.number({
name: "Testing",
required: true,
integer: false,
description: null,
warning: null,
min: null,
max: null,
step: null,
units: null,
placeholder: null,
});
const validator = value.validator();
validator.unsafeCast(2);
testOutput<typeof validator._TYPE, number>()(null);
});
test("optional number", () => {
const value = Value.number({
name: "Testing",
required: false,
integer: false,
description: null,
warning: null,
default: null,
min: null,
max: null,
step: null,
@@ -165,7 +187,6 @@ describe("values", () => {
},
description: null,
warning: null,
default: null,
});
const validator = value.validator();
validator.unsafeCast("a");
@@ -183,7 +204,6 @@ describe("values", () => {
},
description: null,
warning: null,
default: null,
});
const validator = value.validator();
validator.unsafeCast("a");
@@ -337,13 +357,6 @@ describe("Nested nullable values", () => {
description:
"If no name is provided, the name from config will be used",
required: false,
warning: null,
masked: false,
placeholder: null,
minLength: null,
maxLength: null,
patterns: [],
inputmode: "text",
}),
});
const validator = value.validator();
@@ -364,7 +377,6 @@ describe("Nested nullable values", () => {
warning: null,
placeholder: null,
integer: false,
default: null,
min: null,
max: null,
step: null,
@@ -387,7 +399,6 @@ describe("Nested nullable values", () => {
"If no name is provided, the name from config will be used",
required: false,
warning: null,
default: null,
}),
});
const validator = value.validator();
@@ -406,7 +417,6 @@ describe("Nested nullable values", () => {
"If no name is provided, the name from config will be used",
required: false,
warning: null,
default: null,
values: {
a: "A",
},
@@ -417,7 +427,6 @@ describe("Nested nullable values", () => {
description: "If no name is provided, the name from config will be used",
required: false,
warning: null,
default: null,
values: {
a: "A",
},

View File

@@ -109,10 +109,14 @@ export default async function makeFileContentFromOld(
)}Value.number(${JSON.stringify(
{
name: value.name || null,
default: value.default || null,
description: value.description || null,
warning: value.warning || null,
required: !(value.nullable || false),
// prettier-ignore
required: (
value.default != null && !value.nullable ? {default: value.default} :
value.default != null && value.nullable ? {defaultWithRequired: value.default} :
!value.nullable
),
min: null,
max: null,
step: null,
@@ -151,8 +155,13 @@ export default async function makeFileContentFromOld(
name: value.name || null,
description: value.description || null,
warning: value.warning || null,
default: value.default || null,
required: true,
// prettier-ignore
required: (
value.default != null && !value.nullable ? {default: value.default} :
value.default != null && value.nullable ? {defaultWithRequired: value.default} :
!value.nullable
),
values,
},
null,
@@ -180,8 +189,14 @@ export default async function makeFileContentFromOld(
name: ${JSON.stringify(value.name || null)},
description: ${JSON.stringify(value.tag.description || null)},
warning: ${JSON.stringify(value.tag.warning || null)},
required: true,
default: ${JSON.stringify(value.default || null)},
// prettier-ignore
required: ${JSON.stringify(
// prettier-ignore
value.default != null && !value.nullable ? {default: value.default} :
value.default != null && value.nullable ? {defaultWithRequired: value.default} :
!value.nullable,
)},
}, ${variants})`;
}
case "list": {
@@ -189,7 +204,7 @@ export default async function makeFileContentFromOld(
return `Value.list(${list})`;
}
case "pointer": {
return "null as any";
return `/* TODO deal with point removed ${JSON.stringify(value)} */`;
}
}
throw Error(`Unknown type "${value.type}"`);