Skip to content

Commit 924306e

Browse files
authored
feat(types): migrate test suite and config files to TypeScript (Phase 6) (#588)
* feat(types): migrate test suite and config files to TypeScript (Phase 6) Rename all 114 test files and 2 helpers from .js to .ts, plus vitest.config and commitlint.config. Add type annotations to fix noImplicitAnyLet lint errors. Remove jsToTsResolver vite plugin (no longer needed). Drop allowJs/checkJs from tsconfig. * feat(types): migrate scripts and docs examples to TypeScript Rename 16 scripts and 1 docs example from .js to .ts. Update all invocations in package.json, CI workflows, and shell scripts to use node --experimental-strip-types. Remaining .js files (must stay JS): - scripts/test.js, scripts/build-wasm.js (Node 20 bootstrap) - 4 ESM loader hooks (bootstrap .ts support) - scripts/gen-deps.cjs, src/index.cjs (CJS by design) * feat(types): drop Node 20, require Node >= 22 - Bump engines.node from >=20 to >=22 - Remove Node 20 from CI test matrix - Bump native build Node from 20 to 22 - Replace old JS ESM loader hooks with 2 TypeScript hooks (ts-resolve-loader.ts + ts-resolve-hooks.ts) that resolve .js→.ts import specifiers at runtime - Remove canStripTypes helper and version guards from tests - Update src/index.cjs to import('./index.ts') for dev; build step produces dist/index.cjs with ./index.js for published package - Simplify vitest.config.ts to use --experimental-strip-types only - Update child-process test invocations to use --import loader flag - Rewrite scripts/gen-deps.cjs as ESM TypeScript - Rename scripts/build-wasm.js → .ts Impact: 1 functions changed, 1 affected * fix(ci): update embedding regression workflow to reference .ts test file (#588) The test file was renamed from .js to .ts in the Phase 6 migration but the CI workflow was not updated, causing test discovery to fail. * fix: tighten Node engines to >=22.6, restore strip-types guard, use replaceAll (#588) Impact: 1 functions changed, 0 affected * fix(docs): use version-aware strip-types flag in pre-commit example (#588) Detect Node version at runtime and select --strip-types (>=23) vs --experimental-strip-types (22.x), matching the approach in vitest.config.ts. * fix(types): add TypeScript parameter types to test helpers (#588) Replace JSDoc-only annotations in fixtures.ts with proper TypeScript interfaces and typed parameters. Add interfaces and typed parameters to resolution-benchmark.test.ts helper functions. Eliminates all noExplicitAny warnings in both files. Impact: 22 functions changed, 0 affected * fix(hooks): convert pre-commit-checks.ts from CJS require() to ESM imports (#588) The file was renamed from .js to .ts but retained CommonJS require() calls. Since the repo has "type": "module", Node loads .ts files as ESM under --strip-types, where require is not defined. This caused a silent ReferenceError swallowed by 2>/dev/null || true in pre-commit.sh, making all pre-commit checks (cycles, dead exports, diff-impact) non-functional. Convert to ESM imports with createRequire for dynamic runtime requires. Also update the file header comment to reference .ts instead of .js. * fix(ci): add --import loader to benchmark workflow for Node 22 compatibility (#588) Benchmark scripts import ./lib/bench-config.js and ./lib/fork-engine.js but only .ts files exist on disk. Node 22's --experimental-strip-types does not auto-resolve .js to .ts (that was added in Node 23+). Add --import ./scripts/ts-resolve-loader.js to all four benchmark invocations so the ESM loader resolves .js specifiers to their .ts counterparts. * fix: version-aware strip-types flag in benchmark.yml, update docs (#588) - Use dynamic STRIP_FLAG selection in all benchmark.yml node invocations for forward compatibility with Node 23+ (--strip-types vs --experimental-strip-types) - Update token-benchmark.ts usage docs to include --import loader flag - Update CLAUDE.md Node version from >= 20 to >= 22.6 * fix: remove unused .ts loader duplicates (#588) ESM loader hooks must stay as .js files for bootstrap reasons. The .ts duplicates were never referenced by any CI workflow or package script and only created confusion about which version to use. * Revert "fix: remove unused .ts loader duplicates (#588)" This reverts commit 966ec3e. * fix(ci): use version-aware strip-types flag in verify-imports step (#588) * fix(ci): use dynamic strip-types flag in publish workflow (#588) * fix: remove dead scripts/test.js (#588)
1 parent 05b75c0 commit 924306e

152 files changed

Lines changed: 423 additions & 405 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/benchmark.yml

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,18 @@ jobs:
8989
- name: Run build benchmark
9090
if: steps.existing.outputs.skip != 'true'
9191
run: |
92+
STRIP_FLAG=$(node -e "const [M]=process.versions.node.split('.').map(Number); console.log(M>=23?'--strip-types':'--experimental-strip-types')")
9293
ARGS="--version ${{ steps.mode.outputs.version }}"
9394
if [ "${{ steps.mode.outputs.source }}" = "npm" ]; then
9495
ARGS="$ARGS --npm"
9596
fi
96-
node scripts/benchmark.js $ARGS 2>/dev/null > benchmark-result.json
97+
node $STRIP_FLAG --import ./scripts/ts-resolve-loader.js scripts/benchmark.ts $ARGS 2>/dev/null > benchmark-result.json
9798
9899
- name: Update build report
99100
if: steps.existing.outputs.skip != 'true'
100-
run: node scripts/update-benchmark-report.js benchmark-result.json
101+
run: |
102+
STRIP_FLAG=$(node -e "const [M]=process.versions.node.split('.').map(Number); console.log(M>=23?'--strip-types':'--experimental-strip-types')")
103+
node $STRIP_FLAG scripts/update-benchmark-report.ts benchmark-result.json
101104
102105
- name: Upload build result
103106
if: steps.existing.outputs.skip != 'true'
@@ -240,15 +243,18 @@ jobs:
240243
env:
241244
HF_TOKEN: ${{ secrets.HF_TOKEN }}
242245
run: |
246+
STRIP_FLAG=$(node -e "const [M]=process.versions.node.split('.').map(Number); console.log(M>=23?'--strip-types':'--experimental-strip-types')")
243247
ARGS="--version ${{ steps.mode.outputs.version }}"
244248
if [ "${{ steps.mode.outputs.source }}" = "npm" ]; then
245249
ARGS="$ARGS --npm"
246250
fi
247-
node scripts/embedding-benchmark.js $ARGS 2>/dev/null > embedding-benchmark-result.json
251+
node $STRIP_FLAG --import ./scripts/ts-resolve-loader.js scripts/embedding-benchmark.ts $ARGS 2>/dev/null > embedding-benchmark-result.json
248252
249253
- name: Update embedding report
250254
if: steps.existing.outputs.skip != 'true'
251-
run: node scripts/update-embedding-report.js embedding-benchmark-result.json
255+
run: |
256+
STRIP_FLAG=$(node -e "const [M]=process.versions.node.split('.').map(Number); console.log(M>=23?'--strip-types':'--experimental-strip-types')")
257+
node $STRIP_FLAG scripts/update-embedding-report.ts embedding-benchmark-result.json
252258
253259
- name: Upload embedding result
254260
if: steps.existing.outputs.skip != 'true'
@@ -377,15 +383,18 @@ jobs:
377383
- name: Run query benchmark
378384
if: steps.existing.outputs.skip != 'true'
379385
run: |
386+
STRIP_FLAG=$(node -e "const [M]=process.versions.node.split('.').map(Number); console.log(M>=23?'--strip-types':'--experimental-strip-types')")
380387
ARGS="--version ${{ steps.mode.outputs.version }}"
381388
if [ "${{ steps.mode.outputs.source }}" = "npm" ]; then
382389
ARGS="$ARGS --npm"
383390
fi
384-
node scripts/query-benchmark.js $ARGS 2>/dev/null > query-benchmark-result.json
391+
node $STRIP_FLAG --import ./scripts/ts-resolve-loader.js scripts/query-benchmark.ts $ARGS 2>/dev/null > query-benchmark-result.json
385392
386393
- name: Update query report
387394
if: steps.existing.outputs.skip != 'true'
388-
run: node scripts/update-query-report.js query-benchmark-result.json
395+
run: |
396+
STRIP_FLAG=$(node -e "const [M]=process.versions.node.split('.').map(Number); console.log(M>=23?'--strip-types':'--experimental-strip-types')")
397+
node $STRIP_FLAG scripts/update-query-report.ts query-benchmark-result.json
389398
390399
- name: Upload query result
391400
if: steps.existing.outputs.skip != 'true'
@@ -514,15 +523,18 @@ jobs:
514523
- name: Run incremental benchmark
515524
if: steps.existing.outputs.skip != 'true'
516525
run: |
526+
STRIP_FLAG=$(node -e "const [M]=process.versions.node.split('.').map(Number); console.log(M>=23?'--strip-types':'--experimental-strip-types')")
517527
ARGS="--version ${{ steps.mode.outputs.version }}"
518528
if [ "${{ steps.mode.outputs.source }}" = "npm" ]; then
519529
ARGS="$ARGS --npm"
520530
fi
521-
node scripts/incremental-benchmark.js $ARGS 2>/dev/null > incremental-benchmark-result.json
531+
node $STRIP_FLAG --import ./scripts/ts-resolve-loader.js scripts/incremental-benchmark.ts $ARGS 2>/dev/null > incremental-benchmark-result.json
522532
523533
- name: Update incremental report
524534
if: steps.existing.outputs.skip != 'true'
525-
run: node scripts/update-incremental-report.js incremental-benchmark-result.json
535+
run: |
536+
STRIP_FLAG=$(node -e "const [M]=process.versions.node.split('.').map(Number); console.log(M>=23?'--strip-types':'--experimental-strip-types')")
537+
node $STRIP_FLAG scripts/update-incremental-report.ts incremental-benchmark-result.json
526538
527539
- name: Upload incremental result
528540
if: steps.existing.outputs.skip != 'true'

.github/workflows/build-native.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ jobs:
6060
- name: Setup Node.js
6161
uses: actions/setup-node@v6
6262
with:
63-
node-version: 20
63+
node-version: 22
6464

6565
- name: Setup Rust
6666
uses: dtolnay/rust-toolchain@stable

.github/workflows/ci.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jobs:
4343
fail-fast: false
4444
matrix:
4545
os: [ubuntu-latest, macos-latest, windows-latest]
46-
node-version: [20, 22]
46+
node-version: [22]
4747

4848
runs-on: ${{ matrix.os }}
4949
name: Test Node ${{ matrix.node-version }} (${{ matrix.os }})
@@ -113,7 +113,9 @@ jobs:
113113
node-version: 22
114114

115115
- name: Verify all dynamic imports resolve
116-
run: node scripts/verify-imports.js
116+
run: |
117+
STRIP_FLAG=$(node -e "const [M]=process.versions.node.split('.').map(Number); console.log(M>=23?'--strip-types':'--experimental-strip-types')")
118+
node $STRIP_FLAG scripts/verify-imports.ts
117119
118120
rust-check:
119121
runs-on: ubuntu-latest

.github/workflows/embedding-regression.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,4 @@ jobs:
3838
key: hf-models-minilm-v1
3939

4040
- name: Run embedding regression tests
41-
run: npx vitest run tests/search/embedding-regression.test.js
41+
run: npx vitest run tests/search/embedding-regression.test.ts

.github/workflows/publish.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ jobs:
142142
- name: Setup Node.js
143143
uses: actions/setup-node@v6
144144
with:
145-
node-version: 20
145+
node-version: 22
146146

147147
- name: Setup Rust
148148
uses: dtolnay/rust-toolchain@stable
@@ -224,7 +224,8 @@ jobs:
224224
VERSION: ${{ needs.compute-version.outputs.version }}
225225
run: |
226226
npm version "$VERSION" --no-git-tag-version --allow-same-version
227-
node scripts/sync-native-versions.js --strip
227+
STRIP_FLAG=$(node -e "const [M]=process.versions.node.split('.').map(Number); console.log(M>=23?'--strip-types':'--experimental-strip-types')")
228+
node $STRIP_FLAG scripts/sync-native-versions.ts --strip
228229
echo "Packaging version $VERSION"
229230
230231
- name: Build TypeScript
@@ -405,7 +406,8 @@ jobs:
405406
run: |
406407
git checkout -- package-lock.json
407408
npm version "$VERSION" --no-git-tag-version --allow-same-version
408-
node scripts/sync-native-versions.js
409+
STRIP_FLAG=$(node -e "const [M]=process.versions.node.split('.').map(Number); console.log(M>=23?'--strip-types':'--experimental-strip-types')")
410+
node $STRIP_FLAG scripts/sync-native-versions.ts
409411
echo "Publishing version $VERSION"
410412
411413
- name: Build TypeScript

.npmignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ docs/
77
*.db
88
.codegraphrc.json
99
.versionrc.json
10-
commitlint.config.js
10+
commitlint.config.ts
1111
codegraph-improvements.md

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,4 +218,4 @@ This repo uses [Greptile](https://greptile.com) for automated PR reviews. After
218218

219219
## Node Version
220220

221-
Requires Node >= 20.
221+
Requires Node >= 22.6.

docs/examples/claude-code-hooks/pre-commit-checks.js renamed to docs/examples/claude-code-hooks/pre-commit-checks.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/**
2-
* pre-commit-checks.js — Consolidated pre-commit codegraph checks.
2+
* pre-commit-checks.ts — Consolidated pre-commit codegraph checks.
33
* Single Node.js process that runs all checks and returns structured JSON.
44
*
5-
* Usage: node pre-commit-checks.js <WORK_ROOT> <EDITED_FILES> <STAGED_FILES>
5+
* Usage: node pre-commit-checks.ts <WORK_ROOT> <EDITED_FILES> <STAGED_FILES>
66
*
77
* Output JSON: { action: "deny"|"allow", reason?: string, context?: string[] }
88
*
@@ -12,8 +12,11 @@
1212
* 3. Diff-impact (informational) — shows blast radius of staged changes
1313
*/
1414

15-
const fs = require('fs');
16-
const path = require('path');
15+
import fs from 'node:fs';
16+
import path from 'node:path';
17+
import { createRequire } from 'node:module';
18+
19+
const require = createRequire(import.meta.url);
1720

1821
const root = process.argv[2];
1922
const editedRaw = process.argv[3] || '';
@@ -124,7 +127,7 @@ try {
124127

125128
// Scan for dynamic import() consumers
126129
const srcDir = path.join(root, 'src');
127-
function scanDynamic(dir) {
130+
function scanDynamic(dir: string) {
128131
for (const ent of fs.readdirSync(dir, { withFileTypes: true })) {
129132
if (ent.isDirectory()) { scanDynamic(path.join(dir, ent.name)); continue; }
130133
if (!/\.(js|ts|tsx)$/.test(ent.name)) continue;

docs/examples/claude-code-hooks/pre-commit.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ fi
4848

4949
# Run all checks in a single Node.js process
5050
HOOK_DIR="$(cd "$(dirname "$0")" && pwd)"
51-
RESULT=$(node "$HOOK_DIR/pre-commit-checks.js" "$WORK_ROOT" "$EDITED_FILES" "$STAGED" 2>/dev/null) || true
51+
STRIP_FLAG=$(node -e "const [M,m]=process.versions.node.split('.').map(Number); console.log(M>=23?'--strip-types':'--experimental-strip-types')")
52+
RESULT=$(node $STRIP_FLAG "$HOOK_DIR/pre-commit-checks.ts" "$WORK_ROOT" "$EDITED_FILES" "$STAGED" 2>/dev/null) || true
5253

5354
if [ -z "$RESULT" ]; then
5455
exit 0

0 commit comments

Comments
 (0)