add textarea type

This commit is contained in:
Matt Hill
2023-03-29 08:52:51 -06:00
parent f9c558ec25
commit 3e708ab796
7 changed files with 61 additions and 7 deletions

View File

@@ -24,7 +24,6 @@ describe("builder tests", () => {
placeholder: null, placeholder: null,
pattern: null, pattern: null,
patternDescription: null, patternDescription: null,
textarea: null,
}), }),
}).build(); }).build();
expect(JSON.stringify(bitcoinPropertiesBuilt)).toEqual( expect(JSON.stringify(bitcoinPropertiesBuilt)).toEqual(
@@ -39,8 +38,7 @@ describe("builder tests", () => {
"masked": true, "masked": true,
"placeholder": null, "placeholder": null,
"pattern": null, "pattern": null,
"patternDescription": null, "patternDescription": null
"textarea": null
}}` }}`
.replaceAll("\n", " ") .replaceAll("\n", " ")
.replaceAll(/\s{2,}/g, "") .replaceAll(/\s{2,}/g, "")

View File

@@ -38,7 +38,6 @@ export class List<A extends ValueSpecList> extends IBuilder<A> {
placeholder: string | null; placeholder: string | null;
pattern: string | null; pattern: string | null;
patternDescription: string | null; patternDescription: string | null;
textarea: boolean | null;
}; };
} }
>(a: A) { >(a: A) {

View File

@@ -8,6 +8,7 @@ import {
ValueSpecList, ValueSpecList,
ValueSpecNumber, ValueSpecNumber,
ValueSpecString, ValueSpecString,
ValueSpecTextarea,
} from "../config-types"; } from "../config-types";
import { guardAll } from "../../util"; import { guardAll } from "../../util";
@@ -66,7 +67,6 @@ export class Value<A extends ValueSpec> extends IBuilder<A> {
placeholder: string | null; placeholder: string | null;
pattern: string | null; pattern: string | null;
patternDescription: string | null; patternDescription: string | null;
textarea: boolean | null;
} }
>(a: A) { >(a: A) {
return new Value({ return new Value({
@@ -74,6 +74,20 @@ export class Value<A extends ValueSpec> extends IBuilder<A> {
...a, ...a,
} as ValueSpecString); } as ValueSpecString);
} }
static textarea<
A extends {
name: string;
description: string | null;
warning: string | null;
nullable: boolean;
placeholder: string | null;
}
>(a: A) {
return new Value({
type: "textarea" as const,
...a,
} as ValueSpecTextarea);
}
static number< static number<
A extends { A extends {
name: string; name: string;

View File

@@ -2,6 +2,7 @@ export type InputSpec = Record<string, ValueSpec>;
export type ValueType = export type ValueType =
| "string" | "string"
| "textarea"
| "number" | "number"
| "boolean" | "boolean"
| "select" | "select"
@@ -16,6 +17,8 @@ export type ValueSpec = ValueSpecOf<ValueType>;
export type ValueSpecOf<T extends ValueType> = T extends "string" export type ValueSpecOf<T extends ValueType> = T extends "string"
? ValueSpecString ? ValueSpecString
: T extends "number" : T extends "number"
? ValueSpecTextarea
: T extends "textarea"
? ValueSpecNumber ? ValueSpecNumber
: T extends "boolean" : T extends "boolean"
? ValueSpecBoolean ? ValueSpecBoolean
@@ -37,7 +40,12 @@ export interface ValueSpecString extends ListValueSpecString, WithStandalone {
type: "string"; type: "string";
default: null | DefaultString; default: null | DefaultString;
nullable: boolean; nullable: boolean;
textarea: null | boolean; }
export interface ValueSpecTextarea extends WithStandalone {
type: "textarea";
placeholder: null | string;
nullable: boolean;
} }
export interface ValueSpecNumber extends ListValueSpecNumber, WithStandalone { export interface ValueSpecNumber extends ListValueSpecNumber, WithStandalone {

View File

@@ -76,6 +76,18 @@ writeConvertedFile(
copyable: true, copyable: true,
masked: true, masked: true,
}, },
bio: {
type: "string",
nullable: false,
name: "Username",
description: "The username for connecting to Bitcoin over RPC.",
default: "bitcoin",
masked: true,
pattern: "^[a-zA-Z0-9_]+$",
"pattern-description":
"Must be alphanumeric (can contain underscore).",
textarea: true,
},
advanced: { advanced: {
type: "object", type: "object",
name: "Advanced", name: "Advanced",

View File

@@ -11,6 +11,7 @@ const { string, some, object, dictionary, unknown, number, literals, boolean } =
type TypeBoolean = "boolean"; type TypeBoolean = "boolean";
type TypeString = "string"; type TypeString = "string";
type TypeTextarea = "textarea";
type TypeNumber = "number"; type TypeNumber = "number";
type TypeObject = "object"; type TypeObject = "object";
type TypeList = "list"; type TypeList = "list";
@@ -33,6 +34,10 @@ type GuardNumber<A> =
type GuardString<A> = type GuardString<A> =
A extends { type: TypeString } ? GuardDefaultNullable<A, string> : A extends { type: TypeString } ? GuardDefaultNullable<A, string> :
unknown unknown
// prettier-ignore
type GuardTextarea<A> =
A extends { type: TypeTextarea } ? GuardDefaultNullable<A, string> :
unknown
// prettier-ignore // prettier-ignore
type GuardBoolean<A> = type GuardBoolean<A> =
@@ -76,6 +81,7 @@ type GuardUnion<A> =
type _<T> = T; type _<T> = T;
export type GuardAll<A> = GuardNumber<A> & export type GuardAll<A> = GuardNumber<A> &
GuardString<A> & GuardString<A> &
GuardTextarea<A> &
GuardBoolean<A> & GuardBoolean<A> &
GuardObject<A> & GuardObject<A> &
GuardList<A> & GuardList<A> &
@@ -232,6 +238,9 @@ export function guardAll<A extends ValueSpecAny>(
case "string": case "string":
return defaultNullable(string, value) as any; return defaultNullable(string, value) as any;
case "textarea":
return defaultNullable(string, value) as any;
case "number": case "number":
return defaultNullable( return defaultNullable(
withIntegral(withRange(value), value), withIntegral(withRange(value), value),
@@ -267,6 +276,7 @@ export function guardAll<A extends ValueSpecAny>(
) as any; ) as any;
} }
return unknown as any; return unknown as any;
case "multiselect": case "multiselect":
if (matchValues.test(value)) { if (matchValues.test(value)) {
const rangeValidate = const rangeValidate =
@@ -282,6 +292,7 @@ export function guardAll<A extends ValueSpecAny>(
) as any; ) as any;
} }
return unknown as any; return unknown as any;
case "union": case "union":
if (matchUnion.test(value)) { if (matchUnion.test(value)) {
return some( return some(

View File

@@ -52,6 +52,19 @@ export default async function makeFileContent(
function convertValueSpec(value: any): string { function convertValueSpec(value: any): string {
switch (value.type) { switch (value.type) {
case "string": { case "string": {
if (value.textarea) {
return `Value.textarea(${JSON.stringify(
{
name: value.name || null,
description: value.description || null,
warning: value.warning || null,
nullable: value.nullable || false,
placeholder: value.placeholder || null,
},
null,
2
)})`;
}
return `Value.string(${JSON.stringify( return `Value.string(${JSON.stringify(
{ {
name: value.name || null, name: value.name || null,
@@ -63,7 +76,6 @@ export default async function makeFileContent(
placeholder: value.placeholder || null, placeholder: value.placeholder || null,
pattern: value.pattern || null, pattern: value.pattern || null,
patternDescription: value["pattern-description"] || null, patternDescription: value["pattern-description"] || null,
textarea: value.textarea || null,
}, },
null, null,
2 2