Priority: P1
Problem
Signed URL expiry is unconstrained in core and passed directly to each provider. Negative, NaN, and fractional values produce expired or provider-dependent URLs.
Evidence
SignedUrlOptions.expiresIn in packages/storage-core/src/libs/types.ts is unconstrained and is forwarded by the in-memory, R2, Cloudflare Images, and Cloudinary providers.
Desired outcome
Every storage adapter shares one explicit signed-URL expiry contract.
Implementation path
- Define positive safe-integer expiry validation and a documented upper bound in storage-core.
- Use it at every provider boundary.
- Add a conformance table for invalid inputs and expiry propagation.
Acceptance criteria
- All providers reject the same invalid expiry values.
- Valid expiry is propagated without unit ambiguity.
- Error code and message are provider-independent.
Validation
Run tests for @croco/storage-core, @croco/storage-r2, @croco/storage-cloudflare, and @croco/storage-cloudinary.
Scope boundaries
Does not change URL signing algorithms or provider credentials.
Priority: P1
Problem
Signed URL expiry is unconstrained in core and passed directly to each provider. Negative, NaN, and fractional values produce expired or provider-dependent URLs.
Evidence
SignedUrlOptions.expiresIninpackages/storage-core/src/libs/types.tsis unconstrained and is forwarded by the in-memory, R2, Cloudflare Images, and Cloudinary providers.Desired outcome
Every storage adapter shares one explicit signed-URL expiry contract.
Implementation path
Acceptance criteria
Validation
Run tests for
@croco/storage-core,@croco/storage-r2,@croco/storage-cloudflare, and@croco/storage-cloudinary.Scope boundaries
Does not change URL signing algorithms or provider credentials.