You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
If you are interested in working on this issue or have submitted a pull request, please leave a comment
Description
resource/pingone_davinci_flow node data on pingOneFormsConnectorshowForm nodes can reference a DaVinci UI template/theme. The DaVinci UI exposes three distinct configurations for this ("theme" options in the node's editor), and the raw JSON shape differs across all three — this is not a single field with a UUID-or-placeholder value, it's a mode selector plus a conditionally-present second field:
Direct theme UUID — properties.theme.value is a real UUID referencing a specific UI template.
Unset / default — properties.theme key is absent entirely.
Indirect via themeId — properties.theme.value is the literal string "useThemeId" (a mode discriminator, not a UUID), and the actual reference lives in a sibling property, properties.themeId.value, wrapped in the same rich-text/Slate JSON structure used elsewhere in this schema (e.g. mfaPolicyId, userId): "[{\"children\":[{\"text\":\"<uuid-or-variable>\"}]}]".
None of these three are resolved today — the exporter emits them as inert raw strings inside the properties JSON blob, the same treatment as any other opaque form config value. This mirrors a case we already handle correctly for a single-field UUID: properties.form.value (also a UUID, referencing a DaVinci form) is resolved via an EmbeddedReferenceRule with the reference_with_fallback strategy (internal/platform/pingone/resource_flow.go). Case 1 above fits that existing mechanism directly. Cases 2 and 3 do not — case 2 needs no rule to fire at all (already correct/inert), and case 3 requires resolving the reference from a different JSON key (themeId.value) than the one holding the mode flag (theme.value), plus unwrapping the rich-text wrapper before the UUID (or variable) is reachable. No existing code in this repo unwraps that rich-text shape yet (confirmed: mfaPolicyId/userId, which use the identical wrapper, are also just passed through unresolved today) — case 3 may need new handling beyond a simple EmbeddedReferenceRule registration, or an extension to walkJSONPath/the rule mechanism to support unwrapping before UUID extraction.
Emitting a bare UUID string means re-applying the exported HCL against a different environment (or after the referenced theme/template changes ID) silently breaks, with no depends_on edge and no way to override it without editing the JSON blob by hand.
Note: there is currently no pingone_davinci_ui_template/theme resource exported by this tool, so — same as form.value before pingone_davinci_form existed — a resolved reference would start as a variable fallback (UUID exposed as an overridable Terraform variable) rather than a full resource reference, and would automatically upgrade to a reference once a UI template resource is added.
Evidence
Confirmed directly against a real flow export containing all three cases side by side (three pingOneFormsConnectorshowForm nodes):
(An earlier export also showed a fourth string, "activeTheme", in theme.value on a node with no themeId — possibly an older/different sentinel than "useThemeId", or a naming change between DaVinci versions; worth confirming which sentinel(s) are current.)
form.value is a real UUID in all three nodes and is unaffected by which theme mode is set — the form.value reference rule applies identically regardless.
Separately, the same export surfaced a form-connector capability difference worth noting for scoping: the legacy pingOneFormsConnector capability is customForm; the current one is showForm. customForm's property set is a strict subset (dynamicText, form, formData, nodeTitle — no theme/themeId, no outcomes, no authenticationMethodSource, etc.), confirmed absent from a customForm node in the same export. Theme configuration appears to be showForm-specific. The fix shouldn't need capability-aware branching — rules only fire when the relevant JSON key exists — but flagging in case a theme concept appears on customForm in the future with a different shape.
Ping CLI and Plugin Version
Current main (post-#127, DaVinci flow outcomes fix).
Affected Command(s)
pingcli tfr export (or standalone equivalent) for pingone_davinci_flow
Expected Behavior
When properties.theme.value holds a direct UUID (case 1), it is resolved the same way properties.form.value is: replaced with a Terraform variable reference (fallback) or a resource reference (once a UI template/theme resource exists), with a corresponding graph edge / depends_on where applicable.
When properties.theme is absent (case 2), no change is needed — nothing to resolve.
When properties.theme.value is the "useThemeId" mode flag (case 3), the UUID (or variable-slot placeholder) inside properties.themeId.value's rich-text wrapper is extracted and resolved the same way, without disturbing the theme mode flag itself.
Actual Behavior
In all three cases, whatever raw string(s) are present are left embedded in the properties JSON blob verbatim — no variable, no reference, no dependency tracking. Re-applying the exported HCL in a different environment (where a referenced UUID doesn't exist) or after a theme is regenerated will silently point at the wrong (or a nonexistent) theme, for either theme.value (case 1) or the UUID nested in themeId.value (case 3).
Steps to Reproduce
Export a DaVinci flow containing pingOneFormsConnectorshowForm nodes covering the three theme configurations above (a specific theme selected directly, no theme set, and a theme selected via the "use theme ID" option).
Inspect the generated HCL — the properties attribute (rendered via jsonencode_raw) contains the raw theme/themeId values with no variable or reference substitution.
Compare against the same nodes' form.value, which is substituted with a variable/reference.
Important Factoids
No pingone_davinci_ui_template (or theme) resource is exported by this tool yet — a resolved reference would land as a variable fallback initially, same bootstrapping path form.value took before pingone_davinci_form existed.
The existing EmbeddedReferenceRule mechanism (internal/core/embedded_references.go) may need extending, not just a new registration — it currently only supports extracting a UUID from a single JSONKeyPath (via walkJSONPath, which expects a plain string value at the end of the path). Case 3 needs (a) checking a different key's value (theme.value == "useThemeId") as a precondition before acting on themeId, and (b) unwrapping the rich-text [{"children":[{"text":"..."}]}] structure to reach the actual UUID before/after resolution — walkJSONPath returns "" today if the final value isn't a plain string. Case 1 (theme.value as a direct UUID) fits the existing mechanism as-is.
The rich-text wrapper format is shared with at least mfaPolicyId and userId elsewhere in showForm's properties — also currently unresolved/opaque. If a generic rich-text-unwrap helper is built for themeId, it's likely reusable for those too (separate issue/scope, noting here for context).
References
internal/platform/pingone/resource_flow.go — existing form.value rule; direct-UUID case (1) can mirror this
Community Note
Description
resource/pingone_davinci_flownode data onpingOneFormsConnectorshowFormnodes can reference a DaVinci UI template/theme. The DaVinci UI exposes three distinct configurations for this ("theme" options in the node's editor), and the raw JSON shape differs across all three — this is not a single field with a UUID-or-placeholder value, it's a mode selector plus a conditionally-present second field:properties.theme.valueis a real UUID referencing a specific UI template.properties.themekey is absent entirely.themeId—properties.theme.valueis the literal string"useThemeId"(a mode discriminator, not a UUID), and the actual reference lives in a sibling property,properties.themeId.value, wrapped in the same rich-text/Slate JSON structure used elsewhere in this schema (e.g.mfaPolicyId,userId):"[{\"children\":[{\"text\":\"<uuid-or-variable>\"}]}]".None of these three are resolved today — the exporter emits them as inert raw strings inside the
propertiesJSON blob, the same treatment as any other opaque form config value. This mirrors a case we already handle correctly for a single-field UUID:properties.form.value(also a UUID, referencing a DaVinci form) is resolved via anEmbeddedReferenceRulewith thereference_with_fallbackstrategy (internal/platform/pingone/resource_flow.go). Case 1 above fits that existing mechanism directly. Cases 2 and 3 do not — case 2 needs no rule to fire at all (already correct/inert), and case 3 requires resolving the reference from a different JSON key (themeId.value) than the one holding the mode flag (theme.value), plus unwrapping the rich-text wrapper before the UUID (or variable) is reachable. No existing code in this repo unwraps that rich-text shape yet (confirmed:mfaPolicyId/userId, which use the identical wrapper, are also just passed through unresolved today) — case 3 may need new handling beyond a simpleEmbeddedReferenceRuleregistration, or an extension towalkJSONPath/the rule mechanism to support unwrapping before UUID extraction.Emitting a bare UUID string means re-applying the exported HCL against a different environment (or after the referenced theme/template changes ID) silently breaks, with no
depends_onedge and no way to override it without editing the JSON blob by hand.Note: there is currently no
pingone_davinci_ui_template/theme resource exported by this tool, so — same asform.valuebeforepingone_davinci_formexisted — a resolved reference would start as avariablefallback (UUID exposed as an overridable Terraform variable) rather than a full resource reference, and would automatically upgrade to a reference once a UI template resource is added.Evidence
Confirmed directly against a real flow export containing all three cases side by side (three
pingOneFormsConnectorshowFormnodes):{ "capabilityName": "showForm", "properties": { "form": { "value": "860b5cd5-45cc-466d-abbd-64298bb90bed" }, "theme": { "value": "e6fd37f9-11dd-40f3-90f6-eaeb971ee3db" } } }{ "capabilityName": "showForm", "properties": { "form": { "value": "ba30f833-e6a5-4fda-9ff1-2576ece5108c" } } }{ "capabilityName": "showForm", "properties": { "form": { "value": "e439ac2a-8712-4ed0-9619-edd8526d286e" }, "theme": { "value": "useThemeId" }, "themeId": { "value": "[\n {\n \"children\": [\n {\n \"text\": \"abc123\"\n }\n ]\n }\n]" } } }(An earlier export also showed a fourth string,
"activeTheme", intheme.valueon a node with nothemeId— possibly an older/different sentinel than"useThemeId", or a naming change between DaVinci versions; worth confirming which sentinel(s) are current.)form.valueis a real UUID in all three nodes and is unaffected by which theme mode is set — theform.valuereference rule applies identically regardless.Separately, the same export surfaced a form-connector capability difference worth noting for scoping: the legacy
pingOneFormsConnectorcapability iscustomForm; the current one isshowForm.customForm's property set is a strict subset (dynamicText,form,formData,nodeTitle— notheme/themeId, nooutcomes, noauthenticationMethodSource, etc.), confirmed absent from acustomFormnode in the same export. Theme configuration appears to beshowForm-specific. The fix shouldn't need capability-aware branching — rules only fire when the relevant JSON key exists — but flagging in case a theme concept appears oncustomFormin the future with a different shape.Ping CLI and Plugin Version
Current
main(post-#127, DaVinci flowoutcomesfix).Affected Command(s)
pingcli tfr export(or standalone equivalent) forpingone_davinci_flowExpected Behavior
properties.theme.valueholds a direct UUID (case 1), it is resolved the same wayproperties.form.valueis: replaced with a Terraform variable reference (fallback) or a resource reference (once a UI template/theme resource exists), with a corresponding graph edge /depends_onwhere applicable.properties.themeis absent (case 2), no change is needed — nothing to resolve.properties.theme.valueis the"useThemeId"mode flag (case 3), the UUID (or variable-slot placeholder) insideproperties.themeId.value's rich-text wrapper is extracted and resolved the same way, without disturbing thethememode flag itself.Actual Behavior
In all three cases, whatever raw string(s) are present are left embedded in the
propertiesJSON blob verbatim — no variable, no reference, no dependency tracking. Re-applying the exported HCL in a different environment (where a referenced UUID doesn't exist) or after a theme is regenerated will silently point at the wrong (or a nonexistent) theme, for eithertheme.value(case 1) or the UUID nested inthemeId.value(case 3).Steps to Reproduce
pingOneFormsConnectorshowFormnodes covering the three theme configurations above (a specific theme selected directly, no theme set, and a theme selected via the "use theme ID" option).propertiesattribute (rendered viajsonencode_raw) contains the rawtheme/themeIdvalues with no variable or reference substitution.form.value, which is substituted with a variable/reference.Important Factoids
pingone_davinci_ui_template(or theme) resource is exported by this tool yet — a resolved reference would land as avariablefallback initially, same bootstrapping pathform.valuetook beforepingone_davinci_formexisted.EmbeddedReferenceRulemechanism (internal/core/embedded_references.go) may need extending, not just a new registration — it currently only supports extracting a UUID from a singleJSONKeyPath(viawalkJSONPath, which expects a plain string value at the end of the path). Case 3 needs (a) checking a different key's value (theme.value == "useThemeId") as a precondition before acting onthemeId, and (b) unwrapping the rich-text[{"children":[{"text":"..."}]}]structure to reach the actual UUID before/after resolution —walkJSONPathreturns""today if the final value isn't a plain string. Case 1 (theme.valueas a direct UUID) fits the existing mechanism as-is.mfaPolicyIdanduserIdelsewhere inshowForm's properties — also currently unresolved/opaque. If a generic rich-text-unwrap helper is built forthemeId, it's likely reusable for those too (separate issue/scope, noting here for context).References
internal/platform/pingone/resource_flow.go— existingform.valuerule; direct-UUID case (1) can mirror thisinternal/core/embedded_references.go— resolver mechanism;walkJSONPathlikely needs extending for cases 3 (cross-key precondition + rich-text unwrap)