Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion e2e/davinci-app/components/multi-value.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type { MultiSelectCollector, Updater } from '@forgerock/davinci-client/ty
export default function multiValueComponent(
formEl: HTMLFormElement,
collector: MultiSelectCollector,
updater: Updater,
updater: Updater<MultiSelectCollector>,
) {
// Create a container for the checkboxes
const containerDiv = document.createElement('div');
Expand Down
9 changes: 6 additions & 3 deletions e2e/davinci-app/components/object-value.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ import type {
export default function objectValueComponent(
formEl: HTMLFormElement,
collector: DeviceRegistrationCollector | DeviceAuthenticationCollector | PhoneNumberCollector,
updater: Updater,
updater:
| Updater<DeviceRegistrationCollector>
| Updater<DeviceAuthenticationCollector>
| Updater<PhoneNumberCollector>,
submitForm: () => void,
) {
if (
Expand Down Expand Up @@ -50,7 +53,7 @@ export default function objectValueComponent(
console.error('No value found for the selected option');
return;
}
updater(selectedValue);
updater(selectedValue as any);
submitForm();
});

Expand Down Expand Up @@ -84,7 +87,7 @@ export default function objectValueComponent(
updater({
phoneNumber: selectedValue,
countryCode: collector.output.value?.countryCode || '',
});
} as any);
});

formEl.appendChild(phoneLabel);
Expand Down
2 changes: 1 addition & 1 deletion e2e/davinci-app/components/password.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { dotToCamelCase } from '../helper.js';
export default function passwordComponent(
formEl: HTMLFormElement,
collector: PasswordCollector,
updater: Updater,
updater: Updater<PasswordCollector>,
) {
const label = document.createElement('label');
const input = document.createElement('input');
Expand Down
2 changes: 1 addition & 1 deletion e2e/davinci-app/components/protect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import type {
export default function protectComponent(
formEl: HTMLFormElement,
collector: TextCollector | ValidatedTextCollector,
updater: Updater,
updater: Updater<TextCollector | ValidatedTextCollector>,
) {
// create paragraph element with text of "Loading ... "
const p = document.createElement('p');
Expand Down
2 changes: 1 addition & 1 deletion e2e/davinci-app/components/single-value.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import type { SingleSelectCollector, Updater } from '@forgerock/davinci-client/t
export default function singleValueComponent(
formEl: HTMLFormElement,
collector: SingleSelectCollector,
updater: Updater,
updater: Updater<SingleSelectCollector>,
) {
// Create the label element
const labelEl = document.createElement('label');
Expand Down
2 changes: 1 addition & 1 deletion e2e/davinci-app/components/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { dotToCamelCase } from '../helper.js';
export default function textComponent(
formEl: HTMLFormElement,
collector: TextCollector | ValidatedTextCollector,
updater: Updater,
updater: Updater<TextCollector | ValidatedTextCollector>,
validator: Validator,
) {
const collectorKey = dotToCamelCase(collector.output.key);
Expand Down
8 changes: 5 additions & 3 deletions packages/davinci-client/src/lib/client.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,13 +234,15 @@ export async function davinci<ActionType extends ActionTypes = ActionTypes>({
* @param {SingleValueCollector | MultiSelectCollector | ObjectValueCollectors | AutoCollectors} collector - the collector to update
* @returns {function} - a function to call for updating collector value
*/
update: (
collector:
update: <
T extends
| SingleValueCollectors
| MultiSelectCollector
| ObjectValueCollectors
| AutoCollectors,
): Updater => {
>(
collector: T,
): Updater<T> => {
if (!collector.id) {
return handleUpdateValidateError(
'Argument for `collector` has no ID',
Expand Down
63 changes: 56 additions & 7 deletions packages/davinci-client/src/lib/client.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,62 @@ export interface InternalErrorResponse {

export type InitFlow = () => Promise<FlowNode | InternalErrorResponse>;

export type Updater = (
value:
| string
| string[]
| PhoneNumberInputValue
| FidoRegistrationInputValue
| FidoAuthenticationInputValue,
/**
* Maps collector types to the specific value type they accept.
* This enables type narrowing when using the update method with specific collector types.
*
* @example
* ```typescript
* if (collector.type === "PasswordCollector") {
* const updater = davinciClient.update(collector);
* // updater now only accepts: (value: string, index?: number) => ...
* }
* ```
*/
export type CollectorValueType<T> = T extends { type: 'PasswordCollector' }
? string
: T extends { type: 'TextCollector'; category: 'SingleValueCollector' }
? string
: T extends { type: 'TextCollector'; category: 'ValidatedSingleValueCollector' }
? string
: T extends { type: 'SingleSelectCollector' }
? string
: T extends { type: 'MultiSelectCollector' }
? string[]
: T extends { type: 'DeviceRegistrationCollector' }
? string
: T extends { type: 'DeviceAuthenticationCollector' }
? string
: T extends { type: 'PhoneNumberCollector' }
? PhoneNumberInputValue
: T extends { type: 'FidoRegistrationCollector' }
? FidoRegistrationInputValue
: T extends { type: 'FidoAuthenticationCollector' }
? FidoAuthenticationInputValue
: T extends { category: 'SingleValueCollector' }
? string
: T extends { category: 'ValidatedSingleValueCollector' }
? string
: T extends { category: 'MultiValueCollector' }
? string[]
:
| string
| string[]
| PhoneNumberInputValue
| FidoRegistrationInputValue
| FidoAuthenticationInputValue;

/**
* Generic updater function that accepts values appropriate for the collector type.
* When used with type narrowing, the value parameter will be constrained to the correct type.
*
* @template T The collector type (inferred from the collector passed to update())
* @param value The value to update the collector with (type depends on T)
* @param index Optional index for multi-value collectors
* @returns null on success, or an InternalErrorResponse on failure
*/
export type Updater<T = unknown> = (
value: CollectorValueType<T>,
index?: number,
) => InternalErrorResponse | null;
export type Validator = (value: string) =>
Expand Down
Loading
Loading