@openrewrite/rewrite 8.70.0-20251219-160440 → 8.70.0-20251219-215811

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 (94) hide show
  1. package/dist/cli/cli-utils.d.ts +6 -6
  2. package/dist/cli/cli-utils.d.ts.map +1 -1
  3. package/dist/cli/cli-utils.js +50 -228
  4. package/dist/cli/cli-utils.js.map +1 -1
  5. package/dist/javascript/assertions.d.ts.map +1 -1
  6. package/dist/javascript/assertions.js +87 -12
  7. package/dist/javascript/assertions.js.map +1 -1
  8. package/dist/javascript/autodetect.d.ts +11 -11
  9. package/dist/javascript/autodetect.d.ts.map +1 -1
  10. package/dist/javascript/autodetect.js +18 -21
  11. package/dist/javascript/autodetect.js.map +1 -1
  12. package/dist/javascript/format/prettier-config-loader.d.ts.map +1 -1
  13. package/dist/javascript/format/prettier-config-loader.js +1 -1
  14. package/dist/javascript/format/prettier-config-loader.js.map +1 -1
  15. package/dist/javascript/index.d.ts +1 -0
  16. package/dist/javascript/index.d.ts.map +1 -1
  17. package/dist/javascript/index.js +1 -0
  18. package/dist/javascript/index.js.map +1 -1
  19. package/dist/javascript/markers.d.ts.map +1 -1
  20. package/dist/javascript/markers.js +135 -6
  21. package/dist/javascript/markers.js.map +1 -1
  22. package/dist/javascript/node-resolution-result.d.ts +4 -1
  23. package/dist/javascript/node-resolution-result.d.ts.map +1 -1
  24. package/dist/javascript/node-resolution-result.js +22 -1
  25. package/dist/javascript/node-resolution-result.js.map +1 -1
  26. package/dist/javascript/package-json-parser.d.ts +7 -0
  27. package/dist/javascript/package-json-parser.d.ts.map +1 -1
  28. package/dist/javascript/package-json-parser.js +19 -1
  29. package/dist/javascript/package-json-parser.js.map +1 -1
  30. package/dist/javascript/parser.d.ts.map +1 -1
  31. package/dist/javascript/parser.js +1 -13
  32. package/dist/javascript/parser.js.map +1 -1
  33. package/dist/javascript/preconditions.js +4 -4
  34. package/dist/javascript/preconditions.js.map +1 -1
  35. package/dist/javascript/project-parser.d.ts +137 -0
  36. package/dist/javascript/project-parser.d.ts.map +1 -0
  37. package/dist/javascript/project-parser.js +726 -0
  38. package/dist/javascript/project-parser.js.map +1 -0
  39. package/dist/javascript/style.d.ts +9 -26
  40. package/dist/javascript/style.d.ts.map +1 -1
  41. package/dist/javascript/style.js +18 -42
  42. package/dist/javascript/style.js.map +1 -1
  43. package/dist/json/parser.d.ts.map +1 -1
  44. package/dist/json/parser.js +1 -0
  45. package/dist/json/parser.js.map +1 -1
  46. package/dist/markers.d.ts +1 -1
  47. package/dist/markers.js +1 -1
  48. package/dist/markers.js.map +1 -1
  49. package/dist/parser.d.ts +1 -1
  50. package/dist/parser.d.ts.map +1 -1
  51. package/dist/rpc/index.d.ts +0 -1
  52. package/dist/rpc/index.d.ts.map +1 -1
  53. package/dist/rpc/index.js +4 -2
  54. package/dist/rpc/index.js.map +1 -1
  55. package/dist/rpc/request/index.d.ts +1 -0
  56. package/dist/rpc/request/index.d.ts.map +1 -1
  57. package/dist/rpc/request/index.js +1 -0
  58. package/dist/rpc/request/index.js.map +1 -1
  59. package/dist/rpc/request/parse-project.d.ts +25 -0
  60. package/dist/rpc/request/parse-project.d.ts.map +1 -0
  61. package/dist/rpc/request/parse-project.js +304 -0
  62. package/dist/rpc/request/parse-project.js.map +1 -0
  63. package/dist/rpc/rewrite-rpc.d.ts.map +1 -1
  64. package/dist/rpc/rewrite-rpc.js +1 -0
  65. package/dist/rpc/rewrite-rpc.js.map +1 -1
  66. package/dist/text/parser.d.ts.map +1 -1
  67. package/dist/text/parser.js +1 -0
  68. package/dist/text/parser.js.map +1 -1
  69. package/dist/version.txt +1 -1
  70. package/dist/yaml/parser.d.ts.map +1 -1
  71. package/dist/yaml/parser.js +52 -4
  72. package/dist/yaml/parser.js.map +1 -1
  73. package/package.json +1 -1
  74. package/src/cli/cli-utils.ts +46 -237
  75. package/src/javascript/assertions.ts +74 -10
  76. package/src/javascript/autodetect.ts +22 -15
  77. package/src/javascript/format/prettier-config-loader.ts +2 -2
  78. package/src/javascript/index.ts +1 -0
  79. package/src/javascript/markers.ts +157 -7
  80. package/src/javascript/node-resolution-result.ts +23 -2
  81. package/src/javascript/package-json-parser.ts +19 -1
  82. package/src/javascript/parser.ts +1 -16
  83. package/src/javascript/preconditions.ts +1 -1
  84. package/src/javascript/project-parser.ts +657 -0
  85. package/src/javascript/style.ts +43 -28
  86. package/src/json/parser.ts +3 -1
  87. package/src/markers.ts +1 -1
  88. package/src/parser.ts +1 -1
  89. package/src/rpc/index.ts +7 -5
  90. package/src/rpc/request/index.ts +1 -0
  91. package/src/rpc/request/parse-project.ts +283 -0
  92. package/src/rpc/rewrite-rpc.ts +2 -0
  93. package/src/text/parser.ts +3 -1
  94. package/src/yaml/parser.ts +53 -5
@@ -0,0 +1,726 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
+ return new (P || (P = Promise))(function (resolve, reject) {
38
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
42
+ });
43
+ };
44
+ var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
45
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
46
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
47
+ var m = o[Symbol.asyncIterator], i;
48
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
49
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
50
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
51
+ };
52
+ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
53
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
54
+ var g = generator.apply(thisArg, _arguments || []), i, q = [];
55
+ return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
56
+ function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
57
+ function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
58
+ function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
59
+ function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
60
+ function fulfill(value) { resume("next", value); }
61
+ function reject(value) { resume("throw", value); }
62
+ function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
63
+ };
64
+ var __importDefault = (this && this.__importDefault) || function (mod) {
65
+ return (mod && mod.__esModule) ? mod : { "default": mod };
66
+ };
67
+ Object.defineProperty(exports, "__esModule", { value: true });
68
+ exports.ProjectParser = exports.DEFAULT_EXCLUSIONS = void 0;
69
+ /*
70
+ * Copyright 2025 the original author or authors.
71
+ * <p>
72
+ * Licensed under the Moderne Source Available License (the "License");
73
+ * you may not use this file except in compliance with the License.
74
+ * You may obtain a copy of the License at
75
+ * <p>
76
+ * https://docs.moderne.io/licensing/moderne-source-available-license
77
+ * <p>
78
+ * Unless required by applicable law or agreed to in writing, software
79
+ * distributed under the License is distributed on an "AS IS" BASIS,
80
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81
+ * See the License for the specific language governing permissions and
82
+ * limitations under the License.
83
+ */
84
+ const path = __importStar(require("path"));
85
+ const fs = __importStar(require("fs"));
86
+ const fsp = __importStar(require("fs/promises"));
87
+ const child_process_1 = require("child_process");
88
+ const picomatch_1 = __importDefault(require("picomatch"));
89
+ const immer_1 = require("immer");
90
+ const parser_1 = require("../parser");
91
+ const prettier_config_loader_1 = require("./format/prettier-config-loader");
92
+ const execution_1 = require("../execution");
93
+ // Lock file names defined here to avoid circular dependency with package-manager.ts
94
+ // These must be kept in sync with the definitions in package-manager.ts
95
+ const JSON_LOCK_FILE_NAMES = ['bun.lock', 'package-lock.json'];
96
+ const YAML_LOCK_FILE_NAMES = ['pnpm-lock.yaml'];
97
+ const TEXT_LOCK_FILE_NAMES = ['yarn.lock'];
98
+ /**
99
+ * Detects if a yarn.lock file is Yarn Berry (v2+) format based on content.
100
+ * Yarn Berry lock files contain a `__metadata:` key which is not present in Classic.
101
+ */
102
+ function isYarnBerryLockFile(content) {
103
+ return content.includes('__metadata:');
104
+ }
105
+ /**
106
+ * Default exclusion patterns for file discovery.
107
+ */
108
+ exports.DEFAULT_EXCLUSIONS = [
109
+ "**/node_modules/**",
110
+ "**/dist/**",
111
+ "**/build/**",
112
+ "**/.git/**",
113
+ "**/coverage/**",
114
+ "**/*.min.js",
115
+ "**/*.bundle.js"
116
+ ];
117
+ /**
118
+ * Source file extensions for JavaScript/TypeScript.
119
+ */
120
+ const SOURCE_EXTENSIONS = new Set([
121
+ ".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs", ".mts", ".cts"
122
+ ]);
123
+ /**
124
+ * All lock file names for quick lookup.
125
+ */
126
+ const ALL_LOCK_FILE_NAMES = new Set([
127
+ ...JSON_LOCK_FILE_NAMES,
128
+ ...YAML_LOCK_FILE_NAMES,
129
+ ...TEXT_LOCK_FILE_NAMES
130
+ ]);
131
+ /**
132
+ * Plain text config files (no extension).
133
+ */
134
+ const TEXT_CONFIG_FILES = new Set([
135
+ ".prettierignore",
136
+ ".gitignore",
137
+ ".npmignore",
138
+ ".eslintignore"
139
+ ]);
140
+ /**
141
+ * Parses an entire JavaScript/TypeScript project.
142
+ *
143
+ * This class handles:
144
+ * - File discovery (source files, package.json, lock files)
145
+ * - Prettier configuration detection (once per project)
146
+ * - Parsing all files with appropriate parsers
147
+ * - Sharing PrettierConfigLoader across all JavaScript parsers
148
+ *
149
+ * Can be used directly for CLI tools or wrapped by RPC handlers.
150
+ */
151
+ class ProjectParser {
152
+ constructor(projectPath, options = {}) {
153
+ var _a, _b, _c, _d;
154
+ this.projectPath = path.resolve(projectPath);
155
+ this.exclusions = (_a = options.exclusions) !== null && _a !== void 0 ? _a : exports.DEFAULT_EXCLUSIONS;
156
+ this.ctx = (_b = options.ctx) !== null && _b !== void 0 ? _b : new execution_1.ExecutionContext();
157
+ this.useGit = (_c = options.useGit) !== null && _c !== void 0 ? _c : this.isGitRepository();
158
+ this.onProgress = options.onProgress;
159
+ this.verbose = (_d = options.verbose) !== null && _d !== void 0 ? _d : false;
160
+ this.fileFilter = options.fileFilter;
161
+ }
162
+ /**
163
+ * Creates and initializes a PrettierConfigLoader for this project.
164
+ * Use this when you need to handle Prettier detection separately from parsing.
165
+ */
166
+ createPrettierLoader() {
167
+ return __awaiter(this, void 0, void 0, function* () {
168
+ this.log("Detecting Prettier configuration...");
169
+ const prettierLoader = new prettier_config_loader_1.PrettierConfigLoader(this.projectPath);
170
+ yield prettierLoader.detectPrettier();
171
+ return prettierLoader;
172
+ });
173
+ }
174
+ /**
175
+ * Builds an Autodetect marker from the given source files.
176
+ * Samples all files to detect common formatting styles.
177
+ * Uses dynamic import to avoid circular dependencies.
178
+ */
179
+ buildAutodetectMarker(sourceFiles) {
180
+ return __awaiter(this, void 0, void 0, function* () {
181
+ // Dynamic import to break circular dependency at module load time:
182
+ // parse-project.ts → project-parser.ts → autodetect.ts → visitor.ts → java → rpc → parse-project.ts
183
+ // By deferring the import until runtime, all modules are already loaded when this executes.
184
+ const { Autodetect } = yield import("./autodetect.js");
185
+ const { JS } = yield import("./tree.js");
186
+ const detector = Autodetect.detector();
187
+ for (const sf of sourceFiles) {
188
+ if (sf.kind === JS.Kind.CompilationUnit) {
189
+ yield detector.sample(sf);
190
+ }
191
+ }
192
+ return detector.build();
193
+ });
194
+ }
195
+ /**
196
+ * Parses all source files in the project.
197
+ * Yields source files as they are parsed.
198
+ */
199
+ parse() {
200
+ return __asyncGenerator(this, arguments, function* parse_1() {
201
+ var _a, e_1, _b, _c, _d, e_2, _e, _f, _g, e_3, _h, _j, _k, e_4, _l, _m, _o, e_5, _p, _q, _r, e_6, _s, _t, _u, e_7, _v, _w, _x, e_8, _y, _z, _0, e_9, _1, _2;
202
+ var _3, _4, _5, _6, _7, _8, _9, _10, _11, _12;
203
+ // Discover files
204
+ this.log("Discovering files...");
205
+ (_3 = this.onProgress) === null || _3 === void 0 ? void 0 : _3.call(this, "discovering", 0, 0);
206
+ let discovered = yield __await(this.discoverFiles());
207
+ // Apply file filter if provided
208
+ if (this.fileFilter) {
209
+ discovered = this.applyFileFilter(discovered);
210
+ }
211
+ const totalFiles = this.countFiles(discovered);
212
+ this.log(`Found ${totalFiles} files to parse`);
213
+ // Detect Prettier configuration once for the project
214
+ const prettierLoader = yield __await(this.createPrettierLoader());
215
+ let current = 0;
216
+ // Parse package.json files first (they get NodeResolutionResult markers)
217
+ if (discovered.packageJsonFiles.length > 0) {
218
+ this.log(`Parsing ${discovered.packageJsonFiles.length} package.json files...`);
219
+ const parser = parser_1.Parsers.createParser("packageJson", {
220
+ ctx: this.ctx,
221
+ relativeTo: this.projectPath
222
+ });
223
+ try {
224
+ for (var _13 = true, _14 = __asyncValues(parser.parse(...discovered.packageJsonFiles)), _15; _15 = yield __await(_14.next()), _a = _15.done, !_a; _13 = true) {
225
+ _c = _15.value;
226
+ _13 = false;
227
+ const sf = _c;
228
+ current++;
229
+ (_4 = this.onProgress) === null || _4 === void 0 ? void 0 : _4.call(this, "parsing", current, totalFiles, sf.sourcePath);
230
+ yield yield __await(sf);
231
+ }
232
+ }
233
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
234
+ finally {
235
+ try {
236
+ if (!_13 && !_a && (_b = _14.return)) yield __await(_b.call(_14));
237
+ }
238
+ finally { if (e_1) throw e_1.error; }
239
+ }
240
+ }
241
+ // Parse JSON lock files
242
+ if (discovered.lockFiles.json.length > 0) {
243
+ this.log(`Parsing ${discovered.lockFiles.json.length} JSON lock files...`);
244
+ const parser = parser_1.Parsers.createParser("json", {
245
+ ctx: this.ctx,
246
+ relativeTo: this.projectPath
247
+ });
248
+ try {
249
+ for (var _16 = true, _17 = __asyncValues(parser.parse(...discovered.lockFiles.json)), _18; _18 = yield __await(_17.next()), _d = _18.done, !_d; _16 = true) {
250
+ _f = _18.value;
251
+ _16 = false;
252
+ const sf = _f;
253
+ current++;
254
+ (_5 = this.onProgress) === null || _5 === void 0 ? void 0 : _5.call(this, "parsing", current, totalFiles, sf.sourcePath);
255
+ yield yield __await(sf);
256
+ }
257
+ }
258
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
259
+ finally {
260
+ try {
261
+ if (!_16 && !_d && (_e = _17.return)) yield __await(_e.call(_17));
262
+ }
263
+ finally { if (e_2) throw e_2.error; }
264
+ }
265
+ }
266
+ // Parse YAML lock files
267
+ if (discovered.lockFiles.yaml.length > 0) {
268
+ this.log(`Parsing ${discovered.lockFiles.yaml.length} YAML lock files...`);
269
+ const parser = parser_1.Parsers.createParser("yaml", {
270
+ ctx: this.ctx,
271
+ relativeTo: this.projectPath
272
+ });
273
+ try {
274
+ for (var _19 = true, _20 = __asyncValues(parser.parse(...discovered.lockFiles.yaml)), _21; _21 = yield __await(_20.next()), _g = _21.done, !_g; _19 = true) {
275
+ _j = _21.value;
276
+ _19 = false;
277
+ const sf = _j;
278
+ current++;
279
+ (_6 = this.onProgress) === null || _6 === void 0 ? void 0 : _6.call(this, "parsing", current, totalFiles, sf.sourcePath);
280
+ yield yield __await(sf);
281
+ }
282
+ }
283
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
284
+ finally {
285
+ try {
286
+ if (!_19 && !_g && (_h = _20.return)) yield __await(_h.call(_20));
287
+ }
288
+ finally { if (e_3) throw e_3.error; }
289
+ }
290
+ }
291
+ // Parse text lock files (yarn.lock Classic)
292
+ if (discovered.lockFiles.text.length > 0) {
293
+ this.log(`Parsing ${discovered.lockFiles.text.length} text lock files...`);
294
+ const parser = parser_1.Parsers.createParser("plainText", {
295
+ ctx: this.ctx,
296
+ relativeTo: this.projectPath
297
+ });
298
+ try {
299
+ for (var _22 = true, _23 = __asyncValues(parser.parse(...discovered.lockFiles.text)), _24; _24 = yield __await(_23.next()), _k = _24.done, !_k; _22 = true) {
300
+ _m = _24.value;
301
+ _22 = false;
302
+ const sf = _m;
303
+ current++;
304
+ (_7 = this.onProgress) === null || _7 === void 0 ? void 0 : _7.call(this, "parsing", current, totalFiles, sf.sourcePath);
305
+ yield yield __await(sf);
306
+ }
307
+ }
308
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
309
+ finally {
310
+ try {
311
+ if (!_22 && !_k && (_l = _23.return)) yield __await(_l.call(_23));
312
+ }
313
+ finally { if (e_4) throw e_4.error; }
314
+ }
315
+ }
316
+ // Parse JavaScript/TypeScript source files
317
+ if (discovered.jsFiles.length > 0) {
318
+ this.log(`Parsing ${discovered.jsFiles.length} JavaScript/TypeScript files...`);
319
+ const parser = parser_1.Parsers.createParser("javascript", {
320
+ ctx: this.ctx,
321
+ relativeTo: this.projectPath
322
+ });
323
+ // Check if Prettier is available
324
+ const detection = yield __await(prettierLoader.detectPrettier());
325
+ if (detection.available) {
326
+ try {
327
+ // Prettier is available: add per-file PrettierStyle markers
328
+ for (var _25 = true, _26 = __asyncValues(parser.parse(...discovered.jsFiles)), _27; _27 = yield __await(_26.next()), _o = _27.done, !_o; _25 = true) {
329
+ _q = _27.value;
330
+ _25 = false;
331
+ const sf = _q;
332
+ current++;
333
+ (_8 = this.onProgress) === null || _8 === void 0 ? void 0 : _8.call(this, "parsing", current, totalFiles, sf.sourcePath);
334
+ const prettierMarker = yield __await(prettierLoader.getConfigMarker(path.join(this.projectPath, sf.sourcePath)));
335
+ if (prettierMarker) {
336
+ yield yield __await((0, immer_1.produce)(sf, draft => {
337
+ draft.markers.markers = draft.markers.markers.concat([prettierMarker]);
338
+ }));
339
+ }
340
+ else {
341
+ yield yield __await(sf);
342
+ }
343
+ }
344
+ }
345
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
346
+ finally {
347
+ try {
348
+ if (!_25 && !_o && (_p = _26.return)) yield __await(_p.call(_26));
349
+ }
350
+ finally { if (e_5) throw e_5.error; }
351
+ }
352
+ }
353
+ else {
354
+ // Prettier is NOT available: auto-detect styles from parsed files
355
+ this.log("Prettier not found, auto-detecting styles...");
356
+ // Dynamic import to break circular dependency at module load time
357
+ // (see buildAutodetectMarker for explanation)
358
+ const { Autodetect } = yield __await(import("./autodetect.js"));
359
+ const { JS } = yield __await(import("./tree.js"));
360
+ const parsedFiles = [];
361
+ try {
362
+ // Parse all JS files and collect them for sampling
363
+ for (var _28 = true, _29 = __asyncValues(parser.parse(...discovered.jsFiles)), _30; _30 = yield __await(_29.next()), _r = _30.done, !_r; _28 = true) {
364
+ _t = _30.value;
365
+ _28 = false;
366
+ const sf = _t;
367
+ current++;
368
+ (_9 = this.onProgress) === null || _9 === void 0 ? void 0 : _9.call(this, "parsing", current, totalFiles, sf.sourcePath);
369
+ if (sf.kind === JS.Kind.CompilationUnit) {
370
+ parsedFiles.push(sf);
371
+ }
372
+ }
373
+ }
374
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
375
+ finally {
376
+ try {
377
+ if (!_28 && !_r && (_s = _29.return)) yield __await(_s.call(_29));
378
+ }
379
+ finally { if (e_6) throw e_6.error; }
380
+ }
381
+ // Sample all parsed files and build Autodetect marker
382
+ const detector = Autodetect.detector();
383
+ for (const sf of parsedFiles) {
384
+ yield __await(detector.sample(sf));
385
+ }
386
+ const autodetectMarker = detector.build();
387
+ this.log(`Auto-detected styles: indent=${detector.getTabsAndIndentsStyle().indentSize}, ` +
388
+ `useTabs=${detector.getTabsAndIndentsStyle().useTabCharacter}`);
389
+ // Yield all files with the Autodetect marker
390
+ for (const sf of parsedFiles) {
391
+ yield yield __await((0, immer_1.produce)(sf, draft => {
392
+ draft.markers.markers = draft.markers.markers.concat([autodetectMarker]);
393
+ }));
394
+ }
395
+ }
396
+ }
397
+ // Parse other YAML files
398
+ if (discovered.yamlFiles.length > 0) {
399
+ this.log(`Parsing ${discovered.yamlFiles.length} YAML files...`);
400
+ const parser = parser_1.Parsers.createParser("yaml", {
401
+ ctx: this.ctx,
402
+ relativeTo: this.projectPath
403
+ });
404
+ try {
405
+ for (var _31 = true, _32 = __asyncValues(parser.parse(...discovered.yamlFiles)), _33; _33 = yield __await(_32.next()), _u = _33.done, !_u; _31 = true) {
406
+ _w = _33.value;
407
+ _31 = false;
408
+ const sf = _w;
409
+ current++;
410
+ (_10 = this.onProgress) === null || _10 === void 0 ? void 0 : _10.call(this, "parsing", current, totalFiles, sf.sourcePath);
411
+ yield yield __await(sf);
412
+ }
413
+ }
414
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
415
+ finally {
416
+ try {
417
+ if (!_31 && !_u && (_v = _32.return)) yield __await(_v.call(_32));
418
+ }
419
+ finally { if (e_7) throw e_7.error; }
420
+ }
421
+ }
422
+ // Parse other JSON files
423
+ if (discovered.jsonFiles.length > 0) {
424
+ this.log(`Parsing ${discovered.jsonFiles.length} JSON files...`);
425
+ const parser = parser_1.Parsers.createParser("json", {
426
+ ctx: this.ctx,
427
+ relativeTo: this.projectPath
428
+ });
429
+ try {
430
+ for (var _34 = true, _35 = __asyncValues(parser.parse(...discovered.jsonFiles)), _36; _36 = yield __await(_35.next()), _x = _36.done, !_x; _34 = true) {
431
+ _z = _36.value;
432
+ _34 = false;
433
+ const sf = _z;
434
+ current++;
435
+ (_11 = this.onProgress) === null || _11 === void 0 ? void 0 : _11.call(this, "parsing", current, totalFiles, sf.sourcePath);
436
+ yield yield __await(sf);
437
+ }
438
+ }
439
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
440
+ finally {
441
+ try {
442
+ if (!_34 && !_x && (_y = _35.return)) yield __await(_y.call(_35));
443
+ }
444
+ finally { if (e_8) throw e_8.error; }
445
+ }
446
+ }
447
+ // Parse text config files (.prettierignore, .gitignore, etc.)
448
+ if (discovered.textFiles.length > 0) {
449
+ this.log(`Parsing ${discovered.textFiles.length} text config files...`);
450
+ const parser = parser_1.Parsers.createParser("plainText", {
451
+ ctx: this.ctx,
452
+ relativeTo: this.projectPath
453
+ });
454
+ try {
455
+ for (var _37 = true, _38 = __asyncValues(parser.parse(...discovered.textFiles)), _39; _39 = yield __await(_38.next()), _0 = _39.done, !_0; _37 = true) {
456
+ _2 = _39.value;
457
+ _37 = false;
458
+ const sf = _2;
459
+ current++;
460
+ (_12 = this.onProgress) === null || _12 === void 0 ? void 0 : _12.call(this, "parsing", current, totalFiles, sf.sourcePath);
461
+ yield yield __await(sf);
462
+ }
463
+ }
464
+ catch (e_9_1) { e_9 = { error: e_9_1 }; }
465
+ finally {
466
+ try {
467
+ if (!_37 && !_0 && (_1 = _38.return)) yield __await(_1.call(_38));
468
+ }
469
+ finally { if (e_9) throw e_9.error; }
470
+ }
471
+ }
472
+ });
473
+ }
474
+ /**
475
+ * Discovers all files in the project that should be parsed.
476
+ */
477
+ discoverFiles() {
478
+ return __awaiter(this, void 0, void 0, function* () {
479
+ const discovered = {
480
+ packageJsonFiles: [],
481
+ lockFiles: {
482
+ json: [],
483
+ yaml: [],
484
+ text: []
485
+ },
486
+ jsFiles: [],
487
+ jsonFiles: [],
488
+ yamlFiles: [],
489
+ textFiles: []
490
+ };
491
+ let files;
492
+ if (this.useGit) {
493
+ files = yield this.discoverFilesWithGit();
494
+ }
495
+ else {
496
+ files = yield this.discoverFilesWithWalk();
497
+ }
498
+ // Classify files
499
+ const yarnLockFiles = [];
500
+ for (const file of files) {
501
+ const basename = path.basename(file);
502
+ const ext = path.extname(file).toLowerCase();
503
+ if (basename === "package.json") {
504
+ discovered.packageJsonFiles.push(file);
505
+ }
506
+ else if (SOURCE_EXTENSIONS.has(ext)) {
507
+ discovered.jsFiles.push(file);
508
+ }
509
+ else if (JSON_LOCK_FILE_NAMES.includes(basename)) {
510
+ discovered.lockFiles.json.push(file);
511
+ }
512
+ else if (basename === "yarn.lock") {
513
+ // yarn.lock needs content-based classification
514
+ yarnLockFiles.push(file);
515
+ }
516
+ else if (YAML_LOCK_FILE_NAMES.includes(basename)) {
517
+ discovered.lockFiles.yaml.push(file);
518
+ }
519
+ else if (TEXT_LOCK_FILE_NAMES.includes(basename)) {
520
+ discovered.lockFiles.text.push(file);
521
+ }
522
+ else if (ext === ".json") {
523
+ discovered.jsonFiles.push(file);
524
+ }
525
+ else if (ext === ".yaml" || ext === ".yml") {
526
+ discovered.yamlFiles.push(file);
527
+ }
528
+ else if (TEXT_CONFIG_FILES.has(basename)) {
529
+ discovered.textFiles.push(file);
530
+ }
531
+ }
532
+ // Classify yarn.lock files by content
533
+ for (const yarnLockPath of yarnLockFiles) {
534
+ const format = yield this.classifyYarnLockFile(yarnLockPath);
535
+ if (format === "yaml") {
536
+ discovered.lockFiles.yaml.push(yarnLockPath);
537
+ }
538
+ else {
539
+ discovered.lockFiles.text.push(yarnLockPath);
540
+ }
541
+ }
542
+ return discovered;
543
+ });
544
+ }
545
+ /**
546
+ * Discovers files using git ls-files (respects .gitignore).
547
+ */
548
+ discoverFilesWithGit() {
549
+ return __awaiter(this, void 0, void 0, function* () {
550
+ const files = [];
551
+ // Get tracked files
552
+ const tracked = (0, child_process_1.spawnSync)("git", ["ls-files"], {
553
+ cwd: this.projectPath,
554
+ encoding: "utf8"
555
+ });
556
+ if (tracked.status !== 0 || tracked.error) {
557
+ // Fall back to walk if git fails
558
+ return this.discoverFilesWithWalk();
559
+ }
560
+ if (tracked.stdout) {
561
+ for (const line of tracked.stdout.split("\n")) {
562
+ const trimmed = line.trim();
563
+ if (trimmed) {
564
+ const fullPath = path.join(this.projectPath, trimmed);
565
+ // git ls-files can return deleted files that are still tracked
566
+ if (fs.existsSync(fullPath)) {
567
+ files.push(fullPath);
568
+ }
569
+ }
570
+ }
571
+ }
572
+ // Get untracked but not ignored files
573
+ const untracked = (0, child_process_1.spawnSync)("git", ["ls-files", "--others", "--exclude-standard"], {
574
+ cwd: this.projectPath,
575
+ encoding: "utf8"
576
+ });
577
+ if (untracked.stdout) {
578
+ for (const line of untracked.stdout.split("\n")) {
579
+ const trimmed = line.trim();
580
+ if (trimmed) {
581
+ // Untracked files should exist, but check anyway for robustness
582
+ const fullPath = path.join(this.projectPath, trimmed);
583
+ if (fs.existsSync(fullPath)) {
584
+ files.push(fullPath);
585
+ }
586
+ }
587
+ }
588
+ }
589
+ // Filter by our exclusion patterns and accepted file types
590
+ return files.filter(file => this.isAcceptedFile(file));
591
+ });
592
+ }
593
+ /**
594
+ * Discovers files by walking the directory tree.
595
+ */
596
+ discoverFilesWithWalk() {
597
+ return __awaiter(this, void 0, void 0, function* () {
598
+ const files = [];
599
+ const isExcluded = (0, picomatch_1.default)(this.exclusions);
600
+ const walk = (dir_1, ...args_1) => __awaiter(this, [dir_1, ...args_1], void 0, function* (dir, relativePath = "") {
601
+ let entries;
602
+ try {
603
+ entries = yield fsp.readdir(dir, { withFileTypes: true });
604
+ }
605
+ catch (_a) {
606
+ return;
607
+ }
608
+ for (const entry of entries) {
609
+ const fullPath = path.join(dir, entry.name);
610
+ const relPath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
611
+ // Check exclusion patterns
612
+ if (isExcluded(relPath) || isExcluded(`${relPath}/`)) {
613
+ continue;
614
+ }
615
+ // Always skip node_modules
616
+ if (entry.name === "node_modules") {
617
+ continue;
618
+ }
619
+ if (entry.isDirectory()) {
620
+ yield walk(fullPath, relPath);
621
+ }
622
+ else if (entry.isFile() && this.isAcceptedFile(fullPath)) {
623
+ files.push(fullPath);
624
+ }
625
+ }
626
+ });
627
+ yield walk(this.projectPath);
628
+ return files;
629
+ });
630
+ }
631
+ /**
632
+ * Checks if a file should be accepted for parsing.
633
+ */
634
+ isAcceptedFile(filePath) {
635
+ const basename = path.basename(filePath);
636
+ const ext = path.extname(filePath).toLowerCase();
637
+ // Check exclusion patterns with relative path
638
+ const relativePath = path.relative(this.projectPath, filePath);
639
+ const isExcluded = (0, picomatch_1.default)(this.exclusions);
640
+ if (isExcluded(relativePath)) {
641
+ return false;
642
+ }
643
+ // JavaScript/TypeScript files
644
+ if (SOURCE_EXTENSIONS.has(ext)) {
645
+ return true;
646
+ }
647
+ // JSON files
648
+ if (ext === ".json") {
649
+ return true;
650
+ }
651
+ // YAML files
652
+ if (ext === ".yaml" || ext === ".yml") {
653
+ return true;
654
+ }
655
+ // Lock files (some have non-standard extensions)
656
+ if (ALL_LOCK_FILE_NAMES.has(basename)) {
657
+ return true;
658
+ }
659
+ // Text config files
660
+ if (TEXT_CONFIG_FILES.has(basename)) {
661
+ return true;
662
+ }
663
+ return false;
664
+ }
665
+ /**
666
+ * Classifies a yarn.lock file as YAML (Berry) or text (Classic).
667
+ */
668
+ classifyYarnLockFile(filePath) {
669
+ return __awaiter(this, void 0, void 0, function* () {
670
+ try {
671
+ const content = yield fsp.readFile(filePath, "utf-8");
672
+ return isYarnBerryLockFile(content) ? "yaml" : "text";
673
+ }
674
+ catch (_a) {
675
+ return "text";
676
+ }
677
+ });
678
+ }
679
+ /**
680
+ * Checks if the project is a git repository.
681
+ */
682
+ isGitRepository() {
683
+ return fs.existsSync(path.join(this.projectPath, ".git"));
684
+ }
685
+ /**
686
+ * Counts total files to parse.
687
+ */
688
+ countFiles(discovered) {
689
+ return (discovered.packageJsonFiles.length +
690
+ discovered.lockFiles.json.length +
691
+ discovered.lockFiles.yaml.length +
692
+ discovered.lockFiles.text.length +
693
+ discovered.jsFiles.length +
694
+ discovered.jsonFiles.length +
695
+ discovered.yamlFiles.length +
696
+ discovered.textFiles.length);
697
+ }
698
+ /**
699
+ * Applies the file filter to discovered files.
700
+ */
701
+ applyFileFilter(discovered) {
702
+ const filter = this.fileFilter;
703
+ return {
704
+ packageJsonFiles: discovered.packageJsonFiles.filter(filter),
705
+ lockFiles: {
706
+ json: discovered.lockFiles.json.filter(filter),
707
+ yaml: discovered.lockFiles.yaml.filter(filter),
708
+ text: discovered.lockFiles.text.filter(filter)
709
+ },
710
+ jsFiles: discovered.jsFiles.filter(filter),
711
+ jsonFiles: discovered.jsonFiles.filter(filter),
712
+ yamlFiles: discovered.yamlFiles.filter(filter),
713
+ textFiles: discovered.textFiles.filter(filter)
714
+ };
715
+ }
716
+ /**
717
+ * Logs a message if verbose mode is enabled.
718
+ */
719
+ log(message) {
720
+ if (this.verbose) {
721
+ console.log(message);
722
+ }
723
+ }
724
+ }
725
+ exports.ProjectParser = ProjectParser;
726
+ //# sourceMappingURL=project-parser.js.map