|
| 1 | +# Changelog |
| 2 | + |
| 3 | +All notable changes to this project will be documented in this file. |
| 4 | + |
| 5 | +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), |
| 6 | +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). |
| 7 | + |
| 8 | +## [Unreleased] |
| 9 | + |
| 10 | +## [0.6.0] - 2026-08-05 |
| 11 | + |
| 12 | +### Added |
| 13 | +- **JavaScript is analyzed** (#84). Discovery was restricted to `.ts/.tsx/.mts/.cts`, |
| 14 | + so a JavaScript-only project produced an empty symbol table and exited 0 with no |
| 15 | + warning — on OWASP NodeGoat, 0 modules and an 84-byte `analysis.json`. `.js`, |
| 16 | + `.jsx`, `.mjs` and `.cjs` are now discovered, and `.test.js` / `.spec.js` are |
| 17 | + skipped like their TypeScript counterparts. Nothing downstream needed changing: |
| 18 | + the compiler already ran with `allowJs`, and Jelly already accepted `.js` — both |
| 19 | + were simply never handed a file. |
| 20 | +- **Methods declared through dynamic idioms are materialized** (#85): |
| 21 | + `this.<name> = fn` inside a constructor function, and object-literal members |
| 22 | + (`{ foo(){} }`, `{ foo: function(){} }`). Previously the first landed in |
| 23 | + `local_variables` and the second was dropped entirely, so no call could resolve |
| 24 | + to either — call-graph edges are gated to signatures present in the symbol table. |
| 25 | + This is language-neutral: both were missed in TypeScript too. |
| 26 | + |
| 27 | +### Changed |
| 28 | +- **BREAKING: Neo4j labels and relationship types are namespaced per source language** (#88). |
| 29 | + Node labels gain a language twin — a `.js` module is `:Module:JSModule`, a `.ts` module is |
| 30 | + `:Module:TSModule` — and every relationship type is prefixed: `JS_CALLS`, `TS_DECLARES`, |
| 31 | + `JS_HAS_MODULE`, and so on. This matches `codeanalyzer-python`, which already namespaces every |
| 32 | + edge (`PY_CALLS`, `PY_DECLARES`, …), so a database holding output from more than one analyzer no |
| 33 | + longer mingles them. |
| 34 | + |
| 35 | + An edge takes its **source** module's language, falling back to its target's — so the |
| 36 | + application-to-module edge on a JavaScript project is `JS_HAS_MODULE`. Nodes with no language of |
| 37 | + their own (the application root, packages, external library symbols) keep the analyzer's own `TS` |
| 38 | + namespace, since a sibling analyzer emits its own. |
| 39 | + |
| 40 | + **Migration:** every stored query against a graph produced by 0.5.0 or earlier must be updated — |
| 41 | + `MATCH ()-[:CALLS]->()` becomes `MATCH ()-[:TS_CALLS|JS_CALLS]->()`. The Neo4j schema version |
| 42 | + moves 1.1.0 → 2.0.0, which forces a full re-upsert on the next incremental push. |
| 43 | + |
| 44 | +- **A failed Jelly leg is now reported at error level on JavaScript-majority |
| 45 | + projects.** The union provider degrades to tsc-only when Jelly throws, and |
| 46 | + reported that at `info`, which is not printed at default verbosity. On JavaScript |
| 47 | + that is a ~81% edge loss with no signal (Jelly supplies 156 of 161 union edges on |
| 48 | + NodeGoat). TypeScript projects keep the quieter `info` line. The default provider |
| 49 | + is unchanged: `union` is a strict superset of `jelly` on JavaScript, measured both |
| 50 | + with and without dependencies installed. |
| 51 | +- **Caches from 0.5.0 and earlier are invalidated.** Extraction now produces more |
| 52 | + callables from unchanged sources, so `ANALYZER_VERSION` moves with the release and |
| 53 | + every cached `analysis_cache.json` is rebuilt on first run. |
| 54 | + |
| 55 | +### Measured on OWASP NodeGoat (dependencies installed, `-a 2`) |
| 56 | + |
| 57 | +| | 0.5.0 | 0.6.0 | |
| 58 | +| --- | --- | --- | |
| 59 | +| modules | 0 | 27 | |
| 60 | +| callables | 0 | 59 | |
| 61 | +| call-graph edges | 0 | 184 | |
| 62 | +| resolved call sites | 0 | 51 | |
| 63 | + |
| 64 | +59 callables matches the parser-derived count of nameable functions in the source |
| 65 | +exactly. The discovered module set equals the set of `.js` files outside |
| 66 | +`node_modules`, `vendor` and test trees. |
| 67 | + |
| 68 | +### Known gaps |
| 69 | +- CommonJS `require` / `module.exports` are not modelled at module level, so |
| 70 | + `imports` and `exports` stay empty on CommonJS input. Relative `require()` **call |
| 71 | + targets** do resolve. |
| 72 | +- Method calls on an untyped receiver (e.g. `db.collection(...)` where `db` is an |
| 73 | + untyped parameter) produce no edge into the library — tracked in #87. The call is |
| 74 | + still attributable: it is recorded on the enclosing callable with its receiver |
| 75 | + expression, and that callable is reachable from its route. |
0 commit comments