sdk input spec improvements (#2785)

* sdk input spec improvements

* more sdk changes

* fe changes

* alpha.14

* fix tests

* separate validator in filehelper

* use deeppartial for getinput

* fix union type and update ts-matches

* alpha.15

* alpha.16

* alpha.17

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
This commit is contained in:
Aiden McClelland
2024-11-19 11:25:43 -07:00
committed by GitHub
parent 46179f5c83
commit 1771797453
24 changed files with 550 additions and 512 deletions

View File

@@ -1,7 +1,4 @@
import {
RequiredDefault,
Value,
} from "../../base/lib/actions/input/builder/value"
import { Value } from "../../base/lib/actions/input/builder/value"
import {
InputSpec,
ExtractInputSpecType,
@@ -141,9 +138,7 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
...startSdkEffectWrapper,
action: {
run: actions.runAction,
request: <
T extends Action<T.ActionId, any, any, Record<string, unknown>>,
>(
request: <T extends Action<T.ActionId, any, any>>(
effects: T.Effects,
packageId: T.PackageId,
action: T,
@@ -157,9 +152,7 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
severity,
options: options,
}),
requestOwn: <
T extends Action<T.ActionId, Store, any, Record<string, unknown>>,
>(
requestOwn: <T extends Action<T.ActionId, Store, any>>(
effects: T.Effects,
action: T,
severity: T.ActionSeverity,
@@ -1060,14 +1053,14 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
/** Presents a warning prompt before permitting the value to change. */
warning?: string | null
/**
* @description Determines if the field is required. If so, optionally provide a default value.
* @type { false | { default: string | RandomString | null } }
* @example required: false
* @example required: { default: null }
* @example required: { default: 'World' }
* @example required: { default: { charset: 'abcdefg', len: 16 } }
* @description optionally provide a default value.
* @type { string | RandomString | null }
* @example default: null
* @example default: 'World'
* @example default: { charset: 'abcdefg', len: 16 }
*/
required: RequiredDefault<DefaultString>
default: DefaultString | null
required: boolean
/**
* @description Mask (aka camouflage) text input with dots: ● ● ●
* @default false
@@ -1110,15 +1103,12 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
description?: string | null
/** Presents a warning prompt before permitting the value to change. */
warning?: string | null
/**
* @description Unlike other "required" fields, for textarea this is a simple boolean.
*/
default: string | null
required: boolean
minLength?: number | null
maxLength?: number | null
placeholder?: string | null
disabled?: false | string
generate?: null | RandomString
}
>,
) => Value.dynamicTextarea<Store>(getA),
@@ -1131,13 +1121,13 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
/** Presents a warning prompt before permitting the value to change. */
warning?: string | null
/**
* @description Determines if the field is required. If so, optionally provide a default value.
* @type { false | { default: number | null } }
* @example required: false
* @example required: { default: null }
* @example required: { default: 7 }
* @description optionally provide a default value.
* @type { number | null }
* @example default: null
* @example default: 7
*/
required: RequiredDefault<number>
default: number | null
required: boolean
min?: number | null
max?: number | null
/**
@@ -1167,13 +1157,13 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
/** Presents a warning prompt before permitting the value to change. */
warning?: string | null
/**
* @description Determines if the field is required. If so, optionally provide a default value.
* @type { false | { default: string | null } }
* @example required: false
* @example required: { default: null }
* @example required: { default: 'ffffff' }
* @description optionally provide a default value.
* @type { string | null }
* @example default: null
* @example default: 'ffffff'
*/
required: RequiredDefault<string>
default: string | null
required: boolean
disabled?: false | string
}
>,
@@ -1187,13 +1177,13 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
/** Presents a warning prompt before permitting the value to change. */
warning?: string | null
/**
* @description Determines if the field is required. If so, optionally provide a default value.
* @type { false | { default: string | null } }
* @example required: false
* @example required: { default: null }
* @example required: { default: '1985-12-16 18:00:00.000' }
* @description optionally provide a default value.
* @type { string | null }
* @example default: null
* @example default: '1985-12-16 18:00:00.000'
*/
required: RequiredDefault<string>
default: string
required: boolean
/**
* @description Informs the browser how to behave and which date/time component to display.
* @default "datetime-local"
@@ -1205,7 +1195,7 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
}
>,
) => Value.dynamicDatetime<Store>(getA),
dynamicSelect: (
dynamicSelect: <Variants extends Record<string, string>>(
getA: LazyBuild<
Store,
{
@@ -1214,13 +1204,12 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
/** Presents a warning prompt before permitting the value to change. */
warning?: string | null
/**
* @description Determines if the field is required. If so, optionally provide a default value from the list of values.
* @type { false | { default: string | null } }
* @example required: false
* @example required: { default: null }
* @example required: { default: 'radio1' }
* @description provide a default value from the list of values.
* @type { default: string }
* @example default: 'radio1'
*/
required: RequiredDefault<string>
default: keyof Variants & string
required: boolean
/**
* @description A mapping of unique radio options to their human readable display format.
* @example
@@ -1232,7 +1221,7 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
}
* ```
*/
values: Record<string, string>
values: Variants
/**
* @options
* - false - The field can be modified.
@@ -1282,27 +1271,37 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
>,
) => Value.dynamicMultiselect<Store>(getA),
filteredUnion: <
Required extends RequiredDefault<string>,
Type extends Record<string, any>,
VariantValues extends {
[K in string]: {
name: string
spec: InputSpec<any, Store> | InputSpec<any, never>
}
},
>(
getDisabledFn: LazyBuild<Store, string[]>,
a: {
name: string
description?: string | null
warning?: string | null
required: Required
default: keyof VariantValues & string
},
aVariants: Variants<Type, Store> | Variants<Type, never>,
aVariants:
| Variants<VariantValues, Store>
| Variants<VariantValues, never>,
) =>
Value.filteredUnion<Required, Type, Store>(
Value.filteredUnion<VariantValues, Store>(
getDisabledFn,
a,
aVariants,
),
dynamicUnion: <
Required extends RequiredDefault<string>,
Type extends Record<string, any>,
VariantValues extends {
[K in string]: {
name: string
spec: InputSpec<any, Store> | InputSpec<any, never>
}
},
>(
getA: LazyBuild<
Store,
@@ -1312,13 +1311,12 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
/** Presents a warning prompt before permitting the value to change. */
warning?: string | null
/**
* @description Determines if the field is required. If so, optionally provide a default value from the list of variants.
* @type { false | { default: string | null } }
* @example required: false
* @example required: { default: null }
* @example required: { default: 'variant1' }
* @description provide a default value from the list of variants.
* @type { string }
* @example default: 'variant1'
*/
required: Required
default: keyof VariantValues & string
required: boolean
/**
* @options
* - false - The field can be modified.
@@ -1329,8 +1327,10 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
disabled: false | string | string[]
}
>,
aVariants: Variants<Type, Store> | Variants<Type, never>,
) => Value.dynamicUnion<Required, Type, Store>(getA, aVariants),
aVariants:
| Variants<VariantValues, Store>
| Variants<VariantValues, never>,
) => Value.dynamicUnion<VariantValues, Store>(getA, aVariants),
},
Variants: {
of: <

View File

@@ -17,7 +17,8 @@ describe("builder tests", () => {
"peer-tor-address": Value.text({
name: "Peer tor address",
description: "The Tor address of the peer interface",
required: { default: null },
required: true,
default: null,
}),
}).build({} as any)
expect(bitcoinPropertiesBuilt).toMatchObject({
@@ -55,7 +56,8 @@ describe("values", () => {
test("text", async () => {
const value = Value.text({
name: "Testing",
required: { default: null },
required: true,
default: null,
})
const validator = value.validator
const rawIs = await value.build({} as any)
@@ -66,7 +68,8 @@ describe("values", () => {
test("text with default", async () => {
const value = Value.text({
name: "Testing",
required: { default: "this is a default value" },
required: true,
default: "this is a default value",
})
const validator = value.validator
const rawIs = await value.build({} as any)
@@ -78,6 +81,7 @@ describe("values", () => {
const value = Value.text({
name: "Testing",
required: false,
default: null,
})
const validator = value.validator
const rawIs = await value.build({} as any)
@@ -89,6 +93,7 @@ describe("values", () => {
const value = Value.color({
name: "Testing",
required: false,
default: null,
description: null,
warning: null,
})
@@ -99,7 +104,8 @@ describe("values", () => {
test("datetime", async () => {
const value = Value.datetime({
name: "Testing",
required: { default: null },
required: true,
default: null,
description: null,
warning: null,
inputmode: "date",
@@ -114,6 +120,7 @@ describe("values", () => {
const value = Value.datetime({
name: "Testing",
required: false,
default: null,
description: null,
warning: null,
inputmode: "date",
@@ -128,6 +135,7 @@ describe("values", () => {
const value = Value.textarea({
name: "Testing",
required: false,
default: null,
description: null,
warning: null,
minLength: null,
@@ -136,12 +144,13 @@ describe("values", () => {
})
const validator = value.validator
validator.unsafeCast("test text")
testOutput<typeof validator._TYPE, string>()(null)
testOutput<typeof validator._TYPE, string | null | undefined>()(null)
})
test("number", async () => {
const value = Value.number({
name: "Testing",
required: { default: null },
required: true,
default: null,
integer: false,
description: null,
warning: null,
@@ -159,6 +168,7 @@ describe("values", () => {
const value = Value.number({
name: "Testing",
required: false,
default: null,
integer: false,
description: null,
warning: null,
@@ -175,7 +185,7 @@ describe("values", () => {
test("select", async () => {
const value = Value.select({
name: "Testing",
required: { default: null },
default: "a",
values: {
a: "A",
b: "B",
@@ -192,7 +202,7 @@ describe("values", () => {
test("nullable select", async () => {
const value = Value.select({
name: "Testing",
required: false,
default: "a",
values: {
a: "A",
b: "B",
@@ -203,8 +213,7 @@ describe("values", () => {
const validator = value.validator
validator.unsafeCast("a")
validator.unsafeCast("b")
validator.unsafeCast(null)
testOutput<typeof validator._TYPE, "a" | "b" | null | undefined>()(null)
testOutput<typeof validator._TYPE, "a" | "b">()(null)
})
test("multiselect", async () => {
const value = Value.multiselect({
@@ -250,7 +259,7 @@ describe("values", () => {
const value = Value.union(
{
name: "Testing",
required: { default: null },
default: "a",
description: null,
warning: null,
},
@@ -271,7 +280,16 @@ describe("values", () => {
const validator = value.validator
validator.unsafeCast({ selection: "a", value: { b: false } })
type Test = typeof validator._TYPE
testOutput<Test, { selection: "a"; value: { b: boolean } }>()(null)
testOutput<
Test,
{
selection: "a"
value: {
b: boolean
}
other?: {}
}
>()(null)
})
describe("dynamic", () => {
@@ -301,7 +319,8 @@ describe("values", () => {
test("text", async () => {
const value = Value.dynamicText(async () => ({
name: "Testing",
required: { default: null },
required: true,
default: null,
}))
const validator = value.validator
const rawIs = await value.build({} as any)
@@ -317,7 +336,8 @@ describe("values", () => {
test("text with default", async () => {
const value = Value.dynamicText(async () => ({
name: "Testing",
required: { default: "this is a default value" },
required: true,
default: "this is a default value",
}))
const validator = value.validator
validator.unsafeCast("test text")
@@ -333,6 +353,7 @@ describe("values", () => {
const value = Value.dynamicText(async () => ({
name: "Testing",
required: false,
default: null,
}))
const validator = value.validator
const rawIs = await value.build({} as any)
@@ -349,6 +370,7 @@ describe("values", () => {
const value = Value.dynamicColor(async () => ({
name: "Testing",
required: false,
default: null,
description: null,
warning: null,
}))
@@ -414,7 +436,8 @@ describe("values", () => {
return {
name: "Testing",
required: { default: null },
required: true,
default: null,
inputmode: "date",
}
},
@@ -436,6 +459,7 @@ describe("values", () => {
const value = Value.dynamicTextarea(async () => ({
name: "Testing",
required: false,
default: null,
description: null,
warning: null,
minLength: null,
@@ -444,8 +468,7 @@ describe("values", () => {
}))
const validator = value.validator
validator.unsafeCast("test text")
expect(() => validator.unsafeCast(null)).toThrowError()
testOutput<typeof validator._TYPE, string>()(null)
testOutput<typeof validator._TYPE, string | null | undefined>()(null)
expect(await value.build(fakeOptions)).toMatchObject({
name: "Testing",
required: false,
@@ -454,7 +477,8 @@ describe("values", () => {
test("number", async () => {
const value = Value.dynamicNumber(() => ({
name: "Testing",
required: { default: null },
required: true,
default: null,
integer: false,
description: null,
warning: null,
@@ -477,7 +501,7 @@ describe("values", () => {
test("select", async () => {
const value = Value.dynamicSelect(() => ({
name: "Testing",
required: { default: null },
default: "a",
values: {
a: "A",
b: "B",
@@ -489,11 +513,9 @@ describe("values", () => {
validator.unsafeCast("a")
validator.unsafeCast("b")
validator.unsafeCast("c")
validator.unsafeCast(null)
testOutput<typeof validator._TYPE, string | null | undefined>()(null)
testOutput<typeof validator._TYPE, string>()(null)
expect(await value.build(fakeOptions)).toMatchObject({
name: "Testing",
required: true,
})
})
test("multiselect", async () => {
@@ -529,7 +551,7 @@ describe("values", () => {
() => ["a", "c"],
{
name: "Testing",
required: { default: null },
default: "a",
description: null,
warning: null,
},
@@ -563,8 +585,28 @@ describe("values", () => {
type Test = typeof validator._TYPE
testOutput<
Test,
| { selection: "a"; value: { b: boolean } }
| { selection: "b"; value: { b: boolean } }
| {
selection: "a"
value: {
b: boolean
}
other?: {
b?: {
b?: boolean
}
}
}
| {
selection: "b"
value: {
b: boolean
}
other?: {
a?: {
b?: boolean
}
}
}
>()(null)
const built = await value.build({} as any)
@@ -596,7 +638,7 @@ describe("values", () => {
() => ({
disabled: ["a", "c"],
name: "Testing",
required: { default: null },
default: "b",
description: null,
warning: null,
}),
@@ -630,10 +672,28 @@ describe("values", () => {
type Test = typeof validator._TYPE
testOutput<
Test,
| { selection: "a"; value: { b: boolean } }
| { selection: "b"; value: { b: boolean } }
| null
| undefined
| {
selection: "a"
value: {
b: boolean
}
other?: {
b?: {
b?: boolean
}
}
}
| {
selection: "b"
value: {
b: boolean
}
other?: {
a?: {
b?: boolean
}
}
}
>()(null)
const built = await value.build({} as any)
@@ -728,6 +788,7 @@ describe("Nested nullable values", () => {
description:
"If no name is provided, the name from inputSpec will be used",
required: false,
default: null,
}),
})
const validator = value.validator
@@ -743,6 +804,7 @@ describe("Nested nullable values", () => {
description:
"If no name is provided, the name from inputSpec will be used",
required: false,
default: null,
warning: null,
placeholder: null,
integer: false,
@@ -765,6 +827,7 @@ describe("Nested nullable values", () => {
description:
"If no name is provided, the name from inputSpec will be used",
required: false,
default: null,
warning: null,
}),
})
@@ -780,7 +843,7 @@ describe("Nested nullable values", () => {
name: "Temp Name",
description:
"If no name is provided, the name from inputSpec will be used",
required: false,
default: "a",
warning: null,
values: {
a: "A",
@@ -791,7 +854,7 @@ describe("Nested nullable values", () => {
name: "Temp Name",
description:
"If no name is provided, the name from inputSpec will be used",
required: false,
default: "a",
warning: null,
values: {
a: "A",
@@ -799,10 +862,9 @@ describe("Nested nullable values", () => {
}).build({} as any)
const validator = value.validator
validator.unsafeCast({ a: null })
validator.unsafeCast({ a: "a" })
expect(() => validator.unsafeCast({ a: "4" })).toThrowError()
testOutput<typeof validator._TYPE, { a: "a" | null | undefined }>()(null)
testOutput<typeof validator._TYPE, { a: "a" }>()(null)
})
test("Testing multiselect", async () => {
const value = InputSpec.of({

View File

@@ -87,7 +87,7 @@ describe("Inputs", () => {
dbcache: 5,
pruning: {
selection: "disabled",
value: {},
value: { disabled: {} },
},
blockfilters: {
blockfilterindex: false,

View File

@@ -80,7 +80,8 @@ export class FileHelper<A> {
protected constructor(
readonly path: string,
readonly writeData: (dataIn: A) => string,
readonly readData: (stringValue: string) => A,
readonly readData: (stringValue: string) => unknown,
readonly validate: (value: unknown) => A,
) {}
/**
@@ -97,10 +98,7 @@ export class FileHelper<A> {
return null
}
/**
* Reads the file from disk and converts it to structured data.
*/
private async readOnce(): Promise<A | null> {
private async readFile(): Promise<unknown> {
if (!(await exists(this.path))) {
return null
}
@@ -109,6 +107,15 @@ export class FileHelper<A> {
)
}
/**
* Reads the file from disk and converts it to structured data.
*/
private async readOnce(): Promise<A | null> {
const data = await this.readFile()
if (!data) return null
return this.validate(data)
}
private async readConst(effects: T.Effects): Promise<A | null> {
const watch = this.readWatch()
const res = await watch.next()
@@ -156,22 +163,22 @@ export class FileHelper<A> {
* Accepts full structured data and performs a merge with the existing file on disk if it exists.
*/
async write(data: A) {
const fileData = (await this.readOnce()) || {}
const fileData = (await this.readFile()) || {}
const mergeData = merge({}, fileData, data)
return await this.writeFile(mergeData)
return await this.writeFile(this.validate(mergeData))
}
/**
* Accepts partial structured data and performs a merge with the existing file on disk.
*/
async merge(data: Partial<A>) {
async merge(data: T.DeepPartial<A>) {
const fileData =
(await this.readOnce()) ||
(await this.readFile()) ||
(() => {
throw new Error(`${this.path}: does not exist`)
})()
const mergeData = merge({}, fileData, data)
return await this.writeFile(mergeData)
return await this.writeFile(this.validate(mergeData))
}
/**
@@ -179,7 +186,7 @@ export class FileHelper<A> {
* Like one behaviour of another dependency or something similar.
*/
withPath(path: string) {
return new FileHelper<A>(path, this.writeData, this.readData)
return new FileHelper<A>(path, this.writeData, this.readData, this.validate)
}
/**
@@ -190,9 +197,10 @@ export class FileHelper<A> {
static raw<A>(
path: string,
toFile: (dataIn: A) => string,
fromFile: (rawData: string) => A,
fromFile: (rawData: string) => unknown,
validate: (data: unknown) => A,
) {
return new FileHelper<A>(path, toFile, fromFile)
return new FileHelper<A>(path, toFile, fromFile, validate)
}
/**
* Create a File Helper for a .json file.
@@ -200,12 +208,9 @@ export class FileHelper<A> {
static json<A>(path: string, shape: matches.Validator<unknown, A>) {
return new FileHelper<A>(
path,
(inData) => {
return JSON.stringify(inData, null, 2)
},
(inString) => {
return shape.unsafeCast(JSON.parse(inString))
},
(inData) => JSON.stringify(inData, null, 2),
(inString) => JSON.parse(inString),
(data) => shape.unsafeCast(data),
)
}
/**
@@ -217,12 +222,9 @@ export class FileHelper<A> {
) {
return new FileHelper<A>(
path,
(inData) => {
return TOML.stringify(inData as any)
},
(inString) => {
return shape.unsafeCast(TOML.parse(inString))
},
(inData) => TOML.stringify(inData as any),
(inString) => TOML.parse(inString),
(data) => shape.unsafeCast(data),
)
}
/**
@@ -234,12 +236,9 @@ export class FileHelper<A> {
) {
return new FileHelper<A>(
path,
(inData) => {
return YAML.stringify(inData, null, 2)
},
(inString) => {
return shape.unsafeCast(YAML.parse(inString))
},
(inData) => YAML.stringify(inData, null, 2),
(inString) => YAML.parse(inString),
(data) => shape.unsafeCast(data),
)
}
}

View File

@@ -1,12 +1,12 @@
{
"name": "@start9labs/start-sdk",
"version": "0.3.6-alpha.13",
"version": "0.3.6-alpha.16",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@start9labs/start-sdk",
"version": "0.3.6-alpha.13",
"version": "0.3.6-alpha.16",
"license": "MIT",
"dependencies": {
"@iarna/toml": "^2.2.5",
@@ -15,7 +15,7 @@
"isomorphic-fetch": "^3.0.0",
"lodash.merge": "^4.6.2",
"mime-types": "^2.1.35",
"ts-matches": "^5.5.1",
"ts-matches": "^6.0.0",
"yaml": "^2.2.2"
},
"devDependencies": {
@@ -3918,9 +3918,10 @@
"dev": true
},
"node_modules/ts-matches": {
"version": "5.5.1",
"resolved": "https://registry.npmjs.org/ts-matches/-/ts-matches-5.5.1.tgz",
"integrity": "sha512-UFYaKgfqlg9FROK7bdpYqFwG1CJvP4kOJdjXuWoqxo9jCmANoDw1GxkSCpJgoTeIiSTaTH5Qr1klSspb8c+ydg=="
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/ts-matches/-/ts-matches-6.0.0.tgz",
"integrity": "sha512-vR4hhz9bYMW30qIJUuLaeAWlsR54vse6ZI2riVhVLMBE6/vss43jwrOvbHheiyU7e26ssT/yWx69aJHD2REJSA==",
"license": "MIT"
},
"node_modules/ts-morph": {
"version": "18.0.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@start9labs/start-sdk",
"version": "0.3.6-alpha.13",
"version": "0.3.6-alpha.17",
"description": "Software development kit to facilitate packaging services for StartOS",
"main": "./package/lib/index.js",
"types": "./package/lib/index.d.ts",
@@ -33,7 +33,7 @@
"isomorphic-fetch": "^3.0.0",
"lodash.merge": "^4.6.2",
"mime-types": "^2.1.35",
"ts-matches": "^5.5.1",
"ts-matches": "^6.0.0",
"yaml": "^2.2.2",
"@iarna/toml": "^2.2.5",
"@noble/curves": "^1.4.0",

View File

@@ -85,6 +85,7 @@ const {InputSpec, List, Value, Variants} = sdk
description: value.description || null,
warning: value.warning || null,
required: !(value.nullable || false),
default: value.default,
placeholder: value.placeholder || null,
maxLength: null,
minLength: null,
@@ -96,12 +97,8 @@ const {InputSpec, List, Value, Variants} = sdk
return `${rangeToTodoComment(value?.range)}Value.text(${JSON.stringify(
{
name: value.name || null,
// prettier-ignore
required: (
value.default != null ? {default: value.default} :
value.nullable === false ? {default: null} :
!value.nullable
),
default: value.default || null,
required: !value.nullable,
description: value.description || null,
warning: value.warning || null,
masked: value.masked || false,
@@ -130,12 +127,8 @@ const {InputSpec, List, Value, Variants} = sdk
name: value.name || null,
description: value.description || null,
warning: value.warning || null,
// prettier-ignore
required: (
value.default != null ? {default: value.default} :
value.nullable === false ? {default: null} :
!value.nullable
),
default: value.default || null,
required: !value.nullable,
min: null,
max: null,
step: null,
@@ -174,13 +167,7 @@ const {InputSpec, List, Value, Variants} = sdk
name: value.name || null,
description: value.description || null,
warning: value.warning || null,
// prettier-ignore
required:(
value.default != null ? {default: value.default} :
value.nullable === false ? {default: null} :
!value.nullable
),
default: value.default,
values,
},
null,
@@ -207,14 +194,7 @@ const {InputSpec, List, Value, Variants} = sdk
name: ${JSON.stringify(value.name || null)},
description: ${JSON.stringify(value.tag.description || null)},
warning: ${JSON.stringify(value.tag.warning || null)},
// prettier-ignore
required: ${JSON.stringify(
// prettier-ignore
value.default != null ? {default: value.default} :
value.nullable === false ? {default: null} :
!value.nullable,
)},
default: ${JSON.stringify(value.default)},
}, ${variants})`
}
case "list": {
@@ -341,12 +321,7 @@ const {InputSpec, List, Value, Variants} = sdk
value?.spec?.tag?.description || null,
)},
warning: ${JSON.stringify(value?.spec?.tag?.warning || null)},
required: ${JSON.stringify(
// prettier-ignore
'default' in value?.spec ? {default: value?.spec?.default} :
!!value?.spec?.tag?.nullable || false ? {default: null} :
false,
)},
default: ${JSON.stringify(value?.spec?.default || null)},
}, ${variants})
`,
)