{"_id":"@abtasty/codebase-analyzer-typescript","_rev":"23-3384b9dac918e8609685b812a7cb518e","name":"@abtasty/codebase-analyzer-typescript","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@abtasty/codebase-analyzer-typescript","version":"0.1.0","keywords":["feature-flags","codebase-analyzer","abtasty","launchdarkly","openfeature","optimizely","split","vwo"],"license":"MIT","_id":"@abtasty/codebase-analyzer-typescript@0.1.0","maintainers":[{"name":"abtasty-user","email":"devops+npm@abtasty.com"},{"name":"j.u.p.iter","email":"pn79122821224@gmail.com"},{"name":"tcoppin_","email":"tanguy@abtasty.com"},{"name":"jonathangranger","email":"jonathan@abtasty.com"},{"name":"elias-abt","email":"elias@abtasty.com"},{"name":"alexbinet","email":"alexandre.binet@abtasty.com"},{"name":"cquandalle","email":"cyril.quandalle@abtasty.com"},{"name":"benoitdubus","email":"benoit.dubus@abtasty.com"},{"name":"jean-baptiste.agostin","email":"Jean-baptiste.agostin@abtasty.com"},{"name":"simenbjerkeset","email":"simen.bjerkeset@abtasty.com"},{"name":"wallaka","email":"antoine.wallace@abtasty.com"},{"name":"theoletouze","email":"theo.letouze@abtasty.com"},{"name":"pierrevinarnick","email":"pierre.vinarnick@abtasty.com"},{"name":"julien_niedzwiecki","email":"julien.niedzwiecki@abtasty.com"},{"name":"balintfulop","email":"balint.fulop@abtasty.com"},{"name":"bricelof","email":"brice.lof@abtasty.com"},{"name":"romain.guillaume.abtasty.com","email":"romain.guillaume@abtasty.com"},{"name":"merki230","email":"merkitoko@gmail.com"},{"name":"camille.gouaultlamour","email":"camille.gouaultlamour@abtasty.com"},{"name":"enzo.morvan","email":"enzo.morvan@abtasty.com"},{"name":"gnicolas.abtasty","email":"guillaume.nicolas@abtasty.com"},{"name":"alexabt","email":"alexander.hermani@abtasty.com"},{"name":"tiwariamrita","email":"amrita.tiwari@abtasty.com"},{"name":"chloeadr","email":"chloe.adrian@abtasty.com"},{"name":"tastymoca","email":"teo.montlouis-calixte@abtasty.com"},{"name":"mick_mikhail","email":"corey167@gmail.com"},{"name":"pankajpatel_abtasty","email":"pankaj.patel@abtasty.com"},{"name":"mndiaye","email":"mamadou.ndiaye.ext@abtasty.com"},{"name":"stepan-abtasty","email":"stepan.vasnevsky.ext@abtasty.com"},{"name":"jeanszleper-abtasty","email":"jean.szleper@abtasty.com"},{"name":"magomedcharto","email":"magomed.daudov.ext@abtasty.com"},{"name":"anthony-baussard-abtasty","email":"anthony.baussard@abtasty.com"},{"name":"cedric.vimont","email":"cedric.vimont@abtasty.com"},{"name":"tudor.abtasty","email":"tudor.ghetu-bejan@abtasty.com"},{"name":"antoine.witkowski","email":"antoine.witkowski@abtasty.com"},{"name":"aria_v2000","email":"aria.vahidi@abtasty.com"},{"name":"pavel.sprygin.ext","email":"pavel.sprygin.ext@abtasty.com"},{"name":"rlavrov-abtasty","email":"roman.lavrov.ext@abtasty.com"},{"name":"amine.bouchebaba","email":"amine.bouchebaba@abtasty.com"},{"name":"clement.bock.abtasty","email":"clement.bock@abtasty.com"},{"name":"igor.goncharenko","email":"igor.goncharenko@abtasty.com"},{"name":"clementine.carpentier","email":"clementine.carpentier@abtasty.com"},{"name":"chadi-abtasty","email":"chadi.laoulaou@abtasty.com"},{"name":"abtasty.sebastien","email":"sebastien.niang@abtasty.com"},{"name":"karim.d98","email":"karim.dalaize@abtasty.com"},{"name":"maelaj","email":"mael.ajrouche@abtasty.com"},{"name":"lily_zh","email":"liliia.zhukova@abtasty.com"},{"name":"mnogueron-abtasty","email":"matthieu.nogueron@abtasty.com"},{"name":"ab-henri-petrelli","email":"henri.petrelli@abtasty.com"},{"name":"usernameforme","email":"philippe.henoch@abtasty.com"},{"name":"romanabtasty","email":"roman.surkov.ext@abtasty.com"},{"name":"axelviskovic","email":"axel.viskovic@abtasty.com"},{"name":"a.delprat","email":"antoine.delprat@abtasty.com"},{"name":"calice","email":"calice.lefevre@abtasty.com"},{"name":"isabellegautier","email":"isabelle.gautier@abtasty.com"},{"name":"julesabtasty","email":"jules.gobin@abtasty.com"},{"name":"romainpct_ab","email":"romain.penchenat@abtasty.com"},{"name":"audren","email":"audren.mauplot@abtasty.com"},{"name":"eshwar_abtasty","email":"eshwar.tillaisababady@abtasty.com"},{"name":"victor.duveau","email":"victor.duveau@abtasty.com"},{"name":"stephanec","email":"stephane.chimy@abtasty.com"},{"name":"vidal-abtasty","email":"vidal.nono.chiamegne@abtasty.com"},{"name":"michel.martineau","email":"michel.martineau@abtasty.com"},{"name":"vasily.kuplevich.ext","email":"vasily.kuplevich.ext@abtasty.com"},{"name":"indraabt","email":"indra.tinot.patole@abtasty.com"},{"name":"anya117","email":"anya.kurrimboccus@abtasty.com"},{"name":"ragularatnam","email":"ragularatnam.perinparatnam@abtasty.com"},{"name":"alexandre.fritsch","email":"alexandre.fritsch@abtasty.com"},{"name":"andres.munoz.abtasty","email":"andres.munoz@abtasty.com"},{"name":"hemalambert","email":"hema.lambert@abtasty.com"},{"name":"yannickabtasty","email":"yannick.eyl@abtasty.com"},{"name":"samuel_barubiriza","email":"samuel.barubiriza@abtasty.com"},{"name":"leo.coyere-abt","email":"leo.coyere@abtasty.com"}],"dist":{"shasum":"aa15209b6b117a20ef6af5e3724a1e8d6d390d80","tarball":"https://registry.npmjs.org/@abtasty/codebase-analyzer-typescript/-/codebase-analyzer-typescript-0.1.0.tgz","fileCount":9,"integrity":"sha512-5fkKUedl5rzmQxU/GMotRzhLtmsKDWHzEfzEpRdZNQ2EbFymZNKqtgjfeb2C8Tt/L3Y/Lko0iYoDN2mcvGxP/g==","signatures":[{"sig":"MEYCIQCOjZDNAiUIC1tVq4x5FNVshTvi2DYnzrHoe6FMdCdqbwIhAIQkzxfIiGWXQS4h3VBcWHk/xaKojSItS623ISjuHbRh","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":208761},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"b34dce400ec16f4fdfa1b48d896a530edf96476b","scripts":{"lint":"eslint src/","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"chadi-abtasty","email":"chadi.laoulaou@abtasty.com"},"_npmVersion":"10.9.4","description":"Analyze codebases to detect feature flag usage across multiple platforms","directories":{},"_nodeVersion":"22.21.1","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","vitest":"^3.0.0","typescript":"^5.4.0","@types/node":"^25.5.0"},"_npmOperationalInternal":{"tmp":"tmp/codebase-analyzer-typescript_0.1.0_1773755793872_0.11654750343190945","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2026-03-17T13:56:33.871Z","modified":"2026-09-08T07:08:32.073Z","0.1.0":"2026-03-17T13:56:34.066Z"},"license":"MIT","keywords":["feature-flags","codebase-analyzer","abtasty","launchdarkly","openfeature","optimizely","split","vwo"],"description":"Analyze codebases to detect feature flag usage across multiple platforms","maintainers":[{"email":"devops+npm@abtasty.com","name":"abtasty-user"},{"email":"pn79122821224@gmail.com","name":"j.u.p.iter"},{"email":"tanguy@abtasty.com","name":"tcoppin_"},{"email":"jonathan@abtasty.com","name":"jonathangranger"},{"email":"alexandre.binet@abtasty.com","name":"alexbinet"},{"email":"aditya.anand@vwo.com","name":"adityanand"},{"email":"anuj.bansal@vwo.com","name":"anujbansal"},{"email":"cyril.quandalle@abtasty.com","name":"cquandalle"},{"email":"benoit.dubus@abtasty.com","name":"benoitdubus"},{"email":"Jean-baptiste.agostin@abtasty.com","name":"jean-baptiste.agostin"},{"email":"simen.bjerkeset@abtasty.com","name":"simenbjerkeset"},{"email":"pierre.vinarnick@abtasty.com","name":"pierrevinarnick"},{"email":"julien.niedzwiecki@abtasty.com","name":"julien_niedzwiecki"},{"email":"balint.fulop@abtasty.com","name":"balintfulop"},{"email":"merkitoko@gmail.com","name":"merki230"},{"email":"camille.gouaultlamour@abtasty.com","name":"camille.gouaultlamour"},{"email":"enzo.morvan@abtasty.com","name":"enzo.morvan"},{"email":"guillaume.nicolas@abtasty.com","name":"gnicolas.abtasty"},{"email":"alexander.hermani@abtasty.com","name":"alexabt"},{"email":"amrita.tiwari@abtasty.com","name":"tiwariamrita"},{"email":"chloe.adrian@abtasty.com","name":"chloeadr"},{"email":"teo.montlouis-calixte@abtasty.com","name":"tastymoca"},{"email":"corey167@gmail.com","name":"mick_mikhail"},{"email":"mamadou.ndiaye@abtasty.com","name":"mndiaye"},{"email":"stepan.vasnevsky.ext@abtasty.com","name":"stepan-abtasty"},{"email":"jean.szleper@abtasty.com","name":"jeanszleper-abtasty"},{"email":"magomed.daudov.ext@abtasty.com","name":"magomedcharto"},{"email":"anthony.baussard@abtasty.com","name":"anthony-baussard-abtasty"},{"email":"cedric.vimont@abtasty.com","name":"cedric.vimont"},{"email":"antoine.witkowski@abtasty.com","name":"antoine.witkowski"},{"email":"aria.vahidi@abtasty.com","name":"aria_v2000"},{"email":"pavel.sprygin.ext@abtasty.com","name":"pavel.sprygin.ext"},{"email":"roman.lavrov.ext@abtasty.com","name":"rlavrov-abtasty"},{"email":"amine.bouchebaba@abtasty.com","name":"amine.bouchebaba"},{"email":"clement.bock@abtasty.com","name":"clement.bock.abtasty"},{"email":"igor.goncharenko@abtasty.com","name":"igor.goncharenko"},{"email":"karim.dalaize@abtasty.com","name":"karim.d98"},{"email":"mael.ajrouche@abtasty.com","name":"maelaj"},{"email":"kanishka.singhal@wingify.com","name":"kanishkasinghal"},{"email":"deepak.chaudhary@wingify.com","name":"deepakchaudhary07"},{"email":"infra.abtasty@wingify.com","name":"infraabtasty"},{"email":"liliia.zhukova@abtasty.com","name":"lily_zh"},{"email":"valentin.malemanche@abtasty.com","name":"valentin-malemanche"},{"email":"benoit.allibe@abtasty.com","name":"benoit.allibe"},{"email":"matthieu.nogueron@abtasty.com","name":"mnogueron-abtasty"},{"email":"henri.petrelli@abtasty.com","name":"ab-henri-petrelli"},{"email":"gaetan.postorivo@abtasty.com","name":"gaetan.p"},{"email":"kant.chhim@abtasty.com","name":"kanthann"},{"email":"manish.kumar1@wingify.com","name":"manish144"},{"email":"anmol.kurmi@wingify.com","name":"anmolkurmi"},{"email":"philippe.henoch@abtasty.com","name":"usernameforme"},{"email":"nitish.mittal@wingify.com","name":"nitishmittal_wingify"},{"email":"gaetan+npm@abtasty.com","name":"gaetan-philippot-abt2"},{"email":"roman.surkov.ext@abtasty.com","name":"romanabtasty"},{"email":"axel.viskovic@abtasty.com","name":"axelviskovic"},{"email":"antoine.delprat@abtasty.com","name":"a.delprat"},{"email":"calice.lefevre@abtasty.com","name":"calice"},{"email":"isabelle.gautier@abtasty.com","name":"isabellegautier"},{"email":"audren.mauplot@abtasty.com","name":"audren"},{"email":"eshwar.tillaisababady@abtasty.com","name":"eshwar_abtasty"},{"email":"victor.duveau@abtasty.com","name":"victor.duveau"},{"email":"stephane.chimy@abtasty.com","name":"stephanec"},{"email":"vidal.nono.chiamegne@abtasty.com","name":"vidal-abtasty"},{"email":"vasily.kuplevich.ext@abtasty.com","name":"vasily.kuplevich.ext"},{"email":"indra.tinot.patole@abtasty.com","name":"indraabt"},{"email":"anya.kurrimboccus@abtasty.com","name":"anya117"},{"email":"ragularatnam.perinparatnam@abtasty.com","name":"ragularatnam"},{"email":"alexandre.fritsch@abtasty.com","name":"alexandre.fritsch"},{"email":"andres.munoz@abtasty.com","name":"andres.munoz.abtasty"},{"email":"hema.lambert@abtasty.com","name":"hemalambert"},{"email":"yannick.eyl@abtasty.com","name":"yannickabtasty"},{"email":"samuel.barubiriza@abtasty.com","name":"samuel_barubiriza"},{"email":"leo.coyere@abtasty.com","name":"leo.coyere-abt"}],"readme":"# @abtasty/codebase-analyzer-typescript\n\nA TypeScript library that scans codebases to detect feature flag usage across multiple platforms and programming languages.\n\n## Features\n\n- **Multi-platform detection** — AB Tasty (Flagship SDK V3), LaunchDarkly, OpenFeature, Optimizely, Split, VWO\n- **Multi-language support** — JavaScript/TypeScript, Go, Python, Java, Kotlin, PHP, Swift, Objective-C, C#/.NET, VB.NET, Dart, C/C++\n- **Flag metadata extraction** — flag keys, default values, types (boolean, string, number, json), line numbers\n- **Repository linking** — generates direct links to flag usages in your source repository\n- **Custom regex support** — extend detection with your own patterns via JSON configuration\n- **Comment-based detection** — supports `fe:flag: flagKey, type` comments for manual flag annotation\n- **Dual module format** — ships as both CommonJS and ESM with full TypeScript declarations\n\n## Installation\n\n```bash\nnpm install @abtasty/codebase-analyzer-typescript\n```\n\n## Quick start\n\n```typescript\nimport { analyzeCode, createConfig } from \"@abtasty/codebase-analyzer-typescript\";\n\nconst config = createConfig({\n  directory: \"./src\",\n  repositoryURL: \"https://github.com/your-org/your-repo\",\n  repositoryBranch: \"main\",\n});\n\nconst results = analyzeCode(config);\n\nfor (const file of results) {\n  if (file.results.length > 0) {\n    console.log(`${file.file}: ${file.results.length} flag(s) found`);\n    for (const flag of file.results) {\n      console.log(`  - ${flag.flagKey} (${flag.flagType}, default: ${flag.flagDefaultValue})`);\n    }\n  }\n}\n```\n\n## API\n\n### `createConfig(options?)`\n\nCreates an `AnalyzerConfig` with sensible defaults.\n\n```typescript\nconst config = createConfig({\n  directory: \"./src\",             // Directory to scan (default: \".\")\n  repositoryURL: \"https://...\",   // Repository root URL for generating links\n  repositoryBranch: \"main\",      // Branch name (default: \"main\")\n  nbLineCodeEdges: 1,            // Context lines around flag usage (default: 1)\n  filesToExclude: [\".git\", \"node_modules\"], // Exclusion patterns\n  searchCustomRegex: \"\",          // Custom regex patterns as JSON string\n});\n```\n\n### `analyzeCode(config)`\n\nScans the codebase and logs results to the console. Returns an array of `FileAnalyzed` objects.\n\n```typescript\nconst results: FileAnalyzed[] = analyzeCode(config);\n```\n\n### `extractFlagsInfo(config)`\n\nSame as `analyzeCode` but without console output. Use this for silent/programmatic analysis.\n\n```typescript\nconst results: FileAnalyzed[] = extractFlagsInfo(config);\n```\n\n### `getFlagType(defaultValue)`\n\nDetermines the flag type from its default value string.\n\n```typescript\nconst { flagType, defaultValue } = getFlagType('\"hello\"');\n// flagType: \"string\", defaultValue: '\"hello\"'\n\nconst { flagType } = getFlagType(\"true\");\n// flagType: \"boolean\"\n```\n\n### `getPlatformRegexes(platform)`\n\nReturns regex patterns for a specific platform, or `null` if not found.\n\n```typescript\nimport { getPlatformRegexes } from \"@abtasty/codebase-analyzer-typescript\";\n\nconst patterns = getPlatformRegexes(\"launchdarkly\");\n```\n\nSupported platforms: `\"launchdarkly\"`, `\"openfeature\"`, `\"optimizely\"`, `\"split\"`, `\"vwo\"`.\n\n### `getTemplateRegexes()`\n\nReturns template regex patterns that can be used as a starting point for custom patterns.\n\n## Types\n\n```typescript\ninterface AnalyzerConfig {\n  directory: string;\n  repositoryURL: string;\n  repositoryBranch: string;\n  nbLineCodeEdges: number;\n  filesToExclude: string[];\n  searchCustomRegex: string;\n}\n\ninterface FileAnalyzed {\n  file: string;              // Relative file path\n  fileURL: string;           // Full URL to the file in the repository\n  error: string | null;      // Error message if analysis failed\n  results: FlagAnalyzed[];   // Flags found in this file\n}\n\ninterface FlagAnalyzed {\n  lineNumber: number;        // Line where the flag was found\n  flagKey: string;           // The flag key/name\n  flagDefaultValue: string;  // The default value\n  flagType: string;          // \"boolean\" | \"string\" | \"number\" | \"json\" | \"unknown\"\n  exists: boolean;           // Whether the flag exists in the platform\n}\n\ninterface RegexPattern {\n  file_extension: string;    // File extension regex (e.g. \".[jt]s$\")\n  regexes: string[];         // Regex patterns to apply\n}\n\ntype Platform = \"launchdarkly\" | \"openfeature\" | \"optimizely\" | \"split\" | \"vwo\";\n```\n\n## Custom regex patterns\n\nYou can extend detection with custom regex patterns by passing a JSON string to `searchCustomRegex`:\n\n```typescript\nconst customRegex = JSON.stringify([\n  {\n    file_extension: \"\\\\.tsx?$\",\n    regexes: [\n      \"myCustomFlag\\\\(['\\\"]([\\\\w-]+)['\\\"]\\\\s*,\\\\s*([^)]+)\\\\)\"\n    ]\n  }\n]);\n\nconst config = createConfig({\n  directory: \"./src\",\n  repositoryURL: \"https://github.com/org/repo\",\n  searchCustomRegex: customRegex,\n});\n```\n\nEach regex must use capture groups:\n- **Group 1** — the flag key\n- **Group 2** (optional) — the default value\n\n## Comment-based flag annotation\n\nYou can annotate flags directly in your code using comments:\n\n```typescript\n// fe:flag: myFlagKey, boolean\n```\n\nThis is useful for flags that are not detected by the built-in regex patterns.\n\n## Supported SDK methods\n\n### AB Tasty (Flagship)\n`useFsFlag()`, `getFlag()`, `getModification()`, and key/defaultValue object patterns.\n\n### LaunchDarkly\n`variation()`, `boolVariation()`, `stringVariation()`, `intVariation()`, `float64Variation()`, `jsonVariation()`, and more.\n\n### OpenFeature\n`getBooleanValue()`, `getStringValue()`, `getNumberValue()`, `getObjectValue()`, and their `Details` variants.\n\n### Optimizely\n`isFeatureEnabled()`, `getFeatureVariable*()`, `decide()`, and more.\n\n### Split\n`getTreatment()`, `getTreatmentWithConfig()`, and similar.\n\n### VWO\n`isFeatureEnabled()`, `getFeatureVariableValue()`, `activate()`, and more.\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Build\nnpm run build\n\n# Run tests\nnpm test\n\n# Type check\nnpm run typecheck\n\n# Lint\nnpm run lint\n```\n\n## License\n\nMIT\n# codebase-analyzer-typescript\n","readmeFilename":"README.md"}