universal-ast-mapper 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -605,6 +605,7 @@ Not part of the public API: the internal `src/` module layout and the generated
605
605
 
606
606
  | Version | What changed |
607
607
  |---------|--------------|
608
+ | **1.3.0** | **TS/JS decorators** — class and method symbols now carry a `decorators` field (`@Component({...})`, `@Injectable()`, `@Get("/x")`), in skeletons and `get_call_graph`. Extends the Python decorator support (v0.8.7) to TypeScript/JavaScript — traces Angular/NestJS-style framework wiring to its class/handler. |
608
609
  | **1.2.0** | **File-level cross-package resolution** — in a monorepo, bare imports of a workspace package (`@org/utils`, `@org/utils/sub`) now resolve to the actual source file (preferring `src/` over built `dist/`), so `resolve_imports` marks them in-project and `build_symbol_graph` draws cross-package edges. Builds on the v1.1.0 workspace discovery. |
609
610
  | **1.1.0** | **Monorepo support** — new `analyze_workspace` MCP tool + `ast-map workspace` (alias `ws`) CLI: discovers packages from npm/yarn `workspaces`, `pnpm-workspace.yaml`, or `lerna.json`, maps internal package dependencies, and flags circular package deps. **19 MCP tools**. |
610
611
  | **1.0.0** | **Stable release.** Locks the public API (MCP tool names + schemas, CLI surface) for the 1.x line. Adds a **GitHub Action** (`action.yml`) to run `ast-map validate` as a CI architecture gate, plus a project CI workflow. Caps a 12-language engine with 18 MCP tools / 17 CLI commands spanning skeletons, dependency graphs, and deep analysis (dead code · cycles · impact · complexity · duplicates · unused params · decorators · type flow). |
@@ -47,7 +47,7 @@ function handle(node, exported, typeIndex) {
47
47
  const name = nameOf(node) ?? "(anonymous class)";
48
48
  const body = node.childForFieldName("body");
49
49
  const children = body ? collect(namedChildren(body), false, typeIndex) : [];
50
- return makeSymbol({
50
+ const clsSym = makeSymbol({
51
51
  name,
52
52
  kind: "class",
53
53
  node,
@@ -56,6 +56,8 @@ function handle(node, exported, typeIndex) {
56
56
  doc: leadingComment(node),
57
57
  children,
58
58
  });
59
+ attachDecorators(clsSym, node);
60
+ return clsSym;
59
61
  }
60
62
  case "interface_declaration": {
61
63
  const name = nameOf(node) ?? "(anonymous interface)";
@@ -114,7 +116,7 @@ function handle(node, exported, typeIndex) {
114
116
  case "abstract_method_signature": {
115
117
  const name = nameOf(node) ?? "(method)";
116
118
  const body = node.childForFieldName("body");
117
- return makeSymbol({
119
+ const mSym = makeSymbol({
118
120
  name,
119
121
  kind: "method",
120
122
  node,
@@ -123,6 +125,8 @@ function handle(node, exported, typeIndex) {
123
125
  visibility: memberVisibility(node),
124
126
  doc: leadingComment(node),
125
127
  });
128
+ attachDecorators(mSym, node);
129
+ return mSym;
126
130
  }
127
131
  case "public_field_definition":
128
132
  case "field_definition": {
@@ -454,3 +458,34 @@ function attachComponentInfo(sym, funcNode, declNode, name, idx) {
454
458
  if (resolved)
455
459
  sym.props = resolved;
456
460
  }
461
+ // ─── TS/JS decorators ─────────────────────────────────────────────────────────
462
+ /** Strip the leading `@` and collapse whitespace from a decorator node. */
463
+ function decoratorText(node) {
464
+ return node.text.replace(/^@\s*/, "").replace(/\s+/g, " ").trim();
465
+ }
466
+ /**
467
+ * Attach decorators to a class/method symbol. TS decorators appear either as
468
+ * preceding sibling `decorator` nodes (classes, methods) or as leading child
469
+ * decorators (some grammars) — collect both.
470
+ */
471
+ function attachDecorators(sym, node) {
472
+ const decs = [];
473
+ // leading child decorators
474
+ for (let i = 0; i < node.namedChildCount; i++) {
475
+ const c = node.namedChild(i);
476
+ if (c && c.type === "decorator")
477
+ decs.push(decoratorText(c));
478
+ else if (c && c.type !== "decorator")
479
+ break;
480
+ }
481
+ // preceding sibling decorators (most common for classes/methods)
482
+ let prev = node.previousNamedSibling;
483
+ const lead = [];
484
+ while (prev && prev.type === "decorator") {
485
+ lead.unshift(decoratorText(prev));
486
+ prev = prev.previousNamedSibling;
487
+ }
488
+ const all = [...lead, ...decs].filter((t) => t.length > 0);
489
+ if (all.length > 0)
490
+ sym.decorators = all;
491
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "universal-ast-mapper",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "MCP server that maps source files into a normalized code skeleton (JSON + HTML) using tree-sitter.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",