@flagshark/core 1.2.0 → 1.3.1

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.
Files changed (90) hide show
  1. package/README.md +100 -18
  2. package/dist/config/defaults.d.ts +3 -0
  3. package/dist/config/defaults.d.ts.map +1 -0
  4. package/dist/config/defaults.js +6 -0
  5. package/dist/config/defaults.js.map +1 -0
  6. package/dist/config/excluder.d.ts +18 -0
  7. package/dist/config/excluder.d.ts.map +1 -0
  8. package/dist/config/excluder.js +51 -0
  9. package/dist/config/excluder.js.map +1 -0
  10. package/dist/config/ignore-file.d.ts +6 -0
  11. package/dist/config/ignore-file.d.ts.map +1 -0
  12. package/dist/config/ignore-file.js +23 -0
  13. package/dist/config/ignore-file.js.map +1 -0
  14. package/dist/config/index.d.ts +7 -0
  15. package/dist/config/index.d.ts.map +1 -0
  16. package/dist/config/index.js +7 -0
  17. package/dist/config/index.js.map +1 -0
  18. package/dist/config/loader.d.ts +7 -0
  19. package/dist/config/loader.d.ts.map +1 -0
  20. package/dist/config/loader.js +47 -0
  21. package/dist/config/loader.js.map +1 -0
  22. package/dist/config/presets.d.ts +11 -0
  23. package/dist/config/presets.d.ts.map +1 -0
  24. package/dist/config/presets.js +70 -0
  25. package/dist/config/presets.js.map +1 -0
  26. package/dist/config/schema.d.ts +322 -0
  27. package/dist/config/schema.d.ts.map +1 -0
  28. package/dist/config/schema.js +63 -0
  29. package/dist/config/schema.js.map +1 -0
  30. package/dist/detection/detectors/go.d.ts +9 -3
  31. package/dist/detection/detectors/go.d.ts.map +1 -1
  32. package/dist/detection/detectors/go.js +8 -2
  33. package/dist/detection/detectors/go.js.map +1 -1
  34. package/dist/detection/detectors/javascript.d.ts +9 -3
  35. package/dist/detection/detectors/javascript.d.ts.map +1 -1
  36. package/dist/detection/detectors/javascript.js +8 -2
  37. package/dist/detection/detectors/javascript.js.map +1 -1
  38. package/dist/detection/detectors/python.d.ts +9 -3
  39. package/dist/detection/detectors/python.d.ts.map +1 -1
  40. package/dist/detection/detectors/python.js +8 -2
  41. package/dist/detection/detectors/python.js.map +1 -1
  42. package/dist/detection/detectors/typescript.d.ts +9 -3
  43. package/dist/detection/detectors/typescript.d.ts.map +1 -1
  44. package/dist/detection/detectors/typescript.js +8 -2
  45. package/dist/detection/detectors/typescript.js.map +1 -1
  46. package/dist/detection/helpers.d.ts +1 -1
  47. package/dist/detection/helpers.d.ts.map +1 -1
  48. package/dist/detection/helpers.js +9 -1
  49. package/dist/detection/helpers.js.map +1 -1
  50. package/dist/detection/index.d.ts +10 -0
  51. package/dist/detection/index.d.ts.map +1 -1
  52. package/dist/detection/index.js +31 -7
  53. package/dist/detection/index.js.map +1 -1
  54. package/dist/detection/interface.d.ts +3 -1
  55. package/dist/detection/interface.d.ts.map +1 -1
  56. package/dist/detection/registry.d.ts +1 -1
  57. package/dist/detection/registry.d.ts.map +1 -1
  58. package/dist/detection/tree-sitter/const-resolver.d.ts +8 -0
  59. package/dist/detection/tree-sitter/const-resolver.d.ts.map +1 -0
  60. package/dist/detection/tree-sitter/const-resolver.js +36 -0
  61. package/dist/detection/tree-sitter/const-resolver.js.map +1 -0
  62. package/dist/detection/tree-sitter/engine.d.ts +11 -0
  63. package/dist/detection/tree-sitter/engine.d.ts.map +1 -0
  64. package/dist/detection/tree-sitter/engine.js +70 -0
  65. package/dist/detection/tree-sitter/engine.js.map +1 -0
  66. package/dist/detection/tree-sitter/parser-cache.d.ts +6 -0
  67. package/dist/detection/tree-sitter/parser-cache.d.ts.map +1 -0
  68. package/dist/detection/tree-sitter/parser-cache.js +68 -0
  69. package/dist/detection/tree-sitter/parser-cache.js.map +1 -0
  70. package/dist/detection/tree-sitter/queries/go.scm +11 -0
  71. package/dist/detection/tree-sitter/queries/javascript.scm +13 -0
  72. package/dist/detection/tree-sitter/queries/python.scm +11 -0
  73. package/dist/detection/tree-sitter/queries/typescript.scm +11 -0
  74. package/dist/detection/tree-sitter/query-runner.d.ts +20 -0
  75. package/dist/detection/tree-sitter/query-runner.d.ts.map +1 -0
  76. package/dist/detection/tree-sitter/query-runner.js +83 -0
  77. package/dist/detection/tree-sitter/query-runner.js.map +1 -0
  78. package/dist/index.d.ts +1 -0
  79. package/dist/index.d.ts.map +1 -1
  80. package/dist/index.js +2 -0
  81. package/dist/index.js.map +1 -1
  82. package/dist/scan-repo.d.ts +27 -0
  83. package/dist/scan-repo.d.ts.map +1 -1
  84. package/dist/scan-repo.js +26 -5
  85. package/dist/scan-repo.js.map +1 -1
  86. package/dist/scanner.d.ts +11 -2
  87. package/dist/scanner.d.ts.map +1 -1
  88. package/dist/scanner.js +22 -7
  89. package/dist/scanner.js.map +1 -1
  90. package/package.json +12 -4
@@ -0,0 +1,20 @@
1
+ import { Query } from 'web-tree-sitter';
2
+ import type { Node, Tree } from 'web-tree-sitter';
3
+ import type { Language } from '../interface.js';
4
+ /** Loads the .scm query text for a language, relative to this module. */
5
+ export declare function loadQueryText(lang: Language): string;
6
+ export declare function getQuery(lang: Language): Promise<Query>;
7
+ export interface MatchedCall {
8
+ callNode: Node;
9
+ methodName: string;
10
+ argsNode: Node;
11
+ }
12
+ /** Walks query matches and yields one MatchedCall per call expression. */
13
+ export declare function iterateCalls(tree: Tree, query: Query): Generator<MatchedCall>;
14
+ /** Returns the Nth argument node, or null if out of range. */
15
+ export declare function getArgument(argsNode: Node, index: number): Node | null;
16
+ /** Returns the string value if the node is a string literal, else null. */
17
+ export declare function extractStringLiteral(node: Node): string | null;
18
+ /** @internal — for tests */
19
+ export declare function _clearQueryCache(): void;
20
+ //# sourceMappingURL=query-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-runner.d.ts","sourceRoot":"","sources":["../../../src/detection/tree-sitter/query-runner.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AACvC,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAG/C,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CASpD;AAKD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,CAmB7D;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,IAAI,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,IAAI,CAAA;CACf;AAED,0EAA0E;AAC1E,wBAAiB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC,WAAW,CAAC,CAS9E;AAED,8DAA8D;AAC9D,wBAAgB,WAAW,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAGtE;AAED,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAqB9D;AAED,4BAA4B;AAC5B,wBAAgB,gBAAgB,IAAI,IAAI,CAGvC"}
@@ -0,0 +1,83 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { Query } from 'web-tree-sitter';
4
+ import { getParser } from './parser-cache.js';
5
+ /** Loads the .scm query text for a language, relative to this module. */
6
+ export function loadQueryText(lang) {
7
+ // In an Action bundle context, queries are vendored alongside the WASM grammars.
8
+ // FLAGSHARK_QUERIES_DIR (set by the action entry) points at dist/queries/.
9
+ const queriesDir = process.env.FLAGSHARK_QUERIES_DIR;
10
+ if (queriesDir) {
11
+ return readFileSync(`${queriesDir}/${lang}.scm`, 'utf-8');
12
+ }
13
+ const url = new URL(`./queries/${lang}.scm`, import.meta.url);
14
+ return readFileSync(fileURLToPath(url), 'utf-8');
15
+ }
16
+ const queryCache = new Map();
17
+ const inFlightQueries = new Map();
18
+ export async function getQuery(lang) {
19
+ const cached = queryCache.get(lang);
20
+ if (cached)
21
+ return cached;
22
+ const pending = inFlightQueries.get(lang);
23
+ if (pending)
24
+ return pending;
25
+ const load = (async () => {
26
+ const parser = await getParser(lang);
27
+ const tsLang = parser.language;
28
+ if (!tsLang)
29
+ throw new Error(`Parser for ${lang} has no language set`);
30
+ const query = new Query(tsLang, loadQueryText(lang));
31
+ queryCache.set(lang, query);
32
+ inFlightQueries.delete(lang);
33
+ return query;
34
+ })();
35
+ inFlightQueries.set(lang, load);
36
+ return load;
37
+ }
38
+ /** Walks query matches and yields one MatchedCall per call expression. */
39
+ export function* iterateCalls(tree, query) {
40
+ for (const match of query.matches(tree.rootNode)) {
41
+ const captures = match.captures;
42
+ const call = captures.find((c) => c.name === 'call')?.node;
43
+ const method = captures.find((c) => c.name === 'method')?.node;
44
+ const args = captures.find((c) => c.name === 'args')?.node;
45
+ if (!call || !method || !args)
46
+ continue;
47
+ yield { callNode: call, methodName: method.text, argsNode: args };
48
+ }
49
+ }
50
+ /** Returns the Nth argument node, or null if out of range. */
51
+ export function getArgument(argsNode, index) {
52
+ const realChildren = (argsNode.namedChildren.filter((n) => n !== null && n.type !== 'comment'));
53
+ return realChildren[index] ?? null;
54
+ }
55
+ /** Returns the string value if the node is a string literal, else null. */
56
+ export function extractStringLiteral(node) {
57
+ const type = node.type;
58
+ const text = node.text;
59
+ if (type === 'string' ||
60
+ type === 'string_literal' ||
61
+ type === 'interpreted_string_literal' ||
62
+ type === 'raw_string_literal' ||
63
+ type === 'template_string') {
64
+ if (text.length < 2)
65
+ return null;
66
+ const first = text[0];
67
+ const last = text[text.length - 1];
68
+ if (first === last && (first === '"' || first === "'" || first === '`')) {
69
+ return text.slice(1, -1);
70
+ }
71
+ if (text.startsWith('"""') && text.endsWith('"""'))
72
+ return text.slice(3, -3);
73
+ if (text.startsWith("'''") && text.endsWith("'''"))
74
+ return text.slice(3, -3);
75
+ }
76
+ return null;
77
+ }
78
+ /** @internal — for tests */
79
+ export function _clearQueryCache() {
80
+ queryCache.clear();
81
+ inFlightQueries.clear();
82
+ }
83
+ //# sourceMappingURL=query-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-runner.js","sourceRoot":"","sources":["../../../src/detection/tree-sitter/query-runner.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -5,4 +5,5 @@ export { collectFiles } from './scanner.js';
5
5
  export type { ScanOptions } from './scanner.js';
6
6
  export { scanRepo } from './scan-repo.js';
7
7
  export type { ScanRepoOptions, ScanRepoResult, ScanLogger } from './scan-repo.js';
8
+ export * from './config/index.js';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,sBAAsB,CAAA;AAGpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAGlF,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAG/C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,sBAAsB,CAAA;AAGpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAGlF,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAG/C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAGjF,cAAc,mBAAmB,CAAA"}
package/dist/index.js CHANGED
@@ -6,4 +6,6 @@ export { analyzeStaleness } from './staleness.js';
6
6
  export { collectFiles } from './scanner.js';
7
7
  // Re-export scanRepo orchestrator
8
8
  export { scanRepo } from './scan-repo.js';
9
+ // Config module
10
+ export * from './config/index.js';
9
11
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,cAAc,sBAAsB,CAAA;AAEpC,+BAA+B;AAC/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAGjD,gDAAgD;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAG3C,kCAAkC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,cAAc,sBAAsB,CAAA;AAEpC,+BAA+B;AAC/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAGjD,gDAAgD;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAG3C,kCAAkC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAGzC,gBAAgB;AAChB,cAAc,mBAAmB,CAAA"}
@@ -3,6 +3,8 @@
3
3
  * return a single result object that consumers can render however they like.
4
4
  */
5
5
  import type { StaleFlag } from './staleness.js';
6
+ import type { FlagsharkConfig } from './config/schema.js';
7
+ import type { EffectiveRules } from './config/excluder.js';
6
8
  export interface ScanLogger {
7
9
  debug: (...args: unknown[]) => void;
8
10
  info: (...args: unknown[]) => void;
@@ -36,6 +38,25 @@ export interface ScanRepoOptions {
36
38
  * Optional logger for debug/info/warn/error messages. Defaults to a no-op.
37
39
  */
38
40
  logger?: ScanLogger;
41
+ /** @internal — undocumented escape hatch for cross-engine smoke testing */
42
+ engine?: 'regex' | 'tree-sitter';
43
+ /**
44
+ * Explicit config to use. If undefined, scanRepo discovers .flagshark.yml
45
+ * from cwd upward.
46
+ */
47
+ config?: FlagsharkConfig;
48
+ /**
49
+ * Set true to skip auto-discovery of .flagshark.yml (used by --no-config).
50
+ */
51
+ noConfig?: boolean;
52
+ /**
53
+ * Set true to skip .flagsharkignore discovery (used by --no-ignore-file).
54
+ */
55
+ noIgnoreFile?: boolean;
56
+ /**
57
+ * When true, the result will include the list of excluded file paths.
58
+ */
59
+ collectExcludedPaths?: boolean;
39
60
  }
40
61
  export interface ScanRepoResult {
41
62
  /** Total count of unique flag names detected across the repository. */
@@ -62,6 +83,12 @@ export interface ScanRepoResult {
62
83
  healthScore: number;
63
84
  /** Wall-clock duration of the scan in milliseconds. */
64
85
  scanDuration: number;
86
+ /** Number of files skipped due to exclude rules (paths, presets, .flagsharkignore). */
87
+ excludedCount?: number;
88
+ /** Relative paths of excluded files. Only populated when collectExcludedPaths is true. */
89
+ excludedPaths?: string[];
90
+ /** Diagnostic — populated only when logger.debug level is active or callers explicitly opt in. */
91
+ effectiveExcludes?: EffectiveRules;
65
92
  }
66
93
  export declare function scanRepo(opts: ScanRepoOptions): Promise<ScanRepoResult>;
67
94
  //# sourceMappingURL=scan-repo.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scan-repo.d.ts","sourceRoot":"","sources":["../src/scan-repo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE/C,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;IACnC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;IAClC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;IAClC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;CACpC;AAED,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAA;IAEX;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IAEb;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,CAAA;IAEpB;;OAEG;IACH,MAAM,CAAC,EAAE,UAAU,CAAA;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAA;IAElB,yDAAyD;IACzD,YAAY,EAAE,MAAM,CAAA;IAEpB;;;;OAIG;IACH,UAAU,EAAE,SAAS,EAAE,CAAA;IAEvB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,EAAE,CAAA;IAE3B,0EAA0E;IAC1E,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEzC;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAA;IAEnB,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAA;CACrB;AASD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAoD7E"}
1
+ {"version":3,"file":"scan-repo.d.ts","sourceRoot":"","sources":["../src/scan-repo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAYH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE1D,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;IACnC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;IAClC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;IAClC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;CACpC;AAED,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAA;IAEX;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IAEb;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,CAAA;IAEpB;;OAEG;IACH,MAAM,CAAC,EAAE,UAAU,CAAA;IAEnB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,OAAO,GAAG,aAAa,CAAA;IAEhC;;;OAGG;IACH,MAAM,CAAC,EAAE,eAAe,CAAA;IAExB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAElB;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IAEtB;;OAEG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAA;IAElB,yDAAyD;IACzD,YAAY,EAAE,MAAM,CAAA;IAEpB;;;;OAIG;IACH,UAAU,EAAE,SAAS,EAAE,CAAA;IAEvB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,EAAE,CAAA;IAE3B,0EAA0E;IAC1E,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEzC;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAA;IAEnB,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAA;IAEpB,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB,0FAA0F;IAC1F,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IAExB,kGAAkG;IAClG,iBAAiB,CAAC,EAAE,cAAc,CAAA;CACnC;AASD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CA2E7E"}
package/dist/scan-repo.js CHANGED
@@ -3,9 +3,13 @@
3
3
  * return a single result object that consumers can render however they like.
4
4
  */
5
5
  import { collectFiles } from './scanner.js';
6
- import { createDefaultRegistry } from './detection/index.js';
6
+ import { createDefaultRegistry, createRegistryWithEngine } from './detection/index.js';
7
7
  import { PolyglotAnalyzer } from './detection/polyglot-analyzer.js';
8
8
  import { analyzeStaleness } from './staleness.js';
9
+ import { buildDefaultConfig } from './config/defaults.js';
10
+ import { buildExcluder } from './config/excluder.js';
11
+ import { loadConfigFile } from './config/loader.js';
12
+ import { loadIgnoreFile } from './config/ignore-file.js';
9
13
  const NOOP_LOGGER = {
10
14
  debug: () => { },
11
15
  info: () => { },
@@ -15,17 +19,31 @@ const NOOP_LOGGER = {
15
19
  export async function scanRepo(opts) {
16
20
  const start = performance.now();
17
21
  const logger = opts.logger ?? NOOP_LOGGER;
18
- const threshold = opts.threshold ?? 6;
19
- const registry = createDefaultRegistry();
22
+ const config = opts.config ??
23
+ (opts.noConfig
24
+ ? buildDefaultConfig()
25
+ : (await loadConfigFile(opts.cwd))?.config ?? buildDefaultConfig());
26
+ const threshold = opts.threshold ?? config.threshold ?? 6;
27
+ const ignoreFile = opts.noIgnoreFile ? null : await loadIgnoreFile(opts.cwd);
28
+ const excluder = buildExcluder({
29
+ config,
30
+ ignoreFilePatterns: ignoreFile?.patterns ?? [],
31
+ });
32
+ logger.debug('Effective excludes', excluder.effectiveRules);
33
+ const registry = opts.engine
34
+ ? createRegistryWithEngine(opts.engine)
35
+ : createDefaultRegistry();
20
36
  const supportedExtensions = new Set(registry.getSupportedExtensions());
21
37
  const analyzer = new PolyglotAnalyzer(registry, logger);
22
38
  logger.debug('Collecting files...');
23
- const files = collectFiles({
39
+ const { files, excludedCount, excludedPaths } = collectFiles({
24
40
  root: opts.cwd,
25
41
  supportedExtensions,
26
42
  diffRef: opts.diff,
43
+ excluder,
44
+ collectExcludedPaths: opts.collectExcludedPaths,
27
45
  });
28
- logger.debug(`Detected ${files.size} candidate files`);
46
+ logger.debug(`Detected ${files.size} candidate files (excluded ${excludedCount})`);
29
47
  const filesScanned = files.size;
30
48
  const analysisResult = await analyzer.analyzeFiles(files, opts.signal);
31
49
  const staleFlags = await analyzeStaleness(analysisResult.totalFlags, { thresholdMonths: threshold, repoRoot: opts.cwd });
@@ -50,6 +68,9 @@ export async function scanRepo(opts) {
50
68
  languageBreakdown: Object.fromEntries(analysisResult.languages),
51
69
  healthScore,
52
70
  scanDuration: Math.round(performance.now() - start),
71
+ excludedCount,
72
+ excludedPaths,
73
+ effectiveExcludes: excluder.effectiveRules,
53
74
  };
54
75
  }
55
76
  //# sourceMappingURL=scan-repo.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scan-repo.js","sourceRoot":"","sources":["../src/scan-repo.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scan-repo.js","sourceRoot":"","sources":["../src/scan-repo.ts"],"names":[],"mappings":"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"}
package/dist/scanner.d.ts CHANGED
@@ -6,13 +6,22 @@
6
6
  *
7
7
  * walkDir() → filterFiles() → readFiles() → PolyglotAnalyzer.analyzeFiles()
8
8
  */
9
+ import type { Excluder } from './config/excluder.js';
9
10
  export interface ScanOptions {
10
11
  root: string;
11
12
  supportedExtensions: Set<string>;
12
13
  diffRef?: string;
14
+ excluder?: Excluder;
15
+ collectExcludedPaths?: boolean;
16
+ }
17
+ export interface CollectFilesResult {
18
+ files: Map<string, string>;
19
+ excludedCount: number;
20
+ excludedPaths?: string[];
13
21
  }
14
22
  /**
15
- * Collects files to scan, reads their contents, and returns a Map<filePath, content>.
23
+ * Collects files to scan, reads their contents, and returns a Map<filePath, content>
24
+ * along with the count of files excluded by the optional excluder.
16
25
  */
17
- export declare function collectFiles(options: ScanOptions): Map<string, string>;
26
+ export declare function collectFiles(options: ScanOptions): CollectFilesResult;
18
27
  //# sourceMappingURL=scanner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAwBH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAChC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA4BtE"}
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAoBpD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAChC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;CACzB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,kBAAkB,CAwCrE"}
package/dist/scanner.js CHANGED
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import { execFileSync } from 'node:child_process';
10
10
  import { readdirSync, readFileSync, statSync } from 'node:fs';
11
- import { join, extname } from 'node:path';
11
+ import { join, extname, relative } from 'node:path';
12
12
  const SKIP_DIRS = new Set([
13
13
  'node_modules',
14
14
  'vendor',
@@ -26,19 +26,32 @@ const SKIP_DIRS = new Set([
26
26
  ]);
27
27
  const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
28
28
  /**
29
- * Collects files to scan, reads their contents, and returns a Map<filePath, content>.
29
+ * Collects files to scan, reads their contents, and returns a Map<filePath, content>
30
+ * along with the count of files excluded by the optional excluder.
30
31
  */
31
32
  export function collectFiles(options) {
32
- const { root, supportedExtensions, diffRef } = options;
33
+ const { root, supportedExtensions, diffRef, excluder, collectExcludedPaths } = options;
33
34
  const files = new Map();
35
+ let excludedCount = 0;
36
+ const excludedPaths = collectExcludedPaths ? [] : undefined;
34
37
  let filePaths;
35
38
  if (diffRef) {
36
- filePaths = getDiffFiles(diffRef, supportedExtensions);
39
+ filePaths = getDiffFiles(diffRef, supportedExtensions, root);
37
40
  }
38
41
  else {
39
42
  filePaths = walkDir(root, supportedExtensions);
40
43
  }
41
44
  for (const fp of filePaths) {
45
+ if (excluder) {
46
+ const relativePath = relative(root, fp);
47
+ if (excluder.shouldExclude(relativePath)) {
48
+ excludedCount++;
49
+ if (excludedPaths) {
50
+ excludedPaths.push(relativePath);
51
+ }
52
+ continue;
53
+ }
54
+ }
42
55
  try {
43
56
  const stat = statSync(fp);
44
57
  if (stat.size > MAX_FILE_SIZE) {
@@ -53,22 +66,24 @@ export function collectFiles(options) {
53
66
  // Skip unreadable files
54
67
  }
55
68
  }
56
- return files;
69
+ return { files, excludedCount, excludedPaths };
57
70
  }
58
71
  /**
59
72
  * Get files changed since a git ref.
60
73
  */
61
- function getDiffFiles(ref, supportedExtensions) {
74
+ function getDiffFiles(ref, supportedExtensions, root) {
62
75
  try {
63
76
  const output = execFileSync('git', ['diff', ref, '--name-only', '--diff-filter=ACMR'], {
64
77
  encoding: 'utf-8',
65
78
  timeout: 30000,
79
+ cwd: root,
66
80
  });
67
81
  return output
68
82
  .split('\n')
69
83
  .map((line) => line.trim())
70
84
  .filter((line) => line.length > 0)
71
- .filter((line) => supportedExtensions.has(extname(line)));
85
+ .filter((line) => supportedExtensions.has(extname(line)))
86
+ .map((line) => join(root, line));
72
87
  }
73
88
  catch {
74
89
  throw new Error(`Failed to get diff from ref "${ref}". Is this a git repository?`);
@@ -1 +1 @@
1
- {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flagshark/core",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "type": "module",
5
5
  "description": "Detection engine for FlagShark — finds feature flag references across 13 languages.",
6
6
  "license": "MIT",
@@ -20,12 +20,20 @@
20
20
  },
21
21
  "files": ["dist/"],
22
22
  "scripts": {
23
- "build": "rm -rf dist && tsc -p tsconfig.build.json",
23
+ "build": "rm -rf dist && tsc -p tsconfig.build.json && bun run copy-queries",
24
+ "copy-queries": "mkdir -p dist/detection/tree-sitter/queries && cp src/detection/tree-sitter/queries/*.scm dist/detection/tree-sitter/queries/",
24
25
  "test": "vitest run",
25
26
  "typecheck": "tsc --noEmit"
26
27
  },
27
28
  "dependencies": {
29
+ "ignore": "^5.3.0",
28
30
  "p-limit": "^6.0.0",
31
+ "tree-sitter-go": "^0.25.0",
32
+ "tree-sitter-javascript": "^0.25.0",
33
+ "tree-sitter-python": "^0.25.0",
34
+ "tree-sitter-typescript": "^0.23.0",
35
+ "web-tree-sitter": "^0.25.0",
36
+ "yaml": "^2.4.0",
29
37
  "zod": "^3.23.0"
30
38
  },
31
39
  "devDependencies": {
@@ -34,6 +42,6 @@
34
42
  "vitest": "^3.0.0"
35
43
  },
36
44
  "engines": {
37
- "node": ">=18.0.0"
38
- }
45
+ "node": ">=18.0.0"
46
+ }
39
47
  }