Skip to content

refactor: Initial Settings, retry, and fetch refactor - #168

Merged
ale-adobe merged 20 commits into
mainfrom
feat/unification
Aug 10, 2026
Merged

refactor: Initial Settings, retry, and fetch refactor#168
ale-adobe merged 20 commits into
mainfrom
feat/unification

Conversation

@ale-adobe

@ale-adobe ale-adobe commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

This initial refactor is centered around the introduction of a new package: c2pa-utilities, and unifies Settings, retry, and fetch logic shared between c2pa-web and c2pa-node.

Across the board, no new functionality was added. Types or functions maintain their current behavior, but are widened in some cases, due to the unification of shapes across Web and Node, in order to maintain support for both. This is not necessarily the final shape; this just helps put everything in one place so that it will be easier to iterate on moving forward.

New additions

The new c2pa-utilities package contains runtime-agnostic logic that c2pa-web and c2pa-node previously implemented independently (and had drifted on):

  • Settings/TrustSettings/CawgTrustSettings/VerifySettings/BuilderSettings: now one shared shape, mirroring structs in c2pa-rs
  • Functions for handling settings resolution and serialization: resolveSettings, createTrustSettings/createCawgTrustSettings/createVerifySettings, mergeSettings, settingsToJson, snakeCaseify, loadSettingsFromUrl
  • Functions for trust-anchor fetching: resolveTrustSettings

Additionally, this package houses generic HTTP retry mechanics that was also previously implemented by both packages. The new fetchWithRetry.ts module implements fetch-with-retry with exponential backoff and handles Retry-After headers along with configurable options, which will allow the Web and Node packages to inject their own runtime-specific behaviors.

Removals

  • c2pa-web
    • lib/settings.ts removed entirely; re-exports c2pa-utilities directly from index.ts for client convenience
  • c2pa-node
    • Settings.ts reduced to just loadSettingsFromFile (unique to Node thanks to its file system access), plus a re-export of everything else via its respective index.ts for client convenience.
    • TrustConfig/VerifyConfig/SettingsContext kept as @deprecated type aliases for backward compatibility, but otherwise are just re-exposing the unified types now defined in c2pa-utilities

Notable behavior changes / new capabilities

  • mergeSettings now deep-merges nested fields (e.g. builder.thumbnail) instead of overwriting whole sections
  • c2pa-node gains support for nested arrays for trust-anchor fields (previously only a web feature) and a new opt-in resolveTrustAnchors() for validated fetching
  • Fixed a bug in snakeCaseify: array values were being flattened into {"0": ..., "1": ...} objects instead of preserved as arrays

Testing

  • Added new test cases for parity and edge cases, including network errors, Retry-After variants, non-Error rejections, size-cap enforcement, PEM validation across settings.spec.ts and the new fetchWithRetry.spec.ts

Follow-up work

Several smaller PRs will be coming up containing their own bite-sized standalone changes, targeting this one as the base branch:

  • Unification of format allowlists (configurable)
  • Unification of size guards and limitations when fetching (configurable)
  • Unification of retry mechanisms (configurable)
  • Unification of SigningAlg and other shared enums

@changeset-bot

changeset-bot Bot commented Jul 31, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 82de3ba

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

This PR includes changesets to release 3 packages
Name Type
@contentauth/c2pa-utilities Minor
@contentauth/c2pa-node Minor
@contentauth/c2pa-web 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

export { Trustmark } from "./Trustmark.js";
export { isActionsAssertion } from "./assertions.js";
export * from "./Settings.js";
export * from '@contentauth/c2pa-utilities';

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Re-exporting from utilities for client convenience.

vi.mock("node-fetch", () => ({
default: vi.fn(),
}));
import { loadSettingsFromFile } from "./Settings.js";

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Tests are consolidated and moved into the settings.spec.ts in c2pa-utilities. Only the one Node-specific function is tested here.


export interface BuilderInterface {
/** An intent lets the API know what kind of manifest to create.
/**

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Small formatting adjustment.

Comment thread packages/c2pa-utilities/src/fetchWithRetry.ts Outdated
dispose: () => void;
}

/**

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This comment was leftover in c2pa-web/src/index.ts. Not sure when it got lost, but it's meant to be attached to this function, so moving it over here now.

READER_SUPPORTED_FORMATS
} from './lib/supportedFormats.js';

export type {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

These are now re-exported from index.ts.

@@ -0,0 +1,436 @@
/**

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This file unifies Settings-related logic from both Web and Node SDKs, in some cases widening types and function signatures to support both, but without changing behavior. It also re-organizes code into more logical chunks.

Comment on lines +136 to +153
export interface BuilderSettings {
/**
* Whether to generate a C2PA archive (instead of zip) when writing the manifest builder.
*
* Note: `c2pa-rs` is deprecating the zip archive path — this setting is expected to be
* removed in a future release and should always be left `true`.
*/
generateC2paArchive?: boolean;
/**
* Settings for automatic thumbnail generation.
*/
thumbnail?: {
/**
* Whether to automatically generate a thumbnail for the asset being built, if possible.
*/
enabled?: boolean;
};
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This was union'd between the two packages. One had generateC2paArchive as an optional setting, and the other had thumbnail as an optional setting. They now both exist here in the new BuilderSettings as optional.

export async function resolveSettings(
baseSettings: Settings | undefined,
overrideSettings: Settings | undefined,
options?: FetchWithRetryOptions

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

These options could be generalized going forward, rather than being specific to FetchWithRetryOptions. However, at the moment, the only options that are passed in are specific to fetch-with-retry configuration, so I'm opting to name it as such for now.

@ale-adobe
ale-adobe requested review from cdmurph32 and tmathern July 31, 2026 23:32
@@ -0,0 +1,164 @@
/**

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Considering naming this file just fetch.ts.

@tmathern tmathern 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.

  • Please clarify the deprecation note in the types, it is confusing.
  • Also review comments in settings.

Comment thread packages/c2pa-node/js-src/types.d.ts Outdated
Comment thread packages/c2pa-utilities/src/fetchWithRetry.spec.ts Outdated
Comment thread packages/c2pa-utilities/src/fetchWithRetry.ts Outdated
Comment thread packages/c2pa-utilities/src/settings.ts Outdated
Comment thread packages/c2pa-utilities/src/settings.ts Outdated
Comment thread packages/c2pa-utilities/src/settings.ts Outdated
Comment thread packages/c2pa-utilities/src/settings.ts
Comment thread packages/c2pa-utilities/src/settings.ts Outdated
Comment thread packages/c2pa-utilities/src/settings.ts Outdated
Comment thread packages/c2pa-utilities/src/settings.ts Outdated

@cdmurph32 cdmurph32 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.

My only concern here is that this doesn't break anything. Could you please add tests in the c2pa-js and c2pa-node repositories to ensure the settings are applied?

@ale-adobe
ale-adobe requested review from cdmurph32 and tmathern August 6, 2026 22:42

@tmathern tmathern 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.

(Probably also update the PR description, I got no search hit on resolveTrustAnchors in this changeset, other mentioned functions are here).

Comment thread packages/c2pa-utilities/src/settings.ts
Comment thread .changeset/fresh-kiwis-doubt.md
Comment thread packages/c2pa-utilities/src/fetchWithRetry.ts
Comment thread packages/c2pa-utilities/src/settings.ts Outdated
Comment thread packages/c2pa-utilities/src/fetchWithRetry.ts

@cdmurph32 cdmurph32 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.

approved

@ale-adobe
ale-adobe merged commit b3b3196 into main Aug 10, 2026
2 checks passed
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.

3 participants