@eventra_dev/eventra-cli 2.0.1 → 2.0.3

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
@@ -8,7 +8,7 @@
8
8
  <a href="https://www.npmjs.com/package/@eventra_dev/eventra-cli"><img alt="npm version" src="https://img.shields.io/npm/v/@eventra_dev/eventra-cli.svg?style=flat-square&color=blue"></a>
9
9
  <a href="https://www.npmjs.com/package/@eventra_dev/eventra-cli"><img alt="npm downloads" src="https://img.shields.io/npm/dm/@eventra_dev/eventra-cli.svg?style=flat-square&color=blue"></a>
10
10
  <a href="https://github.com/and-1991/eventra-cli/actions/workflows/test.yml"><img alt="tests" src="https://img.shields.io/github/actions/workflow/status/and-1991/eventra-cli/test.yml?branch=main&label=tests&style=flat-square&logo=vitest&logoColor=white"></a>
11
- <img alt="unit tests" src="https://img.shields.io/badge/unit-74%20passing-brightgreen?style=flat-square&logo=vitest&logoColor=white">
11
+ <img alt="unit tests" src="https://img.shields.io/badge/unit-110%20passing-brightgreen?style=flat-square&logo=vitest&logoColor=white">
12
12
  <img alt="e2e fixtures" src="https://img.shields.io/badge/e2e-12%20fixtures-brightgreen?style=flat-square">
13
13
  <img alt="node" src="https://img.shields.io/node/v/@eventra_dev/eventra-cli?style=flat-square&color=darkgreen&logo=node.js&logoColor=white">
14
14
  <a href="https://www.typescriptlang.org/"><img alt="TypeScript" src="https://img.shields.io/badge/TypeScript-ready-blue?style=flat-square&logo=typescript&logoColor=white"></a>
@@ -312,9 +312,9 @@ No runtime execution. No monkey-patching.
312
312
 
313
313
  ## Test Coverage
314
314
 
315
- Two test layers, **74 unit tests + 12 e2e fixtures + 3 `check` exit-code scenarios**.
315
+ Two test layers, **110 unit tests + 12 e2e fixtures + 3 `check` exit-code scenarios + 1 `watch` scenario**.
316
316
 
317
- **Unit tests (vitest)** — 13 suites covering core modules:
317
+ **Unit tests (vitest)** — 21 suites covering core modules:
318
318
 
319
319
  | Module | Covers |
320
320
  |---|---|
@@ -325,12 +325,20 @@ Two test layers, **74 unit tests + 12 e2e fixtures + 3 `check` exit-code scenari
325
325
  | `EventraEngine` | Direct calls, SDK isolation, cross-file wrappers, file updates, file removal, wrapper filtering |
326
326
  | `PluginRegistry` | Built-in SDK sink, preprocessors, virtual-path mapping, include-pattern dedup |
327
327
  | `external plugin adapter` | Transform output mapping, static sink registration, invalid result rejection |
328
+ | `external plugin dynamic sink` | A non-literal argument at a plugin-declared static sink surfaces as a dynamic occurrence instead of being silently dropped |
328
329
  | `vue-shaped external plugin` | Adapter path for script + template virtual modules and `staticSinks` |
329
330
  | `processFile` | Script-kind detection, import/export specifier extraction |
330
331
  | `extractTemplateExpressions` | Vue/Svelte/Astro attribute patterns |
331
- | `normalizeConfig` | Sort events, dedupe wrappers, defaults, preserve `apiKey` / `endpoint` / `sync` / `plugins` |
332
- | `buildConfigFromScan` | Replace events + wrappers, preserve everything else |
332
+ | `config` | `normalizeConfig` (sort events, dedupe wrappers, defaults, preserve `apiKey`/`endpoint`/`sync`/`plugins`); `resolveApiKey` env-var > `eventra.local.json` > legacy-inline priority, `saveLocalApiKey`'s gitignore-append |
333
+ | `scanResults` (`buildConfigFromScan`) | Replace events + wrappers, preserve everything else |
333
334
  | `hash` | Stability and uniqueness |
335
+ | `cross-file SDK detection` | Direct `.track()` and wrapper calls resolve across files even when the call-site file never imports the SDK package itself |
336
+ | `dynamic event reporter` | Dynamic vs. static call classification, end-to-end `registerDynamicEventReporter` invocation |
337
+ | `load plugins` | Trusted-specifier allowlist (`^@eventra_dev/cli-plugin-[a-z0-9-]+$`), accepted/rejected plugin shapes |
338
+ | `Nuxt auto-import compatibility` | Ambient `declare const x: typeof import(...)` shape resolution — a hand-written fixture, not a real `nuxt build` (see `packages/cli-plugin-vue`'s README) |
339
+ | `property propagation` | Direct/optional/nested property access, destructured/aliased/nested-destructured params, element access, enum member access (same-file and cross-file), wrapper detection surviving a cast/non-null assertion, and direct object-literal payloads to `track()` staying ignored (including when cast) |
340
+ | `send()` | Endpoint trust-on-first-use (TOFU): default-trusted, blocked-until-approved, approve-then-persists, re-block-on-change, env-var-bypasses-approval |
341
+ | `wrapper detector plugin` | A custom `WrapperDetector` (e.g. a template-literal wrapper shape the built-in analyzer can't cover) alongside the built-in fallback |
334
342
 
335
343
  **End-to-end fixtures** — 12 isolated TS projects scanned via `eventra sync`:
336
344
 
@@ -351,6 +359,8 @@ Two test layers, **74 unit tests + 12 e2e fixtures + 3 `check` exit-code scenari
351
359
  - `--fix` writes scan results into `eventra.json` → exit `0`
352
360
  - Parity (no drift) → exit `0`
353
361
 
362
+ **`eventra watch` scenario:** a real `watch` process detects a brand-new file (created after startup) and its `.track()` call lands in `eventra.json`.
363
+
354
364
  Run locally:
355
365
 
356
366
  ```bash
@@ -92,7 +92,28 @@ function resolvePropertyAccess(node, checker, context, visited, evaluationCache,
92
92
  }
93
93
  }
94
94
  if (typescript_1.default.isIdentifier(targetExpression)) {
95
- const symbol = checker.getSymbolAtLocation(targetExpression);
95
+ let symbol = checker.getSymbolAtLocation(targetExpression);
96
+ if (symbol) {
97
+ symbol = (0, exportResolver_1.resolveExportedSymbol)(symbol, checker, exportCache) ?? symbol;
98
+ }
99
+ // enum EVENTS {
100
+ // LOGIN = "login"
101
+ // }
102
+ if (symbol) {
103
+ const declarations = symbol.getDeclarations() ?? [];
104
+ for (const declaration of declarations) {
105
+ if (!typescript_1.default.isEnumDeclaration(declaration)) {
106
+ continue;
107
+ }
108
+ for (const member of declaration.members) {
109
+ const memberName = typescript_1.default.isIdentifier(member.name) ? member.name.text : typescript_1.default.isStringLiteral(member.name) ? member.name.text : null;
110
+ if (memberName !== propertyName || !member.initializer) {
111
+ continue;
112
+ }
113
+ return resolveNodeValue(member.initializer, checker, context, visited, evaluationCache, resolvedCallCache, returnPropagationCache, exportCache);
114
+ }
115
+ }
116
+ }
96
117
  // const EVENTS = {
97
118
  // LOGIN: "login"
98
119
  // }
@@ -6,13 +6,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.registerEventraSdkPlugin = registerEventraSdkPlugin;
7
7
  const typescript_1 = __importDefault(require("typescript"));
8
8
  const isEventraTrackCall_1 = require("../../analysis/sdk/isEventraTrackCall");
9
+ const utils_1 = require("../../analysis/shared/utils");
9
10
  /** SDK: track(name: string, options?) — event name is always the first argument. */
10
11
  function extractTrackedArguments(call) {
11
12
  if (call.arguments.length === 0) {
12
13
  return [];
13
14
  }
14
15
  const first = call.arguments[0];
15
- if (typescript_1.default.isObjectLiteralExpression(first)) {
16
+ // A cast/non-null/parens around a misused object literal (e.g.
17
+ // `track({ event: "x" } as any)`) must not defeat this guard — it's still
18
+ // the wrong API shape for `track(name: string, options?)`.
19
+ if (typescript_1.default.isObjectLiteralExpression((0, utils_1.unwrapExpression)(first))) {
16
20
  return [];
17
21
  }
18
22
  return [{ index: 0, propertyPath: [] }];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventra_dev/eventra-cli",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "Static analytics event extraction CLI powered by the TypeScript compiler API",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",