Skip to content

Cut 1.0.0: native fetch, FormsparkError, modern toolchain + CI tests - #12

Merged
botre merged 8 commits into
masterfrom
v1-hardening
May 8, 2026
Merged

Cut 1.0.0: native fetch, FormsparkError, modern toolchain + CI tests#12
botre merged 8 commits into
masterfrom
v1-hardening

Conversation

@botre

@botre botre commented May 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Audit-driven hardening pass. Ships a coherent 1.0.0 that fixes real bugs, modernizes the toolchain, and adds end-to-end tests in one breaking release.

Runtime

  • Reject with FormsparkError (carrying status + parsed body) on non-2xx responses. Was previously resolving with the error body, so consumers couldn't tell a successful submit from a 422.
  • encodeURIComponent the formId before path interpolation.
  • Drop the whatwg-fetch polyfill: native fetch is universal across modern browsers, React Native, and Node 18+.
  • Memoize submit via useCallback([formId]) and destructure formId at hook entry — stable identity across renders.

Build

  • Replace unmaintained tsdx (46 npm advisories, last release 2020) with tsup.
  • npm audit: 46 vulnerabilities → 0.
  • Drop tslib / importHelpers; tsup handles helpers itself.
  • Bump engines.node to >=18, TypeScript to 5, moduleResolution to bundler, target to ES2022.

Tests (new)

  • tests/use-formspark.test.tsx with four cases:
    • Real-network: posts to https://submit-form.com/echo and verifies the echoed payload.
    • Real-network: posts to a non-existent form ID and verifies FormsparkError + status 404.
    • Submitting state toggles true during the call and false after.
    • submit reference is stable across renders for the same formId.
  • vitest + @testing-library/react + happy-dom; 15s per-test timeout for network jitter.

CI

  • actions/checkout v2 → v6, actions/setup-node v2 → v6, Node 16 → 22, cache: 'npm'.
  • New pull-request.yml workflow runs lint + build + test on PRs against master.
  • continuous-deployment.yml now runs npm test before bump/publish.
  • Pin phips28/gh-action-bump-version@master@v11.0.7 (no more moving-branch ref).
  • Replace tsdx lint in the husky pre-commit hook with tsc --noEmit.

README

  • Fix # Yarn trailing whitespace.
  • Rewrite the form-ID / action-URL note.
  • Add a slim Error handling section.

Peer deps

  • Drop React 16/17 from peerDependencies — now ^18.0.0 || ^19.0.0.

Breaking changes

  • Non-2xx responses now throw FormsparkError instead of resolving silently.
  • whatwg-fetch is no longer bundled. Polyfill manually if targeting pre-fetch runtimes.
  • engines.node is now >=18.
  • peerDependencies.react no longer accepts 16.x or 17.x.

Test plan

  • npm install — 0 vulnerabilities
  • npm run lint (tsc --noEmit) — clean
  • npm run build — emits CJS + ESM + .d.ts (~2 KB)
  • npm test — 4/4 passing locally, including live /echo and 404 calls
  • First merge to master will trigger the updated CD workflow — verify phips28/gh-action-bump-version@v11.0.7 accepts the existing tag-prefix: '' input
  • Confirm NPM_TOKEN secret is still valid

botre added 5 commits May 8, 2026 18:59
Audit-driven hardening pass for the package.

Runtime:
- Reject with FormsparkError on non-2xx responses (was silently resolving with the error body).
- encodeURIComponent the formId before path interpolation.
- Drop whatwg-fetch polyfill; native fetch is universal across modern browsers, React Native, and Node 18+.
- Memoize submit via useCallback([formId]); destructure formId at hook entry.

Build:
- Replace unmaintained tsdx (46 npm advisories) with tsup. 0 vulnerabilities after migration.
- Drop tslib/importHelpers; tsup handles helpers itself.
- Bump engines.node to >=18 and TypeScript to 5.

CI:
- actions/checkout v2 -> v6, actions/setup-node v2 -> v6, node 16 -> 22.
- Replace phips28/gh-action-bump-version@master with first-party npm version + softprops/action-gh-release@v2. Bump type read from commit message.

README: fix the form ID / action URL note, add an error-handling section.
Two real-network tests exercising the hook end-to-end:
- Happy path posts to https://submit-form.com/echo and verifies the echoed payload.
- Error path posts to a non-existent form ID and verifies the FormsparkError + 404 status.

Plus two cheap state-shape checks: submitting toggles during a call,
and submit identity is stable across renders for the same formId.

Runs on:
- PR open/sync against master (new pull-request.yml workflow).
- Push to master (added before the bump/publish step in continuous-deployment.yml).

Tooling: vitest + @testing-library/react + happy-dom (already added as
devDeps). 15s per-test timeout to absorb network jitter. tsconfig switched
to moduleResolution=bundler + ES2022 target + skipLibCheck for compatibility
with vitest's modern type declarations.
@botre botre changed the title Cut 1.0.0: native fetch, error rejection, modern build pipeline Cut 1.0.0: native fetch, FormsparkError, modern toolchain + CI tests May 8, 2026
botre added 3 commits May 8, 2026 19:19
Check runs lint/build/test on PRs against master and is also invoked
as a workflow_call from Deploy, so a master push runs the same
validations before bumping and publishing. No more inline duplication
between PR and deploy pipelines.

Renames:
- pull-request.yml -> check.yml
- continuous-deployment.yml -> deploy.yml

Updates the README badge to point at the renamed Deploy workflow.
@botre
botre merged commit 1f3b3ee into master May 8, 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.

1 participant