Skip to content

feat: headless CDN API client and provider wiring - #141

Open
ethanpschoen wants to merge 5 commits into
ethanpschoen/feat/rule-triggersfrom
ethanpschoen/feat/headless-provider-methods
Open

feat: headless CDN API client and provider wiring#141
ethanpschoen wants to merge 5 commits into
ethanpschoen/feat/rule-triggersfrom
ethanpschoen/feat/headless-provider-methods

Conversation

@ethanpschoen

@ethanpschoen ethanpschoen commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Description of this change

Top layer of a 2-PR stack for the headless SDK surface. Review this PR's diff against its base (#139).

main
 └── #139  locale helpers + privacy strings + triggers
  └── #141  headless CDN client + provider wiring   ← this PR
  • Headless CDN API client; synthesize language so environment isn't dropped from config requests
  • Normalize parsed consent purposes to {} instead of undefined
  • Wire headless methods into KetchServiceProvider; read privacy strings from the configured preferenceStorage backend

Why is this change being made?

  • Chore (non-functional changes)
  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

How was this tested? How can the reviewer verify your testing?

Related issues

None.

Checklist

  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • I have evaluated the security impact of this change, and OWASP Secure Coding Practices have been observed.
  • I have informed stakeholders of my changes.

@ethanpschoen ethanpschoen changed the title ethanpschoen/feat/headless provider methods feat: wire headless methods into KetchServiceProvider Aug 6, 2026
@ethanpschoen
ethanpschoen marked this pull request as ready for review August 6, 2026 20:59
@ethanpschoen
ethanpschoen requested review from a team as code owners August 6, 2026 20:59
Adds a standalone client for the config/consent/rights/subscriptions CDN endpoints, independent of the WebView-hosted tag.

Part 4/5 of the split of #126.
…onfig requests

The long config path (which carries environment) was only taken when environment, jurisdiction, and language were all present. A caller who set environment and jurisdiction but not language fell to the short path, which carries no environment at all, so a staging-configured app with a jurisdiction set silently received the default environment's config.

Synthesize language from the device locale whenever environment and jurisdiction are both set, so the long path is always used in that case. Not adding ?environment= to the short path — nothing in ketch-tag suggests the CDN reads it.

Refs #126.
parseConsent() left purposes undefined whenever a server response omitted it, while emptyConsent() returns { purposes: {} }. A vendors-only or protocols-only response therefore returned an inconsistent shape, and a caller doing Object.keys(consent.purposes) on it would throw.

Refs #126.
Wires the headless CDN client into the provider: getRegion, getJurisdiction, getBootstrapConfiguration, getFullConfiguration, fetchConsent, setConsentOnServer, invokeRight, getSubscriptions, setSubscriptions, and preferenceQRUrl are now exposed via useKetchService(), alongside a ketchMobileSdkUrl override that takes precedence over the data-center-implied CDN URL for both the WebView and the headless client.

Breaking change: getRegion, getJurisdiction, and fetchConsent are now required on the KetchService interface, not optional. Any external implementer of KetchService must add them.

Part 5/5 of the split of #126.
getSavedString and the IAB helpers accepted an optional reader (previous PR in this stack) but nothing in the provider ever passed one, so they always read via nativeStorage regardless of preferenceStorage. Writes went through preferenceStorage when configured; reads did not, so privacy strings written to a custom backend (the README's own recommendation for Expo Android) were invisible to these accessors.

Adds a read counterpart to preferenceStorage (SharedPrefencesInterface.getItemAsync, optional) and a readPreference builder mirroring the existing storePreference one, then binds the four accessors to it before exposing them via contextValue.

Refs #126.
ethanpschoen added a commit that referenced this pull request Aug 6, 2026
getSavedString and the IAB helpers always read through nativeStorage.read, so they never saw values persisted via a custom preferenceStorage backend. That backend is required for Expo Android in the README, and on that setup crossPlatformRead falls back to React Native Settings, which is a no-op on Android — so these accessors returned empty strings after consent updates whenever preferenceStorage was configured.

This PR adds the capability (an optional reader parameter, defaulting to the existing nativeStorage.read). The provider wiring that actually builds a reader from the configured preferenceStorage and binds these accessors to it lands in #141, alongside the rest of the KetchService exposure.

Refs #126.
@ethanpschoen
ethanpschoen force-pushed the ethanpschoen/feat/headless-api-client branch from bc61706 to b54c0ab Compare August 6, 2026 21:22
@ethanpschoen
ethanpschoen force-pushed the ethanpschoen/feat/headless-provider-methods branch from 4547541 to c4f6f09 Compare August 6, 2026 21:22
@ethanpschoen ethanpschoen changed the title feat: wire headless methods into KetchServiceProvider feat: headless CDN API client and provider wiring Aug 7, 2026
@ethanpschoen ethanpschoen changed the title feat: headless CDN API client and provider wiring feat: wire headless methods into KetchServiceProvider Aug 7, 2026
@ethanpschoen ethanpschoen changed the title feat: wire headless methods into KetchServiceProvider feat: headless CDN API client and provider wiring Aug 7, 2026
@ethanpschoen
ethanpschoen changed the base branch from ethanpschoen/feat/headless-api-client to ethanpschoen/feat/rule-triggers August 7, 2026 23:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant