Skip to content

feat: add Format constants for convert media types, including JXL - #55

Open
Sreini wants to merge 1 commit into
masterfrom
feat/jxl-format
Open

feat: add Format constants for convert media types, including JXL#55
Sreini wants to merge 1 commit into
masterfrom
feat/jxl-format

Conversation

@Sreini

@Sreini Sreini commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Adds a tinify.Format constant object so the media types accepted by convert
are discoverable at runtime, not only in the type system — matching the
Format API being added to the other five Tinify client libraries.

JXL itself already landed here in 1.8.3 (ea25ea9); this PR is about making the
full set discoverable and consistent across languages.

Members

WEBP, PNG, JPEG, JPG, AVIF, JXL, ANY (*/*) — mirroring the API
allowlist exactly.

SupportedImageTypes is now derived from Format

Rather than duplicating the literal list, the union is computed from the
constant object, so the two cannot drift apart:

type FormatValues = (typeof Format)[keyof typeof Format];
export type SupportedImageTypes = Exclude<FormatValues, typeof Format.ANY>;

The derived union is equivalent to the old one, verified with a negative
typecheck: it still rejects unknown media types, and still excludes the */*
wildcard from the array form. Both @ts-expect-error assertions fired:

// @ts-expect-error bogus media type must NOT be assignable
await tinify.fromFile("/foo").convert({ type: "image/bogus" })
// @ts-expect-error wildcard is not valid inside an array
await tinify.fromFile("/foo").convert({ type: ["*/*"] })

Verification

Full suite green locally: npm test → 85 passing, and the typing test compiles
with the new tinify.Format.* cases added to it.

Note on the remote

This branch was pushed to upstream (tinify/tinify-nodejs), since the local
checkout's origin points at a personal fork while master tracks upstream.

Part of a coordinated change across all six Tinify client libraries, so the same
Format API is available in each.

Adds a Format constant object so the media types accepted by convert()
are discoverable at runtime as well as in the type system, matching the
other Tinify client libraries.

SupportedImageTypes is now derived from Format rather than duplicating
the literal list, so the two cannot drift apart. The derived union is
equivalent to the old one: it still rejects unknown media types and
still excludes the "*/*" wildcard from array form.
@rkoopmans

Copy link
Copy Markdown
Contributor

👍 imo we can create a release (bump version and changelog)

@rkoopmans

Copy link
Copy Markdown
Contributor

Also update the README.md with an example of using the new Format 🏅

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

The PR description’s claimed negative type assertions are not present in the typing test, and there’s a small correctness issue in the new Format documentation (JPG described as an alias despite differing value).

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds a runtime-discoverable tinify.Format constants object so consumers can reference supported convert media types at runtime (not only via TypeScript literal unions), aligning this client with the other Tinify libraries.

Changes:

  • Introduces src/tinify/Format.ts and wires it onto the public tinify export as tinify.Format.
  • Refactors SupportedImageTypes / WildcardOrSupportedImageTypes to be derived from Format (avoiding drift).
  • Updates typing tests and docs/changelog to include the new constants and formats (e.g., JXL, AVIF).
File summaries
File Description
test/tinify-typing-test.ts Extends TS typing coverage for convert to include new formats and tinify.Format constants.
src/tinify/Source.ts Derives SupportedImageTypes and wildcard type from Format rather than duplicating literals.
src/tinify/Format.ts Adds the runtime Format constants object for supported convert media types.
src/tinify.ts Adds Format onto the Tinify instance type so it’s available in generated typings.
src/index.ts Attaches Format to the exported tinify object at runtime (tinify.Format = Format).
README.md Updates format lists to include JXL in the documented capabilities.
CHANGES.md Documents the new tinify.Format API under Unreleased.
Review details
  • Files reviewed: 7/7 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 20 to +28
await tinify.fromFile("/foo/bar").convert({ type: "*/*" })

// The Format constants are accepted everywhere a literal is.
await tinify.fromFile("/foo/bar").convert({ type: tinify.Format.JXL })
await tinify.fromFile("/foo/bar").convert({ type: tinify.Format.ANY })
await tinify.fromFile("/foo/bar").convert({
type: [tinify.Format.JXL, tinify.Format.WEBP],
})

Comment thread src/tinify/Format.ts
Comment on lines +29 to +30
/** JPEG, an alias of `JPEG`. */
JPG: "image/jpg",
Comment thread src/tinify/Source.ts
Comment on lines +9 to +11
type FormatValues = (typeof Format)[keyof typeof Format];

export type SupportedImageTypes = Exclude<FormatValues, typeof Format.ANY>;
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