mirror of
https://github.com/Start9Labs/start-sdk.git
synced 2026-03-26 02:11:56 +00:00
wip: Convert all the requireds needed :fingers-crossed:
This commit is contained in:
@@ -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),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
@@ -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}"`);
|
||||
|
||||
Reference in New Issue
Block a user