@interval/sdk
Advanced tools
Comparing version 0.21.0 to 0.22.0
@@ -39,3 +39,3 @@ "use strict"; | ||
}; | ||
var _IntervalClient_instances, _IntervalClient_interval, _IntervalClient_ghostOrgId, _IntervalClient_apiKey, _IntervalClient_actions, _IntervalClient_endpoint, _IntervalClient_httpEndpoint, _IntervalClient_logger, _IntervalClient_retryIntervalMs, _IntervalClient_pingIntervalMs, _IntervalClient_closeUnresponsiveConnectionTimeoutMs, _IntervalClient_pingIntervalHandle, _IntervalClient_intentionallyClosed, _IntervalClient_log_get, _IntervalClient_ioResponseHandlers, _IntervalClient_pendingIOCalls, _IntervalClient_transactionLoadingStates, _IntervalClient_transactionCompleteCallbacks, _IntervalClient_ws, _IntervalClient_serverRpc, _IntervalClient_isConnected, _IntervalClient_resendPendingIOCalls, _IntervalClient_resendTransactionLoadingStates, _IntervalClient_findOrCreateGhostModeAccount, _IntervalClient_createSocketConnection, _IntervalClient_createRPCClient, _IntervalClient_initializeHost, _IntervalClient_send, _IntervalClient_sendLog; | ||
var _IntervalClient_instances, _IntervalClient_interval, _IntervalClient_ghostOrgId, _IntervalClient_apiKey, _IntervalClient_endpoint, _IntervalClient_httpEndpoint, _IntervalClient_logger, _IntervalClient_retryIntervalMs, _IntervalClient_pingIntervalMs, _IntervalClient_closeUnresponsiveConnectionTimeoutMs, _IntervalClient_pingIntervalHandle, _IntervalClient_intentionallyClosed, _IntervalClient_actionDefinitions, _IntervalClient_groupDefinitions, _IntervalClient_actionHandlers, _IntervalClient_log_get, _IntervalClient_ioResponseHandlers, _IntervalClient_pendingIOCalls, _IntervalClient_transactionLoadingStates, _IntervalClient_transactionCompleteCallbacks, _IntervalClient_ws, _IntervalClient_serverRpc, _IntervalClient_isConnected, _IntervalClient_resendPendingIOCalls, _IntervalClient_resendTransactionLoadingStates, _IntervalClient_findOrCreateGhostModeAccount, _IntervalClient_createSocketConnection, _IntervalClient_createRPCClient, _IntervalClient_initializeHost, _IntervalClient_send, _IntervalClient_sendLog; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -75,3 +75,2 @@ exports.actionLocalStorage = exports.sleep = exports.getHttpEndpoint = exports.DEFAULT_WEBSOCKET_ENDPOINT = void 0; | ||
constructor(interval, config) { | ||
var _a; | ||
_IntervalClient_instances.add(this); | ||
@@ -81,3 +80,2 @@ _IntervalClient_interval.set(this, void 0); | ||
_IntervalClient_apiKey.set(this, void 0); | ||
_IntervalClient_actions.set(this, void 0); | ||
_IntervalClient_endpoint.set(this, exports.DEFAULT_WEBSOCKET_ENDPOINT); | ||
@@ -91,2 +89,5 @@ _IntervalClient_httpEndpoint.set(this, void 0); | ||
_IntervalClient_intentionallyClosed.set(this, false); | ||
_IntervalClient_actionDefinitions.set(this, void 0); | ||
_IntervalClient_groupDefinitions.set(this, void 0); | ||
_IntervalClient_actionHandlers.set(this, void 0); | ||
_IntervalClient_ioResponseHandlers.set(this, new Map()); | ||
@@ -101,3 +102,2 @@ _IntervalClient_pendingIOCalls.set(this, new Map()); | ||
__classPrivateFieldSet(this, _IntervalClient_apiKey, config.apiKey, "f"); | ||
__classPrivateFieldSet(this, _IntervalClient_actions, (_a = config.actions) !== null && _a !== void 0 ? _a : {}, "f"); | ||
__classPrivateFieldSet(this, _IntervalClient_logger, new Logger_1.default(config.logLevel), "f"); | ||
@@ -107,2 +107,42 @@ if (config.endpoint) { | ||
} | ||
const groupDefinitions = []; | ||
const actionDefinitions = []; | ||
const actionHandlers = {}; | ||
if (config.actions) { | ||
for (const [slug, def] of Object.entries(config.actions)) { | ||
actionDefinitions.push({ | ||
slug, | ||
...('handler' in def ? def : {}), | ||
handler: undefined, | ||
}); | ||
actionHandlers[slug] = 'handler' in def ? def.handler : def; | ||
} | ||
} | ||
if (config.groups) { | ||
function walkActionGroup(groupSlug, group) { | ||
for (const [slug, def] of Object.entries(group.actions)) { | ||
groupDefinitions.push({ | ||
slug: groupSlug, | ||
name: group.name, | ||
}); | ||
actionDefinitions.push({ | ||
groupSlug, | ||
slug, | ||
...('handler' in def ? def : {}), | ||
handler: undefined, | ||
}); | ||
actionHandlers[`${groupSlug}/${slug}`] = | ||
'handler' in def ? def.handler : def; | ||
} | ||
for (const [subGroupSlug, subGroup] of Object.entries(group.groups)) { | ||
walkActionGroup(`${groupSlug}/${subGroupSlug}`, subGroup); | ||
} | ||
} | ||
for (const [groupSlug, group] of Object.entries(config.groups)) { | ||
walkActionGroup(groupSlug, group); | ||
} | ||
} | ||
__classPrivateFieldSet(this, _IntervalClient_groupDefinitions, groupDefinitions, "f"); | ||
__classPrivateFieldSet(this, _IntervalClient_actionDefinitions, actionDefinitions, "f"); | ||
__classPrivateFieldSet(this, _IntervalClient_actionHandlers, actionHandlers, "f"); | ||
if (config.retryIntervalMs && config.retryIntervalMs > 0) { | ||
@@ -124,3 +164,3 @@ __classPrivateFieldSet(this, _IntervalClient_retryIntervalMs, config.retryIntervalMs, "f"); | ||
async listen() { | ||
if (Object.keys(__classPrivateFieldGet(this, _IntervalClient_actions, "f")).length === 0) { | ||
if (__classPrivateFieldGet(this, _IntervalClient_actionDefinitions, "f").length === 0) { | ||
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).prod('Calling listen() with no defined actions is a no-op, skipping'); | ||
@@ -140,3 +180,3 @@ return; | ||
} | ||
if (Object.keys(__classPrivateFieldGet(this, _IntervalClient_actions, "f")).length === 0) { | ||
if (Object.keys(__classPrivateFieldGet(this, _IntervalClient_actionHandlers, "f")).length === 0) { | ||
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).prod('Calling respondToRequest() with no defined actions is a no-op, skipping'); | ||
@@ -171,9 +211,3 @@ return; | ||
async declareHost(httpHostId) { | ||
const actions = Object.entries(__classPrivateFieldGet(this, _IntervalClient_actions, "f")).map(([slug, def]) => ({ | ||
slug, | ||
...('handler' in def ? def : {}), | ||
handler: undefined, | ||
})); | ||
const slugs = Object.keys(__classPrivateFieldGet(this, _IntervalClient_actions, "f")); | ||
if (slugs.length === 0) { | ||
if (__classPrivateFieldGet(this, _IntervalClient_actionDefinitions, "f").length === 0) { | ||
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).prod('No actions defined, skipping host declaration'); | ||
@@ -184,3 +218,3 @@ return; | ||
httpHostId, | ||
actions, | ||
actions: __classPrivateFieldGet(this, _IntervalClient_actionDefinitions, "f"), | ||
sdkName: pkg.name, | ||
@@ -215,3 +249,3 @@ sdkVersion: pkg.version, | ||
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).warn('\nAction slugs must contain only letters, numbers, underscores, periods, and hyphens.'); | ||
if (response.invalidSlugs.length === slugs.length) { | ||
if (response.invalidSlugs.length === __classPrivateFieldGet(this, _IntervalClient_actionDefinitions, "f").length) { | ||
throw new __1.IntervalError('No valid slugs provided'); | ||
@@ -232,3 +266,3 @@ } | ||
exports.default = IntervalClient; | ||
_IntervalClient_interval = new WeakMap(), _IntervalClient_ghostOrgId = new WeakMap(), _IntervalClient_apiKey = new WeakMap(), _IntervalClient_actions = new WeakMap(), _IntervalClient_endpoint = new WeakMap(), _IntervalClient_httpEndpoint = new WeakMap(), _IntervalClient_logger = new WeakMap(), _IntervalClient_retryIntervalMs = new WeakMap(), _IntervalClient_pingIntervalMs = new WeakMap(), _IntervalClient_closeUnresponsiveConnectionTimeoutMs = new WeakMap(), _IntervalClient_pingIntervalHandle = new WeakMap(), _IntervalClient_intentionallyClosed = new WeakMap(), _IntervalClient_ioResponseHandlers = new WeakMap(), _IntervalClient_pendingIOCalls = new WeakMap(), _IntervalClient_transactionLoadingStates = new WeakMap(), _IntervalClient_transactionCompleteCallbacks = new WeakMap(), _IntervalClient_ws = new WeakMap(), _IntervalClient_serverRpc = new WeakMap(), _IntervalClient_isConnected = new WeakMap(), _IntervalClient_instances = new WeakSet(), _IntervalClient_log_get = function _IntervalClient_log_get() { | ||
_IntervalClient_interval = new WeakMap(), _IntervalClient_ghostOrgId = new WeakMap(), _IntervalClient_apiKey = new WeakMap(), _IntervalClient_endpoint = new WeakMap(), _IntervalClient_httpEndpoint = new WeakMap(), _IntervalClient_logger = new WeakMap(), _IntervalClient_retryIntervalMs = new WeakMap(), _IntervalClient_pingIntervalMs = new WeakMap(), _IntervalClient_closeUnresponsiveConnectionTimeoutMs = new WeakMap(), _IntervalClient_pingIntervalHandle = new WeakMap(), _IntervalClient_intentionallyClosed = new WeakMap(), _IntervalClient_actionDefinitions = new WeakMap(), _IntervalClient_groupDefinitions = new WeakMap(), _IntervalClient_actionHandlers = new WeakMap(), _IntervalClient_ioResponseHandlers = new WeakMap(), _IntervalClient_pendingIOCalls = new WeakMap(), _IntervalClient_transactionLoadingStates = new WeakMap(), _IntervalClient_transactionCompleteCallbacks = new WeakMap(), _IntervalClient_ws = new WeakMap(), _IntervalClient_serverRpc = new WeakMap(), _IntervalClient_isConnected = new WeakMap(), _IntervalClient_instances = new WeakSet(), _IntervalClient_log_get = function _IntervalClient_log_get() { | ||
return __classPrivateFieldGet(this, _IntervalClient_logger, "f"); | ||
@@ -435,8 +469,3 @@ }, _IntervalClient_resendPendingIOCalls = | ||
const { actionName: actionSlug, transactionId } = inputs; | ||
const actionDef = __classPrivateFieldGet(this, _IntervalClient_actions, "f")[actionSlug]; | ||
if (!actionDef) { | ||
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).debug('No action defined for slug', actionSlug); | ||
return; | ||
} | ||
const actionHandler = 'handler' in actionDef ? actionDef.handler : actionDef; | ||
const actionHandler = __classPrivateFieldGet(this, _IntervalClient_actionHandlers, "f")[actionSlug]; | ||
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).debug(actionHandler); | ||
@@ -610,9 +639,4 @@ if (!actionHandler) { | ||
} | ||
const actions = Object.entries(__classPrivateFieldGet(this, _IntervalClient_actions, "f")).map(([slug, def]) => ({ | ||
slug, | ||
...('handler' in def ? def : {}), | ||
handler: undefined, | ||
})); | ||
const slugs = Object.keys(__classPrivateFieldGet(this, _IntervalClient_actions, "f")); | ||
if (slugs.length === 0) { | ||
const actions = __classPrivateFieldGet(this, _IntervalClient_actionDefinitions, "f"); | ||
if (actions.length === 0) { | ||
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).prod('No actions defined, skipping host initialization'); | ||
@@ -624,2 +648,3 @@ return; | ||
actions, | ||
groups: __classPrivateFieldGet(this, _IntervalClient_groupDefinitions, "f"), | ||
sdkName: pkg.name, | ||
@@ -645,3 +670,3 @@ sdkVersion: pkg.version, | ||
__classPrivateFieldGet(this, _IntervalClient_instances, "a", _IntervalClient_log_get).warn('\nAction slugs must contain only letters, numbers, underscores, periods, and hyphens.'); | ||
if (response.invalidSlugs.length === slugs.length) { | ||
if (response.invalidSlugs.length === actions.length) { | ||
throw new __1.IntervalError('No valid slugs provided'); | ||
@@ -648,0 +673,0 @@ } |
/// <reference types="node" /> | ||
import { z } from 'zod'; | ||
import type { T_IO_RESPONSE, T_IO_PROPS, T_IO_RETURNS, T_IO_METHOD_NAMES } from '../ioSchema'; | ||
import type { T_IO_RESPONSE, T_IO_PROPS, T_IO_RETURNS, T_IO_DISPLAY_METHOD_NAMES, T_IO_INPUT_METHOD_NAMES } from '../ioSchema'; | ||
import Logger from './Logger'; | ||
import { AnyIOComponent } from './IOComponent'; | ||
import { IOPromise } from './IOPromise'; | ||
import { IORenderSender, ResponseHandlerFn, MaybeOptionalGroupIOPromise, GroupIOPromise, OptionalGroupIOPromise, IOComponentFunction, ExclusiveIOComponentFunction, IOComponentDefinition, RequiredPropsIOComponentFunction, RequiredPropsExclusiveIOComponentFunction } from '../types'; | ||
import { IOGroupPromise, IOPromiseValidator, DisplayIOPromise, InputIOPromise } from './IOPromise'; | ||
import { IORenderSender, ResponseHandlerFn, MaybeOptionalGroupIOPromise, ExclusiveIOComponentFunction, IOComponentDefinition, RequiredPropsExclusiveIOComponentFunction, DisplayIOComponentFunction, RequiredPropsDisplayIOComponentFunction, InputIOComponentFunction, RequiredPropsInputIOComponentFunction } from '../types'; | ||
interface ClientConfig { | ||
@@ -12,2 +12,6 @@ logger: Logger; | ||
} | ||
export declare type IOClientRenderReturnValues<Components extends [AnyIOComponent, ...AnyIOComponent[]]> = { | ||
[Idx in keyof Components]: Components[Idx] extends AnyIOComponent ? z.infer<Components[Idx]['schema']['returns']> | undefined : Components[Idx]; | ||
}; | ||
export declare type IOClientRenderValidator<Components extends [AnyIOComponent, ...AnyIOComponent[]]> = IOPromiseValidator<IOClientRenderReturnValues<Components>>; | ||
/** | ||
@@ -35,3 +39,3 @@ * The client class that handles IO calls for a given transaction. | ||
*/ | ||
renderComponents<Components extends [AnyIOComponent, ...AnyIOComponent[]]>(components: Components): Promise<{ [Idx in keyof Components]: Components[Idx] extends AnyIOComponent ? z.TypeOf<Components[Idx]["schema"]["returns"]> | undefined : Components[Idx]; }>; | ||
renderComponents<Components extends [AnyIOComponent, ...AnyIOComponent[]]>(components: Components, groupValidator?: IOClientRenderValidator<Components>): Promise<IOClientRenderReturnValues<Components>>; | ||
/** | ||
@@ -47,8 +51,20 @@ * A thin wrapper around `renderComponents` that converts IOPromises into | ||
...MaybeOptionalGroupIOPromise[] | ||
], Components extends [AnyIOComponent, ...AnyIOComponent[]]>(ioPromises: IOPromises): Promise<{ | ||
[Idx in keyof IOPromises]: IOPromises[Idx] extends GroupIOPromise ? ReturnType<IOPromises[Idx]['getValue']> : IOPromises[Idx] extends OptionalGroupIOPromise ? ReturnType<IOPromises[Idx]['getValue']> : IOPromises[Idx]; | ||
}>; | ||
group(ioPromises: MaybeOptionalGroupIOPromise[]): Promise<ReturnType<MaybeOptionalGroupIOPromise['getValue']>>; | ||
createIOMethod<MethodName extends T_IO_METHOD_NAMES, Props extends object = T_IO_PROPS<MethodName>, Output = T_IO_RETURNS<MethodName>>(methodName: MethodName, propsRequired?: false, componentDef?: IOComponentDefinition<MethodName, Props, Output>): IOComponentFunction<MethodName, Props, Output>; | ||
createIOMethod<MethodName extends T_IO_METHOD_NAMES, Props extends object = T_IO_PROPS<MethodName>, Output = T_IO_RETURNS<MethodName>>(methodName: MethodName, propsRequired?: true, componentDef?: IOComponentDefinition<MethodName, Props, Output>): RequiredPropsIOComponentFunction<MethodName, Props, Output>; | ||
]>(ioPromises: IOPromises): IOGroupPromise<IOPromises>; | ||
group(ioPromises: MaybeOptionalGroupIOPromise[]): IOGroupPromise<MaybeOptionalGroupIOPromise[]>; | ||
createIOMethod<MethodName extends T_IO_DISPLAY_METHOD_NAMES, Props extends object = T_IO_PROPS<MethodName>, Output = T_IO_RETURNS<MethodName>>(methodName: MethodName, config?: { | ||
propsRequired?: false; | ||
componentDef?: IOComponentDefinition<MethodName, Props, Output>; | ||
}): DisplayIOComponentFunction<MethodName, Props, Output>; | ||
createIOMethod<MethodName extends T_IO_DISPLAY_METHOD_NAMES, Props extends object = T_IO_PROPS<MethodName>, Output = T_IO_RETURNS<MethodName>>(methodName: MethodName, config: { | ||
propsRequired?: true; | ||
componentDef?: IOComponentDefinition<MethodName, Props, Output>; | ||
}): RequiredPropsDisplayIOComponentFunction<MethodName, Props, Output>; | ||
createIOMethod<MethodName extends T_IO_INPUT_METHOD_NAMES, Props extends object = T_IO_PROPS<MethodName>, Output = T_IO_RETURNS<MethodName>>(methodName: MethodName, config?: { | ||
propsRequired?: false; | ||
componentDef?: IOComponentDefinition<MethodName, Props, Output>; | ||
}): InputIOComponentFunction<MethodName, Props, Output>; | ||
createIOMethod<MethodName extends T_IO_INPUT_METHOD_NAMES, Props extends object = T_IO_PROPS<MethodName>, Output = T_IO_RETURNS<MethodName>>(methodName: MethodName, config: { | ||
propsRequired?: true; | ||
componentDef?: IOComponentDefinition<MethodName, Props, Output>; | ||
}): RequiredPropsInputIOComponentFunction<MethodName, Props, Output>; | ||
/** | ||
@@ -58,4 +74,4 @@ * A very thin wrapper function that converts an IOPromise to an | ||
*/ | ||
makeExclusive<MethodName extends T_IO_METHOD_NAMES, Props, Output>(inner: IOComponentFunction<MethodName, Props, Output>, propsRequired?: false): ExclusiveIOComponentFunction<MethodName, Props, Output>; | ||
makeExclusive<MethodName extends T_IO_METHOD_NAMES, Props, Output>(inner: IOComponentFunction<MethodName, Props, Output>, propsRequired?: true): RequiredPropsExclusiveIOComponentFunction<MethodName, Props, Output>; | ||
makeExclusive<MethodName extends T_IO_INPUT_METHOD_NAMES, Props, Output>(inner: InputIOComponentFunction<MethodName, Props, Output>, propsRequired?: false): ExclusiveIOComponentFunction<MethodName, Props, Output>; | ||
makeExclusive<MethodName extends T_IO_INPUT_METHOD_NAMES, Props, Output>(inner: InputIOComponentFunction<MethodName, Props, Output>, propsRequired?: true): RequiredPropsExclusiveIOComponentFunction<MethodName, Props, Output>; | ||
/** | ||
@@ -66,4 +82,4 @@ * The namespace of IO functions available in action handlers. | ||
group: { | ||
<IOPromises extends [MaybeOptionalGroupIOPromise, ...MaybeOptionalGroupIOPromise[]], Components extends [AnyIOComponent, ...AnyIOComponent[]]>(ioPromises: IOPromises): Promise<{ [Idx in keyof IOPromises]: IOPromises[Idx] extends GroupIOPromise ? ReturnType<IOPromises[Idx]["getValue"]> : IOPromises[Idx] extends OptionalGroupIOPromise ? ReturnType<IOPromises[Idx]["getValue"]> : IOPromises[Idx]; }>; | ||
(ioPromises: MaybeOptionalGroupIOPromise[]): Promise<any>; | ||
<IOPromises extends [MaybeOptionalGroupIOPromise, ...MaybeOptionalGroupIOPromise[]]>(ioPromises: IOPromises): IOGroupPromise<IOPromises, IOPromises extends [MaybeOptionalGroupIOPromise, ...MaybeOptionalGroupIOPromise[]] ? import("./IOPromise").IOGroupReturnValues<IOPromises> : unknown[]>; | ||
(ioPromises: MaybeOptionalGroupIOPromise[]): IOGroupPromise<MaybeOptionalGroupIOPromise[], unknown[]>; | ||
}; | ||
@@ -83,3 +99,3 @@ confirm: ExclusiveIOComponentFunction<"CONFIRM", { | ||
onSearch: (query: string) => Promise<Result[]>; | ||
}) => IOPromise<"SEARCH", { | ||
}) => InputIOPromise<"SEARCH", { | ||
helpText?: string | undefined; | ||
@@ -95,3 +111,3 @@ placeholder?: string | undefined; | ||
input: { | ||
text: IOComponentFunction<"INPUT_TEXT", { | ||
text: InputIOComponentFunction<"INPUT_TEXT", { | ||
helpText?: string | undefined; | ||
@@ -105,7 +121,7 @@ placeholder?: string | undefined; | ||
}, string>; | ||
boolean: IOComponentFunction<"INPUT_BOOLEAN", { | ||
boolean: InputIOComponentFunction<"INPUT_BOOLEAN", { | ||
helpText?: string | undefined; | ||
defaultValue?: boolean | undefined; | ||
}, boolean>; | ||
number: IOComponentFunction<"INPUT_NUMBER", { | ||
number: InputIOComponentFunction<"INPUT_NUMBER", { | ||
helpText?: string | undefined; | ||
@@ -120,3 +136,3 @@ placeholder?: string | undefined; | ||
}, number>; | ||
email: IOComponentFunction<"INPUT_EMAIL", { | ||
email: InputIOComponentFunction<"INPUT_EMAIL", { | ||
helpText?: string | undefined; | ||
@@ -126,3 +142,3 @@ placeholder?: string | undefined; | ||
}, string>; | ||
richText: IOComponentFunction<"INPUT_RICH_TEXT", { | ||
richText: InputIOComponentFunction<"INPUT_RICH_TEXT", { | ||
helpText?: string | undefined; | ||
@@ -157,3 +173,3 @@ placeholder?: string | undefined; | ||
defaultValue?: Option | undefined; | ||
}) => IOPromise<"SELECT_SINGLE", { | ||
}) => InputIOPromise<"SELECT_SINGLE", { | ||
helpText?: string | undefined; | ||
@@ -192,3 +208,3 @@ defaultValue?: { | ||
defaultValue?: Option_1[] | undefined; | ||
}) => IOPromise<"SELECT_MULTIPLE", { | ||
}) => InputIOPromise<"SELECT_MULTIPLE", { | ||
helpText?: string | undefined; | ||
@@ -238,3 +254,3 @@ defaultValue?: { | ||
columns?: (string | import("../components/table").Column<Row>)[] | undefined; | ||
}) => IOPromise<"SELECT_TABLE", { | ||
}) => InputIOPromise<"SELECT_TABLE", { | ||
helpText?: string | undefined; | ||
@@ -265,5 +281,5 @@ columns?: { | ||
display: { | ||
heading: IOComponentFunction<"DISPLAY_HEADING", {}, null>; | ||
markdown: IOComponentFunction<"DISPLAY_MARKDOWN", {}, null>; | ||
link: IOComponentFunction<"DISPLAY_LINK", { | ||
heading: DisplayIOComponentFunction<"DISPLAY_HEADING", {}, null>; | ||
markdown: DisplayIOComponentFunction<"DISPLAY_MARKDOWN", {}, null>; | ||
link: DisplayIOComponentFunction<"DISPLAY_LINK", { | ||
theme?: "default" | "danger" | undefined; | ||
@@ -276,3 +292,3 @@ } & ({ | ||
}), null>; | ||
object: IOComponentFunction<"DISPLAY_OBJECT", { | ||
object: DisplayIOComponentFunction<"DISPLAY_OBJECT", { | ||
data?: object | (string | number | boolean | Date | null | undefined) | { | ||
@@ -307,3 +323,3 @@ [key: string]: object | (string | number | boolean | Date | null | undefined) | any | (object | (string | number | boolean | Date | null | undefined) | any | (object | (string | number | boolean | Date | null | undefined) | any | (object | (string | number | boolean | Date | null | undefined) | any | (object | (string | number | boolean | Date | null | undefined) | any | (object | (string | number | boolean | Date | null | undefined) | any | (object | (string | number | boolean | Date | null | undefined) | any | (object | (string | number | boolean | Date | null | undefined) | any | (object | (string | number | boolean | Date | null | undefined) | any | (object | (string | number | boolean | Date | null | undefined) | any | (object | (string | number | boolean | Date | null | undefined) | any | (object | (string | number | boolean | Date | null | undefined) | any | any)[])[])[])[])[])[])[])[])[])[])[]; | ||
columns?: (string | import("../components/table").Column<Row_1>)[] | undefined; | ||
}) => IOPromise<"DISPLAY_TABLE", { | ||
}) => DisplayIOPromise<"DISPLAY_TABLE", { | ||
helpText?: string | undefined; | ||
@@ -347,3 +363,3 @@ columns?: { | ||
}[Columns[key]]>; }[] | undefined; | ||
}) => IOPromise<"INPUT_SPREADSHEET", { | ||
}) => InputIOPromise<"INPUT_SPREADSHEET", { | ||
helpText?: string | undefined; | ||
@@ -360,3 +376,3 @@ defaultValue?: Record<string, string | number | boolean | null | undefined>[] | undefined; | ||
}[Columns[key_1]]>; }[]>; | ||
date: IOComponentFunction<"INPUT_DATE", Omit<{ | ||
date: InputIOComponentFunction<"INPUT_DATE", Omit<{ | ||
helpText?: string | undefined; | ||
@@ -400,3 +416,3 @@ defaultValue?: { | ||
}>; | ||
time: IOComponentFunction<"INPUT_TIME", { | ||
time: InputIOComponentFunction<"INPUT_TIME", { | ||
helpText?: string | undefined; | ||
@@ -419,3 +435,3 @@ defaultValue?: { | ||
}>; | ||
datetime: IOComponentFunction<"INPUT_DATETIME", Omit<{ | ||
datetime: InputIOComponentFunction<"INPUT_DATETIME", Omit<{ | ||
helpText?: string | undefined; | ||
@@ -474,3 +490,3 @@ defaultValue?: { | ||
input: { | ||
file: IOComponentFunction<"UPLOAD_FILE", { | ||
file: InputIOComponentFunction<"UPLOAD_FILE", { | ||
helpText?: string | undefined; | ||
@@ -477,0 +493,0 @@ allowedExtensions?: string[] | undefined; |
@@ -42,2 +42,3 @@ "use strict"; | ||
const deserialize_1 = require("../utils/deserialize"); | ||
const __1 = require(".."); | ||
/** | ||
@@ -65,3 +66,3 @@ * The client class that handles IO calls for a given transaction. | ||
*/ | ||
async renderComponents(components) { | ||
async renderComponents(components, groupValidator) { | ||
if (this.isCanceled) { | ||
@@ -71,2 +72,3 @@ // Transaction is already canceled, host attempted more IO calls | ||
} | ||
let validationErrorMessage; | ||
return new Promise(async (resolve, reject) => { | ||
@@ -89,2 +91,3 @@ const inputGroupKey = (0, uuid_1.v4)(); | ||
}), | ||
validationErrorMessage, | ||
kind: 'RENDER', | ||
@@ -119,6 +122,28 @@ }; | ||
if (result.kind === 'RETURN') { | ||
const validities = await Promise.all(result.values.map(async (v, index) => { | ||
const component = components[index]; | ||
if (component.validator) { | ||
const resp = await component.handleValidation(v); | ||
if (resp !== undefined) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
})); | ||
if (validities.some(v => !v)) { | ||
render(); | ||
return; | ||
} | ||
if (groupValidator) { | ||
validationErrorMessage = await groupValidator(result.values); | ||
if (validationErrorMessage) { | ||
render(); | ||
return; | ||
} | ||
} | ||
isReturned = true; | ||
result.values.map((v, index) => | ||
// @ts-ignore | ||
components[index].setReturnValue(v)); | ||
result.values.forEach((v, index) => { | ||
// @ts-ignore | ||
components[index].setReturnValue(v); | ||
}); | ||
return; | ||
@@ -148,13 +173,15 @@ } | ||
} | ||
async group(ioPromises) { | ||
const components = ioPromises.map(pi => { | ||
// In case user is using JavaScript or ignores the type error | ||
if (pi instanceof IOPromise_1.ExclusiveIOPromise) { | ||
this.logger.warn('[Interval]', `Component with label "${pi.component.label}" is not supported inside a group, please remove it from the group`); | ||
} | ||
return pi.component; | ||
group(promises) { | ||
const exclusivePromises = promises.filter(pi => pi instanceof IOPromise_1.ExclusiveIOPromise); | ||
if (exclusivePromises.length > 0) { | ||
throw new __1.IntervalError(`Components with the following labels are not supported inside groups, please remove them from the group: ${exclusivePromises | ||
.map(pi => pi.component.label) | ||
.join(', ')}`); | ||
} | ||
return new IOPromise_1.IOGroupPromise({ | ||
promises, | ||
renderer: this.renderComponents.bind(this), | ||
}); | ||
return this.renderComponents(components).then(values => values.map((val, i) => ioPromises[i].getValue(val))); | ||
} | ||
createIOMethod(methodName, _propsRequired = false, componentDef) { | ||
createIOMethod(methodName, { componentDef, } = {}) { | ||
return (label, props) => { | ||
@@ -176,10 +203,20 @@ let internalProps = props ? props : {}; | ||
} | ||
return new IOPromise_1.IOPromise({ | ||
methodName, | ||
renderer: this.renderComponents.bind(this), | ||
label, | ||
props: internalProps, | ||
valueGetter: getValue, | ||
onStateChange, | ||
}); | ||
const isDisplay = methodName.startsWith('DISPLAY_'); | ||
return isDisplay | ||
? new IOPromise_1.DisplayIOPromise({ | ||
methodName: methodName, | ||
renderer: this.renderComponents.bind(this), | ||
label, | ||
props: internalProps, | ||
valueGetter: getValue, | ||
onStateChange, | ||
}) | ||
: new IOPromise_1.InputIOPromise({ | ||
methodName: methodName, | ||
renderer: this.renderComponents.bind(this), | ||
label, | ||
props: internalProps, | ||
valueGetter: getValue, | ||
onStateChange, | ||
}); | ||
}; | ||
@@ -189,3 +226,3 @@ } | ||
return (label, props) => { | ||
return new IOPromise_1.ExclusiveIOPromise(inner(label, props)); | ||
return inner(label, props).exclusive(); | ||
}; | ||
@@ -200,3 +237,6 @@ } | ||
confirm: this.makeExclusive(this.createIOMethod('CONFIRM')), | ||
search: this.createIOMethod('SEARCH', true, search_1.default), | ||
search: this.createIOMethod('SEARCH', { | ||
propsRequired: true, | ||
componentDef: search_1.default, | ||
}), | ||
input: { | ||
@@ -210,5 +250,14 @@ text: this.createIOMethod('INPUT_TEXT'), | ||
select: { | ||
single: this.createIOMethod('SELECT_SINGLE', true, selectSingle_1.default), | ||
multiple: this.createIOMethod('SELECT_MULTIPLE', true, selectMultiple_1.default), | ||
table: this.createIOMethod('SELECT_TABLE', true, (0, table_1.selectTable)(this.logger)), | ||
single: this.createIOMethod('SELECT_SINGLE', { | ||
propsRequired: true, | ||
componentDef: (0, selectSingle_1.default)(this.logger), | ||
}), | ||
multiple: this.createIOMethod('SELECT_MULTIPLE', { | ||
propsRequired: true, | ||
componentDef: (0, selectMultiple_1.default)(this.logger), | ||
}), | ||
table: this.createIOMethod('SELECT_TABLE', { | ||
propsRequired: true, | ||
componentDef: (0, table_1.selectTable)(this.logger), | ||
}), | ||
}, | ||
@@ -220,11 +269,19 @@ display: { | ||
object: this.createIOMethod('DISPLAY_OBJECT'), | ||
table: this.createIOMethod('DISPLAY_TABLE', true, (0, table_1.displayTable)(this.logger)), | ||
table: this.createIOMethod('DISPLAY_TABLE', { | ||
propsRequired: true, | ||
componentDef: (0, table_1.displayTable)(this.logger), | ||
}), | ||
}, | ||
experimental: { | ||
spreadsheet: this.createIOMethod('INPUT_SPREADSHEET', true, spreadsheet_1.default), | ||
date: this.createIOMethod('INPUT_DATE', false, inputDate_1.date), | ||
spreadsheet: this.createIOMethod('INPUT_SPREADSHEET', { | ||
propsRequired: true, | ||
componentDef: spreadsheet_1.default, | ||
}), | ||
date: this.createIOMethod('INPUT_DATE', { componentDef: inputDate_1.date }), | ||
time: this.createIOMethod('INPUT_TIME'), | ||
datetime: this.createIOMethod('INPUT_DATETIME', false, inputDate_1.datetime), | ||
datetime: this.createIOMethod('INPUT_DATETIME', { | ||
componentDef: inputDate_1.datetime, | ||
}), | ||
input: { | ||
file: this.createIOMethod('UPLOAD_FILE', false, upload_1.file), | ||
file: this.createIOMethod('UPLOAD_FILE', { componentDef: upload_1.file }), | ||
}, | ||
@@ -231,0 +288,0 @@ }, |
import { z } from 'zod'; | ||
import { ioSchema, T_IO_METHOD_NAMES, T_IO_RETURNS } from '../ioSchema'; | ||
import { IOPromiseValidator } from './IOPromise'; | ||
declare type IoSchema = typeof ioSchema; | ||
@@ -11,2 +12,3 @@ export interface ComponentInstance<MN extends keyof IoSchema> { | ||
isOptional?: boolean; | ||
validationErrorMessage?: string | undefined; | ||
} | ||
@@ -31,2 +33,3 @@ export declare type ComponentRenderInfo<MN extends keyof IoSchema> = Omit<ComponentInstance<MN>, 'state'>; | ||
handleStateChange: ((incomingState: z.infer<IoSchema[MethodName]['state']>) => Promise<Partial<z.input<IoSchema[MethodName]['props']>>>) | undefined; | ||
validator: IOPromiseValidator<ComponentReturnValue<MethodName> | undefined> | undefined; | ||
/** | ||
@@ -43,3 +46,4 @@ * @param methodName - The component's method name from ioSchema, used | ||
*/ | ||
constructor(methodName: MethodName, label: string, initialProps?: z.input<IoSchema[MethodName]['props']>, handleStateChange?: (incomingState: z.infer<IoSchema[MethodName]['state']>) => Promise<Partial<z.input<IoSchema[MethodName]['props']>>>, isOptional?: boolean); | ||
constructor(methodName: MethodName, label: string, initialProps?: z.input<IoSchema[MethodName]['props']>, handleStateChange?: (incomingState: z.infer<IoSchema[MethodName]['state']>) => Promise<Partial<z.input<IoSchema[MethodName]['props']>>>, isOptional?: boolean, validator?: IOPromiseValidator<ComponentReturnValue<MethodName> | undefined>); | ||
handleValidation(returnValue: ComponentReturnValue<MethodName> | undefined): Promise<string | undefined>; | ||
setReturnValue(value: z.input<IoSchema[MethodName]['returns']>): void; | ||
@@ -46,0 +50,0 @@ setState(newState: z.infer<IoSchema[MethodName]['state']>): Promise<ComponentInstance<MethodName>>; |
@@ -22,5 +22,6 @@ "use strict"; | ||
*/ | ||
constructor(methodName, label, initialProps, handleStateChange, isOptional = false) { | ||
constructor(methodName, label, initialProps, handleStateChange, isOptional = false, validator) { | ||
this.handleStateChange = handleStateChange; | ||
this.schema = ioSchema_1.ioSchema[methodName]; | ||
this.validator = validator; | ||
try { | ||
@@ -52,2 +53,9 @@ initialProps = this.schema.props.parse(initialProps !== null && initialProps !== void 0 ? initialProps : {}); | ||
} | ||
async handleValidation(returnValue) { | ||
if (this.validator) { | ||
const message = await this.validator(returnValue); | ||
this.instance.validationErrorMessage = message; | ||
return message; | ||
} | ||
} | ||
setReturnValue(value) { | ||
@@ -125,2 +133,3 @@ const returnSchema = this.instance.isOptional | ||
isOptional: this.instance.isOptional, | ||
validationErrorMessage: this.instance.validationErrorMessage, | ||
}; | ||
@@ -127,0 +136,0 @@ } |
@@ -1,5 +0,5 @@ | ||
import { T_IO_METHOD_NAMES, T_IO_PROPS, T_IO_STATE } from '../ioSchema'; | ||
import { T_IO_DISPLAY_METHOD_NAMES, T_IO_INPUT_METHOD_NAMES, T_IO_METHOD_NAMES, T_IO_PROPS, T_IO_STATE } from '../ioSchema'; | ||
import IOComponent, { ComponentReturnValue } from './IOComponent'; | ||
import IOError from './IOError'; | ||
import { ComponentRenderer } from '../types'; | ||
import { ComponentRenderer, ComponentsRenderer, GroupIOPromise, MaybeOptionalGroupIOPromise, OptionalGroupIOPromise } from '../types'; | ||
/** | ||
@@ -14,9 +14,10 @@ * A custom wrapper class that handles creating the underlying component | ||
export declare class IOPromise<MethodName extends T_IO_METHOD_NAMES, Props = T_IO_PROPS<MethodName>, Output = ComponentReturnValue<MethodName>> { | ||
methodName: MethodName; | ||
renderer: ComponentRenderer<MethodName>; | ||
label: string; | ||
props: Props; | ||
valueGetter: ((response: ComponentReturnValue<MethodName>) => Output) | undefined; | ||
onStateChange: ((incomingState: T_IO_STATE<MethodName>) => Promise<Partial<Props>>) | undefined; | ||
constructor({ renderer, methodName, label, props, valueGetter, onStateChange, }: { | ||
protected methodName: MethodName; | ||
protected renderer: ComponentRenderer<MethodName>; | ||
protected label: string; | ||
protected props: Props; | ||
protected valueGetter: ((response: ComponentReturnValue<MethodName>) => Output) | undefined; | ||
protected onStateChange: ((incomingState: T_IO_STATE<MethodName>) => Promise<Partial<Props>>) | undefined; | ||
protected validator: IOPromiseValidator<Output> | undefined; | ||
constructor({ renderer, methodName, label, props, valueGetter, onStateChange, validator, }: { | ||
renderer: ComponentRenderer<MethodName>; | ||
@@ -28,2 +29,3 @@ methodName: MethodName; | ||
onStateChange?: (incomingState: T_IO_STATE<MethodName>) => Promise<Partial<Props>>; | ||
validator?: IOPromiseValidator<Output> | undefined; | ||
}); | ||
@@ -33,5 +35,17 @@ then(resolve: (output: Output) => void, reject?: (err: IOError) => void): void; | ||
get component(): IOComponent<MethodName>; | ||
} | ||
/** | ||
* A thin subtype of IOPromise that does nothing but mark the component | ||
* as "display" for display-only components. | ||
*/ | ||
export declare class DisplayIOPromise<MethodName extends T_IO_DISPLAY_METHOD_NAMES, Props = T_IO_PROPS<MethodName>, Output = ComponentReturnValue<MethodName>> extends IOPromise<MethodName, Props, Output> { | ||
} | ||
export declare class InputIOPromise<MethodName extends T_IO_INPUT_METHOD_NAMES, Props = T_IO_PROPS<MethodName>, Output = ComponentReturnValue<MethodName>> extends IOPromise<MethodName, Props, Output> { | ||
#private; | ||
get component(): IOComponent<MethodName>; | ||
validate(validator: IOPromiseValidator<Output>): this; | ||
optional(isOptional?: true): OptionalIOPromise<MethodName, Props, Output>; | ||
optional(isOptional?: false): IOPromise<MethodName, Props, Output>; | ||
optional(isOptional?: boolean): OptionalIOPromise<MethodName, Props, Output> | IOPromise<MethodName, Props, Output>; | ||
exclusive(): ExclusiveIOPromise<MethodName, Props, Output>; | ||
} | ||
@@ -42,3 +56,4 @@ /** | ||
*/ | ||
export declare class OptionalIOPromise<MethodName extends T_IO_METHOD_NAMES, Props = T_IO_PROPS<MethodName>, Output = ComponentReturnValue<MethodName>> extends IOPromise<MethodName, Props, Output | undefined> { | ||
export declare class OptionalIOPromise<MethodName extends T_IO_INPUT_METHOD_NAMES, Props = T_IO_PROPS<MethodName>, Output = ComponentReturnValue<MethodName>> extends InputIOPromise<MethodName, Props, Output | undefined> { | ||
#private; | ||
then(resolve: (output: Output | undefined) => void, reject?: (err: IOError) => void): void; | ||
@@ -52,3 +67,29 @@ get component(): IOComponent<MethodName>; | ||
*/ | ||
export declare class ExclusiveIOPromise<MethodName extends T_IO_METHOD_NAMES, Props = T_IO_PROPS<MethodName>, Output = ComponentReturnValue<MethodName>> extends IOPromise<MethodName, Props, Output> { | ||
export declare class ExclusiveIOPromise<MethodName extends T_IO_INPUT_METHOD_NAMES, Props = T_IO_PROPS<MethodName>, Output = ComponentReturnValue<MethodName>> extends InputIOPromise<MethodName, Props, Output> { | ||
} | ||
export declare type IOGroupReturnValues<IOPromises extends [ | ||
MaybeOptionalGroupIOPromise, | ||
...MaybeOptionalGroupIOPromise[] | ||
]> = { | ||
[Idx in keyof IOPromises]: IOPromises[Idx] extends GroupIOPromise ? ReturnType<IOPromises[Idx]['getValue']> : IOPromises[Idx] extends OptionalGroupIOPromise ? ReturnType<IOPromises[Idx]['getValue']> : IOPromises[Idx]; | ||
}; | ||
export declare type IOGroupComponents<IOPromises extends [ | ||
MaybeOptionalGroupIOPromise, | ||
...MaybeOptionalGroupIOPromise[] | ||
]> = { | ||
[Idx in keyof IOPromises]: IOPromises[Idx] extends GroupIOPromise ? IOPromises[Idx]['component'] : IOPromises[Idx] extends OptionalGroupIOPromise ? IOPromises[Idx]['component'] : IOPromises[Idx]; | ||
}; | ||
export declare type IOPromiseValidator<ReturnValue> = (returnValue: ReturnValue) => string | undefined | Promise<string | undefined>; | ||
export declare class IOGroupPromise<IOPromises extends MaybeOptionalGroupIOPromise[], ReturnValues = IOPromises extends [ | ||
MaybeOptionalGroupIOPromise, | ||
...MaybeOptionalGroupIOPromise[] | ||
] ? IOGroupReturnValues<IOPromises> : unknown[]> { | ||
#private; | ||
promises: IOPromises; | ||
constructor(config: { | ||
promises: IOPromises; | ||
renderer: ComponentsRenderer; | ||
}); | ||
then(resolve: (output: ReturnValues) => void, reject?: (err: IOError) => void): void; | ||
validate(validator: IOPromiseValidator<ReturnValues> | undefined): this; | ||
} |
"use strict"; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
if (kind === "m") throw new TypeError("Private method is not writable"); | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); | ||
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
var _InputIOPromise_instances, _InputIOPromise_handleValidation, _OptionalIOPromise_instances, _OptionalIOPromise_handleValidation, _IOGroupPromise_instances, _IOGroupPromise_renderer, _IOGroupPromise_validator, _IOGroupPromise_handleValidation; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ExclusiveIOPromise = exports.OptionalIOPromise = exports.IOPromise = void 0; | ||
exports.IOGroupPromise = exports.ExclusiveIOPromise = exports.OptionalIOPromise = exports.InputIOPromise = exports.DisplayIOPromise = exports.IOPromise = void 0; | ||
const IOComponent_1 = __importDefault(require("./IOComponent")); | ||
@@ -17,3 +29,3 @@ /** | ||
class IOPromise { | ||
constructor({ renderer, methodName, label, props, valueGetter, onStateChange, }) { | ||
constructor({ renderer, methodName, label, props, valueGetter, onStateChange, validator, }) { | ||
this.renderer = renderer; | ||
@@ -25,2 +37,3 @@ this.methodName = methodName; | ||
this.onStateChange = onStateChange; | ||
this.validator = validator; | ||
} | ||
@@ -43,9 +56,59 @@ then(resolve, reject) { | ||
get component() { | ||
return new IOComponent_1.default(this.methodName, this.label, this.props, this.onStateChange); | ||
return new IOComponent_1.default(this.methodName, this.label, this.props, this.onStateChange, false); | ||
} | ||
} | ||
exports.IOPromise = IOPromise; | ||
/** | ||
* A thin subtype of IOPromise that does nothing but mark the component | ||
* as "display" for display-only components. | ||
*/ | ||
class DisplayIOPromise extends IOPromise { | ||
} | ||
exports.DisplayIOPromise = DisplayIOPromise; | ||
class InputIOPromise extends IOPromise { | ||
constructor() { | ||
super(...arguments); | ||
_InputIOPromise_instances.add(this); | ||
} | ||
get component() { | ||
return new IOComponent_1.default(this.methodName, this.label, this.props, this.onStateChange, false, this.validator ? __classPrivateFieldGet(this, _InputIOPromise_instances, "m", _InputIOPromise_handleValidation).bind(this) : undefined); | ||
} | ||
validate(validator) { | ||
this.validator = validator; | ||
return this; | ||
} | ||
optional(isOptional = true) { | ||
return isOptional ? new OptionalIOPromise(this) : this; | ||
return isOptional | ||
? new OptionalIOPromise({ | ||
renderer: this.renderer, | ||
methodName: this.methodName, | ||
label: this.label, | ||
props: this.props, | ||
valueGetter: this.valueGetter, | ||
onStateChange: this.onStateChange, | ||
}) | ||
: this; | ||
} | ||
exclusive() { | ||
return new ExclusiveIOPromise({ | ||
renderer: this.renderer, | ||
methodName: this.methodName, | ||
label: this.label, | ||
props: this.props, | ||
valueGetter: this.valueGetter, | ||
onStateChange: this.onStateChange, | ||
validator: this.validator, | ||
}); | ||
} | ||
} | ||
exports.IOPromise = IOPromise; | ||
exports.InputIOPromise = InputIOPromise; | ||
_InputIOPromise_instances = new WeakSet(), _InputIOPromise_handleValidation = async function _InputIOPromise_handleValidation(returnValue) { | ||
if (returnValue === undefined) { | ||
// This should be caught already, primarily here for types | ||
return 'This field is required.'; | ||
} | ||
if (this.validator) { | ||
return this.validator(this.getValue(returnValue)); | ||
} | ||
}; | ||
/** | ||
@@ -55,3 +118,7 @@ * A thin subclass of IOPromise that marks its inner component as | ||
*/ | ||
class OptionalIOPromise extends IOPromise { | ||
class OptionalIOPromise extends InputIOPromise { | ||
constructor() { | ||
super(...arguments); | ||
_OptionalIOPromise_instances.add(this); | ||
} | ||
then(resolve, reject) { | ||
@@ -68,3 +135,3 @@ this.renderer([this.component]) | ||
get component() { | ||
return new IOComponent_1.default(this.methodName, this.label, this.props, this.onStateChange, true); | ||
return new IOComponent_1.default(this.methodName, this.label, this.props, this.onStateChange, true, this.validator ? __classPrivateFieldGet(this, _OptionalIOPromise_instances, "m", _OptionalIOPromise_handleValidation).bind(this) : undefined); | ||
} | ||
@@ -80,2 +147,7 @@ getValue(result) { | ||
exports.OptionalIOPromise = OptionalIOPromise; | ||
_OptionalIOPromise_instances = new WeakSet(), _OptionalIOPromise_handleValidation = async function _OptionalIOPromise_handleValidation(returnValue) { | ||
if (this.validator) { | ||
return this.validator(this.getValue(returnValue)); | ||
} | ||
}; | ||
/** | ||
@@ -85,4 +157,37 @@ * A thin subclass of IOPromise that does nothing but mark the component | ||
*/ | ||
class ExclusiveIOPromise extends IOPromise { | ||
class ExclusiveIOPromise extends InputIOPromise { | ||
} | ||
exports.ExclusiveIOPromise = ExclusiveIOPromise; | ||
class IOGroupPromise { | ||
constructor(config) { | ||
_IOGroupPromise_instances.add(this); | ||
_IOGroupPromise_renderer.set(this, void 0); | ||
_IOGroupPromise_validator.set(this, void 0); | ||
this.promises = config.promises; | ||
__classPrivateFieldSet(this, _IOGroupPromise_renderer, config.renderer, "f"); | ||
} | ||
then(resolve, reject) { | ||
__classPrivateFieldGet(this, _IOGroupPromise_renderer, "f").call(this, this.promises.map(p => p.component), __classPrivateFieldGet(this, _IOGroupPromise_validator, "f") ? __classPrivateFieldGet(this, _IOGroupPromise_instances, "m", _IOGroupPromise_handleValidation).bind(this) : undefined) | ||
.then(values => { | ||
resolve(values.map((val, i) => this.promises[i].getValue(val))); | ||
}) | ||
.catch(err => { | ||
if (reject) | ||
reject(err); | ||
}); | ||
} | ||
validate(validator) { | ||
__classPrivateFieldSet(this, _IOGroupPromise_validator, validator, "f"); | ||
return this; | ||
} | ||
} | ||
exports.IOGroupPromise = IOGroupPromise; | ||
_IOGroupPromise_renderer = new WeakMap(), _IOGroupPromise_validator = new WeakMap(), _IOGroupPromise_instances = new WeakSet(), _IOGroupPromise_handleValidation = | ||
// These types aren't as tight as they could be, but | ||
// TypeScript doesn't like IOGroupComponents defined above here | ||
async function _IOGroupPromise_handleValidation(returnValues) { | ||
if (!__classPrivateFieldGet(this, _IOGroupPromise_validator, "f")) | ||
return; | ||
const values = returnValues.map((v, index) => this.promises[index].getValue(v)); | ||
return __classPrivateFieldGet(this, _IOGroupPromise_validator, "f").call(this, values); | ||
}; |
@@ -6,11 +6,2 @@ "use strict"; | ||
const component = (methodName, label, initialProps, handleStateChange) => { | ||
const schema = ioSchema_1.ioSchema[methodName]; | ||
try { | ||
initialProps = schema.props.parse(initialProps !== null && initialProps !== void 0 ? initialProps : {}); | ||
} | ||
catch (err) { | ||
console.error(`Invalid props found for IO call with label "${label}":`); | ||
console.error(err); | ||
throw err; | ||
} | ||
const instance = { | ||
@@ -29,2 +20,3 @@ methodName, | ||
}); | ||
const schema = ioSchema_1.ioSchema[methodName]; | ||
function setReturnValue(value) { | ||
@@ -31,0 +23,0 @@ const returnSchema = instance.isOptional |
import { z } from 'zod'; | ||
import { T_IO_PROPS, T_IO_RETURNS, labelValue } from '../ioSchema'; | ||
import Logger from '../classes/Logger'; | ||
declare type SelectMultipleProps<Option extends z.infer<typeof labelValue> | string> = Omit<T_IO_PROPS<'SELECT_MULTIPLE'>, 'options' | 'defaultValue'> & { | ||
@@ -7,3 +8,6 @@ options: Option[]; | ||
}; | ||
export default function selectMultiple<Option extends z.infer<typeof labelValue> | string>(props: SelectMultipleProps<Option>): { | ||
export default function selectMultiple(logger: Logger): <Option extends string | { | ||
value: string; | ||
label: string; | ||
}>(props: SelectMultipleProps<Option>) => { | ||
props: { | ||
@@ -10,0 +14,0 @@ defaultValue: { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const ioSchema_1 = require("../ioSchema"); | ||
function selectMultiple(props) { | ||
var _a; | ||
const normalizedOptions = props.options.map(option => { | ||
if (typeof option === 'string') { | ||
return { | ||
label: option, | ||
value: option, | ||
}; | ||
function selectMultiple(logger) { | ||
return (props) => { | ||
var _a; | ||
const normalizedOptions = props.options.map(option => { | ||
if (typeof option === 'string') { | ||
return { | ||
label: option, | ||
value: option, | ||
}; | ||
} | ||
else { | ||
return option; | ||
} | ||
}); | ||
const optionMap = new Map(normalizedOptions.map((o, i) => [o.value, props.options[i]])); | ||
let defaultValue = (_a = props.defaultValue) === null || _a === void 0 ? void 0 : _a.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 = []; | ||
} | ||
else { | ||
return option; | ||
} | ||
}); | ||
const optionMap = new Map(normalizedOptions.map((o, i) => [o.value, props.options[i]])); | ||
const defaultValue = (_a = props.defaultValue) === null || _a === void 0 ? void 0 : _a.map(d => { | ||
if (typeof d === 'string') { | ||
return { | ||
label: d, | ||
value: d, | ||
}; | ||
} | ||
else { | ||
return d; | ||
} | ||
}); | ||
const stripper = ioSchema_1.labelValue.strip(); | ||
return { | ||
props: { | ||
...props, | ||
defaultValue: defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.map(o => stripper.parse(o)), | ||
options: normalizedOptions.map(o => stripper.parse(o)), | ||
}, | ||
getValue(response) { | ||
return response.map(r => optionMap.get(r.value)); | ||
}, | ||
const stripper = ioSchema_1.labelValue.strip(); | ||
return { | ||
props: { | ||
...props, | ||
defaultValue: defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.map(o => stripper.parse(o)), | ||
options: normalizedOptions.map(o => stripper.parse(o)), | ||
}, | ||
getValue(response) { | ||
return response.map(r => optionMap.get(r.value)); | ||
}, | ||
}; | ||
}; | ||
} | ||
exports.default = selectMultiple; |
import { z } from 'zod'; | ||
import { T_IO_PROPS, T_IO_RETURNS, richSelectOption } from '../ioSchema'; | ||
import Logger from '../classes/Logger'; | ||
declare type SelectSingleProps<Option extends z.infer<typeof richSelectOption> | string> = Omit<T_IO_PROPS<'SELECT_SINGLE'>, 'options' | 'defaultValue'> & { | ||
@@ -7,3 +8,8 @@ options: Option[]; | ||
}; | ||
export default function selectSingle<Option extends z.infer<typeof richSelectOption> | string>(props: SelectSingleProps<Option>): { | ||
export default function selectSingle(logger: Logger): <Option extends string | { | ||
description?: string | null | undefined; | ||
imageUrl?: string | null | undefined; | ||
value: string; | ||
label: string; | ||
}>(props: SelectSingleProps<Option>) => { | ||
props: { | ||
@@ -10,0 +16,0 @@ defaultValue: { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const ioSchema_1 = require("../ioSchema"); | ||
function selectSingle(props) { | ||
const normalizedOptions = props.options.map(option => { | ||
if (typeof option === 'string') { | ||
return { | ||
label: option, | ||
value: option, | ||
}; | ||
function selectSingle(logger) { | ||
return (props) => { | ||
const normalizedOptions = props.options.map(option => { | ||
if (typeof option === 'string') { | ||
return { | ||
label: option, | ||
value: option, | ||
}; | ||
} | ||
else { | ||
return option; | ||
} | ||
}); | ||
const optionMap = new Map(normalizedOptions.map((o, i) => [o.value, props.options[i]])); | ||
const stripper = ioSchema_1.richSelectOption.strip(); | ||
let defaultValue = typeof props.defaultValue === 'string' | ||
? { | ||
label: props.defaultValue, | ||
value: props.defaultValue, | ||
} | ||
: props.defaultValue; | ||
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; | ||
} | ||
else { | ||
return option; | ||
} | ||
}); | ||
const optionMap = new Map(normalizedOptions.map((o, i) => [o.value, props.options[i]])); | ||
const stripper = ioSchema_1.richSelectOption.strip(); | ||
const defaultValue = typeof props.defaultValue === 'string' | ||
? { | ||
label: props.defaultValue, | ||
value: props.defaultValue, | ||
} | ||
: props.defaultValue; | ||
return { | ||
props: { | ||
...props, | ||
defaultValue: defaultValue ? stripper.parse(defaultValue) : undefined, | ||
options: normalizedOptions.map(o => stripper.parse(o)), | ||
}, | ||
getValue(response) { | ||
return optionMap.get(response.value); | ||
}, | ||
return { | ||
props: { | ||
...props, | ||
defaultValue: defaultValue ? stripper.parse(defaultValue) : undefined, | ||
options: normalizedOptions.map(o => stripper.parse(o)), | ||
}, | ||
getValue(response) { | ||
return optionMap.get(response.value); | ||
}, | ||
}; | ||
}; | ||
} | ||
exports.default = selectSingle; |
@@ -1,3 +0,1 @@ | ||
/// <reference types="node" /> | ||
import type { IncomingMessage, ServerResponse } from 'http'; | ||
import IOError from './classes/IOError'; | ||
@@ -7,8 +5,9 @@ import Logger from './classes/Logger'; | ||
import { SerializableRecord } from './ioSchema'; | ||
import type { ActionCtx, ActionLogFn, IO, IntervalActionHandler, IntervalActionDefinition, IntervalActionStore, NotifyConfig } from './types'; | ||
import { HttpRequestBody, LambdaRequestPayload, LambdaResponse } from './utils/http'; | ||
import type { ActionCtx, ActionLogFn, IO, IntervalActionHandler, IntervalActionStore, NotifyConfig, IntervalActionDefinitions } from './types'; | ||
import ActionGroup from './classes/ActionGroup'; | ||
export type { ActionCtx, ActionLogFn, IO, IntervalActionHandler, IntervalActionStore, }; | ||
export interface InternalConfig { | ||
apiKey?: string; | ||
actions?: Record<string, IntervalActionDefinition>; | ||
actions?: IntervalActionDefinitions; | ||
groups?: Record<string, ActionGroup>; | ||
endpoint?: string; | ||
@@ -40,9 +39,9 @@ logLevel?: 'prod' | 'debug'; | ||
environment: ActionEnvironment | undefined; | ||
constructor(config: InternalConfig); | ||
constructor(config: Omit<InternalConfig, 'groups'>); | ||
protected get apiKey(): string | undefined; | ||
protected get httpEndpoint(): string; | ||
protected get log(): Logger; | ||
get isConnected(): boolean; | ||
listen(): Promise<void>; | ||
close(): void | undefined; | ||
handleRequest({ requestId, httpHostId, }: HttpRequestBody): Promise<boolean>; | ||
get httpRequestHandler(): (req: IncomingMessage, res: ServerResponse) => Promise<ServerResponse>; | ||
get lambdaRequestHandler(): (event: LambdaRequestPayload) => Promise<LambdaResponse>; | ||
notify(config: NotifyConfig): Promise<void>; | ||
@@ -49,0 +48,0 @@ } |
@@ -39,3 +39,3 @@ "use strict"; | ||
}; | ||
var _Interval_instances, _Interval_logger, _Interval_client, _Interval_apiKey, _Interval_httpEndpoint, _Interval_log_get, _Interval_respondToRequest, _Interval_declareHost, _Actions_instances, _Actions_logger, _Actions_apiKey, _Actions_endpoint, _Actions_getAddress; | ||
var _Interval_instances, _Interval_logger, _Interval_client, _Interval_apiKey, _Interval_httpEndpoint, _Interval_log_get, _Actions_instances, _Actions_logger, _Actions_apiKey, _Actions_endpoint, _Actions_getAddress; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -49,5 +49,3 @@ exports.IOError = exports.Interval = exports.ctx = exports.io = exports.getActionStore = exports.IntervalError = void 0; | ||
const internalRpcSchema_1 = require("./internalRpcSchema"); | ||
const pkg = __importStar(require("../package.json")); | ||
const IntervalClient_1 = __importStar(require("./classes/IntervalClient")); | ||
const http_1 = require("./utils/http"); | ||
class IntervalError extends Error { | ||
@@ -102,2 +100,11 @@ constructor(message) { | ||
} | ||
get apiKey() { | ||
return __classPrivateFieldGet(this, _Interval_apiKey, "f"); | ||
} | ||
get httpEndpoint() { | ||
return __classPrivateFieldGet(this, _Interval_httpEndpoint, "f"); | ||
} | ||
get log() { | ||
return __classPrivateFieldGet(this, _Interval_logger, "f"); | ||
} | ||
get isConnected() { | ||
@@ -117,91 +124,2 @@ var _a, _b; | ||
} | ||
/* | ||
* Handle a serverless host endpoint request. Receives the deserialized request body object. | ||
*/ | ||
async handleRequest({ requestId, httpHostId, }) { | ||
if (requestId) { | ||
await __classPrivateFieldGet(this, _Interval_instances, "m", _Interval_respondToRequest).call(this, requestId); | ||
return true; | ||
} | ||
else if (httpHostId) { | ||
await __classPrivateFieldGet(this, _Interval_instances, "m", _Interval_declareHost).call(this, httpHostId); | ||
return true; | ||
} | ||
else { | ||
return false; | ||
} | ||
} | ||
// A getter that returns a function instead of a method to avoid `this` binding issues. | ||
get httpRequestHandler() { | ||
const interval = this; | ||
return async (req, res) => { | ||
// TODO: Proper headers | ||
if (req.method === 'GET') { | ||
return res.writeHead(200).end('OK'); | ||
} | ||
if (req.method !== 'POST') { | ||
return res.writeHead(405).end(); | ||
} | ||
try { | ||
const body = await (0, http_1.getRequestBody)(req); | ||
if (!body || typeof body !== 'object' || Array.isArray(body)) { | ||
return res.writeHead(400).end(); | ||
} | ||
const successful = await interval.handleRequest(body); | ||
return res.writeHead(successful ? 200 : 400).end(); | ||
} | ||
catch (err) { | ||
__classPrivateFieldGet(interval, _Interval_instances, "a", _Interval_log_get).error('Error in HTTP request handler:', err); | ||
return res.writeHead(500).end(); | ||
} | ||
}; | ||
} | ||
// A getter that returns a function instead of a method to avoid `this` binding issues. | ||
get lambdaRequestHandler() { | ||
const interval = this; | ||
return async (event) => { | ||
function makeResponse(statusCode, body) { | ||
return { | ||
isBase64Encoded: false, | ||
statusCode, | ||
body: body | ||
? typeof body === 'string' | ||
? body | ||
: JSON.stringify(body) | ||
: '', | ||
headers: body && typeof body !== 'string' | ||
? { | ||
'content-type': 'application/json', | ||
} | ||
: {}, | ||
}; | ||
} | ||
if (event.requestContext.http.method === 'GET') { | ||
return makeResponse(200); | ||
} | ||
if (event.requestContext.http.method !== 'POST') { | ||
return makeResponse(405); | ||
} | ||
try { | ||
let body; | ||
if (event.body) { | ||
try { | ||
body = JSON.parse(event.body); | ||
} | ||
catch (err) { | ||
__classPrivateFieldGet(this, _Interval_instances, "a", _Interval_log_get).error('Failed parsing input body as JSON', event.body); | ||
} | ||
} | ||
if (!body) { | ||
return makeResponse(400); | ||
} | ||
const successful = await interval.handleRequest(body); | ||
return makeResponse(successful ? 200 : 500); | ||
} | ||
catch (err) { | ||
__classPrivateFieldGet(this, _Interval_instances, "a", _Interval_log_get).error('Error in Lambda handler', err); | ||
return makeResponse(500); | ||
} | ||
}; | ||
} | ||
async notify(config) { | ||
@@ -246,62 +164,2 @@ let body; | ||
return __classPrivateFieldGet(this, _Interval_logger, "f"); | ||
}, _Interval_respondToRequest = | ||
/** | ||
* Always creates a new host connection to Interval and uses it only for the single request. | ||
*/ | ||
async function _Interval_respondToRequest(requestId) { | ||
if (!requestId) { | ||
throw new Error('Missing request ID'); | ||
} | ||
const client = new IntervalClient_1.default(this, this.config); | ||
const response = await client.respondToRequest(requestId); | ||
client.close(); | ||
return response; | ||
}, _Interval_declareHost = async function _Interval_declareHost(httpHostId) { | ||
var _a; | ||
const actions = Object.entries((_a = this.config.actions) !== null && _a !== void 0 ? _a : {}).map(([slug, def]) => ({ | ||
slug, | ||
...('handler' in def ? def : {}), | ||
handler: undefined, | ||
})); | ||
const slugs = actions.map(a => a.slug); | ||
if (slugs.length === 0) { | ||
__classPrivateFieldGet(this, _Interval_instances, "a", _Interval_log_get).prod('No actions defined, skipping host declaration'); | ||
return; | ||
} | ||
const body = { | ||
httpHostId, | ||
actions, | ||
sdkName: pkg.name, | ||
sdkVersion: pkg.version, | ||
}; | ||
const response = await (0, node_fetch_1.default)(`${__classPrivateFieldGet(this, _Interval_httpEndpoint, "f")}/api/hosts/declare`, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
Authorization: `Bearer ${__classPrivateFieldGet(this, _Interval_apiKey, "f")}`, | ||
}, | ||
body: JSON.stringify(body), | ||
}) | ||
.then(r => r.json()) | ||
.then(r => internalRpcSchema_1.DECLARE_HOST.returns.parseAsync(r)) | ||
.catch(err => { | ||
__classPrivateFieldGet(this, _Interval_logger, "f").debug(err); | ||
throw new IntervalError('Received invalid API response.'); | ||
}); | ||
if (response.type === 'error') { | ||
throw new IntervalError(`There was a problem declaring the host: ${response.message}`); | ||
} | ||
if (response.sdkAlert) { | ||
__classPrivateFieldGet(this, _Interval_instances, "a", _Interval_log_get).handleSdkAlert(response.sdkAlert); | ||
} | ||
if (response.invalidSlugs.length > 0) { | ||
__classPrivateFieldGet(this, _Interval_instances, "a", _Interval_log_get).warn('[Interval]', '⚠ Invalid slugs detected:\n'); | ||
for (const slug of response.invalidSlugs) { | ||
__classPrivateFieldGet(this, _Interval_instances, "a", _Interval_log_get).warn(` - ${slug}`); | ||
} | ||
__classPrivateFieldGet(this, _Interval_instances, "a", _Interval_log_get).warn('\nAction slugs must contain only letters, numbers, underscores, periods, and hyphens.'); | ||
if (response.invalidSlugs.length === slugs.length) { | ||
throw new IntervalError('No valid slugs provided'); | ||
} | ||
} | ||
}; | ||
@@ -308,0 +166,0 @@ /** |
@@ -68,2 +68,3 @@ import { z } from 'zod'; | ||
export declare const ACTION_DEFINITION: z.ZodObject<{ | ||
groupSlug: z.ZodOptional<z.ZodString>; | ||
slug: z.ZodString; | ||
@@ -76,2 +77,3 @@ name: z.ZodOptional<z.ZodString>; | ||
name?: string | undefined; | ||
groupSlug?: string | undefined; | ||
backgroundable?: boolean | undefined; | ||
@@ -82,2 +84,3 @@ slug: string; | ||
name?: string | undefined; | ||
groupSlug?: string | undefined; | ||
backgroundable?: boolean | undefined; | ||
@@ -87,2 +90,13 @@ slug: string; | ||
export declare type ActionDefinition = z.infer<typeof ACTION_DEFINITION>; | ||
export declare const GROUP_DEFINITION: z.ZodObject<{ | ||
slug: z.ZodString; | ||
name: z.ZodString; | ||
}, "strip", z.ZodTypeAny, { | ||
name: string; | ||
slug: string; | ||
}, { | ||
name: string; | ||
slug: string; | ||
}>; | ||
export declare type GroupDefinition = z.infer<typeof GROUP_DEFINITION>; | ||
export declare const ENQUEUE_ACTION: { | ||
@@ -231,2 +245,3 @@ inputs: z.ZodObject<{ | ||
actions: z.ZodArray<z.ZodObject<{ | ||
groupSlug: z.ZodOptional<z.ZodString>; | ||
slug: z.ZodString; | ||
@@ -239,2 +254,3 @@ name: z.ZodOptional<z.ZodString>; | ||
name?: string | undefined; | ||
groupSlug?: string | undefined; | ||
backgroundable?: boolean | undefined; | ||
@@ -245,8 +261,23 @@ slug: string; | ||
name?: string | undefined; | ||
groupSlug?: string | undefined; | ||
backgroundable?: boolean | undefined; | ||
slug: string; | ||
}>, "many">; | ||
groups: z.ZodOptional<z.ZodArray<z.ZodObject<{ | ||
slug: z.ZodString; | ||
name: z.ZodString; | ||
}, "strip", z.ZodTypeAny, { | ||
name: string; | ||
slug: string; | ||
}, { | ||
name: string; | ||
slug: string; | ||
}>, "many">>; | ||
sdkName: z.ZodString; | ||
sdkVersion: z.ZodString; | ||
}, "strip", z.ZodTypeAny, { | ||
groups?: { | ||
name: string; | ||
slug: string; | ||
}[] | undefined; | ||
httpHostId: string; | ||
@@ -256,2 +287,3 @@ actions: { | ||
name?: string | undefined; | ||
groupSlug?: string | undefined; | ||
backgroundable?: boolean | undefined; | ||
@@ -263,2 +295,6 @@ slug: string; | ||
}, { | ||
groups?: { | ||
name: string; | ||
slug: string; | ||
}[] | undefined; | ||
httpHostId: string; | ||
@@ -268,2 +304,3 @@ actions: { | ||
name?: string | undefined; | ||
groupSlug?: string | undefined; | ||
backgroundable?: boolean | undefined; | ||
@@ -505,2 +542,3 @@ slug: string; | ||
actions: z.ZodArray<z.ZodObject<{ | ||
groupSlug: z.ZodOptional<z.ZodString>; | ||
slug: z.ZodString; | ||
@@ -513,2 +551,3 @@ name: z.ZodOptional<z.ZodString>; | ||
name?: string | undefined; | ||
groupSlug?: string | undefined; | ||
backgroundable?: boolean | undefined; | ||
@@ -519,9 +558,25 @@ slug: string; | ||
name?: string | undefined; | ||
groupSlug?: string | undefined; | ||
backgroundable?: boolean | undefined; | ||
slug: string; | ||
}>, "many">; | ||
groups: z.ZodOptional<z.ZodArray<z.ZodObject<{ | ||
slug: z.ZodString; | ||
name: z.ZodString; | ||
}, "strip", z.ZodTypeAny, { | ||
name: string; | ||
slug: string; | ||
}, { | ||
name: string; | ||
slug: string; | ||
}>, "many">>; | ||
}, "strip", z.ZodTypeAny, { | ||
groups?: { | ||
name: string; | ||
slug: string; | ||
}[] | undefined; | ||
actions: { | ||
description?: string | undefined; | ||
name?: string | undefined; | ||
groupSlug?: string | undefined; | ||
backgroundable?: boolean | undefined; | ||
@@ -531,5 +586,10 @@ slug: string; | ||
}, { | ||
groups?: { | ||
name: string; | ||
slug: string; | ||
}[] | undefined; | ||
actions: { | ||
description?: string | undefined; | ||
name?: string | undefined; | ||
groupSlug?: string | undefined; | ||
backgroundable?: boolean | undefined; | ||
@@ -536,0 +596,0 @@ slug: string; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.hostSchema = exports.clientSchema = exports.wsServerSchema = exports.DECLARE_HOST = exports.NOTIFY = exports.DEQUEUE_ACTION = exports.CREATE_GHOST_MODE_ACCOUNT = exports.ENQUEUE_ACTION = exports.ACTION_DEFINITION = exports.LOADING_OPTIONS = exports.actionEnvironment = exports.TRANSACTION_RESULT_SCHEMA_VERSION = exports.DUPLEX_MESSAGE_SCHEMA = void 0; | ||
exports.hostSchema = exports.clientSchema = exports.wsServerSchema = exports.DECLARE_HOST = exports.NOTIFY = exports.DEQUEUE_ACTION = exports.CREATE_GHOST_MODE_ACCOUNT = exports.ENQUEUE_ACTION = exports.GROUP_DEFINITION = exports.ACTION_DEFINITION = exports.LOADING_OPTIONS = exports.actionEnvironment = exports.TRANSACTION_RESULT_SCHEMA_VERSION = exports.DUPLEX_MESSAGE_SCHEMA = void 0; | ||
const zod_1 = require("zod"); | ||
@@ -31,2 +31,3 @@ const ioSchema_1 = require("./ioSchema"); | ||
exports.ACTION_DEFINITION = zod_1.z.object({ | ||
groupSlug: zod_1.z.string().optional(), | ||
slug: zod_1.z.string(), | ||
@@ -37,2 +38,6 @@ name: zod_1.z.string().optional(), | ||
}); | ||
exports.GROUP_DEFINITION = zod_1.z.object({ | ||
slug: zod_1.z.string(), | ||
name: zod_1.z.string(), | ||
}); | ||
exports.ENQUEUE_ACTION = { | ||
@@ -106,2 +111,3 @@ inputs: zod_1.z.object({ | ||
actions: zod_1.z.array(exports.ACTION_DEFINITION), | ||
groups: zod_1.z.array(exports.GROUP_DEFINITION).optional(), | ||
sdkName: zod_1.z.string(), | ||
@@ -198,2 +204,3 @@ sdkVersion: zod_1.z.string(), | ||
actions: zod_1.z.array(exports.ACTION_DEFINITION), | ||
groups: zod_1.z.array(exports.GROUP_DEFINITION).optional(), | ||
}), | ||
@@ -200,0 +207,0 @@ ])), |
@@ -86,4 +86,2 @@ import { z } from 'zod'; | ||
helpText?: string | undefined; | ||
minSelections?: number | undefined; | ||
maxSelections?: number | undefined; | ||
options: { | ||
@@ -99,8 +97,4 @@ value: string; | ||
helpText?: string | undefined; | ||
minSelections?: number | undefined; | ||
maxSelections?: number | undefined; | ||
data: (Record<string, string | number | boolean | Date | { | ||
value?: string | number | boolean | Date | null | undefined; | ||
action?: string | undefined; | ||
params?: Record<string, string | number | boolean | Date | null | undefined> | undefined; | ||
href?: string | undefined; | ||
@@ -111,4 +105,2 @@ label: string; | ||
value?: string | number | boolean | Date | null | undefined; | ||
action?: string | undefined; | ||
params?: Record<string, string | number | boolean | Date | null | undefined> | undefined; | ||
href?: string | undefined; | ||
@@ -122,17 +114,10 @@ label: string; | ||
label: string; | ||
render: (args_0: any, ...args_1: unknown[]) => string | number | boolean | Date | ({ | ||
render: (args_0: any, ...args_1: unknown[]) => string | number | boolean | Date | { | ||
value?: string | number | boolean | Date | null | undefined; | ||
label?: string | null | undefined; | ||
} & ({ | ||
href?: string | undefined; | ||
} | { | ||
action: string; | ||
params: Record<string, string | number | boolean | Date | null | undefined>; | ||
href: never; | ||
})) | null | undefined; | ||
} | null | undefined; | ||
}[] | undefined; | ||
data: (Record<string, string | number | boolean | Date | { | ||
value?: string | number | boolean | Date | null | undefined; | ||
action?: string | undefined; | ||
params?: Record<string, string | number | boolean | Date | null | undefined> | undefined; | ||
href?: string | undefined; | ||
@@ -146,3 +131,2 @@ label: string; | ||
markdown: IOComponentFunction<"DISPLAY_MARKDOWN", null>; | ||
link: IOComponentFunction<"DISPLAY_LINK", null>; | ||
object: IOComponentFunction<"DISPLAY_OBJECT", null>; | ||
@@ -154,8 +138,4 @@ table: <Props_3 extends Omit<{ | ||
helpText?: string | undefined; | ||
minSelections?: number | undefined; | ||
maxSelections?: number | undefined; | ||
data: (Record<string, string | number | boolean | Date | { | ||
value?: string | number | boolean | Date | null | undefined; | ||
action?: string | undefined; | ||
params?: Record<string, string | number | boolean | Date | null | undefined> | undefined; | ||
href?: string | undefined; | ||
@@ -166,4 +146,2 @@ label: string; | ||
value?: string | number | boolean | Date | null | undefined; | ||
action?: string | undefined; | ||
params?: Record<string, string | number | boolean | Date | null | undefined> | undefined; | ||
href?: string | undefined; | ||
@@ -177,17 +155,10 @@ label: string; | ||
label: string; | ||
render: (args_0: any, ...args_1: unknown[]) => string | number | boolean | Date | ({ | ||
render: (args_0: any, ...args_1: unknown[]) => string | number | boolean | Date | { | ||
value?: string | number | boolean | Date | null | undefined; | ||
label?: string | null | undefined; | ||
} & ({ | ||
href?: string | undefined; | ||
} | { | ||
action: string; | ||
params: Record<string, string | number | boolean | Date | null | undefined>; | ||
href: never; | ||
})) | null | undefined; | ||
} | null | undefined; | ||
}[] | undefined; | ||
data: (Record<string, string | number | boolean | Date | { | ||
value?: string | number | boolean | Date | null | undefined; | ||
action?: string | undefined; | ||
params?: Record<string, string | number | boolean | Date | null | undefined> | undefined; | ||
href?: string | undefined; | ||
@@ -194,0 +165,0 @@ label: string; |
@@ -205,3 +205,2 @@ "use strict"; | ||
markdown: aliasComponentName('DISPLAY_MARKDOWN'), | ||
link: aliasComponentName('DISPLAY_LINK'), | ||
object: aliasComponentName('DISPLAY_OBJECT'), | ||
@@ -208,0 +207,0 @@ table: (0, table_1.displayTable)(ioPromiseConstructor), |
@@ -12,5 +12,7 @@ import { z } from 'zod'; | ||
isOptional: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>; | ||
validationErrorMessage: z.ZodOptional<z.ZodString>; | ||
}, "strip", z.ZodTypeAny, { | ||
props?: any; | ||
propsMeta?: any; | ||
validationErrorMessage?: string | undefined; | ||
methodName: string; | ||
@@ -25,7 +27,10 @@ label: string; | ||
isOptional?: boolean | undefined; | ||
validationErrorMessage?: string | undefined; | ||
methodName: string; | ||
label: string; | ||
}>, "many">; | ||
validationErrorMessage: z.ZodOptional<z.ZodString>; | ||
kind: z.ZodLiteral<"RENDER">; | ||
}, "strip", z.ZodTypeAny, { | ||
validationErrorMessage?: string | undefined; | ||
id: string; | ||
@@ -36,2 +41,3 @@ inputGroupKey: string; | ||
propsMeta?: any; | ||
validationErrorMessage?: string | undefined; | ||
methodName: string; | ||
@@ -44,2 +50,3 @@ label: string; | ||
}, { | ||
validationErrorMessage?: string | undefined; | ||
id: string; | ||
@@ -52,2 +59,3 @@ inputGroupKey: string; | ||
isOptional?: boolean | undefined; | ||
validationErrorMessage?: string | undefined; | ||
methodName: string; | ||
@@ -96,2 +104,3 @@ label: string; | ||
}>; | ||
export declare type LabelValue = z.infer<typeof labelValue>; | ||
export declare const richSelectOption: z.ZodObject<{ | ||
@@ -113,2 +122,3 @@ label: z.ZodString; | ||
}>; | ||
export declare type RichSelectOption = z.infer<typeof richSelectOption>; | ||
declare type Literal = boolean | null | number | string | Date | undefined; | ||
@@ -1467,2 +1477,4 @@ declare type KeyValue = Literal | { | ||
export declare type T_IO_METHOD_NAMES = keyof T_IO_Schema; | ||
export declare type T_IO_DISPLAY_METHOD_NAMES = 'DISPLAY_HEADING' | 'DISPLAY_MARKDOWN' | 'DISPLAY_LINK' | 'DISPLAY_OBJECT' | 'DISPLAY_TABLE'; | ||
export declare type T_IO_INPUT_METHOD_NAMES = Exclude<T_IO_METHOD_NAMES, T_IO_DISPLAY_METHOD_NAMES>; | ||
declare type T_Fields = 'props' | 'state' | 'returns'; | ||
@@ -1469,0 +1481,0 @@ export declare type T_IO_METHOD<MN extends T_IO_METHOD_NAMES, Field extends T_Fields> = z.infer<T_IO_Schema[MN][Field]>; |
@@ -15,3 +15,5 @@ "use strict"; | ||
isOptional: zod_1.z.boolean().optional().default(false), | ||
validationErrorMessage: zod_1.z.string().optional(), | ||
})), | ||
validationErrorMessage: zod_1.z.string().optional(), | ||
kind: zod_1.z.literal('RENDER'), | ||
@@ -18,0 +20,0 @@ }); |
import type { z } from 'zod'; | ||
import type { T_IO_RENDER_INPUT, T_IO_RESPONSE, T_IO_PROPS, T_IO_RETURNS, T_IO_STATE, T_IO_Schema, T_IO_METHOD_NAMES, IOFunctionReturnType } from './ioSchema'; | ||
import type { T_IO_RENDER_INPUT, T_IO_RESPONSE, T_IO_PROPS, T_IO_RETURNS, T_IO_STATE, T_IO_Schema, T_IO_METHOD_NAMES, IOFunctionReturnType, T_IO_DISPLAY_METHOD_NAMES, T_IO_INPUT_METHOD_NAMES } from './ioSchema'; | ||
import type { HostSchema } from './internalRpcSchema'; | ||
import type { IOClient } from './classes/IOClient'; | ||
import type { IOClient, IOClientRenderValidator } from './classes/IOClient'; | ||
import type IOComponent from './classes/IOComponent'; | ||
import type { ComponentReturnValue } from './classes/IOComponent'; | ||
import type { IOPromise, OptionalIOPromise, ExclusiveIOPromise } from './classes/IOPromise'; | ||
import type { AnyIOComponent, ComponentReturnValue } from './classes/IOComponent'; | ||
import type { IOPromise, OptionalIOPromise, ExclusiveIOPromise, DisplayIOPromise, InputIOPromise } from './classes/IOPromise'; | ||
import type IOError from './classes/IOError'; | ||
@@ -30,2 +30,3 @@ import type TransactionLoadingState from './classes/TransactionLoadingState'; | ||
export interface ExplicitIntervalActionDefinition { | ||
prefix?: string; | ||
handler: IntervalActionHandler; | ||
@@ -37,7 +38,21 @@ backgroundable?: boolean; | ||
export declare type IntervalActionDefinition = IntervalActionHandler | ExplicitIntervalActionDefinition; | ||
export declare type IntervalActionDefinitions = Record<string, IntervalActionDefinition>; | ||
export declare type RequiredPropsIOComponentFunction<MethodName extends T_IO_METHOD_NAMES, Props, Output = ComponentReturnValue<MethodName>> = (label: string, props: Props) => IOPromise<MethodName, T_IO_PROPS<MethodName>, Output>; | ||
export declare type RequiredPropsExclusiveIOComponentFunction<MethodName extends T_IO_METHOD_NAMES, Props, Output = ComponentReturnValue<MethodName>> = (label: string, props: Props) => ExclusiveIOPromise<MethodName, T_IO_PROPS<MethodName>, Output>; | ||
export declare type RequiredPropsExclusiveIOComponentFunction<MethodName extends T_IO_INPUT_METHOD_NAMES, Props, Output = ComponentReturnValue<MethodName>> = (label: string, props: Props) => ExclusiveIOPromise<MethodName, T_IO_PROPS<MethodName>, Output>; | ||
export declare type IOComponentFunction<MethodName extends T_IO_METHOD_NAMES, Props, Output = ComponentReturnValue<MethodName>> = (label: string, props?: Props) => IOPromise<MethodName, T_IO_PROPS<MethodName>, Output>; | ||
export declare type ExclusiveIOComponentFunction<MethodName extends T_IO_METHOD_NAMES, Props, Output = ComponentReturnValue<MethodName>> = (label: string, props?: Props) => ExclusiveIOPromise<MethodName, T_IO_PROPS<MethodName>, Output>; | ||
export declare type ComponentRenderer<MethodName extends T_IO_METHOD_NAMES> = (components: [IOComponent<MethodName>]) => Promise<[ComponentReturnValue<MethodName>]>; | ||
export declare type InputIOComponentFunction<MethodName extends T_IO_INPUT_METHOD_NAMES, Props, Output = ComponentReturnValue<MethodName>> = (label: string, props?: Props) => InputIOPromise<MethodName, T_IO_PROPS<MethodName>, Output>; | ||
export declare type RequiredPropsInputIOComponentFunction<MethodName extends T_IO_INPUT_METHOD_NAMES, Props, Output = ComponentReturnValue<MethodName>> = (label: string, props: Props) => InputIOPromise<MethodName, T_IO_PROPS<MethodName>, Output>; | ||
export declare type DisplayIOComponentFunction<MethodName extends T_IO_DISPLAY_METHOD_NAMES, Props, Output = ComponentReturnValue<MethodName>> = (label: string, props?: Props) => DisplayIOPromise<MethodName, T_IO_PROPS<MethodName>, Output>; | ||
export declare type RequiredPropsDisplayIOComponentFunction<MethodName extends T_IO_DISPLAY_METHOD_NAMES, Props, Output = ComponentReturnValue<MethodName>> = (label: string, props: Props) => DisplayIOPromise<MethodName, T_IO_PROPS<MethodName>, Output>; | ||
export declare type ExclusiveIOComponentFunction<MethodName extends T_IO_INPUT_METHOD_NAMES, Props, Output = ComponentReturnValue<MethodName>> = (label: string, props?: Props) => ExclusiveIOPromise<MethodName, T_IO_PROPS<MethodName>, Output>; | ||
export declare type ComponentRenderer<MethodName extends T_IO_METHOD_NAMES> = (components: [IOComponent<MethodName>, ...IOComponent<MethodName>[]]) => Promise<[ | ||
ComponentReturnValue<MethodName>, | ||
...ComponentReturnValue<MethodName>[] | ||
]>; | ||
export declare type ComponentsRenderer<Components extends [AnyIOComponent, ...AnyIOComponent[]] = [ | ||
AnyIOComponent, | ||
...AnyIOComponent[] | ||
]> = (components: Components, validator?: IOClientRenderValidator<Components>) => Promise<{ | ||
[Idx in keyof Components]: Components[Idx] extends AnyIOComponent ? z.infer<Components[Idx]['schema']['returns']> | undefined : Components[Idx]; | ||
}>; | ||
export declare type IORenderSender = (ioToRender: T_IO_RENDER_INPUT) => Promise<void>; | ||
@@ -73,7 +88,7 @@ export interface NotificationDeliveryInstruction { | ||
export declare type OptionalGroupIOPromiseMap = { | ||
[MethodName in T_IO_METHOD_NAMES]: T_IO_Schema[MethodName] extends { | ||
[MethodName in T_IO_INPUT_METHOD_NAMES]: T_IO_Schema[MethodName] extends { | ||
exclusive: z.ZodLiteral<true>; | ||
} ? never : OptionalIOPromise<MethodName, T_IO_PROPS<MethodName>, any>; | ||
}; | ||
export declare type OptionalGroupIOPromise = OptionalGroupIOPromiseMap[T_IO_METHOD_NAMES]; | ||
export declare type OptionalGroupIOPromise = OptionalGroupIOPromiseMap[T_IO_INPUT_METHOD_NAMES]; | ||
export declare type MaybeOptionalGroupIOPromise = GroupIOPromise | OptionalGroupIOPromise; | ||
@@ -80,0 +95,0 @@ export declare type IOComponentDefinition<MethodName extends T_IO_METHOD_NAMES, Props, Output> = (props: Props) => { |
{ | ||
"name": "@interval/sdk", | ||
"version": "0.21.0", | ||
"version": "0.22.0", | ||
"homepage": "https://interval.com", | ||
"repository": { | ||
"type": "git", | ||
"url": "github:interval/interval-node" | ||
}, | ||
"bugs": "https://github.com/interval/interval-node/issues", | ||
"keywords": ["internal tool", "app", "ui", "ui builder"], | ||
"license": "MIT", | ||
@@ -26,2 +33,3 @@ "engines": { | ||
"devDependencies": { | ||
"@faker-js/faker": "^7.3.0", | ||
"@interval/envoy": "^1.0.1", | ||
@@ -28,0 +36,0 @@ "@types/dedent": "^0.7.0", |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
76
10884
1
2
473453
10