@openrewrite/rewrite 8.69.0-20251210-214835 → 8.69.0-20251211-110844

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 (70) hide show
  1. package/dist/cli/cli-utils.d.ts.map +1 -1
  2. package/dist/cli/cli-utils.js +6 -0
  3. package/dist/cli/cli-utils.js.map +1 -1
  4. package/dist/cli/rewrite.d.ts.map +1 -1
  5. package/dist/cli/rewrite.js +55 -23
  6. package/dist/cli/rewrite.js.map +1 -1
  7. package/dist/data-table.d.ts +23 -0
  8. package/dist/data-table.d.ts.map +1 -1
  9. package/dist/data-table.js +125 -6
  10. package/dist/data-table.js.map +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +2 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/javascript/node-resolution-result.d.ts +9 -0
  15. package/dist/javascript/node-resolution-result.d.ts.map +1 -1
  16. package/dist/javascript/node-resolution-result.js +10 -1
  17. package/dist/javascript/node-resolution-result.js.map +1 -1
  18. package/dist/javascript/package-manager.d.ts +76 -89
  19. package/dist/javascript/package-manager.d.ts.map +1 -1
  20. package/dist/javascript/package-manager.js +114 -139
  21. package/dist/javascript/package-manager.js.map +1 -1
  22. package/dist/javascript/recipes/add-dependency.d.ts +57 -0
  23. package/dist/javascript/recipes/add-dependency.d.ts.map +1 -0
  24. package/dist/javascript/recipes/add-dependency.js +404 -0
  25. package/dist/javascript/recipes/add-dependency.js.map +1 -0
  26. package/dist/javascript/recipes/index.d.ts +1 -0
  27. package/dist/javascript/recipes/index.d.ts.map +1 -1
  28. package/dist/javascript/recipes/index.js +1 -0
  29. package/dist/javascript/recipes/index.js.map +1 -1
  30. package/dist/javascript/recipes/upgrade-dependency-version.d.ts +3 -24
  31. package/dist/javascript/recipes/upgrade-dependency-version.d.ts.map +1 -1
  32. package/dist/javascript/recipes/upgrade-dependency-version.js +34 -157
  33. package/dist/javascript/recipes/upgrade-dependency-version.js.map +1 -1
  34. package/dist/javascript/recipes/upgrade-transitive-dependency-version.d.ts +2 -19
  35. package/dist/javascript/recipes/upgrade-transitive-dependency-version.d.ts.map +1 -1
  36. package/dist/javascript/recipes/upgrade-transitive-dependency-version.js +21 -137
  37. package/dist/javascript/recipes/upgrade-transitive-dependency-version.js.map +1 -1
  38. package/dist/javascript/search/find-dependency.d.ts.map +1 -1
  39. package/dist/javascript/search/find-dependency.js +8 -47
  40. package/dist/javascript/search/find-dependency.js.map +1 -1
  41. package/dist/json/tree.d.ts +30 -0
  42. package/dist/json/tree.d.ts.map +1 -1
  43. package/dist/json/tree.js +113 -0
  44. package/dist/json/tree.js.map +1 -1
  45. package/dist/parser.d.ts +9 -0
  46. package/dist/parser.d.ts.map +1 -1
  47. package/dist/parser.js +27 -0
  48. package/dist/parser.js.map +1 -1
  49. package/dist/reference.d.ts.map +1 -1
  50. package/dist/reference.js +1 -1
  51. package/dist/reference.js.map +1 -1
  52. package/dist/version.txt +1 -1
  53. package/dist/visitor.js +1 -1
  54. package/dist/visitor.js.map +1 -1
  55. package/package.json +1 -1
  56. package/src/cli/cli-utils.ts +6 -0
  57. package/src/cli/rewrite.ts +53 -17
  58. package/src/data-table.ts +83 -2
  59. package/src/index.ts +2 -1
  60. package/src/javascript/node-resolution-result.ts +16 -0
  61. package/src/javascript/package-manager.ts +197 -174
  62. package/src/javascript/recipes/add-dependency.ts +467 -0
  63. package/src/javascript/recipes/index.ts +1 -0
  64. package/src/javascript/recipes/upgrade-dependency-version.ts +52 -199
  65. package/src/javascript/recipes/upgrade-transitive-dependency-version.ts +39 -165
  66. package/src/javascript/search/find-dependency.ts +13 -52
  67. package/src/json/tree.ts +98 -1
  68. package/src/parser.ts +17 -0
  69. package/src/reference.ts +1 -1
  70. package/src/visitor.ts +1 -1
@@ -5,7 +5,7 @@
5
5
  * you may not use this file except in compliance with the License.
6
6
  * You may obtain a copy of the License at
7
7
  * <p>
8
- * https://docs.moderne.io/licensing/moderate-source-available-license
8
+ * https://docs.moderne.io/licensing/moderne-source-available-license
9
9
  * <p>
10
10
  * Unless required by applicable law or agreed to in writing, software
11
11
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,10 +17,12 @@
17
17
  import {Option, Recipe} from "../../recipe";
18
18
  import {ExecutionContext} from "../../execution";
19
19
  import {TreeVisitor} from "../../visitor";
20
- import {Json, JsonVisitor} from "../../json";
20
+ import {getMemberKeyName, isMember, Json, JsonVisitor} from "../../json";
21
21
  import {foundSearchResult} from "../../markers";
22
22
  import {
23
+ allDependencyScopes,
23
24
  Dependency,
25
+ DependencyScope,
24
26
  findNodeResolutionResult,
25
27
  NodeResolutionResult,
26
28
  ResolvedDependency
@@ -29,12 +31,7 @@ import * as semver from "semver";
29
31
  import * as picomatch from "picomatch";
30
32
 
31
33
  /** Dependency section names in package.json */
32
- const DEPENDENCY_SECTIONS = new Set([
33
- 'dependencies',
34
- 'devDependencies',
35
- 'peerDependencies',
36
- 'optionalDependencies'
37
- ]);
34
+ const DEPENDENCY_SECTIONS = new Set<DependencyScope>(allDependencyScopes);
38
35
 
39
36
  /**
40
37
  * Finds npm/Node.js dependencies declared in package.json.
@@ -134,7 +131,7 @@ export class FindDependency extends Recipe {
134
131
  }
135
132
 
136
133
  // Get the package name from the member key
137
- const depName = this.getMemberKeyName(member);
134
+ const depName = getMemberKeyName(member);
138
135
  if (!depName) {
139
136
  return super.visitMember(member, ctx);
140
137
  }
@@ -179,18 +176,16 @@ export class FindDependency extends Recipe {
179
176
  * Checks if the current member's parent is a dependency section object.
180
177
  * Returns the section name if so, undefined otherwise.
181
178
  */
182
- private getParentDependencySection(): string | undefined {
179
+ private getParentDependencySection(): DependencyScope | undefined {
183
180
  // Walk up the cursor to find the parent member that contains this dependency
184
181
  // Structure: Document > Object > Member("dependencies") > Object > Member("lodash")
185
182
  let cursor = this.cursor.parent;
186
183
  while (cursor) {
187
184
  const tree = cursor.value;
188
- if (tree && typeof tree === 'object' && 'kind' in tree) {
189
- if (tree.kind === Json.Kind.Member) {
190
- const memberKey = this.getMemberKeyName(tree as Json.Member);
191
- if (memberKey && DEPENDENCY_SECTIONS.has(memberKey)) {
192
- return memberKey;
193
- }
185
+ if (tree && typeof tree === 'object' && 'kind' in tree && isMember(tree as Json)) {
186
+ const memberKey = getMemberKeyName(tree as Json.Member);
187
+ if (memberKey && DEPENDENCY_SECTIONS.has(memberKey as DependencyScope)) {
188
+ return memberKey as DependencyScope;
194
189
  }
195
190
  }
196
191
  cursor = cursor.parent;
@@ -198,46 +193,12 @@ export class FindDependency extends Recipe {
198
193
  return undefined;
199
194
  }
200
195
 
201
- /**
202
- * Extracts the key name from a Json.Member
203
- */
204
- private getMemberKeyName(member: Json.Member): string | undefined {
205
- const key = member.key.element;
206
- if (key.kind === Json.Kind.Literal) {
207
- // Remove quotes from string literal
208
- const source = (key as Json.Literal).source;
209
- if (source.startsWith('"') && source.endsWith('"')) {
210
- return source.slice(1, -1);
211
- }
212
- return source;
213
- } else if (key.kind === Json.Kind.Identifier) {
214
- return (key as Json.Identifier).name;
215
- }
216
- return undefined;
217
- }
218
-
219
196
  /**
220
197
  * Finds a dependency by name in the appropriate section of the resolution result.
221
198
  */
222
- private findDependencyByName(name: string, section: string): Dependency | undefined {
199
+ private findDependencyByName(name: string, section: DependencyScope): Dependency | undefined {
223
200
  if (!this.resolution) return undefined;
224
-
225
- let deps: Dependency[] | undefined;
226
- switch (section) {
227
- case 'dependencies':
228
- deps = this.resolution.dependencies;
229
- break;
230
- case 'devDependencies':
231
- deps = this.resolution.devDependencies;
232
- break;
233
- case 'peerDependencies':
234
- deps = this.resolution.peerDependencies;
235
- break;
236
- case 'optionalDependencies':
237
- deps = this.resolution.optionalDependencies;
238
- break;
239
- }
240
-
201
+ const deps = this.resolution[section];
241
202
  return deps?.find(d => d.name === name);
242
203
  }
243
204
  };
package/src/json/tree.ts CHANGED
@@ -13,7 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import {Markers} from "../markers";
16
+ import {emptyMarkers, Markers} from "../markers";
17
17
  import {SourceFile, Tree} from "../tree";
18
18
 
19
19
 
@@ -117,3 +117,100 @@ const jsonKindValues = new Set(Object.values(Json.Kind));
117
117
  export function isJson(tree: any): tree is Json {
118
118
  return jsonKindValues.has(tree["kind"]);
119
119
  }
120
+
121
+ export function isLiteral(json: Json): json is Json.Literal {
122
+ return json.kind === Json.Kind.Literal;
123
+ }
124
+
125
+ export function isObject(json: Json): json is Json.Object {
126
+ return json.kind === Json.Kind.Object;
127
+ }
128
+
129
+ export function isArray(json: Json): json is Json.Array {
130
+ return json.kind === Json.Kind.Array;
131
+ }
132
+
133
+ export function isIdentifier(json: Json): json is Json.Identifier {
134
+ return json.kind === Json.Kind.Identifier;
135
+ }
136
+
137
+ export function isMember(json: Json): json is Json.Member {
138
+ return json.kind === Json.Kind.Member;
139
+ }
140
+
141
+ /**
142
+ * Gets the key name from a Json.Member.
143
+ * Handles both string literals (quoted keys) and identifiers (unquoted keys).
144
+ *
145
+ * @param member The JSON member to extract the key name from
146
+ * @returns The key name as a string, or undefined if extraction fails
147
+ */
148
+ export function getMemberKeyName(member: Json.Member): string | undefined {
149
+ const key = member.key.element;
150
+ if (isLiteral(key)) {
151
+ const source = key.source;
152
+ // Remove quotes from string literal
153
+ if (source.startsWith('"') && source.endsWith('"')) {
154
+ return source.slice(1, -1);
155
+ }
156
+ return source;
157
+ } else if (isIdentifier(key)) {
158
+ return key.name;
159
+ }
160
+ return undefined;
161
+ }
162
+
163
+ /**
164
+ * Detects the indentation used in a JSON document by examining existing members or array elements.
165
+ * Returns the base indent string (e.g., " " for 2 spaces, " " for 4 spaces).
166
+ *
167
+ * @param doc The JSON document to analyze
168
+ * @returns The detected indent string, or " " (4 spaces) as default
169
+ */
170
+ export function detectIndent(doc: Json.Document): string {
171
+ const defaultIndent = ' '; // Default to 4 spaces
172
+
173
+ if (isObject(doc.value)) {
174
+ if (doc.value.members && doc.value.members.length > 0) {
175
+ // Look at the prefix of the first member's key to detect indentation
176
+ const firstMemberRightPadded = doc.value.members[0];
177
+ const firstMember = firstMemberRightPadded.element as Json.Member;
178
+ const prefix = firstMember.key.element.prefix.whitespace;
179
+ // Extract just the spaces/tabs after the newline
180
+ const match = prefix.match(/\n([ \t]+)/);
181
+ if (match) {
182
+ return match[1];
183
+ }
184
+ }
185
+ } else if (isArray(doc.value)) {
186
+ if (doc.value.values && doc.value.values.length > 0) {
187
+ // Look at the prefix of the first array element to detect indentation
188
+ const firstElement = doc.value.values[0].element;
189
+ const prefix = firstElement.prefix.whitespace;
190
+ // Extract just the spaces/tabs after the newline
191
+ const match = prefix.match(/\n([ \t]+)/);
192
+ if (match) {
193
+ return match[1];
194
+ }
195
+ }
196
+ }
197
+
198
+ return defaultIndent;
199
+ }
200
+
201
+ /**
202
+ * Creates a RightPadded wrapper for a JSON element.
203
+ *
204
+ * @param element The JSON element to wrap
205
+ * @param after The trailing space after the element
206
+ * @param markers Optional markers to attach
207
+ * @returns A RightPadded wrapper containing the element
208
+ */
209
+ export function rightPadded<T extends Json>(element: T, after: Json.Space, markers?: Markers): Json.RightPadded<T> {
210
+ return {
211
+ kind: Json.Kind.RightPadded,
212
+ element,
213
+ after,
214
+ markers: markers ?? emptyMarkers
215
+ };
216
+ }
package/src/parser.ts CHANGED
@@ -57,6 +57,23 @@ export abstract class Parser {
57
57
 
58
58
  abstract parse(...sourcePaths: ParserInput[]): AsyncGenerator<SourceFile>
59
59
 
60
+ /**
61
+ * Parses a single input and returns the first source file.
62
+ * This is a convenience method for when you know you're parsing exactly one input.
63
+ *
64
+ * @param input The input to parse
65
+ * @returns The parsed source file
66
+ * @throws Error if the parser produces no results
67
+ */
68
+ async parseOne(input: ParserInput): Promise<SourceFile> {
69
+ const result = await this.parse(input).next();
70
+ if (result.done) {
71
+ const sourcePath = typeof input === 'string' ? input : input.sourcePath;
72
+ throw new Error(`Parser produced no results for: ${sourcePath}`);
73
+ }
74
+ return result.value;
75
+ }
76
+
60
77
  protected relativePath(sourcePath: ParserInput): string {
61
78
  const path = typeof sourcePath === "string" ? sourcePath : sourcePath.sourcePath;
62
79
  return isAbsolute(path) && this.relativeTo ? relative(this.relativeTo, path) : path;
package/src/reference.ts CHANGED
@@ -18,7 +18,7 @@ import {setAutoFreeze} from "immer";
18
18
  // this is required because otherwise `asRef()` won't work for objects created using immer
19
19
  setAutoFreeze(false);
20
20
 
21
- const REFERENCE_KEY = Symbol("org.openrewrite.rpc.Reference");
21
+ const REFERENCE_KEY = Symbol.for("org.openrewrite.rpc.Reference");
22
22
 
23
23
  export interface Reference {
24
24
  [REFERENCE_KEY]: true;
package/src/visitor.ts CHANGED
@@ -43,7 +43,7 @@ export async function produceAsync<Base extends Objectish>(
43
43
  return finishDraft(draft) as Base;
44
44
  }
45
45
 
46
- const stopAfterPreVisit = Symbol("STOP_AFTER_PRE_VISIT")
46
+ const stopAfterPreVisit = Symbol.for("STOP_AFTER_PRE_VISIT")
47
47
 
48
48
  export abstract class TreeVisitor<T extends Tree, P> {
49
49
  protected cursor: Cursor = rootCursor();