Affected package or area
@sapiom/fetch
Affected version, release, or commit
@sapiom/fetch 0.5.0, commit d7d480a
Environment
- Node.js: v24.14.1
- Package manager and version: pnpm 10.34.3 via Corepack
- Operating system: WSL2 / Linux 5.15.167.4-microsoft-standard-WSL2 x86_64
- Runtime or framework (if relevant): native Fetch API / Request
Minimal reproduction and steps
Reproduction code sample:
const r = new Request("https://example.test/public");
r.__sapiom = { enabled: false };
const copy = new Request(r);
console.log(JSON.stringify({
original: r.__sapiom,
cloned: copy.__sapiom ?? null,
clonedHasOwn: Object.prototype.hasOwnProperty.call(copy, "__sapiom"),
}, null, 2));
Steps:
- Create a Request object.
- Attach
__sapiom = { enabled: false } to it.
- Clone it with
new Request(request), matching what @sapiom/fetch does internally.
- Check whether the cloned request still has
__sapiom.
Actual output from the reproduction:
{
"original": {
"enabled": false
},
"cloned": null,
"clonedHasOwn": false
}
The metadata is lost during cloning, so @sapiom/fetch reads no per-request override after new Request(input, init).
Expected behavior
The documented per-request override should be honored for Request inputs.
When a request is created like this:
const publicRequest = new Request("/api/public");
(publicRequest as any).__sapiom = { enabled: false };
await fetch(publicRequest);
@sapiom/fetch should bypass Sapiom authorization/payment handling for that single request.
The metadata should be read from the original Request before cloning, or copied onto the cloned request before interceptors run.
Actual behavior
@sapiom/fetch clones the input with new Request(input, init) before reading __sapiom.
Native Request cloning does not preserve custom properties, so __sapiom is lost. As a result, a request with __sapiom = { enabled: false } is treated as if no per-request override was provided, and the request can still continue through Sapiom authorization/payment handling instead of being bypassed.
Logs, screenshots, and additional context
Relevant code:
packages/fetch/src/fetch.ts documents Request.__sapiom per-request overrides, including { enabled: false }.
packages/fetch/src/fetch.ts clones the input with new Request(input, init) before reading (request as any).__sapiom.
packages/fetch/src/interceptors.ts also reads metadata from the cloned request.
I checked open issue/PR searches for __sapiom / enabled and did not find an open duplicate.
Acknowledgements
Affected package or area
@sapiom/fetch
Affected version, release, or commit
@sapiom/fetch 0.5.0, commit d7d480a
Environment
Minimal reproduction and steps
Reproduction code sample:
Steps:
__sapiom = { enabled: false }to it.new Request(request), matching what @sapiom/fetch does internally.__sapiom.Actual output from the reproduction:
{ "original": { "enabled": false }, "cloned": null, "clonedHasOwn": false }The metadata is lost during cloning, so @sapiom/fetch reads no per-request override after
new Request(input, init).Expected behavior
The documented per-request override should be honored for Request inputs.
When a request is created like this:
@sapiom/fetch should bypass Sapiom authorization/payment handling for that single request.
The metadata should be read from the original Request before cloning, or copied onto the cloned request before interceptors run.
Actual behavior
@sapiom/fetch clones the input with
new Request(input, init)before reading__sapiom.Native Request cloning does not preserve custom properties, so
__sapiomis lost. As a result, a request with__sapiom = { enabled: false }is treated as if no per-request override was provided, and the request can still continue through Sapiom authorization/payment handling instead of being bypassed.Logs, screenshots, and additional context
Relevant code:
packages/fetch/src/fetch.tsdocumentsRequest.__sapiomper-request overrides, including{ enabled: false }.packages/fetch/src/fetch.tsclones the input withnew Request(input, init)before reading(request as any).__sapiom.packages/fetch/src/interceptors.tsalso reads metadata from the cloned request.I checked open issue/PR searches for
__sapiom/enabledand did not find an open duplicate.Acknowledgements