@liendev/parser 0.39.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.
Files changed (153) hide show
  1. package/dist/ast/chunker.d.ts +30 -0
  2. package/dist/ast/chunker.d.ts.map +1 -0
  3. package/dist/ast/chunker.js +310 -0
  4. package/dist/ast/chunker.js.map +1 -0
  5. package/dist/ast/complexity/cognitive.d.ts +16 -0
  6. package/dist/ast/complexity/cognitive.d.ts.map +1 -0
  7. package/dist/ast/complexity/cognitive.js +137 -0
  8. package/dist/ast/complexity/cognitive.js.map +1 -0
  9. package/dist/ast/complexity/cyclomatic.d.ts +12 -0
  10. package/dist/ast/complexity/cyclomatic.d.ts.map +1 -0
  11. package/dist/ast/complexity/cyclomatic.js +54 -0
  12. package/dist/ast/complexity/cyclomatic.js.map +1 -0
  13. package/dist/ast/complexity/halstead.d.ts +56 -0
  14. package/dist/ast/complexity/halstead.d.ts.map +1 -0
  15. package/dist/ast/complexity/halstead.js +196 -0
  16. package/dist/ast/complexity/halstead.js.map +1 -0
  17. package/dist/ast/complexity/index.d.ts +13 -0
  18. package/dist/ast/complexity/index.d.ts.map +1 -0
  19. package/dist/ast/complexity/index.js +12 -0
  20. package/dist/ast/complexity/index.js.map +1 -0
  21. package/dist/ast/extractors/index.d.ts +35 -0
  22. package/dist/ast/extractors/index.d.ts.map +1 -0
  23. package/dist/ast/extractors/index.js +41 -0
  24. package/dist/ast/extractors/index.js.map +1 -0
  25. package/dist/ast/extractors/symbol-helpers.d.ts +20 -0
  26. package/dist/ast/extractors/symbol-helpers.d.ts.map +1 -0
  27. package/dist/ast/extractors/symbol-helpers.js +58 -0
  28. package/dist/ast/extractors/symbol-helpers.js.map +1 -0
  29. package/dist/ast/extractors/types.d.ts +108 -0
  30. package/dist/ast/extractors/types.d.ts.map +1 -0
  31. package/dist/ast/extractors/types.js +2 -0
  32. package/dist/ast/extractors/types.js.map +1 -0
  33. package/dist/ast/languages/javascript.d.ts +134 -0
  34. package/dist/ast/languages/javascript.d.ts.map +1 -0
  35. package/dist/ast/languages/javascript.js +787 -0
  36. package/dist/ast/languages/javascript.js.map +1 -0
  37. package/dist/ast/languages/php.d.ts +84 -0
  38. package/dist/ast/languages/php.d.ts.map +1 -0
  39. package/dist/ast/languages/php.js +452 -0
  40. package/dist/ast/languages/php.js.map +1 -0
  41. package/dist/ast/languages/python.d.ts +96 -0
  42. package/dist/ast/languages/python.d.ts.map +1 -0
  43. package/dist/ast/languages/python.js +448 -0
  44. package/dist/ast/languages/python.js.map +1 -0
  45. package/dist/ast/languages/registry.d.ts +30 -0
  46. package/dist/ast/languages/registry.d.ts.map +1 -0
  47. package/dist/ast/languages/registry.js +95 -0
  48. package/dist/ast/languages/registry.js.map +1 -0
  49. package/dist/ast/languages/rust.d.ts +113 -0
  50. package/dist/ast/languages/rust.d.ts.map +1 -0
  51. package/dist/ast/languages/rust.js +614 -0
  52. package/dist/ast/languages/rust.js.map +1 -0
  53. package/dist/ast/languages/types.d.ts +52 -0
  54. package/dist/ast/languages/types.d.ts.map +1 -0
  55. package/dist/ast/languages/types.js +2 -0
  56. package/dist/ast/languages/types.js.map +1 -0
  57. package/dist/ast/languages/typescript.d.ts +3 -0
  58. package/dist/ast/languages/typescript.d.ts.map +1 -0
  59. package/dist/ast/languages/typescript.js +134 -0
  60. package/dist/ast/languages/typescript.js.map +1 -0
  61. package/dist/ast/parser.d.ts +29 -0
  62. package/dist/ast/parser.d.ts.map +1 -0
  63. package/dist/ast/parser.js +67 -0
  64. package/dist/ast/parser.js.map +1 -0
  65. package/dist/ast/symbols.d.ts +74 -0
  66. package/dist/ast/symbols.d.ts.map +1 -0
  67. package/dist/ast/symbols.js +171 -0
  68. package/dist/ast/symbols.js.map +1 -0
  69. package/dist/ast/traversers/index.d.ts +19 -0
  70. package/dist/ast/traversers/index.d.ts.map +1 -0
  71. package/dist/ast/traversers/index.js +21 -0
  72. package/dist/ast/traversers/index.js.map +1 -0
  73. package/dist/ast/traversers/types.d.ts +98 -0
  74. package/dist/ast/traversers/types.d.ts.map +1 -0
  75. package/dist/ast/traversers/types.js +2 -0
  76. package/dist/ast/traversers/types.js.map +1 -0
  77. package/dist/ast/types.d.ts +54 -0
  78. package/dist/ast/types.d.ts.map +1 -0
  79. package/dist/ast/types.js +2 -0
  80. package/dist/ast/types.js.map +1 -0
  81. package/dist/chunk-only-index.d.ts +25 -0
  82. package/dist/chunk-only-index.d.ts.map +1 -0
  83. package/dist/chunk-only-index.js +107 -0
  84. package/dist/chunk-only-index.js.map +1 -0
  85. package/dist/chunker.d.ts +12 -0
  86. package/dist/chunker.d.ts.map +1 -0
  87. package/dist/chunker.js +98 -0
  88. package/dist/chunker.js.map +1 -0
  89. package/dist/constants.d.ts +8 -0
  90. package/dist/constants.d.ts.map +1 -0
  91. package/dist/constants.js +11 -0
  92. package/dist/constants.js.map +1 -0
  93. package/dist/content-hash.d.ts +20 -0
  94. package/dist/content-hash.d.ts.map +1 -0
  95. package/dist/content-hash.js +91 -0
  96. package/dist/content-hash.js.map +1 -0
  97. package/dist/dependency-analyzer.d.ts +79 -0
  98. package/dist/dependency-analyzer.d.ts.map +1 -0
  99. package/dist/dependency-analyzer.js +408 -0
  100. package/dist/dependency-analyzer.js.map +1 -0
  101. package/dist/ecosystem-presets.d.ts +32 -0
  102. package/dist/ecosystem-presets.d.ts.map +1 -0
  103. package/dist/ecosystem-presets.js +325 -0
  104. package/dist/ecosystem-presets.js.map +1 -0
  105. package/dist/gitignore.d.ts +22 -0
  106. package/dist/gitignore.d.ts.map +1 -0
  107. package/dist/gitignore.js +128 -0
  108. package/dist/gitignore.js.map +1 -0
  109. package/dist/index.d.ts +32 -0
  110. package/dist/index.d.ts.map +1 -0
  111. package/dist/index.js +68 -0
  112. package/dist/index.js.map +1 -0
  113. package/dist/insights/chunk-complexity.d.ts +89 -0
  114. package/dist/insights/chunk-complexity.d.ts.map +1 -0
  115. package/dist/insights/chunk-complexity.js +332 -0
  116. package/dist/insights/chunk-complexity.js.map +1 -0
  117. package/dist/insights/types.d.ts +73 -0
  118. package/dist/insights/types.d.ts.map +1 -0
  119. package/dist/insights/types.js +9 -0
  120. package/dist/insights/types.js.map +1 -0
  121. package/dist/json-template-chunker.d.ts +12 -0
  122. package/dist/json-template-chunker.d.ts.map +1 -0
  123. package/dist/json-template-chunker.js +87 -0
  124. package/dist/json-template-chunker.js.map +1 -0
  125. package/dist/liquid-chunker.d.ts +16 -0
  126. package/dist/liquid-chunker.d.ts.map +1 -0
  127. package/dist/liquid-chunker.js +274 -0
  128. package/dist/liquid-chunker.js.map +1 -0
  129. package/dist/scanner.d.ts +16 -0
  130. package/dist/scanner.d.ts.map +1 -0
  131. package/dist/scanner.js +95 -0
  132. package/dist/scanner.js.map +1 -0
  133. package/dist/symbol-extractor.d.ts +18 -0
  134. package/dist/symbol-extractor.d.ts.map +1 -0
  135. package/dist/symbol-extractor.js +343 -0
  136. package/dist/symbol-extractor.js.map +1 -0
  137. package/dist/test-associations.d.ts +16 -0
  138. package/dist/test-associations.d.ts.map +1 -0
  139. package/dist/test-associations.js +43 -0
  140. package/dist/test-associations.js.map +1 -0
  141. package/dist/types.d.ts +75 -0
  142. package/dist/types.d.ts.map +1 -0
  143. package/dist/types.js +2 -0
  144. package/dist/types.js.map +1 -0
  145. package/dist/utils/path-matching.d.ts +71 -0
  146. package/dist/utils/path-matching.d.ts.map +1 -0
  147. package/dist/utils/path-matching.js +258 -0
  148. package/dist/utils/path-matching.js.map +1 -0
  149. package/dist/utils/repo-id.d.ts +6 -0
  150. package/dist/utils/repo-id.d.ts.map +1 -0
  151. package/dist/utils/repo-id.js +12 -0
  152. package/dist/utils/repo-id.js.map +1 -0
  153. package/package.json +66 -0
@@ -0,0 +1,258 @@
1
+ /**
2
+ * Shared path matching utilities for dependency analysis.
3
+ *
4
+ * These functions handle path normalization and matching logic used by
5
+ * the get_dependents tool to find reverse dependencies.
6
+ */
7
+ import { getSupportedExtensions } from '../ast/languages/registry.js';
8
+ /**
9
+ * Escape special regex characters in a string.
10
+ * This ensures extensions like "c++" don't break the regex pattern.
11
+ */
12
+ function escapeRegex(str) {
13
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
14
+ }
15
+ /**
16
+ * Build the extension-stripping regex from the language registry.
17
+ * Cached after first call.
18
+ */
19
+ let extensionRegex = null;
20
+ function getExtensionRegex() {
21
+ if (!extensionRegex) {
22
+ const extPattern = getSupportedExtensions().map(escapeRegex).join('|');
23
+ extensionRegex = new RegExp(`\\.(${extPattern})$`);
24
+ }
25
+ return extensionRegex;
26
+ }
27
+ /**
28
+ * Normalizes a file path for comparison.
29
+ *
30
+ * - Removes quotes and trims whitespace
31
+ * - Converts backslashes to forward slashes
32
+ * - Strips file extensions for all AST-supported languages
33
+ * - Converts absolute paths to relative (if within workspace root)
34
+ *
35
+ * @param path - The path to normalize
36
+ * @param workspaceRoot - The workspace root directory (normalized with forward slashes)
37
+ * @returns Normalized path
38
+ */
39
+ export function normalizePath(path, workspaceRoot) {
40
+ let normalized = path.replace(/['"]/g, '').trim().replace(/\\/g, '/');
41
+ // Normalize extensions: strip all AST-supported language extensions
42
+ // This handles TypeScript's ESM requirement of .js imports for .ts files
43
+ // Also handles PHP files where namespaces don't include extensions
44
+ // Also handles Python files where module imports don't include extensions
45
+ normalized = normalized.replace(getExtensionRegex(), '');
46
+ // Normalize to relative path if it starts with workspace root
47
+ if (normalized.startsWith(workspaceRoot + '/')) {
48
+ normalized = normalized.substring(workspaceRoot.length + 1);
49
+ }
50
+ return normalized;
51
+ }
52
+ /**
53
+ * Checks if a pattern matches at path component boundaries.
54
+ *
55
+ * Ensures matches occur at proper path boundaries (/) to avoid false positives like:
56
+ * - "logger" matching "logger-utils" ❌
57
+ * - "src/logger" matching "src/logger-service" ❌
58
+ *
59
+ * @param str - The string to search in
60
+ * @param pattern - The pattern to search for
61
+ * @returns True if pattern matches at a boundary
62
+ */
63
+ export function matchesAtBoundary(str, pattern) {
64
+ const index = str.indexOf(pattern);
65
+ if (index === -1)
66
+ return false;
67
+ // Check character before match (must be start or path separator)
68
+ const charBefore = index > 0 ? str[index - 1] : '/';
69
+ if (charBefore !== '/' && index !== 0)
70
+ return false;
71
+ // Check character after match (must be end or path separator)
72
+ // Extensions are already stripped during normalization, so we only need to check for '/' as a valid path separator
73
+ const endIndex = index + pattern.length;
74
+ if (endIndex === str.length)
75
+ return true;
76
+ const charAfter = str[endIndex];
77
+ return charAfter === '/';
78
+ }
79
+ /**
80
+ * Determines if an import path matches a target file path.
81
+ *
82
+ * Handles various matching strategies:
83
+ * 1. Exact match
84
+ * 2. Target path appears in import (at boundaries)
85
+ * 3. Import path appears in target (at boundaries)
86
+ * 4. Relative imports (./logger vs src/utils/logger)
87
+ * 5. PHP namespace imports (App\Models\User vs app/Models/User.php)
88
+ * 6. Python module imports (django.http → django/http/__init__.py or django/http/*.py)
89
+ *
90
+ * @param normalizedImport - Normalized import path
91
+ * @param normalizedTarget - Normalized target file path
92
+ * @returns True if the import matches the target file
93
+ */
94
+ export function matchesFile(normalizedImport, normalizedTarget) {
95
+ // Exact match
96
+ if (normalizedImport === normalizedTarget)
97
+ return true;
98
+ // Strategy 1: Check if target path appears in import at path boundaries
99
+ if (matchesAtBoundary(normalizedImport, normalizedTarget)) {
100
+ return true;
101
+ }
102
+ // Strategy 2: Check if import path appears in target (for longer target paths)
103
+ if (matchesAtBoundary(normalizedTarget, normalizedImport)) {
104
+ return true;
105
+ }
106
+ // Strategy 3: Handle relative imports (./logger vs src/utils/logger)
107
+ // Remove leading ./ and ../ from import
108
+ const cleanedImport = normalizedImport.replace(/^(\.\.?\/)+/, '');
109
+ if (matchesAtBoundary(cleanedImport, normalizedTarget) ||
110
+ matchesAtBoundary(normalizedTarget, cleanedImport)) {
111
+ return true;
112
+ }
113
+ // Strategy 4: PHP namespace matching
114
+ // PHP imports use namespaces like "App\Models\User" which should match "app/Models/User.php"
115
+ if (matchesPHPNamespace(normalizedImport, normalizedTarget)) {
116
+ return true;
117
+ }
118
+ // Strategy 5: Python module matching
119
+ // Python imports use dotted paths like "django.http" which should match "django/http/response.py"
120
+ if (matchesPythonModule(normalizedImport, normalizedTarget)) {
121
+ return true;
122
+ }
123
+ return false;
124
+ }
125
+ /**
126
+ * Check if target exactly matches the module path (handles __init__.py)
127
+ */
128
+ function matchesDirectPythonModule(moduleAsPath, targetWithoutPy) {
129
+ return (targetWithoutPy === moduleAsPath ||
130
+ targetWithoutPy === moduleAsPath + '/__init__' ||
131
+ targetWithoutPy.replace(/\/__init__$/, '') === moduleAsPath);
132
+ }
133
+ /**
134
+ * Check if target is a child of the module package
135
+ */
136
+ function matchesParentPythonPackage(moduleAsPath, targetWithoutPy) {
137
+ return targetWithoutPy.startsWith(moduleAsPath + '/');
138
+ }
139
+ /**
140
+ * Check if module path appears as a suffix in the target path
141
+ */
142
+ function matchesSuffixPythonModule(moduleAsPath, targetWithoutPy) {
143
+ return (targetWithoutPy.endsWith('/' + moduleAsPath) ||
144
+ targetWithoutPy.endsWith('/' + moduleAsPath + '/__init__'));
145
+ }
146
+ /**
147
+ * Check if module appears after a single source directory prefix
148
+ */
149
+ function matchesWithSourcePrefix(moduleAsPath, targetWithoutPy) {
150
+ const moduleIndex = targetWithoutPy.indexOf(moduleAsPath);
151
+ if (moduleIndex < 0)
152
+ return false;
153
+ const prefix = targetWithoutPy.substring(0, moduleIndex);
154
+ const prefixSlashes = (prefix.match(/\//g) || []).length;
155
+ // Prefix should be empty or a single directory (e.g., "src/")
156
+ // The check for prefix === '' || prefix.endsWith('/') ensures we're at a directory boundary:
157
+ // - If prefix is empty, moduleIndex is 0 (start of string)
158
+ // - If prefix ends with '/', then it's a valid directory separator
159
+ return prefixSlashes <= 1 && (prefix === '' || prefix.endsWith('/'));
160
+ }
161
+ /**
162
+ * Checks if a Python dotted module path matches a file path.
163
+ *
164
+ * Python imports use dotted paths like "django.http" which should match:
165
+ * - django/http/__init__.py (package)
166
+ * - django/http/response.py (module within package)
167
+ * - django/http.py (direct module, less common)
168
+ *
169
+ * @param importPath - The import path (may contain dots)
170
+ * @param targetPath - The normalized file path
171
+ * @returns True if the Python module matches the file path
172
+ */
173
+ function matchesPythonModule(importPath, targetPath) {
174
+ // Only apply to Python-style dotted module identifiers (e.g., django.http.response)
175
+ // Excludes file paths (contain /), relative imports (start with .), and npm-style packages (lodash.get)
176
+ if (!/^[A-Za-z_]\w*(\.[A-Za-z_]\w*)+$/.test(importPath)) {
177
+ return false;
178
+ }
179
+ // Convert dotted path to slash path: django.http → django/http
180
+ const moduleAsPath = importPath.replace(/\./g, '/');
181
+ // Strip .py extension from target for comparison
182
+ const targetWithoutPy = targetPath.replace(/\.py$/, '');
183
+ // Try matching strategies in order of specificity
184
+ return (matchesDirectPythonModule(moduleAsPath, targetWithoutPy) ||
185
+ matchesParentPythonPackage(moduleAsPath, targetWithoutPy) ||
186
+ matchesSuffixPythonModule(moduleAsPath, targetWithoutPy) ||
187
+ matchesWithSourcePrefix(moduleAsPath, targetWithoutPy));
188
+ }
189
+ /**
190
+ * Checks if paths match using case-insensitive component matching.
191
+ *
192
+ * This handles PHP namespace imports where:
193
+ * - App/Models/User should match app/Models/User (case difference in first component)
194
+ * - Domain/Services/Auth should match web/Domain/Services/Auth (prefix in target)
195
+ *
196
+ * Also useful for case-insensitive file systems.
197
+ *
198
+ * @param importPath - The normalized import path
199
+ * @param targetPath - The normalized file path
200
+ * @returns True if paths match case-insensitively at component boundaries
201
+ */
202
+ function matchesPHPNamespace(importPath, targetPath) {
203
+ // Split into path components
204
+ const importComponents = importPath.split('/').filter(Boolean);
205
+ const targetComponents = targetPath.split('/').filter(Boolean);
206
+ // Need at least one component to match
207
+ if (importComponents.length === 0 || targetComponents.length === 0) {
208
+ return false;
209
+ }
210
+ // Match from the end, case-insensitively
211
+ // This handles prefixes like "web/app" matching "App"
212
+ let matched = 0;
213
+ for (let i = 1; i <= importComponents.length && i <= targetComponents.length; i++) {
214
+ const impComp = importComponents[importComponents.length - i].toLowerCase();
215
+ const targetComp = targetComponents[targetComponents.length - i].toLowerCase();
216
+ if (impComp === targetComp) {
217
+ matched++;
218
+ }
219
+ else {
220
+ break;
221
+ }
222
+ }
223
+ // All import components must match (from the end)
224
+ // This ensures App/Models/User matches web/app/Models/User but not app/Services/User
225
+ return matched === importComponents.length;
226
+ }
227
+ /**
228
+ * Gets a canonical path representation (relative to workspace, with extension).
229
+ *
230
+ * @param filepath - The file path to canonicalize
231
+ * @param workspaceRoot - The workspace root directory (normalized with forward slashes)
232
+ * @returns Canonical path
233
+ */
234
+ export function getCanonicalPath(filepath, workspaceRoot) {
235
+ let canonical = filepath.replace(/\\/g, '/');
236
+ if (canonical.startsWith(workspaceRoot + '/')) {
237
+ canonical = canonical.substring(workspaceRoot.length + 1);
238
+ }
239
+ return canonical;
240
+ }
241
+ /**
242
+ * Determines if a file is a test file based on naming conventions.
243
+ *
244
+ * Uses precise regex patterns to avoid false positives:
245
+ * - Files with .test. or .spec. extensions (e.g., foo.test.ts, bar.spec.js)
246
+ * - Files in test/, tests/, or __tests__/ directories
247
+ *
248
+ * Avoids false positives like:
249
+ * - contest.ts (contains ".test." but isn't a test)
250
+ * - latest/config.ts (contains "/test/" but isn't a test)
251
+ *
252
+ * @param filepath - The file path to check
253
+ * @returns True if the file is a test file
254
+ */
255
+ export function isTestFile(filepath) {
256
+ return (/\.(test|spec)\.[^/]+$/.test(filepath) || /(^|[/\\])(test|tests|__tests__)[/\\]/.test(filepath));
257
+ }
258
+ //# sourceMappingURL=path-matching.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-matching.js","sourceRoot":"","sources":["../../src/utils/path-matching.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Extract repository identifier from project root.
3
+ * Uses project name + path hash for stable, unique identification.
4
+ */
5
+ export declare function extractRepoId(projectRoot: string): string;
6
+ //# sourceMappingURL=repo-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-id.d.ts","sourceRoot":"","sources":["../../src/utils/repo-id.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAIzD"}
@@ -0,0 +1,12 @@
1
+ import crypto from 'crypto';
2
+ import path from 'path';
3
+ /**
4
+ * Extract repository identifier from project root.
5
+ * Uses project name + path hash for stable, unique identification.
6
+ */
7
+ export function extractRepoId(projectRoot) {
8
+ const projectName = path.basename(projectRoot);
9
+ const pathHash = crypto.createHash('md5').update(projectRoot).digest('hex').substring(0, 8);
10
+ return `${projectName}-${pathHash}`;
11
+ }
12
+ //# sourceMappingURL=repo-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-id.js","sourceRoot":"","sources":["../../src/utils/repo-id.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,WAAmB;IAC/C,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5F,OAAO,GAAG,WAAW,IAAI,QAAQ,EAAE,CAAC;AACtC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@liendev/parser",
3
+ "version": "0.39.0",
4
+ "description": "AST parsing, complexity analysis, and semantic chunking for Lien",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "typecheck": "tsc --noEmit",
18
+ "test": "vitest run",
19
+ "test:coverage": "vitest run --coverage"
20
+ },
21
+ "dependencies": {
22
+ "glob": "^10.5.0",
23
+ "ignore": "5.3.0",
24
+ "p-limit": "5.0.0",
25
+ "tree-sitter": "^0.25.0",
26
+ "tree-sitter-javascript": "0.23.1",
27
+ "tree-sitter-php": "^0.24.2",
28
+ "tree-sitter-python": "^0.25.0",
29
+ "tree-sitter-rust": "^0.24.0",
30
+ "tree-sitter-typescript": "0.23.2"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^20.0.0",
34
+ "typescript": "^5.3.0",
35
+ "vitest": "^4.0.8"
36
+ },
37
+ "files": [
38
+ "dist"
39
+ ],
40
+ "publishConfig": {
41
+ "access": "public",
42
+ "provenance": true
43
+ },
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "git+https://github.com/getlien/lien.git",
47
+ "directory": "packages/parser"
48
+ },
49
+ "homepage": "https://lien.dev",
50
+ "bugs": {
51
+ "url": "https://github.com/getlien/lien/issues"
52
+ },
53
+ "keywords": [
54
+ "ast",
55
+ "parser",
56
+ "code-analysis",
57
+ "complexity-analysis",
58
+ "tree-sitter",
59
+ "semantic-chunking"
60
+ ],
61
+ "author": "Alf Henderson",
62
+ "license": "AGPL-3.0-only",
63
+ "engines": {
64
+ "node": ">=22.21.0"
65
+ }
66
+ }