Skip to content

feat(davinci-client): add form image collector#698

Open
vatsalparikh wants to merge 4 commits into
mainfrom
SDKS-5101
Open

feat(davinci-client): add form image collector#698
vatsalparikh wants to merge 4 commits into
mainfrom
SDKS-5101

Conversation

@vatsalparikh

@vatsalparikh vatsalparikh commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

JIRA Ticket

https://pingidentity.atlassian.net/browse/SDKS-5101

Review Note:

The third commit davinci-client: add image collector e2e test against old env is only added temporarily. Right now, only the old Davinci env has the feature flag DV-21617-forms-image-component-sdk-response enabled. So instead of updating the form to match the old env, I've added a new file form-image.test.ts and added old Davinci config to server-configs.ts file as a separate commit. Will remove this commit as soon as the flag is enabled for new Davinci console.

Description

Adds support for the IMAGE field type in DaVinci forms. When a form includes an image component, the SDK now parses it into an ImageCollector, a read-only collector with description, imageUrl, and hyperlink properties.

How to test

Recording

Screen.Recording.2026-06-22.at.11.52.23.AM.mov

Summary by CodeRabbit

  • New Features
    • Added support for IMAGE form fields from DaVinci Forms, enabling images to render within form fields.
    • Images support optional hyperlinks and descriptive text.
    • Improved handling when an image can’t be rendered, so form submissions display a clear error state.
  • API Updates
    • Updated the public client types to include ImageCollector/ImageField and IMAGE read-only fields.
  • Tests
    • Added/updated end-to-end coverage for image rendering and adjusted form submission synchronization.

@changeset-bot

changeset-bot Bot commented Jun 20, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: ae48a69

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 12 packages
Name Type
@forgerock/davinci-client Minor
@forgerock/device-client Minor
@forgerock/journey-client Minor
@forgerock/oidc-client Minor
@forgerock/protect Minor
@forgerock/sdk-types Minor
@forgerock/sdk-utilities Minor
@forgerock/iframe-manager Minor
@forgerock/sdk-logger Minor
@forgerock/sdk-oidc Minor
@forgerock/sdk-request-middleware Minor
@forgerock/storage Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cc6bbda2-3e89-4b7d-bfed-ffcfa86522ec

📥 Commits

Reviewing files that changed from the base of the PR and between b0d790d and ae48a69.

📒 Files selected for processing (4)
  • .changeset/curly-wolves-swim.md
  • e2e/davinci-suites/src/form-image.test.ts
  • packages/davinci-client/src/lib/collector.types.test-d.ts
  • packages/davinci-client/src/lib/collector.types.ts
✅ Files skipped from review due to trivial changes (2)
  • e2e/davinci-suites/src/form-image.test.ts
  • .changeset/curly-wolves-swim.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/davinci-client/src/lib/collector.types.test-d.ts
  • packages/davinci-client/src/lib/collector.types.ts

📝 Walkthrough

Walkthrough

Adds ImageCollector as a new no-value collector type for DaVinci IMAGE form fields. The change defines ImageField and ImageCollector types, implements a returnImageCollector factory, branches the node reducer to handle IMAGE field types, updates both public API reports, adds an e2e DOM rendering component, and introduces a Playwright test to verify image rendering attributes.

Changes

ImageCollector Feature

Layer / File(s) Summary
ImageField and ImageCollector type contracts
packages/davinci-client/src/lib/davinci.types.ts, packages/davinci-client/src/lib/collector.types.ts, packages/davinci-client/src/lib/node.types.ts, packages/davinci-client/src/lib/collector.types.test-d.ts, packages/davinci-client/src/lib/node.types.test-d.ts
ImageField (type: 'IMAGE', imageUrl, description, optional hyperlinkUrl) and ImageCollector interface added; ReadOnlyFields, NoValueCollectorTypes, InferNoValueCollectorType, NoValueCollectors, and Collectors unions extended; type-check assertions added.
returnImageCollector factory and node reducer branch
packages/davinci-client/src/lib/collector.utils.ts, packages/davinci-client/src/lib/node.reducer.ts, packages/davinci-client/src/lib/collector.utils.test.ts, packages/davinci-client/src/lib/node.reducer.test.ts
returnImageCollector factory builds an ImageCollector from an ImageField, mapping imageUrl, description, and conditional hyperlinkUrl; returnNoValueCollector's label assignment hardened; node/next reducer gains an IMAGE branch; unit tests cover all field shapes and read-only enforcement.
Public API report updates
packages/davinci-client/api-report/davinci-client.api.md, packages/davinci-client/api-report/davinci-client.types.api.md
Both generated API reports updated to surface ImageCollector, ImageField, updated union types, reordered davinci() return unions, and normalized error property type ordering in RTK cache helper signatures.
E2E app image component and wiring
e2e/davinci-app/components/form-image.ts, e2e/davinci-app/main.ts, e2e/davinci-app/server-configs.ts
New form-image.ts renders an img from ImageCollector output, optionally wrapped in an anchor; renderForm dispatch gains an ImageCollector branch; new server config entry added for the image feature flag environment.
Playwright e2e tests and changeset
e2e/davinci-suites/src/form-image.test.ts, e2e/davinci-suites/src/form-fields.test.ts, .changeset/curly-wolves-swim.md
New form-image.test.ts asserts image src, alt, and anchor href; form-fields.test.ts waitForRequest matcher corrected from customForm to showForm; minor-bump changeset added.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • ForgeRock/ping-javascript-sdk#562: Both PRs add new DaVinci "no-value" collector support by extending the same collector type system and node/next reducer dispatch (early-return on a specific field.type) plus corresponding e2e rendering wiring—ImageCollector mirrors the QRCodeCollector implementation pattern.
  • ForgeRock/ping-javascript-sdk#637: Both PRs modify packages/davinci-client collector typing and exported API report types, with node.reducer.ts changes in the same area (type/collector handling), though the main PR adds ImageCollector/IMAGE rendering while the retrieved PR refactors CollectorValueTypes usage and updater/value typing.

Suggested reviewers

  • cerebrl
  • ryanbas21

🐇 A hop through the forms, what do I see?
An image collector, as bright as can be!
With imageUrl mapped and hyperlinkUrl too,
The rabbit stamps types and the reducer runs true.
Playwright checks src and the alt and the href
Now IMAGE fields render without any fear! 🖼️

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(davinci-client): add form image collector' accurately describes the main change—adding support for IMAGE field types in DaVinci forms through a new ImageCollector. It follows conventional commit format and clearly summarizes the primary objective.
Description check ✅ Passed The description includes JIRA ticket, detailed explanation of changes, testing instructions, and a video recording. It explains that a temporary commit will be removed once the feature flag is enabled on the new environment, providing necessary context for reviewers.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch SDKS-5101

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nx-cloud

nx-cloud Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit ae48a69

Command Status Duration Result
nx run-many -t build --no-agents ✅ Succeeded <1s View ↗
nx affected -t build lint test typecheck e2e-ci ✅ Succeeded 7m 58s View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-06-22 23:45:05 UTC

nx-cloud[bot]

This comment was marked as outdated.

nx-cloud[bot]

This comment was marked as outdated.

nx-cloud[bot]

This comment was marked as outdated.

@nx-cloud nx-cloud Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

At least one additional CI pipeline execution has run since the conclusion below was written and it may no longer be applicable.

Nx Cloud has identified a possible root cause for your failed CI:

We investigated the form-fields.test.ts timeout and determined it is not caused by this PR's changes. The failure occurs while waiting for a POST to an external PingOne/DaVinci customForm endpoint — a network dependency unrelated to the additive ImageCollector code introduced here. We recommend re-running the pipeline once the external service has recovered.

No code changes were suggested for this issue.

Trigger a rerun:

Rerun CI

Nx Cloud View detailed reasoning on Nx Cloud ↗


🎓 Learn more about Self-Healing CI on nx.dev

@pkg-pr-new

pkg-pr-new Bot commented Jun 22, 2026

Copy link
Copy Markdown

Open in StackBlitz

@forgerock/davinci-client

pnpm add https://pkg.pr.new/@forgerock/davinci-client@698

@forgerock/device-client

pnpm add https://pkg.pr.new/@forgerock/device-client@698

@forgerock/journey-client

pnpm add https://pkg.pr.new/@forgerock/journey-client@698

@forgerock/oidc-client

pnpm add https://pkg.pr.new/@forgerock/oidc-client@698

@forgerock/protect

pnpm add https://pkg.pr.new/@forgerock/protect@698

@forgerock/sdk-types

pnpm add https://pkg.pr.new/@forgerock/sdk-types@698

@forgerock/sdk-utilities

pnpm add https://pkg.pr.new/@forgerock/sdk-utilities@698

@forgerock/iframe-manager

pnpm add https://pkg.pr.new/@forgerock/iframe-manager@698

@forgerock/sdk-logger

pnpm add https://pkg.pr.new/@forgerock/sdk-logger@698

@forgerock/sdk-oidc

pnpm add https://pkg.pr.new/@forgerock/sdk-oidc@698

@forgerock/sdk-request-middleware

pnpm add https://pkg.pr.new/@forgerock/sdk-request-middleware@698

@forgerock/storage

pnpm add https://pkg.pr.new/@forgerock/storage@698

commit: ae48a69

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Deployed 1bf304e to https://ForgeRock.github.io/ping-javascript-sdk/pr-698/1bf304e8f150cd33d57a82f26a8edc5e7e935fc8 branch gh-pages in ForgeRock/ping-javascript-sdk

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Size Analysis

📦 Bundle Size Analysis

🚨 Significant Changes

🔻 @forgerock/device-client - 0.0 KB (-10.0 KB, -100.0%)
🔻 @forgerock/journey-client - 0.0 KB (-93.0 KB, -100.0%)

📊 Minor Changes

📈 @forgerock/davinci-client - 54.5 KB (+0.7 KB)
📉 @forgerock/device-client - 10.0 KB (-0.0 KB)

➖ No Changes

@forgerock/oidc-client - 35.2 KB
@forgerock/sdk-types - 7.9 KB
@forgerock/sdk-utilities - 11.9 KB
@forgerock/journey-client - 93.0 KB
@forgerock/protect - 144.6 KB
@forgerock/iframe-manager - 3.2 KB
@forgerock/sdk-logger - 1.6 KB
@forgerock/storage - 1.5 KB
@forgerock/sdk-request-middleware - 4.6 KB
@forgerock/sdk-oidc - 5.7 KB


14 packages analyzed • Baseline from latest main build

Legend

🆕 New package
🔺 Size increased
🔻 Size decreased
➖ No change

ℹ️ How bundle sizes are calculated
  • Current Size: Total gzipped size of all files in the package's dist directory
  • Baseline: Comparison against the latest build from the main branch
  • Files included: All build outputs except source maps and TypeScript build cache
  • Exclusions: .map, .tsbuildinfo, and .d.ts.map files

🔄 Updated automatically on each push to this PR

@codecov-commenter

codecov-commenter commented Jun 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 22.02%. Comparing base (eafe277) to head (ae48a69).
⚠️ Report is 32 commits behind head on main.

❌ Your project status has failed because the head coverage (22.02%) is below the target coverage (40.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #698      +/-   ##
==========================================
+ Coverage   18.07%   22.02%   +3.95%     
==========================================
  Files         155      157       +2     
  Lines       24398    25205     +807     
  Branches     1203     1479     +276     
==========================================
+ Hits         4410     5552    +1142     
+ Misses      19988    19653     -335     
Files with missing lines Coverage Δ
packages/davinci-client/src/lib/collector.types.ts 100.00% <ø> (ø)
packages/davinci-client/src/lib/collector.utils.ts 86.34% <100.00%> (+1.19%) ⬆️
packages/davinci-client/src/lib/davinci.types.ts 100.00% <ø> (ø)
packages/davinci-client/src/lib/node.reducer.ts 71.72% <100.00%> (+1.24%) ⬆️
packages/davinci-client/src/lib/node.types.ts 100.00% <ø> (ø)

... and 15 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@vatsalparikh vatsalparikh marked this pull request as ready for review June 22, 2026 19:00

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/davinci-client/src/lib/collector.types.test-d.ts (1)

658-672: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add a companion type test without hyperlinkUrl to lock optional semantics.

Current coverage validates the “present” case only. Adding a second ImageCollector sample without hyperlinkUrl would protect against accidentally making it required later.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/davinci-client/src/lib/collector.types.test-d.ts` around lines 658 -
672, Add a second type test case for ImageCollector that omits the hyperlinkUrl
property from the output object. Create a new test (likely another it block)
that validates the InferNoValueCollectorType type inference for ImageCollector
but with a minimal output structure that excludes hyperlinkUrl, ensuring the
type definition correctly treats hyperlinkUrl as optional and prevents
accidental breaking changes that might make it required.
packages/davinci-client/src/lib/collector.types.ts (1)

640-649: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Align ImageCollector docs with the declared required description field.

The JSDoc says description is optional, but output.description is typed as required (string). Please make the comment consistent with the type contract.

Suggested doc-only fix
- * hyperlink URL (`hyperlink.url`), and an optional `description` (alt text).
+ * hyperlink URL (`hyperlink.url`), and `description` (alt text).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/davinci-client/src/lib/collector.types.ts` around lines 640 - 649,
The JSDoc comment for the `ImageCollector` interface incorrectly describes
`description` as an optional field when the type definition shows `description:
string` as required (non-nullable). Update the comment above the
`ImageCollector` interface to remove the "optional" designation for
`description` and accurately reflect that it is a required field in the output
type, while keeping the reference to it being alt text.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@e2e/davinci-suites/src/form-image.test.ts`:
- Around line 22-25: The test assertion for the formImage src attribute uses a
brittle full URL equality check that will fail if query parameters, their order,
or optimization values change. Instead of checking the entire URL with
toHaveAttribute, use a more flexible assertion that checks if the src contains
or matches just the essential parts of the URL (such as the base image path from
destinationcanada.com without the query parameters) to make the test more
resilient to parameter changes.

---

Nitpick comments:
In `@packages/davinci-client/src/lib/collector.types.test-d.ts`:
- Around line 658-672: Add a second type test case for ImageCollector that omits
the hyperlinkUrl property from the output object. Create a new test (likely
another it block) that validates the InferNoValueCollectorType type inference
for ImageCollector but with a minimal output structure that excludes
hyperlinkUrl, ensuring the type definition correctly treats hyperlinkUrl as
optional and prevents accidental breaking changes that might make it required.

In `@packages/davinci-client/src/lib/collector.types.ts`:
- Around line 640-649: The JSDoc comment for the `ImageCollector` interface
incorrectly describes `description` as an optional field when the type
definition shows `description: string` as required (non-nullable). Update the
comment above the `ImageCollector` interface to remove the "optional"
designation for `description` and accurately reflect that it is a required field
in the output type, while keeping the reference to it being alt text.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d0ed34c7-4971-4ef6-b40c-f2162503f81c

📥 Commits

Reviewing files that changed from the base of the PR and between 35816b4 and b0d790d.

📒 Files selected for processing (17)
  • .changeset/curly-wolves-swim.md
  • e2e/davinci-app/components/form-image.ts
  • e2e/davinci-app/main.ts
  • e2e/davinci-app/server-configs.ts
  • e2e/davinci-suites/src/form-fields.test.ts
  • e2e/davinci-suites/src/form-image.test.ts
  • packages/davinci-client/api-report/davinci-client.api.md
  • packages/davinci-client/api-report/davinci-client.types.api.md
  • packages/davinci-client/src/lib/collector.types.test-d.ts
  • packages/davinci-client/src/lib/collector.types.ts
  • packages/davinci-client/src/lib/collector.utils.test.ts
  • packages/davinci-client/src/lib/collector.utils.ts
  • packages/davinci-client/src/lib/davinci.types.ts
  • packages/davinci-client/src/lib/node.reducer.test.ts
  • packages/davinci-client/src/lib/node.reducer.ts
  • packages/davinci-client/src/lib/node.types.test-d.ts
  • packages/davinci-client/src/lib/node.types.ts

Comment thread e2e/davinci-suites/src/form-image.test.ts Outdated

@cerebrl cerebrl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to simplify the property names, but otherwise, looks good.

Comment on lines +647 to +649
imageUrl: string;
description: string;
hyperlinkUrl?: string;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to avoid compound property names, if possible. How do you feel about borrowing from HTML here and just use src, instead of imageUrl and href, instead of hyperlinkUrl?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to keep the parity with what we receive from Davinci, but totally open to using simpler names. This is what we receive from Davinci

   "type": "IMAGE",
   "key": "<field key>",
   "description": "<alt text>",
   "imageUrl": "<absolute URL>",
   "hyperlinkUrl": "<absolute URL>"

Do you have a preference there? I feel it's easier to reason through and debug when we keep the same properties as what Davinci returns. Besides, I checked and almost all collectors except for QrCodeField follow property names the same as what Davinci returns.

I can change it to alt, src, href. However, would be good to know your opinion on whether we should keep that parity or borrow from HTML.

@ancheetah ancheetah left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lgtm, some minor comments and suggestions

Comment thread .changeset/curly-wolves-swim.md Outdated
Comment thread e2e/davinci-app/server-configs.ts
output: {
key: `${field.key || field.type}-${idx}`,
label: field.content,
label: 'content' in field ? field.content : '',

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about copying field.description here into label so it's not empty?

@vatsalparikh vatsalparikh Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you mean, something like field.content ?? field.description ?? ''

Among the NoValueCollectors, description is used only by ImageCollector. We can put that as a label, but it seems like we're adding an image collector specific property to a generic NoValueCollector.

However, if we were to extend no value collector for other fields later and if we find that description is an alternative property to content, maybe we can add it there then.

Right now, I feel like it might cause future bugs where NoValueCollector now checks for description if content is null, which is something specific to only image collector, and description may not be a property or description might mean something else for other no value collectors that we add later.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we only override the label property in the returnImageCollector function?

@ancheetah

Copy link
Copy Markdown
Collaborator

@vatsalparikh One more question, should this have a do not merge label so that it doesn't go out in 2.1 release?

@vatsalparikh

Copy link
Copy Markdown
Contributor Author

@vatsalparikh One more question, should this have a do not merge label so that it doesn't go out in 2.1 release?

Is there a reason to hold back ImageCollector feature in 2.1 release?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants