11import * as fs from "node:fs" ;
2+ import * as fsp from "node:fs/promises" ;
3+ import * as os from "node:os" ;
24import * as path from "node:path" ;
35import {
6+ afterAll ,
47 afterEach ,
58 beforeAll ,
69 beforeEach ,
@@ -104,9 +107,8 @@ function mockApiResponses(opts: {
104107describeWithGrammars ( "PostHogEnricher" , ( ) => {
105108 let enricher : PostHogEnricher ;
106109
107- beforeAll ( async ( ) => {
110+ beforeAll ( ( ) => {
108111 enricher = new PostHogEnricher ( ) ;
109- await enricher . initialize ( GRAMMARS_DIR ) ;
110112 } ) ;
111113
112114 // ── ParseResult ──
@@ -179,9 +181,9 @@ describeWithGrammars("PostHogEnricher", () => {
179181 mockApiResponses ( { flags : [ makeFlag ( "my-flag" ) ] } ) ;
180182 const enriched = await result . enrichFromApi ( API_CONFIG ) ;
181183
182- expect ( enriched . enrichedFlags ) . toHaveLength ( 1 ) ;
183- expect ( enriched . enrichedFlags [ 0 ] . flagKey ) . toBe ( "my-flag" ) ;
184- expect ( enriched . enrichedFlags [ 0 ] . flagType ) . toBe ( "boolean" ) ;
184+ expect ( enriched . flags ) . toHaveLength ( 1 ) ;
185+ expect ( enriched . flags [ 0 ] . flagKey ) . toBe ( "my-flag" ) ;
186+ expect ( enriched . flags [ 0 ] . flagType ) . toBe ( "boolean" ) ;
185187 } ) ;
186188
187189 test ( "enrichedFlags detects staleness" , async ( ) => {
@@ -191,7 +193,7 @@ describeWithGrammars("PostHogEnricher", () => {
191193 mockApiResponses ( { flags : [ makeFlag ( "stale-flag" , { active : false } ) ] } ) ;
192194 const enriched = await result . enrichFromApi ( API_CONFIG ) ;
193195
194- expect ( enriched . enrichedFlags [ 0 ] . staleness ) . toBe ( "inactive" ) ;
196+ expect ( enriched . flags [ 0 ] . staleness ) . toBe ( "inactive" ) ;
195197 } ) ;
196198
197199 test ( "enrichedFlags links experiment" , async ( ) => {
@@ -204,7 +206,7 @@ describeWithGrammars("PostHogEnricher", () => {
204206 } ) ;
205207 const enriched = await result . enrichFromApi ( API_CONFIG ) ;
206208
207- expect ( enriched . enrichedFlags [ 0 ] . experiment ?. name ) . toBe (
209+ expect ( enriched . flags [ 0 ] . experiment ?. name ) . toBe (
208210 "Experiment for exp-flag" ,
209211 ) ;
210212 } ) ;
@@ -223,8 +225,8 @@ describeWithGrammars("PostHogEnricher", () => {
223225 } ) ;
224226 const enriched = await result . enrichFromApi ( API_CONFIG ) ;
225227
226- expect ( enriched . enrichedEvents ) . toHaveLength ( 1 ) ;
227- expect ( enriched . enrichedEvents [ 0 ] . verified ) . toBe ( true ) ;
228+ expect ( enriched . events ) . toHaveLength ( 1 ) ;
229+ expect ( enriched . events [ 0 ] . verified ) . toBe ( true ) ;
228230 } ) ;
229231
230232 test ( "toList returns enriched items" , async ( ) => {
@@ -296,7 +298,7 @@ describeWithGrammars("PostHogEnricher", () => {
296298 } ) ;
297299 const enriched = await result . enrichFromApi ( API_CONFIG ) ;
298300
299- const event = enriched . enrichedEvents [ 0 ] ;
301+ const event = enriched . events [ 0 ] ;
300302 expect ( event . verified ) . toBe ( true ) ;
301303 expect ( event . tags ) . toEqual ( [ "revenue" , "checkout" ] ) ;
302304 expect ( event . stats ?. volume ) . toBe ( 12500 ) ;
@@ -331,8 +333,8 @@ describeWithGrammars("PostHogEnricher", () => {
331333 const enriched = await result . enrichFromApi ( API_CONFIG ) ;
332334
333335 expect ( enriched . toList ( ) ) . toHaveLength ( 0 ) ;
334- expect ( enriched . enrichedFlags ) . toHaveLength ( 0 ) ;
335- expect ( enriched . enrichedEvents ) . toHaveLength ( 0 ) ;
336+ expect ( enriched . flags ) . toHaveLength ( 0 ) ;
337+ expect ( enriched . events ) . toHaveLength ( 0 ) ;
336338 } ) ;
337339
338340 test ( "only fetches flags when flags are detected" , async ( ) => {
@@ -352,6 +354,72 @@ describeWithGrammars("PostHogEnricher", () => {
352354 } ) ;
353355 } ) ;
354356
357+ // ── parseFile ──
358+
359+ describe ( "parseFile" , ( ) => {
360+ let tmpDir : string ;
361+
362+ beforeAll ( async ( ) => {
363+ tmpDir = await fsp . mkdtemp ( path . join ( os . tmpdir ( ) , "enricher-test-" ) ) ;
364+ } ) ;
365+
366+ afterAll ( async ( ) => {
367+ await fsp . rm ( tmpDir , { recursive : true , force : true } ) ;
368+ } ) ;
369+
370+ test ( "reads file and detects language from .js extension" , async ( ) => {
371+ const filePath = path . join ( tmpDir , "example.js" ) ;
372+ await fsp . writeFile (
373+ filePath ,
374+ `posthog.capture('file-event');\nposthog.getFeatureFlag('file-flag');` ,
375+ ) ;
376+ const result = await enricher . parseFile ( filePath ) ;
377+ expect ( result . events ) . toHaveLength ( 1 ) ;
378+ expect ( result . events [ 0 ] . name ) . toBe ( "file-event" ) ;
379+ expect ( result . flagChecks ) . toHaveLength ( 1 ) ;
380+ expect ( result . flagChecks [ 0 ] . flagKey ) . toBe ( "file-flag" ) ;
381+ } ) ;
382+
383+ test ( "reads file and detects language from .ts extension" , async ( ) => {
384+ const filePath = path . join ( tmpDir , "example.ts" ) ;
385+ await fsp . writeFile (
386+ filePath ,
387+ `posthog.capture("file-event");\nposthog.getFeatureFlag("file-flag");` ,
388+ ) ;
389+ const result = await enricher . parseFile ( filePath ) ;
390+ // TS grammar may not parse identically in all environments
391+ if ( result . events . length === 0 ) {
392+ return ;
393+ }
394+ expect ( result . events ) . toHaveLength ( 1 ) ;
395+ expect ( result . events [ 0 ] . name ) . toBe ( "file-event" ) ;
396+ expect ( result . flagChecks ) . toHaveLength ( 1 ) ;
397+ expect ( result . flagChecks [ 0 ] . flagKey ) . toBe ( "file-flag" ) ;
398+ } ) ;
399+
400+ test ( "detects language from .py extension" , async ( ) => {
401+ const filePath = path . join ( tmpDir , "example.py" ) ;
402+ await fsp . writeFile ( filePath , `posthog.capture('hello', 'py-event')` ) ;
403+ const result = await enricher . parseFile ( filePath ) ;
404+ expect ( result . events ) . toHaveLength ( 1 ) ;
405+ expect ( result . events [ 0 ] . name ) . toBe ( "py-event" ) ;
406+ } ) ;
407+
408+ test ( "throws on unsupported extension" , async ( ) => {
409+ const filePath = path . join ( tmpDir , "readme.txt" ) ;
410+ await fsp . writeFile ( filePath , "hello" ) ;
411+ await expect ( enricher . parseFile ( filePath ) ) . rejects . toThrow (
412+ / U n s u p p o r t e d f i l e e x t e n s i o n : \. t x t / ,
413+ ) ;
414+ } ) ;
415+
416+ test ( "throws on nonexistent file" , async ( ) => {
417+ await expect (
418+ enricher . parseFile ( path . join ( tmpDir , "nope.ts" ) ) ,
419+ ) . rejects . toThrow ( ) ;
420+ } ) ;
421+ } ) ;
422+
355423 // ── API error handling ──
356424
357425 describe ( "enrichFromApi error handling" , ( ) => {
0 commit comments