chore: adopt the oxc toolchain, share release tooling with sf-formula-parser - #297
chore: adopt the oxc toolchain, share release tooling with sf-formula-parser#297paustint wants to merge 8 commits into
Conversation
Replace Prettier with oxfmt and add oxlint, which the repository did not have at all. Config moves from .prettierrc to .oxfmtrc.json, every option carried over except the no-op insertPragma, with .oxlintrc.json alongside. oxlint runs correctness, suspicious and perf as errors. style and pedantic stay off: on a hand-written recursive-descent parser they ask for the code to be restructured rather than pointing at defects. Disabled rules carry their reason inline, including two false positives - no-unmodified-loop-condition does not see that the paren-matching loops mutate parenCount.right, and no-await-in-loop flags polling loops whose iterations are sequential by design. Upgrade to TypeScript 7 and the latest esbuild, release-it and tsx. Drop npm-run-all and lodash.get, add @vitest/coverage-v8, and rename vitest.config.ts to .mts since it is ESM while the root package is CommonJS. Remove .npmignore: files in package.json takes precedence, so it had no effect - npm pack produces a byte identical 21 file tarball without it - and it had drifted, listing CHANGELOG.md and AUTHORS.md as excluded while files ships both.
No behavior change to the published library. A redundant double negation,
a ? true : false ternary, an unused local and an unused catch binding
removed; new Array(n).fill(' ').join('') in pad() became ' '.repeat(n);
three shadowed variables renamed.
In the tests, the performance benchmark had no assertion and now checks
that every iteration actually parsed, two toThrow() calls gained the
message matcher their neighbours already used, and unused imports were
dropped.
removeComments dropped every JSDoc block from dist/types, so editors showed no documentation on hover for any exported symbol. Removing it restores them for 12 KB of declaration output and leaves the JavaScript bundles untouched, since esbuild builds those. isolatedDeclarations is on and the target is ES2022, matching sf-formula-parser. The target only affects emitted declarations and esbuild was already producing es2020/es2022 bundles, so the shipped JavaScript is unchanged. tsconfig.typecheck.json covers tests, scripts and the cli, which the build's declaration-only tsconfig.json excludes.
A pre-commit hook blocks commits whose staged files are unformatted or fail lint, running both so one attempt reports everything to fix. CI gates on format:check, lint and typecheck alongside the tests and build, because the hook can be bypassed with --no-verify. It installs with npm ci rather than npm install, and runs on pushes to main and on pull requests instead of on every push. A Changelog workflow requires an [Unreleased] entry on pull requests that touch published code. That section decides the version, so a change nobody wrote down was previously only noticed at release time. Touching the file is not enough: the check runs derive-increment.mjs, so an edit that leaves the section unclassifiable fails too. The skip-changelog label opts out.
derive-increment.mjs reads the [Unreleased] section and maps its headings to an increment: Breaking Changes is a major, Added and Deprecated a minor, Changed, Removed, Fixed and Security a patch. Only headings are read, never the entry text - scanning the body for a word like BREAKING fires on ordinary prose, and an entry that merely mentions a breaking change would silently turn a patch into a major. An unrecognized heading is an error rather than a guess. npm run release starts a release from the terminal, verifying main is clean and matches origin, printing the plan for confirmation, then dispatching the workflow and tailing the run. The release still runs in CI, which holds the publish credentials; release-it moves to release:ci. The workflow now matches the Jetstream monorepo: it authenticates with client-id rather than the deprecated app-id, and derives the commit identity from the token instead of the unresolvable Release Workflow <support@getjetstream.app>. app-slug names the committer and the App's numeric user id forms the address GitHub links back to the App, so release commits carry the bot's avatar. Actions are pinned to commit SHAs, since a tag can be repointed and a SHA cannot. tasks/ is renamed to scripts/ so the layout matches sf-formula-parser.
The playground's parse, compose and utility function output, and the install command on the home page, reveal a copy to clipboard button on hover, matching the one Docusaurus already renders on markdown code blocks. The site publishes llms.txt and llms-full.txt via docusaurus-plugin-llms, with links in the footer. CLAUDE.md becomes AGENTS.md and records the formatter and linter workflow, the release rules, and the two constraints that are not obvious from the code: "type": "module" must not be added to the root package.json, and docs/ is a separate npm project. The README still described commander, chevrotain and lodash.get as dependencies of the library. Those went away in 8.0.0; the package has no runtime dependencies.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Pull request overview
This PR modernizes the repository’s tooling and release process around the oxc toolchain and shared automation with sf-formula-parser, while also restoring consumer-visible JSDoc in published type declarations.
Changes:
- Adopt oxfmt/oxlint, add pre-commit enforcement, and update CI to gate on format/lint/typecheck/tests/build.
- Update TypeScript config/build pipeline (TypeScript 7,
isolatedDeclarations, preserve JSDoc in emitted.d.ts). - Share/standardize changelog-driven release tooling and improve docs UX (copy buttons, llms.txt generation).
Reviewed changes
Copilot reviewed 43 out of 48 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| vitest.config.mts | Centralizes Vitest include pattern and test timeout. |
| tsconfig.typecheck.json | Adds full-tree typecheck config for src/tests/scripts/cli without emitting. |
| tsconfig.json | Enables isolatedDeclarations, preserves JSDoc in d.ts, bumps target to ES2022. |
| test/test.spec.ts | Adjusts tests for stricter typing (where!). |
| test/public-utils.spec.ts | Removes lodash.get dependency from tests and tightens throw assertions. |
| test/performance-test.spec.ts | Adds assertion to ensure all iterations parsed successfully. |
| test/lexer.spec.ts | Formatting cleanup and more specific error assertions / lint annotations. |
| test/cli.spec.ts | Avoids shadowing resolve by renaming promise resolver. |
| src/utils.ts | Minor refactors, adds explicit return types for exported functions. |
| src/parser/parser.ts | Removes unused local and unused catch binding. |
| src/composer/composer.ts | Simplifies boolean coercion for config.format. |
| src/api/public-utils.ts | Minor boolean simplification and variable renaming for clarity. |
| scripts/wait-for-npm-version.mjs | Small style cleanup in helper sleep function. |
| scripts/release.mjs | Adds changelog-derived release dispatcher/tailer script. |
| scripts/derive-increment.mjs | Adds changelog heading parser to derive semver bump. |
| scripts/copy-test-cases-to-docs.ts | Ensures generated JSON includes trailing newline for format checks. |
| scripts/build.mjs | Moves build orchestration into shared esbuild-based script. |
| README.md | Updates dependency/runtime-deps statement and formatter note. |
| package.json | Updates scripts for oxc toolchain, release flow, typecheck, and Vitest usage. |
| docs/static/sample-queries-json.json | Regenerates sample query list output formatting. |
| docs/src/pages/index.tsx | Adds install command copy button to homepage hero. |
| docs/src/pages/index.module.css | Adds styling for copy button integration in hero install pill. |
| docs/src/components/Utilities/Highlight.tsx | Adds optional copy button support to custom code highlighting. |
| docs/src/components/Utilities/Highlight.module.css | Adds positioning/hover styling for highlight copy button. |
| docs/src/components/Utilities/CopyButton.tsx | Introduces reusable copy-to-clipboard button component. |
| docs/src/components/Utilities/CopyButton.module.css | Provides copy button visuals and copied-state transitions. |
| docs/src/components/SoqlList/index.tsx | Disables copy button for picker rows where it would obscure content. |
| docs/src/components/HomepageFeatures/styles.module.css | Formatting update for multi-line transition property. |
| docs/scripts/serve-csp.mjs | Minor style cleanup in path resolution logic. |
| docs/scripts/generate-csp.mjs | Minor style cleanup and formatting consistency. |
| docs/package.json | Adds llms plugin and aligns TypeScript version. |
| docs/package-lock.json | Lockfile updates for added docs dependencies. |
| docs/docusaurus.config.ts | Enables Docusaurus v4 future flags and llms plugin + footer links. |
| docs/docs/overview.md | Formatting updates to published type snippets. |
| CONTRIBUTING.md | Updates contributor workflow to use npm run format. |
| CHANGELOG.md | Adds detailed unreleased entries documenting tooling/release/docs changes and JSDoc fix. |
| AUTHORS.md | Normalizes list formatting. |
| AGENTS.md | Documents repo-wide formatting/linting/types/release workflows. |
| .release-it.json | Ensures release commits bypass pre-commit hook and updates script paths. |
| .oxlintrc.json | Introduces oxlint config with scoped overrides and ignores. |
| .oxfmtrc.json | Introduces oxfmt config schema and package.json sort behavior. |
| .npmignore | Removes denylist in favor of files allowlist in package.json. |
| .github/workflows/release.yml | Updates/pins release workflow; derives version and uses GitHub App identity. |
| .github/workflows/ci.yml | Adds format/lint/typecheck gates and conditional docs build job. |
| .github/workflows/changelog.yml | Enforces changelog entry for published-code changes unless skipped. |
| .githooks/pre-commit | Adds pre-commit hook to enforce formatting and lint on staged files. |
| .claude/settings.json | Aligns agent tool permissions with the new npm scripts/toolchain. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The CLI suite spawns dist/cli/index.js, so running tests before the build left 36 of its cases executing a binary that did not exist yet. The previous workflow built first; that ordering was lost when this file was made identical across both repositories. Building first is the right order regardless: tests then run against a build that is known to have succeeded.
3278ae4 to
163565d
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 44 out of 49 changed files in this pull request and generated no new comments.
Suppressed comments (2)
README.md:35
- README still claims Node 11+ compatibility, but this PR's build now targets ES2022 (scripts/build.mjs) and the source uses ES2020+ operators (e.g.
??). Unless the build is meant to downlevel for Node 11, the documented minimum Node version should be raised to match what the published bundles require.
**Node**: version 11 or higher, or a polyfill for [Array.flat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat)
**Browser**: Tested in all modern browsers, may not work with older browsers.
This library has no runtime dependencies - the parser, composer, formatter and cli are all self contained.
CONTRIBUTING.md:17
- This section still instructs contributors to branch from and target the "master" branch, but the repo tooling/workflows in this PR are based on "main" (e.g. release/CI). Update both references to avoid sending contributors to a non-existent branch.
- Run `npm run format` before committing - a pre-commit hook rejects unformatted files
(`npm install` enables it, and `npm run format:check` reports without writing)
- open a Pull Request for the master branch
|
Went through Copilot's suppressed (low-confidence) comments — both were valid:
Both recorded under |
… and CONTRIBUTING.md
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 44 out of 49 changed files in this pull request and generated no new comments.
Suppressed comments (1)
.github/workflows/ci.yml:22
- CI currently runs tests only on Node 24, but the README states the supported minimum is Node 20. Without running CI on Node 20 (or a version range), regressions against the advertised minimum can slip in unnoticed. Consider using a Node version matrix (at least 20 + latest) for the main
testjob.
- name: Use Node.js 24
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
cache: npm
Tooling, release process, docs and the dependency upgrade. One user-facing fix: JSDoc is restored in the published type declarations.
Six commits, each self-contained:
chore: adopt the oxc toolchain and upgrade dependencies.npmignoreremovedfix: resolve everything oxlint flaggedbuild: enable isolatedDeclarations and keep JSDoc in declarationsci: enforce formatting, linting and a changelog entryci: derive the release version from the changelogderive-increment.mjs,tasks/→scripts/docs: add copy buttons, llms.txt and AGENTS.mdHighlights
removeCommentswas stripping every JSDoc block fromdist/types— editors showed no documentation on hover for any exported symbol. Removing it costs 12 KB of declaration output and leaves the JavaScript bundles untouched, since esbuild builds those. This is the one change consumers will notice.oxlint is new here —
correctness,suspiciousandperfrun as errors.styleandpedanticstay off because on a hand-written recursive-descent parser they ask for the code to be restructured rather than pointing at defects. Two disabled rules are genuine false positives, each documented inline..npmignoreremoved.filesin package.json takes precedence, so it had no effect —npm pack --dry-runproduces a byte-identical 21-file tarball without it (same shasum). It had also drifted, listingCHANGELOG.mdandAUTHORS.mdas excluded whilefilesships both.filesis an allowlist, which is the safer default.The release commit identity was unresolvable. Commits were authored by
Release Workflow <support@getjetstream.app>, which is not a GitHub account. The identity now derives from the App token, so release commits are attributed to the bot with its avatar.The release workflow authenticates with
client-idinstead of the deprecatedapp-idand needs aCLIENT_IDsecret. Org-wide secrets should cover this, but worth confirming.Shared with sf-formula-parser
scripts/derive-increment.mjs,scripts/release.mjs,.githooks/pre-commit, and theci,releaseandchangelogworkflows are now identical in both repos (each names the other in a header comment). Companion PR: jetstreamapp/sf-formula-parser#59Verification
format:check,lint,typecheck,buildall pass; 2273 tests green.