Skip to content

Commit

Permalink
Merge branch 'main' into validate
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobmischka committed Jul 15, 2022
2 parents 3b6d9bf + e075315 commit d71eb14
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 74 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@interval/sdk",
"version": "0.21.0",
"version": "0.22.0-dev",
"homepage": "https://interval.com",
"repository": {
"type": "git",
Expand Down
4 changes: 2 additions & 2 deletions src/classes/IOClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -420,11 +420,11 @@ export class IOClient {
select: {
single: this.createIOMethod('SELECT_SINGLE', {
propsRequired: true,
componentDef: selectSingle,
componentDef: selectSingle(this.logger),
}),
multiple: this.createIOMethod('SELECT_MULTIPLE', {
propsRequired: true,
componentDef: selectMultiple,
componentDef: selectMultiple(this.logger),
}),
table: this.createIOMethod('SELECT_TABLE', {
propsRequired: true,
Expand Down
78 changes: 44 additions & 34 deletions src/components/selectMultiple.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,63 @@
import { z } from 'zod'
import { T_IO_PROPS, T_IO_RETURNS, labelValue } from '../ioSchema'
import Logger from '../classes/Logger'

type SelectMultipleProps<Option extends z.infer<typeof labelValue> | string> =
Omit<T_IO_PROPS<'SELECT_MULTIPLE'>, 'options' | 'defaultValue'> & {
options: Option[]
defaultValue?: Option[]
}

export default function selectMultiple<
Option extends z.infer<typeof labelValue> | string
>(props: SelectMultipleProps<Option>) {
const normalizedOptions: z.infer<typeof labelValue>[] = props.options.map(
option => {
if (typeof option === 'string') {
export default function selectMultiple(logger: Logger) {
return <Option extends z.infer<typeof labelValue> | string>(
props: SelectMultipleProps<Option>
) => {
const normalizedOptions: z.infer<typeof labelValue>[] = props.options.map(
option => {
if (typeof option === 'string') {
return {
label: option,
value: option,
}
} else {
return option as Exclude<Option, string>
}
}
)
type Options = typeof props.options
const optionMap = new Map(
normalizedOptions.map((o, i) => [o.value, props.options[i]])
)

let defaultValue = props.defaultValue?.map(d => {
if (typeof d === 'string') {
return {
label: option,
value: option,
label: d,
value: d,
}
} else {
return option as Exclude<Option, string>
return d as Exclude<Option, string>
}
}
)
type Options = typeof props.options
const optionMap = new Map(
normalizedOptions.map((o, i) => [o.value, props.options[i]])
)
})

const defaultValue = props.defaultValue?.map(d => {
if (typeof d === 'string') {
return {
label: d,
value: d,
}
} else {
return d
if (defaultValue && defaultValue.every(val => !optionMap.has(val.value))) {
logger.warn(
'The defaultValue property must be a subset of the provided options, the provided defaultValue will be discarded.'
)
defaultValue = []
}
})

const stripper = labelValue.strip()
const stripper = labelValue.strip()

return {
props: {
...props,
defaultValue: defaultValue?.map(o => stripper.parse(o)),
options: normalizedOptions.map(o => stripper.parse(o)),
},
getValue(response: T_IO_RETURNS<'SELECT_MULTIPLE'>): Options {
return response.map(r => optionMap.get(r.value)) as Options
},
return {
props: {
...props,
defaultValue: defaultValue?.map(o => stripper.parse(o)),
options: normalizedOptions.map(o => stripper.parse(o)),
},
getValue(response: T_IO_RETURNS<'SELECT_MULTIPLE'>): Options {
return response.map(r => optionMap.get(r.value)) as Options
},
}
}
}
76 changes: 43 additions & 33 deletions src/components/selectSingle.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { z } from 'zod'
import { T_IO_PROPS, T_IO_RETURNS, richSelectOption } from '../ioSchema'
import Logger from '../classes/Logger'

type SelectSingleProps<
Option extends z.infer<typeof richSelectOption> | string
Expand All @@ -8,42 +9,51 @@ type SelectSingleProps<
defaultValue?: Option
}

export default function selectSingle<
Option extends z.infer<typeof richSelectOption> | string
>(props: SelectSingleProps<Option>) {
const normalizedOptions = props.options.map(option => {
if (typeof option === 'string') {
return {
label: option,
value: option,
export default function selectSingle(logger: Logger) {
return <Option extends z.infer<typeof richSelectOption> | string>(
props: SelectSingleProps<Option>
) => {
const normalizedOptions = props.options.map(option => {
if (typeof option === 'string') {
return {
label: option,
value: option,
}
} else {
return option as Exclude<Option, string>
}
} else {
return option as Exclude<Option, string>
}
})
})

type Options = typeof props.options
const optionMap = new Map(
normalizedOptions.map((o, i) => [o.value, props.options[i]])
)
const stripper = richSelectOption.strip()
type Options = typeof props.options
const optionMap = new Map(
normalizedOptions.map((o, i) => [o.value, props.options[i]])
)
const stripper = richSelectOption.strip()

const defaultValue =
typeof props.defaultValue === 'string'
? {
label: props.defaultValue,
value: props.defaultValue,
}
: (props.defaultValue as Exclude<Option, string>)
let defaultValue =
typeof props.defaultValue === 'string'
? {
label: props.defaultValue,
value: props.defaultValue,
}
: (props.defaultValue as Exclude<Option, string> | undefined)

return {
props: {
...props,
defaultValue: defaultValue ? stripper.parse(defaultValue) : undefined,
options: normalizedOptions.map(o => stripper.parse(o)),
},
getValue(response: T_IO_RETURNS<'SELECT_SINGLE'>) {
return optionMap.get(response.value) as Options[0]
},
if (defaultValue && !optionMap.has(defaultValue.value)) {
logger.warn(
'The defaultValue property must be a value in the provided options, the provided defaultValue will be discarded.'
)
defaultValue = undefined
}

return {
props: {
...props,
defaultValue: defaultValue ? stripper.parse(defaultValue) : undefined,
options: normalizedOptions.map(o => stripper.parse(o)),
},
getValue(response: T_IO_RETURNS<'SELECT_SINGLE'>) {
return optionMap.get(response.value) as Options[0]
},
}
}
}
14 changes: 14 additions & 0 deletions src/examples/basic/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,20 @@ const interval = new Interval({
io.input.boolean('Boolean'),
])
},
petr_repro: async () => {
// Data will be undefined if you just click "continue" without modifying the form.
const data = await io.select.single('Some field', {
options: [],
defaultValue: { label: 'my label', value: 'my_value' },
})

// This should be an object equal to the defaultValue
console.log('data', data)

await io.display.object('Return', {
data: { mySuperValue: data || 'No data' },
})
},
enter_a_number: async io => {
const num = await io.input.number('Enter a number')

Expand Down
4 changes: 2 additions & 2 deletions src/examples/nested/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { IntervalActionHandler } from '../..'
import ExperimentalInterval, { ActionGroup } from '../../experimental'
import ExperimentalInterval, { ActionGroup, io } from '../../experimental'

const interval = new ExperimentalInterval({
apiKey: 'alex_dev_kcLjzxNFxmGLf0aKtLVhuckt6sziQJtxFOdtM19tBrMUp5mj',
logLevel: 'debug',
endpoint: 'ws://localhost:3000/websocket',
})

const action: IntervalActionHandler = async io => {
const action: IntervalActionHandler = async () => {
const message = await io.input.text('Hello?')

return message
Expand Down
4 changes: 2 additions & 2 deletions src/experimental.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { z } from 'zod'
import fetch from 'node-fetch'
import type { IncomingMessage, ServerResponse } from 'http'
import Interval, { IntervalError } from '.'
import Interval, { io, ctx, IntervalError } from '.'
import IntervalClient from './classes/IntervalClient'
import ActionGroup from './classes/ActionGroup'
import * as pkg from '../package.json'
Expand All @@ -13,7 +13,7 @@ import {
LambdaResponse,
} from './utils/http'

export { ActionGroup }
export { ActionGroup, io, ctx, IntervalError }

export default class ExperimentalInterval extends Interval {
/*
Expand Down
4 changes: 4 additions & 0 deletions src/ioSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ export const labelValue = z
})
.passthrough()

export type LabelValue = z.infer<typeof labelValue>

export const richSelectOption = z
.object({
label: z.string(),
Expand All @@ -62,6 +64,8 @@ export const richSelectOption = z
})
.passthrough()

export type RichSelectOption = z.infer<typeof richSelectOption>

const objectLiteralSchema = z.union([
z.string(),
z.number(),
Expand Down

0 comments on commit d71eb14

Please sign in to comment.