@openrewrite/rewrite 8.69.0-20251207-160255 → 8.69.0-20251207-214914

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 (68) hide show
  1. package/dist/cli/cli-utils.d.ts.map +1 -1
  2. package/dist/cli/cli-utils.js +3 -2
  3. package/dist/cli/cli-utils.js.map +1 -1
  4. package/dist/cli/rewrite.js +2 -1
  5. package/dist/cli/rewrite.js.map +1 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +3 -2
  8. package/dist/index.js.map +1 -1
  9. package/dist/javascript/add-import.d.ts.map +1 -1
  10. package/dist/javascript/add-import.js +99 -56
  11. package/dist/javascript/add-import.js.map +1 -1
  12. package/dist/javascript/parser.d.ts.map +1 -1
  13. package/dist/javascript/parser.js +48 -8
  14. package/dist/javascript/parser.js.map +1 -1
  15. package/dist/javascript/recipes/async-callback-in-sync-array-method.d.ts +40 -0
  16. package/dist/javascript/recipes/async-callback-in-sync-array-method.d.ts.map +1 -0
  17. package/dist/javascript/recipes/async-callback-in-sync-array-method.js +232 -0
  18. package/dist/javascript/recipes/async-callback-in-sync-array-method.js.map +1 -0
  19. package/dist/javascript/recipes/change-import.d.ts +51 -0
  20. package/dist/javascript/recipes/change-import.d.ts.map +1 -0
  21. package/dist/javascript/recipes/change-import.js +658 -0
  22. package/dist/javascript/recipes/change-import.js.map +1 -0
  23. package/dist/javascript/recipes/index.d.ts +3 -0
  24. package/dist/javascript/recipes/index.d.ts.map +1 -1
  25. package/dist/javascript/recipes/index.js +3 -0
  26. package/dist/javascript/recipes/index.js.map +1 -1
  27. package/dist/javascript/recipes/order-imports.d.ts +10 -0
  28. package/dist/javascript/recipes/order-imports.d.ts.map +1 -0
  29. package/dist/javascript/recipes/order-imports.js +240 -0
  30. package/dist/javascript/recipes/order-imports.js.map +1 -0
  31. package/dist/javascript/templating/index.d.ts +1 -1
  32. package/dist/javascript/templating/index.d.ts.map +1 -1
  33. package/dist/javascript/templating/index.js +2 -1
  34. package/dist/javascript/templating/index.js.map +1 -1
  35. package/dist/javascript/templating/rewrite.d.ts +36 -2
  36. package/dist/javascript/templating/rewrite.d.ts.map +1 -1
  37. package/dist/javascript/templating/rewrite.js +76 -0
  38. package/dist/javascript/templating/rewrite.js.map +1 -1
  39. package/dist/json/parser.js +78 -30
  40. package/dist/json/parser.js.map +1 -1
  41. package/dist/run.d.ts.map +1 -1
  42. package/dist/run.js +7 -4
  43. package/dist/run.js.map +1 -1
  44. package/dist/version.txt +1 -1
  45. package/package.json +1 -1
  46. package/src/cli/cli-utils.ts +3 -2
  47. package/src/cli/rewrite.ts +2 -1
  48. package/src/index.ts +3 -2
  49. package/src/javascript/add-import.ts +125 -69
  50. package/src/javascript/parser.ts +49 -8
  51. package/src/javascript/recipes/async-callback-in-sync-array-method.ts +237 -0
  52. package/src/javascript/recipes/change-import.ts +700 -0
  53. package/src/javascript/recipes/index.ts +3 -0
  54. package/src/javascript/recipes/order-imports.ts +242 -0
  55. package/src/javascript/templating/index.ts +2 -1
  56. package/src/javascript/templating/rewrite.ts +89 -4
  57. package/src/json/parser.ts +69 -24
  58. package/src/run.ts +5 -4
  59. package/dist/recipe/index.d.ts +0 -2
  60. package/dist/recipe/index.d.ts.map +0 -1
  61. package/dist/recipe/index.js +0 -21
  62. package/dist/recipe/index.js.map +0 -1
  63. package/dist/recipe/order-imports.d.ts +0 -10
  64. package/dist/recipe/order-imports.d.ts.map +0 -1
  65. package/dist/recipe/order-imports.js +0 -213
  66. package/dist/recipe/order-imports.js.map +0 -1
  67. package/src/recipe/index.ts +0 -17
  68. package/src/recipe/order-imports.ts +0 -195
@@ -0,0 +1,658 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright 2025 the original author or authors.
4
+ * <p>
5
+ * Licensed under the Moderne Source Available License (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ * <p>
9
+ * https://docs.moderne.io/licensing/moderne-source-available-license
10
+ * <p>
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
18
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
19
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
20
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
21
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
22
+ };
23
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
24
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
25
+ return new (P || (P = Promise))(function (resolve, reject) {
26
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
27
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
28
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
29
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
30
+ });
31
+ };
32
+ Object.defineProperty(exports, "__esModule", { value: true });
33
+ exports.ChangeImport = void 0;
34
+ const recipe_1 = require("../../recipe");
35
+ const index_1 = require("../index");
36
+ const add_import_1 = require("../add-import");
37
+ const java_1 = require("../../java");
38
+ const immer_1 = require("immer");
39
+ /**
40
+ * Changes an import from one module to another, updating all type attributions.
41
+ *
42
+ * This recipe is useful for:
43
+ * - Library migrations (e.g., moving `act` from `react-dom/test-utils` to `react`)
44
+ * - Module restructuring (e.g., split packages)
45
+ * - Renaming exported members
46
+ *
47
+ * @example
48
+ * // Migrate act import from react-dom/test-utils to react
49
+ * const recipe = new ChangeImport({
50
+ * oldModule: "react-dom/test-utils",
51
+ * oldMember: "act",
52
+ * newModule: "react"
53
+ * });
54
+ * // Before: import { act } from 'react-dom/test-utils';
55
+ * // After: import { act } from 'react';
56
+ *
57
+ * @example
58
+ * // Change a named import to a different name
59
+ * const recipe = new ChangeImport({
60
+ * oldModule: "lodash",
61
+ * oldMember: "extend",
62
+ * newModule: "lodash",
63
+ * newMember: "assign"
64
+ * });
65
+ * // Before: import { extend } from 'lodash';
66
+ * // After: import { assign } from 'lodash';
67
+ */
68
+ class ChangeImport extends recipe_1.Recipe {
69
+ constructor(options) {
70
+ super(options);
71
+ this.name = "org.openrewrite.javascript.change-import";
72
+ this.displayName = "Change import";
73
+ this.description = "Changes an import from one module/member to another, updating all type attributions.";
74
+ }
75
+ editor() {
76
+ return __awaiter(this, void 0, void 0, function* () {
77
+ var _a;
78
+ const oldModule = this.oldModule;
79
+ const oldMember = this.oldMember;
80
+ const newModule = this.newModule;
81
+ const newMember = (_a = this.newMember) !== null && _a !== void 0 ? _a : oldMember;
82
+ const newAlias = this.newAlias;
83
+ // Build the old and new FQNs for type attribution updates
84
+ const oldFqn = oldMember === 'default' || oldMember === '*'
85
+ ? oldModule
86
+ : `${oldModule}.${oldMember}`;
87
+ const newFqn = newMember === 'default' || newMember === '*'
88
+ ? newModule
89
+ : `${newModule}.${newMember}`;
90
+ return new class extends index_1.JavaScriptVisitor {
91
+ constructor() {
92
+ super(...arguments);
93
+ this.hasOldImport = false;
94
+ this.transformedImport = false;
95
+ }
96
+ visitJsCompilationUnit(cu, ctx) {
97
+ const _super = Object.create(null, {
98
+ visitJsCompilationUnit: { get: () => super.visitJsCompilationUnit }
99
+ });
100
+ return __awaiter(this, void 0, void 0, function* () {
101
+ var _a;
102
+ // Reset tracking for each file
103
+ this.hasOldImport = false;
104
+ this.oldAlias = undefined;
105
+ this.transformedImport = false;
106
+ // First pass: check if the old import exists and capture any alias
107
+ for (const statement of cu.statements) {
108
+ const stmt = (_a = statement.element) !== null && _a !== void 0 ? _a : statement;
109
+ if (stmt.kind === index_1.JS.Kind.Import) {
110
+ const jsImport = stmt;
111
+ const aliasInfo = this.checkForOldImport(jsImport);
112
+ if (aliasInfo.found) {
113
+ this.hasOldImport = true;
114
+ this.oldAlias = aliasInfo.alias;
115
+ break;
116
+ }
117
+ }
118
+ }
119
+ // Visit the compilation unit (this will transform imports via visitJsImport)
120
+ let result = yield _super.visitJsCompilationUnit.call(this, cu, ctx);
121
+ // If we transformed an import but need to add to existing import from new module,
122
+ // or if we only removed a member from a multi-import, use maybeAddImport
123
+ if (this.hasOldImport && !this.transformedImport) {
124
+ const aliasToUse = newAlias !== null && newAlias !== void 0 ? newAlias : this.oldAlias;
125
+ if (newMember === 'default') {
126
+ (0, add_import_1.maybeAddImport)(this, {
127
+ module: newModule,
128
+ member: 'default',
129
+ alias: aliasToUse,
130
+ onlyIfReferenced: false
131
+ });
132
+ }
133
+ else if (newMember === '*') {
134
+ (0, add_import_1.maybeAddImport)(this, {
135
+ module: newModule,
136
+ member: '*',
137
+ alias: aliasToUse,
138
+ onlyIfReferenced: false
139
+ });
140
+ }
141
+ else if (aliasToUse && aliasToUse !== newMember) {
142
+ (0, add_import_1.maybeAddImport)(this, {
143
+ module: newModule,
144
+ member: newMember,
145
+ alias: aliasToUse,
146
+ onlyIfReferenced: false
147
+ });
148
+ }
149
+ else {
150
+ (0, add_import_1.maybeAddImport)(this, {
151
+ module: newModule,
152
+ member: newMember,
153
+ onlyIfReferenced: false
154
+ });
155
+ }
156
+ }
157
+ return result;
158
+ });
159
+ }
160
+ visitImportDeclaration(jsImport, ctx) {
161
+ const _super = Object.create(null, {
162
+ visitImportDeclaration: { get: () => super.visitImportDeclaration }
163
+ });
164
+ return __awaiter(this, void 0, void 0, function* () {
165
+ var _a;
166
+ let imp = yield _super.visitImportDeclaration.call(this, jsImport, ctx);
167
+ if (!this.hasOldImport) {
168
+ return imp;
169
+ }
170
+ const aliasInfo = this.checkForOldImport(imp);
171
+ if (!aliasInfo.found) {
172
+ return imp;
173
+ }
174
+ // Check if this is the only import from the old module
175
+ const namedImports = this.getNamedImports(imp);
176
+ const isOnlyImport = namedImports.length === 1 ||
177
+ (oldMember === 'default' && !((_a = imp.importClause) === null || _a === void 0 ? void 0 : _a.namedBindings)) ||
178
+ (oldMember === '*');
179
+ if (isOnlyImport) {
180
+ // Transform the module specifier in place
181
+ this.transformedImport = true;
182
+ return (0, immer_1.produce)(imp, draft => {
183
+ var _a;
184
+ if (draft.moduleSpecifier) {
185
+ const literal = draft.moduleSpecifier.element;
186
+ literal.value = newModule;
187
+ // Update valueSource to preserve quote style
188
+ const originalSource = literal.valueSource || `"${oldModule}"`;
189
+ const quoteChar = originalSource.startsWith("'") ? "'" : '"';
190
+ literal.valueSource = `${quoteChar}${newModule}${quoteChar}`;
191
+ }
192
+ // If we're also renaming the member, update the import specifier
193
+ if (newMember !== oldMember && oldMember !== 'default' && oldMember !== '*') {
194
+ const importClause = draft.importClause;
195
+ if (((_a = importClause === null || importClause === void 0 ? void 0 : importClause.namedBindings) === null || _a === void 0 ? void 0 : _a.kind) === index_1.JS.Kind.NamedImports) {
196
+ const namedImports = importClause.namedBindings;
197
+ for (const elem of namedImports.elements.elements) {
198
+ const specifier = elem.element;
199
+ if (specifier.specifier.kind === java_1.J.Kind.Identifier &&
200
+ specifier.specifier.simpleName === oldMember) {
201
+ specifier.specifier.simpleName = newMember;
202
+ }
203
+ }
204
+ }
205
+ }
206
+ });
207
+ }
208
+ else {
209
+ // Remove just the specific member from the import
210
+ // maybeAddImport will add the new import
211
+ return this.removeNamedImportMember(imp, oldMember, ctx);
212
+ }
213
+ });
214
+ }
215
+ removeNamedImportMember(imp, memberToRemove, _ctx) {
216
+ return __awaiter(this, void 0, void 0, function* () {
217
+ return (0, immer_1.produce)(imp, draft => {
218
+ const importClause = draft.importClause;
219
+ if (!(importClause === null || importClause === void 0 ? void 0 : importClause.namedBindings))
220
+ return;
221
+ if (importClause.namedBindings.kind !== index_1.JS.Kind.NamedImports)
222
+ return;
223
+ const namedImports = importClause.namedBindings;
224
+ const elements = namedImports.elements.elements;
225
+ const filteredElements = elements.filter(elem => {
226
+ const specifier = elem.element;
227
+ const specifierNode = specifier.specifier;
228
+ if (specifierNode.kind === java_1.J.Kind.Identifier) {
229
+ return specifierNode.simpleName !== memberToRemove;
230
+ }
231
+ if (specifierNode.kind === index_1.JS.Kind.Alias) {
232
+ const alias = specifierNode;
233
+ const propertyName = alias.propertyName.element;
234
+ if (propertyName.kind === java_1.J.Kind.Identifier) {
235
+ return propertyName.simpleName !== memberToRemove;
236
+ }
237
+ }
238
+ return true;
239
+ });
240
+ namedImports.elements.elements = filteredElements;
241
+ });
242
+ });
243
+ }
244
+ getNamedImports(imp) {
245
+ const imports = [];
246
+ const importClause = imp.importClause;
247
+ if (!importClause)
248
+ return imports;
249
+ const namedBindings = importClause.namedBindings;
250
+ if (!namedBindings || namedBindings.kind !== index_1.JS.Kind.NamedImports)
251
+ return imports;
252
+ const namedImports = namedBindings;
253
+ for (const elem of namedImports.elements.elements) {
254
+ const specifier = elem.element;
255
+ const specifierNode = specifier.specifier;
256
+ if ((0, java_1.isIdentifier)(specifierNode)) {
257
+ imports.push(specifierNode.simpleName);
258
+ }
259
+ else if (specifierNode.kind === index_1.JS.Kind.Alias) {
260
+ const alias = specifierNode;
261
+ const propertyName = alias.propertyName.element;
262
+ if ((0, java_1.isIdentifier)(propertyName)) {
263
+ imports.push(propertyName.simpleName);
264
+ }
265
+ }
266
+ }
267
+ return imports;
268
+ }
269
+ visitIdentifier(identifier, ctx) {
270
+ const _super = Object.create(null, {
271
+ visitIdentifier: { get: () => super.visitIdentifier }
272
+ });
273
+ return __awaiter(this, void 0, void 0, function* () {
274
+ let ident = yield _super.visitIdentifier.call(this, identifier, ctx);
275
+ if (!this.hasOldImport) {
276
+ return ident;
277
+ }
278
+ // Check and update type attribution
279
+ let changed = false;
280
+ // Update type if it references the old module
281
+ const updatedType = this.updateType(ident.type);
282
+ if (updatedType !== ident.type) {
283
+ changed = true;
284
+ }
285
+ // Update fieldType if it references the old module
286
+ // fieldType is specifically Type.Variable, so we need to handle it specially
287
+ let updatedFieldType = ident.fieldType;
288
+ if (ident.fieldType) {
289
+ const updated = this.updateVariableType(ident.fieldType);
290
+ if (updated !== ident.fieldType) {
291
+ updatedFieldType = updated;
292
+ changed = true;
293
+ }
294
+ }
295
+ if (changed) {
296
+ return (0, immer_1.produce)(ident, draft => {
297
+ if (updatedType !== ident.type) {
298
+ draft.type = updatedType;
299
+ }
300
+ if (updatedFieldType !== ident.fieldType) {
301
+ draft.fieldType = updatedFieldType;
302
+ }
303
+ });
304
+ }
305
+ return ident;
306
+ });
307
+ }
308
+ visitMethodInvocation(method, ctx) {
309
+ const _super = Object.create(null, {
310
+ visitMethodInvocation: { get: () => super.visitMethodInvocation }
311
+ });
312
+ return __awaiter(this, void 0, void 0, function* () {
313
+ let m = yield _super.visitMethodInvocation.call(this, method, ctx);
314
+ if (!this.hasOldImport) {
315
+ return m;
316
+ }
317
+ // Update methodType if it references the old module
318
+ const updatedMethodType = this.updateMethodType(m.methodType);
319
+ if (updatedMethodType !== m.methodType) {
320
+ return (0, immer_1.produce)(m, draft => {
321
+ draft.methodType = updatedMethodType;
322
+ });
323
+ }
324
+ return m;
325
+ });
326
+ }
327
+ visitFieldAccess(fieldAccess, ctx) {
328
+ const _super = Object.create(null, {
329
+ visitFieldAccess: { get: () => super.visitFieldAccess }
330
+ });
331
+ return __awaiter(this, void 0, void 0, function* () {
332
+ let fa = yield _super.visitFieldAccess.call(this, fieldAccess, ctx);
333
+ if (!this.hasOldImport) {
334
+ return fa;
335
+ }
336
+ // Update type if it references the old module
337
+ const updatedType = this.updateType(fa.type);
338
+ if (updatedType !== fa.type) {
339
+ return (0, immer_1.produce)(fa, draft => {
340
+ draft.type = updatedType;
341
+ });
342
+ }
343
+ return fa;
344
+ });
345
+ }
346
+ visitFunctionCall(functionCall, ctx) {
347
+ const _super = Object.create(null, {
348
+ visitFunctionCall: { get: () => super.visitFunctionCall }
349
+ });
350
+ return __awaiter(this, void 0, void 0, function* () {
351
+ let fc = yield _super.visitFunctionCall.call(this, functionCall, ctx);
352
+ if (!this.hasOldImport) {
353
+ return fc;
354
+ }
355
+ // Update methodType if it references the old module
356
+ const updatedMethodType = this.updateMethodType(fc.methodType);
357
+ if (updatedMethodType !== fc.methodType) {
358
+ return (0, immer_1.produce)(fc, draft => {
359
+ draft.methodType = updatedMethodType;
360
+ });
361
+ }
362
+ return fc;
363
+ });
364
+ }
365
+ visitNewClass(newClass, ctx) {
366
+ const _super = Object.create(null, {
367
+ visitNewClass: { get: () => super.visitNewClass }
368
+ });
369
+ return __awaiter(this, void 0, void 0, function* () {
370
+ let nc = yield _super.visitNewClass.call(this, newClass, ctx);
371
+ if (!this.hasOldImport) {
372
+ return nc;
373
+ }
374
+ let changed = false;
375
+ // Update methodType if it references the old module
376
+ const updatedMethodType = this.updateMethodType(nc.methodType);
377
+ if (updatedMethodType !== nc.methodType) {
378
+ changed = true;
379
+ }
380
+ // Update constructorType if it references the old module
381
+ const updatedConstructorType = this.updateMethodType(nc.constructorType);
382
+ if (updatedConstructorType !== nc.constructorType) {
383
+ changed = true;
384
+ }
385
+ // Update type if it references the old module
386
+ const updatedType = this.updateType(nc.type);
387
+ if (updatedType !== nc.type) {
388
+ changed = true;
389
+ }
390
+ if (changed) {
391
+ return (0, immer_1.produce)(nc, draft => {
392
+ if (updatedMethodType !== nc.methodType) {
393
+ draft.methodType = updatedMethodType;
394
+ }
395
+ if (updatedConstructorType !== nc.constructorType) {
396
+ draft.constructorType = updatedConstructorType;
397
+ }
398
+ if (updatedType !== nc.type) {
399
+ draft.type = updatedType;
400
+ }
401
+ });
402
+ }
403
+ return nc;
404
+ });
405
+ }
406
+ /**
407
+ * Update a type if it references the old module
408
+ */
409
+ updateType(type) {
410
+ if (!type)
411
+ return type;
412
+ switch (type.kind) {
413
+ case java_1.Type.Kind.Class:
414
+ case java_1.Type.Kind.ShallowClass:
415
+ return this.updateClassType(type);
416
+ case java_1.Type.Kind.Method:
417
+ return this.updateMethodType(type);
418
+ case java_1.Type.Kind.Variable:
419
+ return this.updateVariableType(type);
420
+ case java_1.Type.Kind.Parameterized:
421
+ return this.updateParameterizedType(type);
422
+ case java_1.Type.Kind.Array:
423
+ return this.updateArrayType(type);
424
+ default:
425
+ return type;
426
+ }
427
+ }
428
+ /**
429
+ * Update a Class type if its FQN references the old module
430
+ */
431
+ updateClassType(classType) {
432
+ let changed = false;
433
+ let newFullyQualifiedName = classType.fullyQualifiedName;
434
+ let newOwningClass = classType.owningClass;
435
+ // Check if the FQN matches or starts with the old module
436
+ if (classType.fullyQualifiedName === oldFqn) {
437
+ newFullyQualifiedName = newFqn;
438
+ changed = true;
439
+ }
440
+ else if (classType.fullyQualifiedName === oldModule) {
441
+ newFullyQualifiedName = newModule;
442
+ changed = true;
443
+ }
444
+ else if (classType.fullyQualifiedName.startsWith(oldModule + '.')) {
445
+ newFullyQualifiedName = newModule + classType.fullyQualifiedName.substring(oldModule.length);
446
+ changed = true;
447
+ }
448
+ // Recursively update owningClass
449
+ if (classType.owningClass) {
450
+ const updatedOwningClass = this.updateClassType(classType.owningClass);
451
+ if (updatedOwningClass !== classType.owningClass) {
452
+ newOwningClass = updatedOwningClass;
453
+ changed = true;
454
+ }
455
+ }
456
+ if (changed) {
457
+ // Type objects are marked as non-draftable, so we manually create new objects
458
+ return Object.assign(Object.assign({}, classType), { fullyQualifiedName: newFullyQualifiedName, owningClass: newOwningClass });
459
+ }
460
+ return classType;
461
+ }
462
+ /**
463
+ * Update a Method type if its declaringType references the old module
464
+ */
465
+ updateMethodType(methodType) {
466
+ if (!methodType)
467
+ return methodType;
468
+ // Update the declaring type
469
+ if (java_1.Type.isFullyQualified(methodType.declaringType)) {
470
+ const declaringTypeFqn = java_1.Type.FullyQualified.getFullyQualifiedName(methodType.declaringType);
471
+ if (declaringTypeFqn === oldModule ||
472
+ declaringTypeFqn === oldFqn ||
473
+ declaringTypeFqn.startsWith(oldModule + '.')) {
474
+ // Need to update the declaring type
475
+ const updatedDeclaringType = this.updateType(methodType.declaringType);
476
+ // Also update the method name if we're renaming the member
477
+ const updatedName = (oldMember !== 'default' && oldMember !== '*' &&
478
+ methodType.name === oldMember && newMember !== oldMember)
479
+ ? newMember
480
+ : methodType.name;
481
+ // Type objects are marked as non-draftable, so we manually create new objects
482
+ return Object.assign(Object.assign({}, methodType), { declaringType: updatedDeclaringType, name: updatedName });
483
+ }
484
+ }
485
+ return methodType;
486
+ }
487
+ /**
488
+ * Update a Variable type if its owner references the old module
489
+ */
490
+ updateVariableType(variableType) {
491
+ let changed = false;
492
+ let newOwner = variableType.owner;
493
+ let newInnerType = variableType.type;
494
+ // Update owner if it references the old module
495
+ if (variableType.owner) {
496
+ const updatedOwner = this.updateType(variableType.owner);
497
+ if (updatedOwner !== variableType.owner) {
498
+ newOwner = updatedOwner;
499
+ changed = true;
500
+ }
501
+ }
502
+ // Update inner type if it references the old module
503
+ const updatedInnerType = this.updateType(variableType.type);
504
+ if (updatedInnerType !== variableType.type) {
505
+ newInnerType = updatedInnerType;
506
+ changed = true;
507
+ }
508
+ if (changed) {
509
+ // Type objects are marked as non-draftable, so we manually create new objects
510
+ return Object.assign(Object.assign({}, variableType), { owner: newOwner, type: newInnerType });
511
+ }
512
+ return variableType;
513
+ }
514
+ /**
515
+ * Update a Parameterized type if its base type references the old module
516
+ */
517
+ updateParameterizedType(paramType) {
518
+ let changed = false;
519
+ let newBaseType = paramType.type;
520
+ let newTypeParams = paramType.typeParameters;
521
+ // Update base type
522
+ if (java_1.Type.isFullyQualified(paramType.type)) {
523
+ const updatedType = this.updateType(paramType.type);
524
+ if (updatedType !== paramType.type) {
525
+ newBaseType = updatedType;
526
+ changed = true;
527
+ }
528
+ }
529
+ // Update type parameters
530
+ const updatedParams = paramType.typeParameters.map(tp => this.updateType(tp));
531
+ if (updatedParams.some((p, i) => p !== paramType.typeParameters[i])) {
532
+ newTypeParams = updatedParams;
533
+ changed = true;
534
+ }
535
+ if (changed) {
536
+ // Type objects are marked as non-draftable, so we manually create new objects
537
+ return Object.assign(Object.assign({}, paramType), { type: newBaseType, typeParameters: newTypeParams });
538
+ }
539
+ return paramType;
540
+ }
541
+ /**
542
+ * Update an Array type if its element type references the old module
543
+ */
544
+ updateArrayType(arrayType) {
545
+ const updatedElemType = this.updateType(arrayType.elemType);
546
+ if (updatedElemType !== arrayType.elemType) {
547
+ // Type objects are marked as non-draftable, so we manually create new objects
548
+ return Object.assign(Object.assign({}, arrayType), { elemType: updatedElemType });
549
+ }
550
+ return arrayType;
551
+ }
552
+ checkForOldImport(jsImport) {
553
+ // Check if this import is from the old module
554
+ const moduleSpecifier = jsImport.moduleSpecifier;
555
+ if (!moduleSpecifier)
556
+ return { found: false };
557
+ const literal = moduleSpecifier.element;
558
+ if (literal.kind !== java_1.J.Kind.Literal)
559
+ return { found: false };
560
+ const value = literal.value;
561
+ if (value !== oldModule)
562
+ return { found: false };
563
+ const importClause = jsImport.importClause;
564
+ if (!importClause) {
565
+ // Side-effect import - not what we're looking for
566
+ return { found: false };
567
+ }
568
+ // Check for default import
569
+ if (oldMember === 'default') {
570
+ if (importClause.name) {
571
+ const nameElem = importClause.name.element;
572
+ if ((0, java_1.isIdentifier)(nameElem)) {
573
+ return { found: true, alias: nameElem.simpleName };
574
+ }
575
+ }
576
+ return { found: false };
577
+ }
578
+ // Check for namespace import
579
+ if (oldMember === '*') {
580
+ const namedBindings = importClause.namedBindings;
581
+ if ((namedBindings === null || namedBindings === void 0 ? void 0 : namedBindings.kind) === index_1.JS.Kind.Alias) {
582
+ const alias = namedBindings;
583
+ if ((0, java_1.isIdentifier)(alias.alias)) {
584
+ return { found: true, alias: alias.alias.simpleName };
585
+ }
586
+ }
587
+ return { found: false };
588
+ }
589
+ // Check for named imports
590
+ const namedBindings = importClause.namedBindings;
591
+ if (!namedBindings)
592
+ return { found: false };
593
+ if (namedBindings.kind !== index_1.JS.Kind.NamedImports)
594
+ return { found: false };
595
+ const namedImports = namedBindings;
596
+ const elements = namedImports.elements.elements;
597
+ for (const elem of elements) {
598
+ const specifier = elem.element;
599
+ const specifierNode = specifier.specifier;
600
+ // Handle direct import: import { act }
601
+ if ((0, java_1.isIdentifier)(specifierNode) && specifierNode.simpleName === oldMember) {
602
+ return { found: true };
603
+ }
604
+ // Handle aliased import: import { act as something }
605
+ if (specifierNode.kind === index_1.JS.Kind.Alias) {
606
+ const alias = specifierNode;
607
+ const propertyName = alias.propertyName.element;
608
+ if ((0, java_1.isIdentifier)(propertyName) && propertyName.simpleName === oldMember) {
609
+ if ((0, java_1.isIdentifier)(alias.alias)) {
610
+ return { found: true, alias: alias.alias.simpleName };
611
+ }
612
+ }
613
+ }
614
+ }
615
+ return { found: false };
616
+ }
617
+ }();
618
+ });
619
+ }
620
+ }
621
+ exports.ChangeImport = ChangeImport;
622
+ __decorate([
623
+ (0, recipe_1.Option)({
624
+ displayName: "Old module",
625
+ description: "The module to change imports from",
626
+ example: "react-dom/test-utils"
627
+ })
628
+ ], ChangeImport.prototype, "oldModule", void 0);
629
+ __decorate([
630
+ (0, recipe_1.Option)({
631
+ displayName: "Old member",
632
+ description: "The member to change (or 'default' for default imports, '*' for namespace imports)",
633
+ example: "act"
634
+ })
635
+ ], ChangeImport.prototype, "oldMember", void 0);
636
+ __decorate([
637
+ (0, recipe_1.Option)({
638
+ displayName: "New module",
639
+ description: "The module to change imports to",
640
+ example: "react"
641
+ })
642
+ ], ChangeImport.prototype, "newModule", void 0);
643
+ __decorate([
644
+ (0, recipe_1.Option)({
645
+ displayName: "New member",
646
+ description: "The new member name. If not specified, keeps the same member name.",
647
+ example: "act",
648
+ required: false
649
+ })
650
+ ], ChangeImport.prototype, "newMember", void 0);
651
+ __decorate([
652
+ (0, recipe_1.Option)({
653
+ displayName: "New alias",
654
+ description: "Optional alias for the new import. Required when newMember is 'default' or '*'.",
655
+ required: false
656
+ })
657
+ ], ChangeImport.prototype, "newAlias", void 0);
658
+ //# sourceMappingURL=change-import.js.map