Skip to content

Modernize tooling and add TypeScript strict mode + tests - #3

Merged
alijany merged 5 commits into
mainfrom
claude/sleepy-babbage-m5ndx2
Jun 18, 2026
Merged

Modernize tooling and add TypeScript strict mode + tests#3
alijany merged 5 commits into
mainfrom
claude/sleepy-babbage-m5ndx2

Conversation

@alijany

@alijany alijany commented Jun 17, 2026

Copy link
Copy Markdown
Owner

Summary

This PR brings the cropo project up to date with modern tooling and best practices. The library code behavior is unchanged, but the build system, linting, testing, and TypeScript configuration have been completely refreshed after a long maintenance pause.

Key Changes

Build & Distribution:

  • Migrated from unmaintained microbundle to tsup (esbuild-based)
  • Now outputs ESM, CommonJS, IIFE/global, and type declarations
  • Updated package.json exports to properly declare all entry points (import/require/unpkg)
  • Added package-lock.json to version control for reproducibility

TypeScript & Type Safety:

  • Added explicit tsconfig.json with strict: true mode enabled
  • Updated script.ts to satisfy strict null/initialization checks using definite-assignment assertions (!) on properties initialized via load* methods
  • Added npm run typecheck script

Linting:

  • Migrated from legacy .eslintrc.json + unmaintained eslint-config-standard to ESLint 9 flat config (eslint.config.mjs)
  • Integrated typescript-eslint for proper TypeScript linting
  • Added npm run lint script

Testing:

  • Introduced Vitest with jsdom environment
  • Added test/setup.ts with lightweight stubs for Canvas 2D context, HTMLImageElement, and ResizeObserver
  • Created script.test.ts with initial test suite covering:
    • Constructor and initialization
    • Crop info math and image dimensions
    • Panning behavior (free vs. clamped)
    • Export guards (error handling)
  • Added npm test script

CI/CD:

  • Replaced ad-hoc GitHub Actions with unified ci.yml that runs typecheck, lint, test, and build on every push/PR
  • Updated npm-publish.yml to run the same quality gates before publishing
  • Upgraded deprecated GitHub Actions (checkout@v4, setup-node@v4, codeql-action@v3)

Demo Site (docsSrc/):

  • Removed unused React dependency and hardcoded local tarball reference
  • Updated Parcel and Tailwind to latest versions (Tailwind 3)
  • Fixed tailwind.config.js to use modern content key instead of deprecated purge
  • Removed autoprefixer (no longer needed with Tailwind 3)
  • Added proper npm scripts (start, build, clean)

Documentation:

  • Added ROADMAP.md outlining the path to 1.0.0, including planned breaking changes:
    • Removal of deprecated function-style API
    • Making constructor options required
    • Expanding test coverage before the major release

Notable Implementation Details

  • Definite-assignment assertions (!) are used on properties like canvas, img, scale that are initialized asynchronously via loadCanvas() and loadImageFromUrl() methods, satisfying TypeScript strict mode while preserving the existing lazy-initialization pattern
  • The test setup uses queueMicrotask to simulate the browser's image load lifecycle without requiring real network calls
  • Canvas context and ResizeObserver are stubbed at module scope before script.ts is imported, ensuring the deprecated module-level new Cropo({}) instance can be tested
  • Node 18+ is now required (specified in engines field)

https://claude.ai/code/session_01RZusPpnLpewhvkmrd2UV7y

claude and others added 5 commits June 17, 2026 18:28
The project had not been updated since Jan 2022. Refresh the tooling so it
builds, lints, type-checks, and tests on a current Node/toolchain:

- Replace the unmaintained microbundle (broken against modern TypeScript) with
  tsup; emit ESM/CJS/IIFE + type declarations and update package exports.
- Add a strict tsconfig.json and an "npm run typecheck" script; satisfy strict
  null/initialization checks in script.ts (definite-assignment assertions,
  null-guards on getContext/toBlob).
- Migrate ESLint to flat config (eslint.config.mjs) with typescript-eslint,
  replacing the legacy .eslintrc.json and unmaintained eslint-config-standard.
- Add a Vitest (jsdom) suite covering construction, crop-info math,
  panning/clamping, and export guards.
- Commit package-lock.json (stop ignoring it) for reproducible npm ci builds.
- Add ci.yml (typecheck/lint/test/build on push & PR, Node 20); modernize
  npm-publish.yml and bump deprecated GitHub Actions (checkout@v4, setup-node@v4,
  codeql-action@v3). Remove the redundant super-linter workflow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RZusPpnLpewhvkmrd2UV7y
The demo could not install on any machine: docsSrc/package.json referenced cropo
via a hardcoded Windows tarball path, plus unused React and css.gg dependencies.

- Remove the broken cropo tarball path (the demo imports ../script directly) and
  the unused react/react-dom/@types/react and css.gg deps.
- Add real start/build scripts and upgrade Parcel + Tailwind to 3.x; convert the
  Tailwind config to v3 (content/darkMode) and drop autoprefixer (Parcel handles
  prefixing).
- Rebuild the published docs/ output.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RZusPpnLpewhvkmrd2UV7y
Document the path from the 0.6.x maintenance refresh to a breaking 1.0.0:
removing the deprecated function-style API and the module-level shared instance,
making constructor options required, and expanding test coverage first. Includes
a consumer migration example.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RZusPpnLpewhvkmrd2UV7y
Expand from 6 to 23 cases covering previously untested behavior, driving the
class through its public API and real dispatched DOM events.

Harness (test/setup.ts, test/helpers.ts):
- Stub canvas export (toDataURL/toBlob) with a controllable blob result.
- Make the FakeImage size configurable (landscape/portrait fit scenarios).
- Capture the ResizeObserver callback so resize can be triggered in tests.
- Add event-factory helpers: firePointer, fireSliderInput, triggerResize.

New/relocated tests under test/:
- core: construction, getCropInfo, error paths (moved from script.test.ts).
- export: getDataUrl/getBlob (+ null-blob rejection), download anchor/click,
  export-canvas scaling.
- zoom: slider-driven zoomScale, min/max scale clamping and custom options.
- pan: full move clamping (both axes/bounds) and a pointer-drag sequence.
- pinch: two-pointer zoomDelta growth and maxScale limit.
- resize: debounced onResize via fake timers, plus the no-image no-op.

Test-only change; script.ts and the published bundles are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RZusPpnLpewhvkmrd2UV7y
@alijany
alijany requested review from mh-alijany and removed request for mh-alijany June 18, 2026 05:07

@alijany alijany left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

LG

@alijany
alijany merged commit 482efdb into main Jun 18, 2026
1 check 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.

2 participants