Skip to content

Commit 7fc77f9

Browse files
committed
fix(davinci-client): address PR review comments on ImageCollector
1 parent c1803d9 commit 7fc77f9

10 files changed

Lines changed: 73 additions & 59 deletions

File tree

.changeset/curly-wolves-swim.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
'@forgerock/davinci-client': minor
33
---
44

5-
Add `ImageCollector` for rendering `IMAGE` form fields from DaVinci Forms.
5+
Add `ImageCollector` for rendering `IMAGE` form fields from PingOne Forms.

e2e/davinci-app/components/form-image.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved.
2+
* Copyright (c) 2026 Ping Identity Corporation. All rights reserved.
33
*
44
* This software may be modified and distributed under the terms
55
* of the MIT license. See the LICENSE file for details.

e2e/davinci-suites/src/form-image.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved.
2+
* Copyright (c) 2026 Ping Identity Corporation. All rights reserved.
33
*
44
* This software may be modified and distributed under the terms
55
* of the MIT license. See the LICENSE file for details.

packages/davinci-client/api-report/davinci-client.api.md

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -283,16 +283,12 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
283283
resume: (input: {
284284
continueToken: string;
285285
}) => Promise<InternalErrorResponse | NodeStates>;
286-
start: <QueryParams extends OutgoingQueryParams = OutgoingQueryParams>(options?: StartOptions<QueryParams> | undefined) => Promise<ContinueNode | ErrorNode | FailureNode | StartNode | SuccessNode>;
286+
start: <QueryParams extends OutgoingQueryParams = OutgoingQueryParams>(options?: StartOptions<QueryParams> | undefined) => Promise<StartNode | ErrorNode | FailureNode | ContinueNode | SuccessNode>;
287287
update: <T extends SingleValueCollectors | MultiSelectCollector | ObjectValueCollectors | AutoCollectors>(collector: T) => Updater<T>;
288288
validate: (collector: SingleValueCollectors | ObjectValueCollectors | MultiValueCollectors | AutoCollectors) => Validator;
289289
pollStatus: (collector: PollingCollector) => Poller;
290290
getClient: () => {
291-
action: string;
292-
collectors: Collectors[];
293-
description?: string;
294-
name?: string;
295-
status: "continue";
291+
status: "start";
296292
} | {
297293
action: string;
298294
collectors: Collectors[];
@@ -302,7 +298,11 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
302298
} | {
303299
status: "failure";
304300
} | {
305-
status: "start";
301+
action: string;
302+
collectors: Collectors[];
303+
description?: string;
304+
name?: string;
305+
status: "continue";
306306
} | {
307307
authorization?: {
308308
code?: string;
@@ -313,15 +313,9 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
313313
getCollectors: () => Collectors[];
314314
getError: () => DaVinciError | null;
315315
getErrorCollectors: () => CollectorErrors[];
316-
getNode: () => ContinueNode | ErrorNode | FailureNode | StartNode | SuccessNode;
316+
getNode: () => StartNode | ErrorNode | FailureNode | ContinueNode | SuccessNode;
317317
getServer: () => {
318-
_links?: Links;
319-
id?: string;
320-
interactionId?: string;
321-
interactionToken?: string;
322-
href?: string;
323-
eventName?: string;
324-
status: "continue";
318+
status: "start";
325319
} | {
326320
_links?: Links;
327321
eventName?: string;
@@ -338,7 +332,13 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
338332
interactionToken?: string;
339333
status: "failure";
340334
} | {
341-
status: "start";
335+
_links?: Links;
336+
id?: string;
337+
interactionId?: string;
338+
interactionToken?: string;
339+
href?: string;
340+
eventName?: string;
341+
status: "continue";
342342
} | {
343343
_links?: Links;
344344
eventName?: string;
@@ -355,14 +355,14 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
355355
} & Omit<{
356356
requestId: string;
357357
data?: unknown;
358-
error?: FetchBaseQueryError | SerializedError | undefined;
358+
error?: SerializedError | FetchBaseQueryError | undefined;
359359
endpointName: string;
360360
startedTimeStamp: number;
361361
fulfilledTimeStamp?: number;
362362
}, "data" | "fulfilledTimeStamp"> & Required<Pick<{
363363
requestId: string;
364364
data?: unknown;
365-
error?: FetchBaseQueryError | SerializedError | undefined;
365+
error?: SerializedError | FetchBaseQueryError | undefined;
366366
endpointName: string;
367367
startedTimeStamp: number;
368368
fulfilledTimeStamp?: number;
@@ -379,14 +379,14 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
379379
} & Omit<{
380380
requestId: string;
381381
data?: unknown;
382-
error?: FetchBaseQueryError | SerializedError | undefined;
382+
error?: SerializedError | FetchBaseQueryError | undefined;
383383
endpointName: string;
384384
startedTimeStamp: number;
385385
fulfilledTimeStamp?: number;
386386
}, "error"> & Required<Pick<{
387387
requestId: string;
388388
data?: unknown;
389-
error?: FetchBaseQueryError | SerializedError | undefined;
389+
error?: SerializedError | FetchBaseQueryError | undefined;
390390
endpointName: string;
391391
startedTimeStamp: number;
392392
fulfilledTimeStamp?: number;
@@ -407,14 +407,14 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
407407
} & Omit<{
408408
requestId: string;
409409
data?: unknown;
410-
error?: FetchBaseQueryError | SerializedError | undefined;
410+
error?: SerializedError | FetchBaseQueryError | undefined;
411411
endpointName: string;
412412
startedTimeStamp: number;
413413
fulfilledTimeStamp?: number;
414414
}, "data" | "fulfilledTimeStamp"> & Required<Pick<{
415415
requestId: string;
416416
data?: unknown;
417-
error?: FetchBaseQueryError | SerializedError | undefined;
417+
error?: SerializedError | FetchBaseQueryError | undefined;
418418
endpointName: string;
419419
startedTimeStamp: number;
420420
fulfilledTimeStamp?: number;
@@ -431,14 +431,14 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
431431
} & Omit<{
432432
requestId: string;
433433
data?: unknown;
434-
error?: FetchBaseQueryError | SerializedError | undefined;
434+
error?: SerializedError | FetchBaseQueryError | undefined;
435435
endpointName: string;
436436
startedTimeStamp: number;
437437
fulfilledTimeStamp?: number;
438438
}, "error"> & Required<Pick<{
439439
requestId: string;
440440
data?: unknown;
441-
error?: FetchBaseQueryError | SerializedError | undefined;
441+
error?: SerializedError | FetchBaseQueryError | undefined;
442442
endpointName: string;
443443
startedTimeStamp: number;
444444
fulfilledTimeStamp?: number;

packages/davinci-client/api-report/davinci-client.types.api.md

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -283,16 +283,12 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
283283
resume: (input: {
284284
continueToken: string;
285285
}) => Promise<InternalErrorResponse | NodeStates>;
286-
start: <QueryParams extends OutgoingQueryParams = OutgoingQueryParams>(options?: StartOptions<QueryParams> | undefined) => Promise<ContinueNode | ErrorNode | FailureNode | StartNode | SuccessNode>;
286+
start: <QueryParams extends OutgoingQueryParams = OutgoingQueryParams>(options?: StartOptions<QueryParams> | undefined) => Promise<StartNode | ErrorNode | FailureNode | ContinueNode | SuccessNode>;
287287
update: <T extends SingleValueCollectors | MultiSelectCollector | ObjectValueCollectors | AutoCollectors>(collector: T) => Updater<T>;
288288
validate: (collector: SingleValueCollectors | ObjectValueCollectors | MultiValueCollectors | AutoCollectors) => Validator;
289289
pollStatus: (collector: PollingCollector) => Poller;
290290
getClient: () => {
291-
action: string;
292-
collectors: Collectors[];
293-
description?: string;
294-
name?: string;
295-
status: "continue";
291+
status: "start";
296292
} | {
297293
action: string;
298294
collectors: Collectors[];
@@ -302,7 +298,11 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
302298
} | {
303299
status: "failure";
304300
} | {
305-
status: "start";
301+
action: string;
302+
collectors: Collectors[];
303+
description?: string;
304+
name?: string;
305+
status: "continue";
306306
} | {
307307
authorization?: {
308308
code?: string;
@@ -313,15 +313,9 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
313313
getCollectors: () => Collectors[];
314314
getError: () => DaVinciError | null;
315315
getErrorCollectors: () => CollectorErrors[];
316-
getNode: () => ContinueNode | ErrorNode | FailureNode | StartNode | SuccessNode;
316+
getNode: () => StartNode | ErrorNode | FailureNode | ContinueNode | SuccessNode;
317317
getServer: () => {
318-
_links?: Links;
319-
id?: string;
320-
interactionId?: string;
321-
interactionToken?: string;
322-
href?: string;
323-
eventName?: string;
324-
status: "continue";
318+
status: "start";
325319
} | {
326320
_links?: Links;
327321
eventName?: string;
@@ -338,7 +332,13 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
338332
interactionToken?: string;
339333
status: "failure";
340334
} | {
341-
status: "start";
335+
_links?: Links;
336+
id?: string;
337+
interactionId?: string;
338+
interactionToken?: string;
339+
href?: string;
340+
eventName?: string;
341+
status: "continue";
342342
} | {
343343
_links?: Links;
344344
eventName?: string;
@@ -355,14 +355,14 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
355355
} & Omit<{
356356
requestId: string;
357357
data?: unknown;
358-
error?: FetchBaseQueryError | SerializedError | undefined;
358+
error?: SerializedError | FetchBaseQueryError | undefined;
359359
endpointName: string;
360360
startedTimeStamp: number;
361361
fulfilledTimeStamp?: number;
362362
}, "data" | "fulfilledTimeStamp"> & Required<Pick<{
363363
requestId: string;
364364
data?: unknown;
365-
error?: FetchBaseQueryError | SerializedError | undefined;
365+
error?: SerializedError | FetchBaseQueryError | undefined;
366366
endpointName: string;
367367
startedTimeStamp: number;
368368
fulfilledTimeStamp?: number;
@@ -379,14 +379,14 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
379379
} & Omit<{
380380
requestId: string;
381381
data?: unknown;
382-
error?: FetchBaseQueryError | SerializedError | undefined;
382+
error?: SerializedError | FetchBaseQueryError | undefined;
383383
endpointName: string;
384384
startedTimeStamp: number;
385385
fulfilledTimeStamp?: number;
386386
}, "error"> & Required<Pick<{
387387
requestId: string;
388388
data?: unknown;
389-
error?: FetchBaseQueryError | SerializedError | undefined;
389+
error?: SerializedError | FetchBaseQueryError | undefined;
390390
endpointName: string;
391391
startedTimeStamp: number;
392392
fulfilledTimeStamp?: number;
@@ -407,14 +407,14 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
407407
} & Omit<{
408408
requestId: string;
409409
data?: unknown;
410-
error?: FetchBaseQueryError | SerializedError | undefined;
410+
error?: SerializedError | FetchBaseQueryError | undefined;
411411
endpointName: string;
412412
startedTimeStamp: number;
413413
fulfilledTimeStamp?: number;
414414
}, "data" | "fulfilledTimeStamp"> & Required<Pick<{
415415
requestId: string;
416416
data?: unknown;
417-
error?: FetchBaseQueryError | SerializedError | undefined;
417+
error?: SerializedError | FetchBaseQueryError | undefined;
418418
endpointName: string;
419419
startedTimeStamp: number;
420420
fulfilledTimeStamp?: number;
@@ -431,14 +431,14 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
431431
} & Omit<{
432432
requestId: string;
433433
data?: unknown;
434-
error?: FetchBaseQueryError | SerializedError | undefined;
434+
error?: SerializedError | FetchBaseQueryError | undefined;
435435
endpointName: string;
436436
startedTimeStamp: number;
437437
fulfilledTimeStamp?: number;
438438
}, "error"> & Required<Pick<{
439439
requestId: string;
440440
data?: unknown;
441-
error?: FetchBaseQueryError | SerializedError | undefined;
441+
error?: SerializedError | FetchBaseQueryError | undefined;
442442
endpointName: string;
443443
startedTimeStamp: number;
444444
fulfilledTimeStamp?: number;

packages/davinci-client/src/lib/collector.utils.test.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,8 +1177,8 @@ describe('returnImageCollector', () => {
11771177
expect(result.output.label).toBe('Friendly alt text');
11781178
});
11791179

1180-
// (e) imageUrl absent — src defaults to empty string
1181-
it('should default src to empty string when imageUrl is absent', () => {
1180+
// (e) imageUrl absent — src defaults to empty string, error is null
1181+
it('should default src to empty string and keep error null when imageUrl is absent', () => {
11821182
const mockField: ImageField = {
11831183
type: 'IMAGE',
11841184
key: 'image',
@@ -1187,6 +1187,20 @@ describe('returnImageCollector', () => {
11871187
};
11881188
const result = returnImageCollector(mockField, 0);
11891189
expect(result.output.src).toBe('');
1190+
expect(result.error).toBeNull();
1191+
});
1192+
1193+
// (e2) imageUrl present — src passes through verbatim
1194+
it('should pass imageUrl through as src', () => {
1195+
const mockField: ImageField = {
1196+
type: 'IMAGE',
1197+
key: 'image',
1198+
description: 'Alt text',
1199+
imageUrl: 'https://example.com/image.png',
1200+
};
1201+
const result = returnImageCollector(mockField, 0);
1202+
expect(result.output.src).toBe('https://example.com/image.png');
1203+
expect(result.error).toBeNull();
11901204
});
11911205

11921206
// (f) output.label mirrors alt

packages/davinci-client/src/lib/collector.utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,9 +1044,9 @@ export function returnImageCollector(field: ImageField, idx: number): ImageColle
10441044
error: null,
10451045
output: {
10461046
...base.output,
1047-
label: field.description,
1048-
src: field.imageUrl,
1049-
alt: field.description,
1047+
label: field.description || '',
1048+
src: field.imageUrl || '',
1049+
alt: field.description || '',
10501050
...(field.hyperlinkUrl ? { href: field.hyperlinkUrl } : {}),
10511051
},
10521052
};

packages/davinci-client/src/lib/node.reducer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2025 Ping Identity Corporation. All rights reserved.
2+
* Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved.
33
*
44
* This software may be modified and distributed under the terms
55
* of the MIT license. See the LICENSE file for details.

packages/davinci-client/src/lib/node.types.test-d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2025 Ping Identity Corporation. All rights reserved.
2+
* Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved.
33
*
44
* This software may be modified and distributed under the terms
55
* of the MIT license. See the LICENSE file for details.

packages/davinci-client/src/lib/node.types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2025 Ping Identity Corporation. All rights reserved.
2+
* Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved.
33
*
44
* This software may be modified and distributed under the terms
55
* of the MIT license. See the LICENSE file for details.

0 commit comments

Comments
 (0)