Skip to content

chore: fix format glob, gate stale dist/ in CI, drop dead config - #276

Merged
joris974 merged 9 commits into
mainfrom
chore/fix-prettier-format-glob
Aug 28, 2026
Merged

chore: fix format glob, gate stale dist/ in CI, drop dead config#276
joris974 merged 9 commits into
mainfrom
chore/fix-prettier-format-glob

Conversation

@joris974

@joris974 joris974 commented Aug 25, 2026

Copy link
Copy Markdown
Member

Nine independent commits, rebased onto main at #278.

chore: fix the prettier format glob to target .ts sources

format was prettier --write 'src/**/*.js'. Every source in src/ is .ts, so the glob matched nothing and prettier treated that as an error:

$ pnpm format
[error] No files matching the pattern were found: "src/**/*.js".
[ELIFECYCLE] Command failed with exit code 2.

There is no formatting backlog behind it. .restyled.yaml already lists src/**/*.ts under its prettier restyler, so the bot has been formatting these files all along, and pnpm format with the fixed glob reports all six files unchanged.

ci: check for stale dist/ with check-git-clean-action

dist/ is committed, but no workflow verified it matched src/, so a PR could merge with the two out of sync. check-git-clean.sh and the check-git-clean script existed for this and nothing called them. The script was also committed without its executable bit (100644), so pnpm check-git-clean died with Permission denied regardless.

Both are replaced by freckle/check-git-clean-action@v1, matching ajax-js after freckle/ajax-js#200. The action checks git status --porcelain --untracked-files=normal, so it also catches untracked build output that the script's git diff missed.

chore: remove dead eslint-disable comment

src/formatting.ts carried a no-prototype-builtins directive. There's no eslint config and no eslint dependency, and neither CI nor .restyled.yaml runs a linter, so nothing read it.

It was also being emitted into dist/formatting.js, since tsc preserves comments by default. The rebuilt dist/ joins the arrow body back onto one line now that the comment no longer splits it. Normalising whitespace on both sides shows the emitted code is otherwise identical.

chore: drop deprecated jsxBracketSameLine from prettier config

Prettier warns jsxBracketSameLine is deprecated on every run. Its replacement is bracketSameLine, whose default of false matches the value set here, so removing the option leaves formatting unchanged. This package has no JSX either way.

fix(release): pin conventional-changelog-conventionalcommits to the major

#268 pinned the exact patch, 9.3.1. Pinning the major keeps patch and minor releases flowing while still excluding 10.x, which requires conventional-changelog-writer@9+ that the bundled @semantic-release/release-notes-generator doesn't provide. Matches maybe-js and ajax-js.

chore: remove the PR checklist comment

#272 left the comment with one item: that dist/ reflect the changes in the PR. The check-git-clean-action step added in this branch now fails the build on exactly that, so the comment has nothing left to tell a reviewer. The config and the workflow that posts it both go, matching ajax-js after freckle/ajax-js#203.

chore: add trailing newline to .gitignore

The whitespace restyler covers **/*, excluding only dist/ and flow/.

chore: drop dead restyled globs

The prettier restyler listed src/**/*.js alongside src/**/*.ts. src/ holds only .ts files and no .js has ever been tracked there, so the first glob matched nothing. The whitespace restyler excluded flow/, which has never existed in this repo's history.

chore(deps): refresh the lockfile to clear dev-tree advisories

Eight open Dependabot alerts, all development scope, were stale lockfile pins rather than range constraints. vitest@^4.1.11 already permits vite ^6 || ^7 || ^8, so package.json needed no change:

vite     7.3.1  -> 8.2.2   (3 high, 2 moderate)
postcss  8.5.15 -> 8.5.26  (1 high, 1 moderate)
esbuild  0.27.7 -> dropped (1 low)

vite 8 does not depend on esbuild, so that subtree leaves entirely: 81 esbuild references in the lockfile become 2, both an optional peer range that nothing installs. The lockfile shrinks by 570 lines.

Worth knowing for reproducing it: pnpm update and rm pnpm-lock.yaml both no-op, since pnpm rebuilds an identical lock from node_modules. It took rm -rf node_modules pnpm-lock.yaml && pnpm install --force.

Verification

Ran the sequence ci.yml now defines: pnpm install --frozen-lockfile, pnpm build, pnpm test (82 tests pass), then the action's own check, git status --porcelain --untracked-files=normal, which comes back empty.

Not covered here

Three open Dependabot alerts against lodash at runtime scope come in through @freckle/non-empty@^3.0.0, which pins lodash 4.17.21:

lodash@4.17.21 └─┬ @freckle/non-empty@3.0.0 └── @freckle/parser (dependencies)

GHSA-r5fr-rjxr-66jc (high), GHSA-f23m-r3pf-42rh and GHSA-xxjr-mmjv-4gpg (moderate), all fixed in lodash 4.18.0. Bumping to @freckle/non-empty@^4 is not a way out: v4.0.1 cannot be imported by any ESM consumer. Its dist/index.js:1 is import { first, flatten, last, map, sortBy } from 'lodash', and lodash is CommonJS with no named ESM exports, so node --input-type=module -e "import {mkNonEmpty} from '@freckle/non-empty'" throws SyntaxError: Named export 'first' not found. These alerts need a fix in non-empty-js first.

@freckle/non-empty also ships declarations that import ArrayIterator and ListIterator from lodash while listing @types/lodash only in devDependencies, so consumers with skipLibCheck: false get TS2307. That needs fixing in non-empty-js.

@joris974
joris974 marked this pull request as ready for review August 25, 2026 20:21
@joris974
joris974 requested a review from a team as a code owner August 25, 2026 20:21
@joris974
joris974 requested review from cristygrant and removed request for a team August 25, 2026 20:21
@joris974 joris974 self-assigned this Aug 25, 2026
@joris974
joris974 enabled auto-merge August 25, 2026 22:04
@joris974
joris974 disabled auto-merge August 25, 2026 22:11
@joris974
joris974 enabled auto-merge August 25, 2026 22:12
@joris974
joris974 marked this pull request as draft August 27, 2026 17:41
auto-merge was automatically disabled August 27, 2026 17:41

Pull request was converted to draft

@joris974
joris974 force-pushed the chore/fix-prettier-format-glob branch from ea0c548 to 64160a4 Compare August 27, 2026 17:44
@joris974 joris974 changed the title chore: fix the prettier format glob to target .ts sources chore: fix format glob, gate stale dist/ in CI, drop dead config Aug 27, 2026
@joris974
joris974 marked this pull request as ready for review August 27, 2026 19:52
joris974 added a commit to freckle/non-empty-js that referenced this pull request Aug 27, 2026
This package is "type": "module", and src/index.ts named-imported first,
flatten, last, map and sortBy from lodash. lodash is CommonJS and exposes
no named ESM exports, so importing the built package from Node threw:

  SyntaxError: Named export 'first' not found. The requested module 'lodash'
  is a CommonJS module, which may not support all module.exports as named
  exports.

Every published 4.x is unloadable by any ESM consumer as a result. parser-js
stays pinned to ^3.0.0 because of it, which is what keeps the vulnerable
lodash 4.17.21 in its tree (freckle/parser-js#276).

Rather than work around the interop, the five functions are gone:

  first(a)      -> a.at(0)
  last(a)       -> a.at(-1)
  flatten(a)    -> a.flat()
  map(a, f)     -> a.map(f)
  sortBy(a, k)  -> decorate/sort/undecorate with compareKeys

@freckle/maybe 2.3.1 has no dependencies of its own, so lodash leaves the
tree entirely and this package now depends on @freckle/maybe alone. That
also removes the three open lodash advisories at their source rather than by
version bump, and drops the @types/lodash requirement that made published
declarations unresolvable for consumers with skipLibCheck: false.

sortBy needed care. It is stable and orders unorderable keys last, and
groupAllWith relies on equal keys landing adjacent. A bare a < b comparator
leaves null, undefined and NaN keys wherever they started, splitting their
groups. compareKeys ranks them instead, reproducing lodash's order:
orderable keys ascending, then null, then undefined, then NaN. Array sort is
stable per spec, so equal keys keep insertion order. The decorated form also
keeps key at one call per item for the sort rather than twice per comparison.

Verified by differencing groupAllWith against the lodash implementation over
numbers, booleans, strings, all-equal, duplicate, object-field, undefined,
null, NaN and mixed null/undefined keys: identical output on all ten.

mapOnNonEmpty's f changes from lodash's ListIterator<T,U> | ArrayIterator<T,U>
to (value: T, index: number, array: Array<T>) => U. Both lodash and native
map pass (value, index, collection), so callers are unaffected, and a
function annotated with the old lodash types stays assignable. The union also
defeated contextual inference, so mapOnNonEmpty(ne, x => x + 1) now infers x
instead of erroring with TS7006.
joris974 added a commit to freckle/non-empty-js that referenced this pull request Aug 27, 2026
Replaces the hand-rolled script with freckle/check-git-clean-action@v1,
matching ajax-js after freckle/ajax-js#200 and parser-js after
freckle/parser-js#276.

The action checks git status --porcelain --untracked-files=normal, so it
also catches untracked build output that the script's git diff missed.
joris974 added a commit to freckle/non-empty-js that referenced this pull request Aug 27, 2026
This package is "type": "module", and src/index.ts named-imported first,
flatten, last, map and sortBy from lodash. lodash is CommonJS and exposes
no named ESM exports, so importing the built package from Node threw:

  SyntaxError: Named export 'first' not found. The requested module 'lodash'
  is a CommonJS module, which may not support all module.exports as named
  exports.

Every published 4.x is unloadable by any ESM consumer as a result. parser-js
stays pinned to ^3.0.0 because of it, which is what keeps the vulnerable
lodash 4.17.21 in its tree (freckle/parser-js#276).

Rather than work around the interop, the five functions are gone:

  first(a)      -> a.at(0)
  last(a)       -> a.at(-1)
  flatten(a)    -> a.flat()
  map(a, f)     -> a.map(f)
  sortBy(a, k)  -> decorate/sort/undecorate with compareKeys

@freckle/maybe 2.3.1 has no dependencies of its own, so lodash leaves the
tree entirely and this package now depends on @freckle/maybe alone. That
also removes the three open lodash advisories at their source rather than by
version bump, and drops the @types/lodash requirement that made published
declarations unresolvable for consumers with skipLibCheck: false.

sortBy needed care. It is stable and orders unorderable keys last, and
groupAllWith relies on equal keys landing adjacent. A bare a < b comparator
leaves null, undefined and NaN keys wherever they started, splitting their
groups. compareKeys ranks them instead, reproducing lodash's order:
orderable keys ascending, then null, then undefined, then NaN. Array sort is
stable per spec, so equal keys keep insertion order. The decorated form also
keeps key at one call per item for the sort rather than twice per comparison.

Verified by differencing groupAllWith against the lodash implementation over
numbers, booleans, strings, all-equal, duplicate, object-field, undefined,
null, NaN and mixed null/undefined keys: identical output on all ten.

BREAKING CHANGE: lodash is no longer a dependency, and mapOnNonEmpty's
iteratee type changes from lodash's ListIterator<T, U> | ArrayIterator<T, U>
to (value: T, index: number, array: Array<T>) => U.

Callers passing a lambda are unaffected, since both lodash and native map
pass (value, index, collection), and a function annotated with the old
lodash types stays structurally assignable. Two things do change for
consumers: anyone who relied on lodash or @types/lodash being installed
transitively through this package must now depend on them directly, and
anyone who imported ListIterator or ArrayIterator to annotate a callback
should drop the annotation, since the union defeated contextual inference
and a bare lambda now infers.
joris974 added a commit to freckle/non-empty-js that referenced this pull request Aug 27, 2026
Replaces the hand-rolled script with freckle/check-git-clean-action@v1,
matching ajax-js after freckle/ajax-js#200 and parser-js after
freckle/parser-js#276.

The action checks git status --porcelain --untracked-files=normal, so it
also catches untracked build output that the script's git diff missed.
cristygrant
cristygrant previously approved these changes Aug 28, 2026
joris974 and others added 9 commits August 28, 2026 08:08
`format` was `prettier --write 'src/**/*.js'`, but this is a TypeScript
repo with no .js sources under src/. Prettier treats an unmatched
pattern as an error, so `pnpm format` failed with exit code 2:

  [error] No files matching the pattern were found: "src/**/*.js".

Pointing the glob at 'src/**/*.ts' matches the six real sources and
mirrors what .restyled.yaml already enforces. No reformat resulted --
all six files report "(unchanged)".

Found by the Dead Weight audit of Freckle JS/TS repos.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
dist/ is committed, but no workflow verified it matched src/, so a PR
could merge with the two out of sync. check-git-clean.sh and the
check-git-clean script existed for this and nothing called them.

Replaces both with freckle/check-git-clean-action@v1, matching ajax-js
after freckle/ajax-js#200. The action uses git status --porcelain
--untracked-files=normal, so it catches untracked build output that the
script's git diff missed.

The script was also committed without its executable bit (100644), so
pnpm check-git-clean died with Permission denied regardless.
Prettier warns "jsxBracketSameLine is deprecated" on every run. Its
replacement is bracketSameLine, whose default of false matches the value
set here, so removing the option leaves formatting unchanged. This package
has no JSX either way.
src/formatting.ts carried a no-prototype-builtins directive. The repo has
no eslint config and no eslint dependency, and neither CI nor
.restyled.yaml runs a linter, so nothing read it.

It was also being emitted into dist/formatting.js, since tsc preserves
comments by default. Rebuilt dist/ joins the arrow body back onto one line
now that the comment no longer splits it; the emitted code is otherwise
identical.
…ajor

#268 pinned the exact patch, 9.3.1. Pinning the major keeps patch and
minor releases flowing while still excluding 10.x, which requires
conventional-changelog-writer@9+ that the bundled
@semantic-release/release-notes-generator does not provide.

Matches maybe-js and ajax-js.
The whitespace restyler covers '**/*', excluding only dist/ and flow/.
#272 left the comment with one item: that dist/ reflect the changes in the
PR. The check-git-clean-action step added earlier in this branch now fails
the build on exactly that, so the comment has nothing left to tell a
reviewer.

The config and the workflow that posts it both go, matching ajax-js after
freckle/ajax-js#203.
The prettier restyler listed src/**/*.js alongside src/**/*.ts. src/ holds
only .ts files and no .js has ever been tracked there, so the first glob
matched nothing.

The whitespace restyler excluded flow/, which has never existed in this
repo's history.
Eight open Dependabot alerts, all development scope, were stale lockfile
pins rather than range constraints. vitest@^4.1.11 already permits
vite ^6 || ^7 || ^8, so package.json needed no change:

  vite     7.3.1  -> 8.2.2   (3 high, 2 moderate)
  postcss  8.5.15 -> 8.5.26  (1 high, 1 moderate)
  esbuild  0.27.7 -> dropped (1 low)

vite 8 does not depend on esbuild, so that subtree leaves entirely: 81
esbuild references in the lockfile become 2, both an optional peer range
that nothing installs. The lockfile shrinks by 570 lines.

pnpm update and rm pnpm-lock.yaml both no-op here, since pnpm rebuilds an
identical lock from node_modules. This took
rm -rf node_modules pnpm-lock.yaml && pnpm install --force.
@joris974
joris974 requested a review from cristygrant August 28, 2026 15:10
@joris974
joris974 merged commit 0f5780c into main Aug 28, 2026
5 checks passed
@joris974
joris974 deleted the chore/fix-prettier-format-glob branch August 28, 2026 19:58
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