Skip to content

feat(type): support File size bounds#1637

Open
ooospooky wants to merge 4 commits into
arktypeio:mainfrom
ooospooky:feat/file-size-validation
Open

feat(type): support File size bounds#1637
ooospooky wants to merge 4 commits into
arktypeio:mainfrom
ooospooky:feat/file-size-validation

Conversation

@ooospooky

@ooospooky ooospooky commented Jul 12, 2026

Copy link
Copy Markdown

Summary

Issue #1166 (Discord thread).

Adds size bounds for File, using the same comparator syntax as numeric, length, and date bounds:

type("File <= 5MB")        // at most 5MB
type("File > 100KB")       // more than 100KB
type("1MB < File <= 10MB") // range
type("File == 5MB")        // exactly 5MB
type("File >= 1000")       // bare number = bytes

Units are decimal SI (B/KB/MB/GB/TB, 1000-based) and a bare number is bytes, per the questions raised on the issue — happy to switch to IEC/1024 units if you'd prefer.

Implementation notes

  • minSize/maxSize join the existing bound kinds (min/max, minLength/maxLength, after/before), keyed off $ark.intrinsic.File and checking data.size.
  • A size literal is resolved to its byte count in the type parser, so the schema stays canonical: File >= 5MB, >= 5000KB, and >= 5000000 are the same node ({ minSize: 5000000 }), with the description derived back to the most compact unit — the same approach Date bounds use with describeCollapsibleDate.
  • The File intrinsic uses the existing FileConstructor (globalThis.File ?? Blob) so importing the library doesn't throw on Node 18/19 where File isn't a global.
  • The rule is validated as a non-negative integer, and fractional-unit literals like 1.005KB round to exact bytes (avoiding the 1004.999… IEEE-754 boundary). A File bound rejects date literals (and vice versa) at both the type and runtime level, and toJsonSchema gains a size fallback so the constraint isn't silently dropped.

Test plan

  • Code is up-to-date with the main branch
  • You've successfully run pnpm prChecks locally
  • New unit tests cover each comparator, ranges, all units, fractional-byte rounding, empty-file rejection, and invalid-limit errors (range.test.ts, bounds.test.ts, keywords/file.test.ts); DTS snapshots regenerated

@pullfrog pullfrog Bot 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.

✅ No new issues found.

Reviewed changes — Added byte-size bounds (minSize/maxSize) for the File intrinsic using SI unit literals, with parser support, schema nodes, JSON Schema fallback, and comprehensive tests.

  • Added minSize/maxSize constraint nodes in ark/schema/refinements/minSize.ts and maxSize.ts, mirroring the existing minLength/maxLength pattern, with minSize: 0 reducing to unconstrained and size-0 descriptions special-cased.
  • Added size-literal parsing in ark/util/sizes.ts for B/KB/MB/GB/TB, resolving to canonical byte counts and rounding away IEEE-754 artifacts from fractional units like 1.005KB.
  • Wired File bounds through the type parser in ark/type/parser/ast/bounds.ts and ark/type/parser/shift/operator/bounds.ts, allowing numeric or size-literal limits while rejecting date literals for File and vice versa at the type level.
  • Registered File in the intrinsic scope in ark/schema/intrinsic.ts so bound detection can anchor on $ark.intrinsic.File.
  • Added size JSON Schema fallback in ark/schema/shared/toJsonSchema.ts so size constraints fail loudly rather than being silently dropped.
  • Expanded test coverage across bounds.test.ts, range.test.ts, and keywords/file.test.ts for comparators, ranges, units, fractional rounding, empty-file rejection, and invalid-limit errors.

Pullfrog  | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: To do

Development

Successfully merging this pull request may close these issues.

1 participant