@plumeria/codemod 18.0.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.
- package/LICENSE +21 -0
- package/README.md +74 -0
- package/bin/codemod.js +13 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +238 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +7 -0
- package/dist/transforms/rename-prop.d.ts +7 -0
- package/dist/transforms/rename-prop.js +93 -0
- package/package.json +45 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) zss-in-js contributer
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# @plumeria/codemod
|
|
2
|
+
|
|
3
|
+
Codemods for migrating Plumeria APIs. No install needed — run it with `npx`.
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npx @plumeria/codemod rename-prop classStyle sx
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## `rename-prop`
|
|
10
|
+
|
|
11
|
+
Renames the styling prop across your source. The names are arguments, so it
|
|
12
|
+
works for any rename, not just default prop:
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
npx @plumeria/codemod rename-prop <from> <to> [paths...]
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
| Option | Effect |
|
|
19
|
+
| ------------- | ----------------------------------------------- |
|
|
20
|
+
| `-d, --dry-run` | report what would change without writing |
|
|
21
|
+
| `--no-types` | leave TypeScript declarations untouched |
|
|
22
|
+
|
|
23
|
+
Paths default to the current directory. `node_modules`, `dist`, `build`, `out`,
|
|
24
|
+
`.next` and `coverage` are skipped.
|
|
25
|
+
|
|
26
|
+
### What it rewrites
|
|
27
|
+
|
|
28
|
+
JSX attributes:
|
|
29
|
+
|
|
30
|
+
```diff
|
|
31
|
+
- <div classStyle={styles.card} />
|
|
32
|
+
+ <div sx={styles.card} />
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
And property signatures annotated with Plumeria's `Style`, which covers the
|
|
36
|
+
global augmentation in your `plumeria.d.ts` as well as your own component props:
|
|
37
|
+
|
|
38
|
+
```diff
|
|
39
|
+
interface CardProps {
|
|
40
|
+
- classStyle?: Style;
|
|
41
|
+
+ sx?: Style;
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The annotation has to be `Style` for the rename to happen, so an unrelated
|
|
46
|
+
interface that happens to use the same key is left alone.
|
|
47
|
+
|
|
48
|
+
### What it reports instead of rewriting
|
|
49
|
+
|
|
50
|
+
Where the prop is destructured or read off an object, renaming it would change a
|
|
51
|
+
local binding and not just the prop, so those are listed for you to handle:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
2 occurrence(s) need a manual rename — "classStyle" is bound to a local name there:
|
|
55
|
+
src/components/Card.tsx:8:12
|
|
56
|
+
src/components/Card.tsx:14:22
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## After the rename
|
|
60
|
+
|
|
61
|
+
The rewrite only touches your source. Point the rest of the toolchain at the new
|
|
62
|
+
name too:
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
// next.config.ts / unplugin options
|
|
66
|
+
withPlumeria(nextConfig, { styleProp: 'sx' });
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
// eslint.config.js
|
|
71
|
+
settings: { plumeria: { styleProp: 'sx' } }
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Commit before running, so the rewrite can be reverted with `git checkout`.
|
package/bin/codemod.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { main } = require('../dist/cli.js');
|
|
4
|
+
|
|
5
|
+
main(process.argv.slice(2)).then(
|
|
6
|
+
(code) => {
|
|
7
|
+
process.exitCode = code;
|
|
8
|
+
},
|
|
9
|
+
(error) => {
|
|
10
|
+
console.error(`✖ ${(error && error.message) || error}`);
|
|
11
|
+
process.exitCode = 1;
|
|
12
|
+
},
|
|
13
|
+
);
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function main(argv: string[]): Promise<number>;
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
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 __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.main = main;
|
|
40
|
+
const node_child_process_1 = require("node:child_process");
|
|
41
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
42
|
+
const eslint_1 = require("eslint");
|
|
43
|
+
const tsParser = __importStar(require("@typescript-eslint/parser"));
|
|
44
|
+
const rename_prop_1 = require("./transforms/rename-prop");
|
|
45
|
+
const { version } = require('../package.json');
|
|
46
|
+
const TRANSFORMS = ['rename-prop'];
|
|
47
|
+
const SOURCE_FILES = '**/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}';
|
|
48
|
+
const IGNORES = [
|
|
49
|
+
'**/dist/**',
|
|
50
|
+
'**/build/**',
|
|
51
|
+
'**/out/**',
|
|
52
|
+
'**/.next/**',
|
|
53
|
+
'**/coverage/**',
|
|
54
|
+
];
|
|
55
|
+
const IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
56
|
+
const RESERVED = new Set(['className', 'key', 'ref', 'children', 'style']);
|
|
57
|
+
const USAGE = `plumeria-codemod — codemods for migrating Plumeria APIs
|
|
58
|
+
|
|
59
|
+
Usage
|
|
60
|
+
npx @plumeria/codemod rename-prop <from> <to> [paths...]
|
|
61
|
+
|
|
62
|
+
Options
|
|
63
|
+
-d, --dry-run report what would change without writing
|
|
64
|
+
--no-types leave TypeScript declarations untouched
|
|
65
|
+
-h, --help show this message
|
|
66
|
+
-v, --version show the version
|
|
67
|
+
|
|
68
|
+
Examples
|
|
69
|
+
npx @plumeria/codemod rename-prop classStyle sx
|
|
70
|
+
npx @plumeria/codemod rename-prop classStyle sx src app --dry-run
|
|
71
|
+
|
|
72
|
+
Paths default to the current directory. After the rewrite, point the toolchain
|
|
73
|
+
at the new name with \`styleProp\` on your bundler plugin, and with
|
|
74
|
+
\`settings: { plumeria: { styleProp: '<to>' } }\` in your ESLint config.`;
|
|
75
|
+
class UsageError extends Error {
|
|
76
|
+
}
|
|
77
|
+
function parseArgs(argv) {
|
|
78
|
+
if (argv.length === 0 || argv.includes('-h') || argv.includes('--help')) {
|
|
79
|
+
console.log(USAGE);
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
if (argv.includes('-v') || argv.includes('--version')) {
|
|
83
|
+
console.log(version);
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
const positional = [];
|
|
87
|
+
let dryRun = false;
|
|
88
|
+
let includeTypes = true;
|
|
89
|
+
for (const arg of argv) {
|
|
90
|
+
switch (arg) {
|
|
91
|
+
case '-d':
|
|
92
|
+
case '--dry-run':
|
|
93
|
+
dryRun = true;
|
|
94
|
+
break;
|
|
95
|
+
case '--no-types':
|
|
96
|
+
includeTypes = false;
|
|
97
|
+
break;
|
|
98
|
+
default:
|
|
99
|
+
if (arg.startsWith('-'))
|
|
100
|
+
throw new UsageError(`unknown option "${arg}"`);
|
|
101
|
+
positional.push(arg);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const [transform, from, to, ...targets] = positional;
|
|
105
|
+
if (!TRANSFORMS.includes(transform)) {
|
|
106
|
+
throw new UsageError(`unknown transform "${transform}". Available: ${TRANSFORMS.join(', ')}`);
|
|
107
|
+
}
|
|
108
|
+
if (!from || !to) {
|
|
109
|
+
throw new UsageError('rename-prop needs both <from> and <to>');
|
|
110
|
+
}
|
|
111
|
+
if (!IDENTIFIER.test(to)) {
|
|
112
|
+
throw new UsageError(`"${to}" is not a valid identifier`);
|
|
113
|
+
}
|
|
114
|
+
if (from === to) {
|
|
115
|
+
throw new UsageError(`<from> and <to> are both "${from}"`);
|
|
116
|
+
}
|
|
117
|
+
if (RESERVED.has(to)) {
|
|
118
|
+
throw new UsageError(`"${to}" is already used by React`);
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
from,
|
|
122
|
+
to,
|
|
123
|
+
targets: targets.length > 0 ? targets : ['.'],
|
|
124
|
+
dryRun,
|
|
125
|
+
includeTypes,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function buildConfig(options) {
|
|
129
|
+
const { from, to, includeTypes } = options;
|
|
130
|
+
return [
|
|
131
|
+
{ ignores: IGNORES },
|
|
132
|
+
{
|
|
133
|
+
files: [SOURCE_FILES],
|
|
134
|
+
languageOptions: {
|
|
135
|
+
parser: tsParser,
|
|
136
|
+
parserOptions: {
|
|
137
|
+
sourceType: 'module',
|
|
138
|
+
ecmaFeatures: { jsx: true },
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
plugins: { codemod: { rules: { 'rename-prop': rename_prop_1.renameProp } } },
|
|
142
|
+
rules: { 'codemod/rename-prop': ['error', { from, to, includeTypes }] },
|
|
143
|
+
},
|
|
144
|
+
];
|
|
145
|
+
}
|
|
146
|
+
function warnIfDirty() {
|
|
147
|
+
try {
|
|
148
|
+
const status = (0, node_child_process_1.execFileSync)('git', ['status', '--porcelain'], {
|
|
149
|
+
encoding: 'utf8',
|
|
150
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
151
|
+
});
|
|
152
|
+
if (status.trim()) {
|
|
153
|
+
console.warn('! git working tree is not clean. Commit first so the rewrite can be reverted.\n');
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async function main(argv) {
|
|
160
|
+
let options;
|
|
161
|
+
try {
|
|
162
|
+
options = parseArgs(argv);
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
if (!(error instanceof UsageError))
|
|
166
|
+
throw error;
|
|
167
|
+
console.error(`✖ ${error.message}\n`);
|
|
168
|
+
console.error(USAGE);
|
|
169
|
+
return 1;
|
|
170
|
+
}
|
|
171
|
+
if (!options)
|
|
172
|
+
return 0;
|
|
173
|
+
const { from, to, targets, dryRun } = options;
|
|
174
|
+
const baseConfig = {
|
|
175
|
+
overrideConfigFile: true,
|
|
176
|
+
overrideConfig: buildConfig(options),
|
|
177
|
+
errorOnUnmatchedPattern: false,
|
|
178
|
+
};
|
|
179
|
+
const results = await new eslint_1.ESLint(baseConfig).lintFiles(targets);
|
|
180
|
+
const cwd = process.cwd();
|
|
181
|
+
const relative = (filePath) => node_path_1.default.relative(cwd, filePath) || '.';
|
|
182
|
+
const changes = [];
|
|
183
|
+
const manual = [];
|
|
184
|
+
const unparsed = [];
|
|
185
|
+
let total = 0;
|
|
186
|
+
for (const result of results) {
|
|
187
|
+
let count = 0;
|
|
188
|
+
for (const message of result.messages) {
|
|
189
|
+
if (message.fatal) {
|
|
190
|
+
unparsed.push(`${relative(result.filePath)}: ${message.message}`);
|
|
191
|
+
}
|
|
192
|
+
else if (message.fix) {
|
|
193
|
+
count++;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
manual.push(`${relative(result.filePath)}:${message.line}:${message.column}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (count > 0) {
|
|
200
|
+
changes.push({ file: relative(result.filePath), count });
|
|
201
|
+
total += count;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (total === 0 && manual.length === 0) {
|
|
205
|
+
console.log(`No "${from}" found.`);
|
|
206
|
+
return unparsed.length > 0 ? report(unparsed) : 0;
|
|
207
|
+
}
|
|
208
|
+
if (total === 0) {
|
|
209
|
+
console.log(`Every remaining "${from}" needs a manual rename.`);
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
for (const { file, count } of changes) {
|
|
213
|
+
console.log(` ${file} ${count}`);
|
|
214
|
+
}
|
|
215
|
+
if (dryRun) {
|
|
216
|
+
console.log(`\n${total} occurrence(s) in ${changes.length} file(s) would become "${to}".`);
|
|
217
|
+
console.log('Run without --dry-run to apply.');
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
warnIfDirty();
|
|
221
|
+
const applied = await new eslint_1.ESLint({ ...baseConfig, fix: true }).lintFiles(targets);
|
|
222
|
+
await eslint_1.ESLint.outputFixes(applied);
|
|
223
|
+
console.log(`\n✔ renamed ${total} occurrence(s) of "${from}" to "${to}" in ${changes.length} file(s).`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (manual.length > 0) {
|
|
227
|
+
console.log(`\n${manual.length} occurrence(s) need a manual rename — "${from}" is bound to a local name there:`);
|
|
228
|
+
for (const location of manual)
|
|
229
|
+
console.log(` ${location}`);
|
|
230
|
+
}
|
|
231
|
+
return unparsed.length > 0 ? report(unparsed) : 0;
|
|
232
|
+
}
|
|
233
|
+
function report(unparsed) {
|
|
234
|
+
console.error(`\n✖ ${unparsed.length} file(s) could not be parsed:`);
|
|
235
|
+
for (const failure of unparsed)
|
|
236
|
+
console.error(` ${failure}`);
|
|
237
|
+
return 1;
|
|
238
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.main = exports.renameProp = void 0;
|
|
4
|
+
const rename_prop_1 = require("./transforms/rename-prop");
|
|
5
|
+
Object.defineProperty(exports, "renameProp", { enumerable: true, get: function () { return rename_prop_1.renameProp; } });
|
|
6
|
+
var cli_1 = require("./cli");
|
|
7
|
+
Object.defineProperty(exports, "main", { enumerable: true, get: function () { return cli_1.main; } });
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renameProp = void 0;
|
|
4
|
+
function isStyleAnnotation(node) {
|
|
5
|
+
if (!node)
|
|
6
|
+
return false;
|
|
7
|
+
switch (node.type) {
|
|
8
|
+
case 'TSTypeReference': {
|
|
9
|
+
const name = node.typeName;
|
|
10
|
+
if (name?.type === 'Identifier')
|
|
11
|
+
return name.name === 'Style';
|
|
12
|
+
if (name?.type === 'TSQualifiedName')
|
|
13
|
+
return name.right?.name === 'Style';
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
case 'TSUnionType':
|
|
17
|
+
case 'TSIntersectionType':
|
|
18
|
+
return node.types.some(isStyleAnnotation);
|
|
19
|
+
default:
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.renameProp = {
|
|
24
|
+
meta: {
|
|
25
|
+
type: 'suggestion',
|
|
26
|
+
docs: {
|
|
27
|
+
description: 'Rename a JSX prop to a new name',
|
|
28
|
+
},
|
|
29
|
+
fixable: 'code',
|
|
30
|
+
messages: {
|
|
31
|
+
rename: 'Rename "{{from}}" to "{{to}}".',
|
|
32
|
+
manual: '"{{from}}" is forwarded here. Rename it to "{{to}}" by hand — an autofix would change the local binding too.',
|
|
33
|
+
},
|
|
34
|
+
schema: [
|
|
35
|
+
{
|
|
36
|
+
type: 'object',
|
|
37
|
+
properties: {
|
|
38
|
+
from: { type: 'string' },
|
|
39
|
+
to: { type: 'string' },
|
|
40
|
+
includeTypes: { type: 'boolean' },
|
|
41
|
+
},
|
|
42
|
+
required: ['from', 'to'],
|
|
43
|
+
additionalProperties: false,
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
create(context) {
|
|
48
|
+
const { from, to, includeTypes = true, } = context.options[0];
|
|
49
|
+
const rename = (node) => context.report({
|
|
50
|
+
node,
|
|
51
|
+
messageId: 'rename',
|
|
52
|
+
data: { from, to },
|
|
53
|
+
fix: (fixer) => fixer.replaceText(node, to),
|
|
54
|
+
});
|
|
55
|
+
const manual = (node) => context.report({ node, messageId: 'manual', data: { from, to } });
|
|
56
|
+
return {
|
|
57
|
+
JSXAttribute(node) {
|
|
58
|
+
if (node.name.type !== 'JSXIdentifier')
|
|
59
|
+
return;
|
|
60
|
+
if (node.name.name !== from)
|
|
61
|
+
return;
|
|
62
|
+
rename(node.name);
|
|
63
|
+
},
|
|
64
|
+
TSPropertySignature(node) {
|
|
65
|
+
if (!includeTypes)
|
|
66
|
+
return;
|
|
67
|
+
if (node.key.type !== 'Identifier' || node.key.name !== from)
|
|
68
|
+
return;
|
|
69
|
+
if (!isStyleAnnotation(node.typeAnnotation?.typeAnnotation))
|
|
70
|
+
return;
|
|
71
|
+
rename(node.key);
|
|
72
|
+
},
|
|
73
|
+
Property(node) {
|
|
74
|
+
if (node.parent?.type !== 'ObjectPattern')
|
|
75
|
+
return;
|
|
76
|
+
if (node.computed)
|
|
77
|
+
return;
|
|
78
|
+
if (node.key.type !== 'Identifier' || node.key.name !== from)
|
|
79
|
+
return;
|
|
80
|
+
manual(node.key);
|
|
81
|
+
},
|
|
82
|
+
MemberExpression(node) {
|
|
83
|
+
if (node.computed)
|
|
84
|
+
return;
|
|
85
|
+
if (node.property.type !== 'Identifier')
|
|
86
|
+
return;
|
|
87
|
+
if (node.property.name !== from)
|
|
88
|
+
return;
|
|
89
|
+
manual(node.property);
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
},
|
|
93
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@plumeria/codemod",
|
|
3
|
+
"version": "18.0.0",
|
|
4
|
+
"description": "Codemods for migrating Plumeria APIs",
|
|
5
|
+
"author": "Refirst 11",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"funding": "https://github.com/sponsors/refirst11",
|
|
8
|
+
"homepage": "https://plumeria.dev",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/zss-in-js/plumeria.git",
|
|
12
|
+
"directory": "packages/codemod"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/zss-in-js/plumeria/issues"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"plumeria",
|
|
19
|
+
"codemod",
|
|
20
|
+
"migration",
|
|
21
|
+
"eslint",
|
|
22
|
+
"css-in-js"
|
|
23
|
+
],
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"main": "dist/index.js",
|
|
26
|
+
"types": "dist/index.d.ts",
|
|
27
|
+
"bin": {
|
|
28
|
+
"plumeria-codemod": "bin/codemod.js"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist/",
|
|
32
|
+
"bin/"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "rimraf dist && pnpm cjs",
|
|
36
|
+
"cjs": "tsc --project tsconfig.cjs.json"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@typescript-eslint/parser": "^8.60.0",
|
|
40
|
+
"eslint": "^10.4.1"
|
|
41
|
+
},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
}
|
|
45
|
+
}
|