@kamaalio/codemod-kit 0.0.14 → 0.0.16
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.
- package/README.md +59 -0
- package/dist/codemods/index.d.ts +1 -1
- package/dist/codemods/utils.d.ts +5 -1
- package/dist/index.cjs +22 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +17 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -44,6 +44,65 @@ Runs a single codemod.
|
|
|
44
44
|
- `globItems`: An array of file paths to transform.
|
|
45
45
|
- `options`: Optional configuration for the run.
|
|
46
46
|
|
|
47
|
+
### `findAndReplace(content, rule, transformer)`
|
|
48
|
+
|
|
49
|
+
A utility function for finding and replacing AST nodes based on a rule.
|
|
50
|
+
|
|
51
|
+
- `content`: An `SgRoot<TypesMap>` object representing the parsed AST.
|
|
52
|
+
- `rule`: A `Rule<TypesMap>` object defining the pattern to search for.
|
|
53
|
+
- `transformer`: A function that takes a matched node and returns an optional string replacement.
|
|
54
|
+
|
|
55
|
+
Returns the transformed content as a string with all matching nodes replaced.
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { findAndReplace } from '@kamaalio/codemod-kit';
|
|
59
|
+
import { parseAsync } from '@ast-grep/napi';
|
|
60
|
+
|
|
61
|
+
const code = `
|
|
62
|
+
function oldFunction() {
|
|
63
|
+
return "hello";
|
|
64
|
+
}
|
|
65
|
+
`;
|
|
66
|
+
|
|
67
|
+
const ast = await parseAsync('javascript', code);
|
|
68
|
+
const result = findAndReplace(
|
|
69
|
+
ast,
|
|
70
|
+
{ pattern: 'function oldFunction() { $$$ }' },
|
|
71
|
+
node => 'function newFunction() { return "hello world"; }',
|
|
72
|
+
);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### `findAndReplaceEdits(content, rule, transformer)`
|
|
76
|
+
|
|
77
|
+
A utility function for finding AST nodes and generating edit operations without committing them.
|
|
78
|
+
|
|
79
|
+
- `content`: An `SgRoot<TypesMap>` object representing the parsed AST.
|
|
80
|
+
- `rule`: A `Rule<TypesMap>` object defining the pattern to search for.
|
|
81
|
+
- `transformer`: A function that takes a matched node and returns an optional string replacement.
|
|
82
|
+
|
|
83
|
+
Returns an array of `Edit` objects that can be committed later using `commitEdits()`.
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
import { findAndReplaceEdits } from '@kamaalio/codemod-kit';
|
|
87
|
+
import { parseAsync } from '@ast-grep/napi';
|
|
88
|
+
|
|
89
|
+
const code = `
|
|
90
|
+
function oldFunction() {
|
|
91
|
+
return "hello";
|
|
92
|
+
}
|
|
93
|
+
`;
|
|
94
|
+
|
|
95
|
+
const ast = await parseAsync('javascript', code);
|
|
96
|
+
const edits = findAndReplaceEdits(
|
|
97
|
+
ast,
|
|
98
|
+
{ pattern: 'function oldFunction() { $$$ }' },
|
|
99
|
+
node => 'function newFunction() { return "hello world"; }',
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
// Commit the edits later
|
|
103
|
+
const result = ast.root().commitEdits(edits);
|
|
104
|
+
```
|
|
105
|
+
|
|
47
106
|
### `Codemod`
|
|
48
107
|
|
|
49
108
|
A codemod is defined by the `Codemod` type:
|
package/dist/codemods/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { runCodemods, runCodemod, commitEditModifications } from './utils.js';
|
|
1
|
+
export { runCodemods, runCodemod, commitEditModifications, findAndReplace, findAndReplaceEdits } from './utils.js';
|
|
2
2
|
export type { Codemod, Modifications } from './types.js';
|
package/dist/codemods/utils.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { type Result } from 'neverthrow';
|
|
2
|
-
import { type Edit } from '@ast-grep/napi';
|
|
2
|
+
import { type Rule, type Edit, type SgNode, type SgRoot } from '@ast-grep/napi';
|
|
3
|
+
import type { Kinds, TypesMap } from '@ast-grep/napi/types/staticTypes.js';
|
|
3
4
|
import type { Codemod, Modifications } from './types.js';
|
|
5
|
+
import type { Optional } from '../utils/type-utils.js';
|
|
4
6
|
type RunCodemodHooks<C extends Codemod> = {
|
|
5
7
|
targetFiltering?: (filepath: string, codemod: C) => boolean;
|
|
6
8
|
preCodemodRun?: (codemod: C) => Promise<void>;
|
|
@@ -19,5 +21,7 @@ export declare function runCodemod<C extends Codemod>(codemod: C, transformation
|
|
|
19
21
|
hasChanges: boolean;
|
|
20
22
|
content: string;
|
|
21
23
|
}, Error>>>;
|
|
24
|
+
export declare function findAndReplaceEdits(content: SgRoot<TypesMap>, rule: Rule<TypesMap>, transformer: (node: SgNode<TypesMap, Kinds<TypesMap>>) => Optional<string>): Array<Edit>;
|
|
25
|
+
export declare function findAndReplace(content: SgRoot<TypesMap>, rule: Rule<TypesMap>, transformer: (node: SgNode<TypesMap, Kinds<TypesMap>>) => Optional<string>): string;
|
|
22
26
|
export declare function commitEditModifications(edits: Array<Edit>, modifications: Modifications): Promise<Modifications>;
|
|
23
27
|
export {};
|
package/dist/index.cjs
CHANGED
|
@@ -35,6 +35,8 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
35
35
|
__webpack_require__.d(__webpack_exports__, {
|
|
36
36
|
commitEditModifications: ()=>commitEditModifications,
|
|
37
37
|
runCodemod: ()=>runCodemod,
|
|
38
|
+
findAndReplace: ()=>findAndReplace,
|
|
39
|
+
findAndReplaceEdits: ()=>findAndReplaceEdits,
|
|
38
40
|
runCodemods: ()=>runCodemods
|
|
39
41
|
});
|
|
40
42
|
const external_node_path_namespaceObject = require("node:path");
|
|
@@ -45,6 +47,7 @@ const external_fast_glob_namespaceObject = require("fast-glob");
|
|
|
45
47
|
var external_fast_glob_default = /*#__PURE__*/ __webpack_require__.n(external_fast_glob_namespaceObject);
|
|
46
48
|
const external_neverthrow_namespaceObject = require("neverthrow");
|
|
47
49
|
const napi_namespaceObject = require("@ast-grep/napi");
|
|
50
|
+
const kamaal_namespaceObject = require("@kamaalio/kamaal");
|
|
48
51
|
const JAVASCRIPT_EXTENSIONS = [
|
|
49
52
|
'.js',
|
|
50
53
|
'.cjs',
|
|
@@ -126,6 +129,21 @@ async function runCodemod(codemod, transformationPath, options) {
|
|
|
126
129
|
}
|
|
127
130
|
}));
|
|
128
131
|
}
|
|
132
|
+
function findAndReplaceEdits(content, rule, transformer) {
|
|
133
|
+
const nodes = content.root().findAll({
|
|
134
|
+
rule
|
|
135
|
+
});
|
|
136
|
+
return kamaal_namespaceObject.arrays.compactMap(nodes, (node)=>{
|
|
137
|
+
const transformed = transformer(node);
|
|
138
|
+
if (null == transformed) return null;
|
|
139
|
+
return node.replace(transformed);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
function findAndReplace(content, rule, transformer) {
|
|
143
|
+
const root = content.root();
|
|
144
|
+
const edits = findAndReplaceEdits(content, rule, transformer);
|
|
145
|
+
return root.commitEdits(edits);
|
|
146
|
+
}
|
|
129
147
|
async function commitEditModifications(edits, modifications) {
|
|
130
148
|
if (0 === edits.length) return modifications;
|
|
131
149
|
const root = modifications.ast.root();
|
|
@@ -160,10 +178,14 @@ function defaultedHooks(hooks) {
|
|
|
160
178
|
};
|
|
161
179
|
}
|
|
162
180
|
exports.commitEditModifications = __webpack_exports__.commitEditModifications;
|
|
181
|
+
exports.findAndReplace = __webpack_exports__.findAndReplace;
|
|
182
|
+
exports.findAndReplaceEdits = __webpack_exports__.findAndReplaceEdits;
|
|
163
183
|
exports.runCodemod = __webpack_exports__.runCodemod;
|
|
164
184
|
exports.runCodemods = __webpack_exports__.runCodemods;
|
|
165
185
|
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
166
186
|
"commitEditModifications",
|
|
187
|
+
"findAndReplace",
|
|
188
|
+
"findAndReplaceEdits",
|
|
167
189
|
"runCodemod",
|
|
168
190
|
"runCodemods"
|
|
169
191
|
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { runCodemods, runCodemod, commitEditModifications, type Codemod, type Modifications, } from './codemods/index.js';
|
|
1
|
+
export { runCodemods, runCodemod, commitEditModifications, findAndReplace, findAndReplaceEdits, type Codemod, type Modifications, } from './codemods/index.js';
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import promises from "node:fs/promises";
|
|
|
3
3
|
import fast_glob from "fast-glob";
|
|
4
4
|
import { err, ok } from "neverthrow";
|
|
5
5
|
import { Lang, parseAsync } from "@ast-grep/napi";
|
|
6
|
+
import { arrays } from "@kamaalio/kamaal";
|
|
6
7
|
const JAVASCRIPT_EXTENSIONS = [
|
|
7
8
|
'.js',
|
|
8
9
|
'.cjs',
|
|
@@ -84,6 +85,21 @@ async function runCodemod(codemod, transformationPath, options) {
|
|
|
84
85
|
}
|
|
85
86
|
}));
|
|
86
87
|
}
|
|
88
|
+
function findAndReplaceEdits(content, rule, transformer) {
|
|
89
|
+
const nodes = content.root().findAll({
|
|
90
|
+
rule
|
|
91
|
+
});
|
|
92
|
+
return arrays.compactMap(nodes, (node)=>{
|
|
93
|
+
const transformed = transformer(node);
|
|
94
|
+
if (null == transformed) return null;
|
|
95
|
+
return node.replace(transformed);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
function findAndReplace(content, rule, transformer) {
|
|
99
|
+
const root = content.root();
|
|
100
|
+
const edits = findAndReplaceEdits(content, rule, transformer);
|
|
101
|
+
return root.commitEdits(edits);
|
|
102
|
+
}
|
|
87
103
|
async function commitEditModifications(edits, modifications) {
|
|
88
104
|
if (0 === edits.length) return modifications;
|
|
89
105
|
const root = modifications.ast.root();
|
|
@@ -117,4 +133,4 @@ function defaultedHooks(hooks) {
|
|
|
117
133
|
preCodemodRun
|
|
118
134
|
};
|
|
119
135
|
}
|
|
120
|
-
export { commitEditModifications, runCodemod, runCodemods };
|
|
136
|
+
export { commitEditModifications, findAndReplace, findAndReplaceEdits, runCodemod, runCodemods };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kamaalio/codemod-kit",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.16",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": "Kamaal Farah",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@ast-grep/napi": "^0.38.5",
|
|
23
|
+
"@kamaalio/kamaal": "^0.7.6",
|
|
23
24
|
"fast-glob": "^3.3.3",
|
|
24
25
|
"neverthrow": "^8.2.0"
|
|
25
26
|
},
|