chore: fix format glob, gate stale dist/ in CI, drop dead config - #276
Merged
Conversation
joris974
marked this pull request as ready for review
August 25, 2026 20:21
joris974
enabled auto-merge
August 25, 2026 22:04
joris974
disabled auto-merge
August 25, 2026 22:11
joris974
enabled auto-merge
August 25, 2026 22:12
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
force-pushed
the
chore/fix-prettier-format-glob
branch
from
August 27, 2026 17:44
ea0c548 to
64160a4
Compare
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
previously approved these changes
Aug 28, 2026
`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
force-pushed
the
chore/fix-prettier-format-glob
branch
from
August 28, 2026 15:09
04946fa to
af87eef
Compare
cristygrant
approved these changes
Aug 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Nine independent commits, rebased onto
mainat #278.chore: fix the prettier format glob to target .ts sourcesformatwasprettier --write 'src/**/*.js'. Every source insrc/is.ts, so the glob matched nothing and prettier treated that as an error:There is no formatting backlog behind it.
.restyled.yamlalready listssrc/**/*.tsunder its prettier restyler, so the bot has been formatting these files all along, andpnpm formatwith the fixed glob reports all six files unchanged.ci: check for stale dist/ with check-git-clean-actiondist/is committed, but no workflow verified it matchedsrc/, so a PR could merge with the two out of sync.check-git-clean.shand thecheck-git-cleanscript existed for this and nothing called them. The script was also committed without its executable bit (100644), sopnpm check-git-cleandied withPermission deniedregardless.Both are replaced by
freckle/check-git-clean-action@v1, matching ajax-js after freckle/ajax-js#200. The action checksgit status --porcelain --untracked-files=normal, so it also catches untracked build output that the script'sgit diffmissed.chore: remove dead eslint-disable commentsrc/formatting.tscarried ano-prototype-builtinsdirective. There's no eslint config and no eslint dependency, and neither CI nor.restyled.yamlruns a linter, so nothing read it.It was also being emitted into
dist/formatting.js, since tsc preserves comments by default. The rebuiltdist/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 configPrettier warns
jsxBracketSameLine is deprecatedon every run. Its replacement isbracketSameLine, whose default offalsematches 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 requiresconventional-changelog-writer@9+that the bundled@semantic-release/release-notes-generatordoesn'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. Thecheck-git-clean-actionstep 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 .gitignoreThe whitespace restyler covers
**/*, excluding onlydist/andflow/.chore: drop dead restyled globsThe prettier restyler listed
src/**/*.jsalongsidesrc/**/*.ts.src/holds only.tsfiles and no.jshas ever been tracked there, so the first glob matched nothing. The whitespace restyler excludedflow/, which has never existed in this repo's history.chore(deps): refresh the lockfile to clear dev-tree advisoriesEight open Dependabot alerts, all development scope, were stale lockfile pins rather than range constraints.
vitest@^4.1.11already permitsvite ^6 || ^7 || ^8, sopackage.jsonneeded no change: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 updateandrm pnpm-lock.yamlboth no-op, since pnpm rebuilds an identical lock fromnode_modules. It tookrm -rf node_modules pnpm-lock.yaml && pnpm install --force.Verification
Ran the sequence
ci.ymlnow 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
lodashat runtime scope come in through@freckle/non-empty@^3.0.0, which pinslodash 4.17.21: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@^4is not a way out: v4.0.1 cannot be imported by any ESM consumer. Itsdist/index.js:1isimport { first, flatten, last, map, sortBy } from 'lodash', and lodash is CommonJS with no named ESM exports, sonode --input-type=module -e "import {mkNonEmpty} from '@freckle/non-empty'"throwsSyntaxError: Named export 'first' not found. These alerts need a fix in non-empty-js first.@freckle/non-emptyalso ships declarations that importArrayIteratorandListIteratorfromlodashwhile listing@types/lodashonly indevDependencies, so consumers withskipLibCheck: falsegetTS2307. That needs fixing in non-empty-js.