aihand 0.0.1 → 0.1.1
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 +152 -2
- package/dist/chunk-2NTK7H4W.js +10 -0
- package/dist/chunk-3X4FTHLC.cjs +369 -0
- package/dist/chunk-BXVNR4E2.js +399 -0
- package/dist/chunk-C7DGE6MY.cjs +1456 -0
- package/dist/chunk-DUUCVLC3.cjs +254 -0
- package/dist/chunk-FAHI53KO.cjs +125 -0
- package/dist/chunk-G7KVJ7NF.js +369 -0
- package/dist/chunk-GNEUSRGP.js +52 -0
- package/dist/chunk-IGNEAOLT.cjs +130 -0
- package/dist/chunk-IS5XFUDB.js +125 -0
- package/dist/chunk-JLYC76XL.js +2448 -0
- package/dist/chunk-KQOABC2O.cjs +52 -0
- package/dist/chunk-OVMK33AC.cjs +104 -0
- package/dist/chunk-OWYK2IGV.js +250 -0
- package/dist/chunk-PQSQN4CN.js +126 -0
- package/dist/chunk-QF6AG3M5.cjs +410 -0
- package/dist/chunk-QSAMLXML.js +1456 -0
- package/dist/chunk-VEKYRKPF.cjs +399 -0
- package/dist/chunk-Y6H7W7PI.cjs +2451 -0
- package/dist/chunk-YKSYW77R.js +410 -0
- package/dist/chunk-Z2Y65YOY.cjs +7 -0
- package/dist/chunk-ZJQRNIK7.js +104 -0
- package/dist/cli-3J7EYI6G.cjs +651 -0
- package/dist/cli-FIJLKAGI.js +649 -0
- package/dist/cli-JQEIE7RQ.js +120 -0
- package/dist/cli-K3OS2QQH.cjs +122 -0
- package/dist/cli-OSYG6LJD.cjs +89 -0
- package/dist/cli-TXRW5PG6.js +89 -0
- package/dist/cli.cjs +81 -0
- package/dist/cli.js +81 -0
- package/dist/config-5KEQLN6L.cjs +13 -0
- package/dist/config-PJPYKDLQ.js +13 -0
- package/dist/graph-IH56SCPK.js +8 -0
- package/dist/graph-ZUXXCJ5A.cjs +8 -0
- package/dist/index.cjs +481 -0
- package/dist/index.d.cts +461 -0
- package/dist/index.d.ts +461 -0
- package/dist/index.js +479 -0
- package/dist/locate-5XFSXJ5J.cjs +15 -0
- package/dist/locate-NKSUGL3A.js +15 -0
- package/dist/refactor-5FWSZIBN.cjs +19 -0
- package/dist/refactor-BOB3SZSA.js +19 -0
- package/dist/scan-4R7GQG2W.cjs +9 -0
- package/dist/scan-VF54GAAX.js +9 -0
- package/dist/ui/probe/server.cjs +505 -0
- package/dist/ui/probe/server.js +507 -0
- package/dist/vite.cjs +12 -0
- package/dist/vite.d.cts +12 -0
- package/dist/vite.d.ts +12 -0
- package/dist/vite.js +12 -0
- package/package.json +82 -9
- package/src/cli.ts +107 -0
- package/src/index.ts +54 -0
- package/src/read/cli.ts +650 -0
- package/src/read/compact.ts +286 -0
- package/src/read/config.ts +62 -0
- package/src/read/graph.ts +182 -0
- package/src/read/index.ts +12 -0
- package/src/read/inject.ts +121 -0
- package/src/read/locate.ts +104 -0
- package/src/read/panel.ts +335 -0
- package/src/read/pipeline.ts +78 -0
- package/src/read/refactor.ts +576 -0
- package/src/read/render.ts +1118 -0
- package/src/read/scan.ts +61 -0
- package/src/read/seam.ts +0 -0
- package/src/read/security.ts +171 -0
- package/src/read/signals.ts +333 -0
- package/src/read/state.ts +71 -0
- package/src/read/stategraph.ts +205 -0
- package/src/read/types.ts +162 -0
- package/src/read/vite.ts +77 -0
- package/src/ui/babel/line-profiler.ts +197 -0
- package/src/ui/babel/source-loc.ts +68 -0
- package/src/ui/bridge/cdp-bridge.ts +138 -0
- package/src/ui/bridge/compile-probe.ts +80 -0
- package/src/ui/bridge/transport.ts +26 -0
- package/src/ui/bridge/vite-bridge.ts +116 -0
- package/src/ui/client/client-patch.ts +899 -0
- package/src/ui/client/client.ts +2562 -0
- package/src/ui/core/action.ts +747 -0
- package/src/ui/core/candidates.ts +348 -0
- package/src/ui/core/canvas.ts +305 -0
- package/src/ui/core/check.ts +34 -0
- package/src/ui/core/compact.ts +314 -0
- package/src/ui/core/detail.ts +244 -0
- package/src/ui/core/diff.ts +253 -0
- package/src/ui/core/emit.ts +198 -0
- package/src/ui/core/knob-exec.ts +137 -0
- package/src/ui/core/perf.ts +254 -0
- package/src/ui/core/types.ts +164 -0
- package/src/ui/core/util.ts +221 -0
- package/src/ui/index.ts +5 -0
- package/src/ui/probe/cli.ts +139 -0
- package/src/ui/probe/server.ts +468 -0
- package/src/ui/self/act.ts +47 -0
- package/src/ui/self/discover.ts +101 -0
- package/src/ui/self/grow.ts +121 -0
- package/src/ui/self/install.ts +100 -0
- package/src/ui/self/probe.ts +105 -0
- package/src/ui/self/screen-hook.ts +44 -0
- package/src/ui/self/self.ts +48 -0
- package/src/ui/self/store-refs.ts +123 -0
- package/src/ui/self/store-schema.ts +65 -0
- package/src/ui/self/synth.ts +37 -0
- package/src/ui/server/cli.ts +102 -0
- package/src/ui/server/dispatch.ts +276 -0
- package/src/ui/server/help-text.ts +237 -0
- package/src/ui/server/knob-schema.ts +87 -0
- package/src/ui/server/plugin.ts +1151 -0
- package/src/vite.ts +39 -0
- package/index.js +0 -2
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/read/refactor.ts
|
|
2
|
+
var _fs = require('fs');
|
|
3
|
+
var _path = require('path');
|
|
4
|
+
var _process = require('process'); var _process2 = _interopRequireDefault(_process);
|
|
5
|
+
var _tsmorph = require('ts-morph');
|
|
6
|
+
async function openProject() {
|
|
7
|
+
const { Project, QuoteKind } = await Promise.resolve().then(() => _interopRequireWildcard(require("ts-morph")));
|
|
8
|
+
const tsConfigFilePath = ["tsconfig.app.json", "tsconfig.json"].map((f) => _path.resolve.call(void 0, f)).find(_fs.existsSync);
|
|
9
|
+
if (!tsConfigFilePath) {
|
|
10
|
+
console.error("refactor: no tsconfig.json (or tsconfig.app.json) found in cwd");
|
|
11
|
+
_process2.default.exit(1);
|
|
12
|
+
}
|
|
13
|
+
return new Project({ tsConfigFilePath, manipulationSettings: { quoteKind: QuoteKind.Single } });
|
|
14
|
+
}
|
|
15
|
+
function aliasPrefixes(project) {
|
|
16
|
+
const opts = project.getCompilerOptions();
|
|
17
|
+
const base = _nullishCoalesce(opts.baseUrl, () => ( _process2.default.cwd()));
|
|
18
|
+
const out = [];
|
|
19
|
+
for (const [pattern, targets] of Object.entries(_nullishCoalesce(opts.paths, () => ( {})))) {
|
|
20
|
+
if (!pattern.endsWith("/*") || !_optionalChain([targets, 'access', _ => _[0], 'optionalAccess', _2 => _2.endsWith, 'call', _3 => _3("/*")]))
|
|
21
|
+
continue;
|
|
22
|
+
out.push({ alias: pattern.slice(0, -2), target: _path.resolve.call(void 0, base, targets[0].slice(0, -2)) });
|
|
23
|
+
}
|
|
24
|
+
return out;
|
|
25
|
+
}
|
|
26
|
+
function stripExt(p) {
|
|
27
|
+
const ext = [".tsx", ".ts", ".jsx", ".js"].find((e) => p.endsWith(e));
|
|
28
|
+
return ext ? p.slice(0, -ext.length) : p;
|
|
29
|
+
}
|
|
30
|
+
function toAlias(absPath, prefixes) {
|
|
31
|
+
const noExt = stripExt(absPath);
|
|
32
|
+
for (const { alias, target } of prefixes) {
|
|
33
|
+
if (noExt === target || noExt.startsWith(`${target}/`))
|
|
34
|
+
return `${alias}/${noExt.slice(target.length + 1)}`;
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
function aliasSpecToAbs(spec, prefixes) {
|
|
39
|
+
for (const { alias, target } of prefixes) {
|
|
40
|
+
if (spec === alias)
|
|
41
|
+
return target;
|
|
42
|
+
if (spec.startsWith(`${alias}/`))
|
|
43
|
+
return `${target}/${spec.slice(alias.length + 1)}`;
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
function moveInProject(project, srcAbs, destAbs) {
|
|
48
|
+
const sf = project.getSourceFile(srcAbs);
|
|
49
|
+
if (!sf)
|
|
50
|
+
throw new Error(`${srcAbs} not in project`);
|
|
51
|
+
if (srcAbs !== destAbs && project.getSourceFile(destAbs))
|
|
52
|
+
throw new Error(`destination ${destAbs} already exists; move to a fresh path or delete it first`);
|
|
53
|
+
const prefixes = aliasPrefixes(project);
|
|
54
|
+
const srcNoExt = stripExt(srcAbs);
|
|
55
|
+
const pointsAtSrc = (spec) => {
|
|
56
|
+
const resolved = aliasSpecToAbs(spec, prefixes);
|
|
57
|
+
return resolved !== null && stripExt(resolved) === srcNoExt;
|
|
58
|
+
};
|
|
59
|
+
const declFixups = [];
|
|
60
|
+
const litFixups = [];
|
|
61
|
+
const changed = /* @__PURE__ */ new Set();
|
|
62
|
+
for (const ref of project.getSourceFiles()) {
|
|
63
|
+
if (ref === sf)
|
|
64
|
+
continue;
|
|
65
|
+
for (const d of ref.getImportDeclarations()) {
|
|
66
|
+
if (pointsAtSrc(d.getModuleSpecifierValue())) {
|
|
67
|
+
changed.add(ref);
|
|
68
|
+
declFixups.push({ decl: d, file: ref });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
for (const d of ref.getExportDeclarations()) {
|
|
72
|
+
const spec = d.getModuleSpecifierValue();
|
|
73
|
+
if (spec && pointsAtSrc(spec)) {
|
|
74
|
+
changed.add(ref);
|
|
75
|
+
declFixups.push({ decl: d, file: ref });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
for (const call of ref.getDescendantsOfKind(_tsmorph.SyntaxKind.CallExpression)) {
|
|
79
|
+
if (call.getExpression().getKind() !== _tsmorph.SyntaxKind.ImportKeyword)
|
|
80
|
+
continue;
|
|
81
|
+
const arg = call.getArguments()[0];
|
|
82
|
+
if (arg && _tsmorph.Node.isStringLiteral(arg) && pointsAtSrc(arg.getLiteralValue())) {
|
|
83
|
+
changed.add(ref);
|
|
84
|
+
litFixups.push({ lit: arg, file: ref });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
for (const ref of sf.getReferencingSourceFiles())
|
|
89
|
+
changed.add(ref);
|
|
90
|
+
sf.move(destAbs);
|
|
91
|
+
changed.add(sf);
|
|
92
|
+
for (const { decl, file } of declFixups)
|
|
93
|
+
decl.setModuleSpecifier(specifierFrom(file, destAbs, prefixes));
|
|
94
|
+
for (const { lit, file } of litFixups)
|
|
95
|
+
lit.setLiteralValue(specifierFrom(file, destAbs, prefixes));
|
|
96
|
+
return [...changed];
|
|
97
|
+
}
|
|
98
|
+
function findNamedDecl(sf, name) {
|
|
99
|
+
return _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(sf.getVariableDeclaration(name), () => ( sf.getFunction(name))), () => ( sf.getClass(name))), () => ( sf.getInterface(name))), () => ( sf.getTypeAlias(name))), () => ( sf.getEnum(name))), () => ( null));
|
|
100
|
+
}
|
|
101
|
+
function renameInProject(project, fileAbs, oldName, newName) {
|
|
102
|
+
const sf = project.getSourceFile(fileAbs);
|
|
103
|
+
if (!sf)
|
|
104
|
+
throw new Error(`${fileAbs} not in project`);
|
|
105
|
+
const decl = findNamedDecl(sf, oldName);
|
|
106
|
+
if (!decl)
|
|
107
|
+
throw new Error(`no top-level declaration named '${oldName}' in ${fileAbs}`);
|
|
108
|
+
for (const exp of sf.getExportDeclarations()) {
|
|
109
|
+
for (const spec of exp.getNamedExports()) {
|
|
110
|
+
if (spec.getAliasNode() && spec.getNameNode().getText() === oldName)
|
|
111
|
+
throw new Error(`'${oldName}' is exported under the alias '${spec.getAliasNode().getText()}' (export { ${oldName} as ${spec.getAliasNode().getText()} }); renaming the local name would corrupt importers that reference the public name. Rename '${spec.getAliasNode().getText()}' instead, or rewrite the export by hand.`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const changed = /* @__PURE__ */ new Set([sf]);
|
|
115
|
+
for (const ref of decl.findReferences()) {
|
|
116
|
+
for (const r of ref.getReferences())
|
|
117
|
+
changed.add(r.getSourceFile());
|
|
118
|
+
}
|
|
119
|
+
decl.rename(newName);
|
|
120
|
+
return [...changed];
|
|
121
|
+
}
|
|
122
|
+
function specifierFrom(from, toAbs, prefixes) {
|
|
123
|
+
const alias = toAlias(toAbs, prefixes);
|
|
124
|
+
if (alias)
|
|
125
|
+
return alias;
|
|
126
|
+
const to = _nullishCoalesce(from.getProject().getSourceFile(toAbs), () => ( from.getProject().addSourceFileAtPath(toAbs)));
|
|
127
|
+
return from.getRelativePathAsModuleSpecifierTo(to);
|
|
128
|
+
}
|
|
129
|
+
function bindingNodeOf(ni) {
|
|
130
|
+
return _nullishCoalesce(ni.getAliasNode(), () => ( ni.getNameNode()));
|
|
131
|
+
}
|
|
132
|
+
function scopeUsesBinding(scope, bindingNode) {
|
|
133
|
+
const target = bindingNode.getSymbol();
|
|
134
|
+
if (!target)
|
|
135
|
+
return false;
|
|
136
|
+
let used = false;
|
|
137
|
+
scope.forEachDescendant((node, traversal) => {
|
|
138
|
+
if (used) {
|
|
139
|
+
traversal.stop();
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (!_tsmorph.Node.isIdentifier(node))
|
|
143
|
+
return;
|
|
144
|
+
if (node === bindingNode)
|
|
145
|
+
return;
|
|
146
|
+
const parent = node.getParent();
|
|
147
|
+
if (_tsmorph.Node.isPropertyAccessExpression(parent) && parent.getNameNode() === node)
|
|
148
|
+
return;
|
|
149
|
+
if (_tsmorph.Node.isPropertyAssignment(parent) && parent.getNameNode() === node)
|
|
150
|
+
return;
|
|
151
|
+
if (node.getSymbol() === target)
|
|
152
|
+
used = true;
|
|
153
|
+
});
|
|
154
|
+
return used;
|
|
155
|
+
}
|
|
156
|
+
function moveSymbolInProject(project, fromAbs, name, toAbs) {
|
|
157
|
+
const from = project.getSourceFile(fromAbs);
|
|
158
|
+
if (!from)
|
|
159
|
+
throw new Error(`${fromAbs} not in project`);
|
|
160
|
+
const decl = findNamedDecl(from, name);
|
|
161
|
+
if (!decl)
|
|
162
|
+
throw new Error(`no top-level declaration named '${name}' in ${fromAbs}`);
|
|
163
|
+
if (fromAbs === toAbs)
|
|
164
|
+
throw new Error(`source and destination are the same file (${fromAbs}); nothing to move`);
|
|
165
|
+
const to = _nullishCoalesce(project.getSourceFile(toAbs), () => ( project.createSourceFile(toAbs, "")));
|
|
166
|
+
if (to !== from && findNamedDecl(to, name))
|
|
167
|
+
throw new Error(`${toAbs} already declares '${name}'`);
|
|
168
|
+
const guardScope = decl.getKindName() === "VariableDeclaration" ? decl.getVariableStatementOrThrow() : decl;
|
|
169
|
+
const siblingDeps = /* @__PURE__ */ new Set();
|
|
170
|
+
for (const id of guardScope.getDescendantsOfKind(
|
|
171
|
+
80
|
|
172
|
+
/* Identifier */
|
|
173
|
+
)) {
|
|
174
|
+
const parent = id.getParent();
|
|
175
|
+
if (_tsmorph.Node.isPropertyAccessExpression(parent) && parent.getNameNode() === id)
|
|
176
|
+
continue;
|
|
177
|
+
const sym = id.getSymbol();
|
|
178
|
+
if (!sym)
|
|
179
|
+
continue;
|
|
180
|
+
for (const d of sym.getDeclarations()) {
|
|
181
|
+
if (d.getSourceFile() !== from || d === decl)
|
|
182
|
+
continue;
|
|
183
|
+
const stmt = _tsmorph.Node.isVariableDeclaration(d) ? d.getVariableStatementOrThrow() : d;
|
|
184
|
+
if (_optionalChain([stmt, 'access', _4 => _4.getParent, 'call', _5 => _5(), 'optionalAccess', _6 => _6.getKindName, 'call', _7 => _7()]) !== "SourceFile")
|
|
185
|
+
continue;
|
|
186
|
+
const exported = _tsmorph.Node.isExportable(stmt) && stmt.isExported();
|
|
187
|
+
if (!exported)
|
|
188
|
+
throw new Error(`'${name}' depends on local symbol '${id.getText()}' (not exported); export it or move them together`);
|
|
189
|
+
siblingDeps.add(id.getText());
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
for (const ref of from.getReferencingSourceFiles()) {
|
|
193
|
+
for (const ed of ref.getExportDeclarations()) {
|
|
194
|
+
if (ed.getModuleSpecifierSourceFile() === from && ed.getNamedExports().some((ne) => ne.getName() === name))
|
|
195
|
+
throw new Error(`'${name}' is re-exported by ${ref.getFilePath()}; update the barrel first or move it manually`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
for (const r of decl.findReferences()) {
|
|
199
|
+
for (const ref of r.getReferences()) {
|
|
200
|
+
const node = ref.getNode();
|
|
201
|
+
const parent = node.getParent();
|
|
202
|
+
if (_tsmorph.Node.isPropertyAccessExpression(parent) && parent.getNameNode() === node && ref.getSourceFile() !== from)
|
|
203
|
+
throw new Error(`'${name}' is accessed via a namespace import in ${ref.getSourceFile().getFilePath()}; move it manually`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (_tsmorph.Node.isExportable(guardScope) && guardScope.isDefaultExport())
|
|
207
|
+
throw new Error(`'${name}' is the default export of ${fromAbs}; default importers bind arbitrary local names that can't be rewritten. Make it a named export first, or move it manually.`);
|
|
208
|
+
for (const ed of from.getExportDeclarations()) {
|
|
209
|
+
for (const ne of ed.getNamedExports()) {
|
|
210
|
+
if (ed.getModuleSpecifierValue()) continue;
|
|
211
|
+
if (ne.getNameNode().getText() === name && _optionalChain([ne, 'access', _8 => _8.getAliasNode, 'call', _9 => _9(), 'optionalAccess', _10 => _10.getText, 'call', _11 => _11()]) === "default")
|
|
212
|
+
throw new Error(`'${name}' is the default export of ${fromAbs} (export { ${name} as default }); default importers bind arbitrary local names that can't be rewritten. Make it a named export first, or move it manually.`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
for (const ed of from.getExportDeclarations()) {
|
|
216
|
+
if (ed.getModuleSpecifierValue()) continue;
|
|
217
|
+
for (const ne of ed.getNamedExports()) {
|
|
218
|
+
const alias = _optionalChain([ne, 'access', _12 => _12.getAliasNode, 'call', _13 => _13(), 'optionalAccess', _14 => _14.getText, 'call', _15 => _15()]);
|
|
219
|
+
if (ne.getNameNode().getText() === name && alias && alias !== "default")
|
|
220
|
+
throw new Error(`'${name}' is exported under the alias '${alias}' (export { ${name} as ${alias} }); the public name '${alias}' that importers reference can't survive a plain move. Rewrite the export, or move it manually.`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const prefixes = aliasPrefixes(project);
|
|
224
|
+
const varStmt = decl.getKindName() === "VariableDeclaration" ? decl.getVariableStatementOrThrow() : null;
|
|
225
|
+
const sharedDeclarators = varStmt ? varStmt.getDeclarations().length > 1 : false;
|
|
226
|
+
const declText = varStmt ? sharedDeclarators ? `${varStmt.isExported() ? "export " : ""}${varStmt.getDeclarationKind()} ${decl.getText()}` : varStmt.getText(true) : decl.getText(true);
|
|
227
|
+
const depScope = _nullishCoalesce(varStmt, () => ( decl));
|
|
228
|
+
const carried = [];
|
|
229
|
+
for (const imp of from.getImportDeclarations()) {
|
|
230
|
+
const struct = imp.getStructure();
|
|
231
|
+
const keptNamed = imp.getNamedImports().filter((n) => scopeUsesBinding(depScope, bindingNodeOf(n)));
|
|
232
|
+
const dflt = imp.getDefaultImport();
|
|
233
|
+
const ns = imp.getNamespaceImport();
|
|
234
|
+
const keepDflt = dflt ? scopeUsesBinding(depScope, dflt) : false;
|
|
235
|
+
const keepNs = ns ? scopeUsesBinding(depScope, ns) : false;
|
|
236
|
+
if (!keptNamed.length && !keepDflt && !keepNs)
|
|
237
|
+
continue;
|
|
238
|
+
let spec = struct.moduleSpecifier;
|
|
239
|
+
if (spec.startsWith(".")) {
|
|
240
|
+
const target = imp.getModuleSpecifierSourceFile();
|
|
241
|
+
if (target)
|
|
242
|
+
spec = specifierFrom(to, target.getFilePath(), prefixes);
|
|
243
|
+
}
|
|
244
|
+
carried.push({
|
|
245
|
+
...struct,
|
|
246
|
+
moduleSpecifier: spec,
|
|
247
|
+
defaultImport: keepDflt ? struct.defaultImport : void 0,
|
|
248
|
+
namespaceImport: keepNs ? struct.namespaceImport : void 0,
|
|
249
|
+
namedImports: keptNamed.map((n) => n.getStructure())
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
const refFiles = /* @__PURE__ */ new Set();
|
|
253
|
+
const rewrites = [];
|
|
254
|
+
for (const ref of decl.findReferences()) {
|
|
255
|
+
for (const r of ref.getReferences()) {
|
|
256
|
+
const rf = r.getSourceFile();
|
|
257
|
+
if (rf !== from)
|
|
258
|
+
refFiles.add(rf);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
for (const rf of refFiles) {
|
|
262
|
+
for (const imp of rf.getImportDeclarations()) {
|
|
263
|
+
if (imp.getModuleSpecifierSourceFile() !== from)
|
|
264
|
+
continue;
|
|
265
|
+
const ni = imp.getNamedImports().find((n) => n.getName() === name);
|
|
266
|
+
if (ni)
|
|
267
|
+
rewrites.push({ rf, imp, moved: ni.getStructure(), typeOnly: imp.isTypeOnly() });
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
const aStillUses = decl.findReferences().some((ref) => ref.getReferences().some((r) => r.getSourceFile() === from && r.getNode() !== _optionalChain([decl, 'access', _16 => _16.getNameNode, 'optionalCall', _17 => _17()])));
|
|
271
|
+
const existing = to.getFullText();
|
|
272
|
+
const lead = existing.length && !existing.endsWith("\n") ? "\n" : "";
|
|
273
|
+
to.insertText(existing.length, `${lead}${declText}
|
|
274
|
+
`);
|
|
275
|
+
for (const c of carried) {
|
|
276
|
+
const existingImp = to.getImportDeclarations().find((d) => d.getModuleSpecifierValue() === c.moduleSpecifier);
|
|
277
|
+
if (existingImp && !c.defaultImport && !c.namespaceImport && Array.isArray(c.namedImports)) {
|
|
278
|
+
for (const ni of c.namedImports)
|
|
279
|
+
existingImp.addNamedImport(ni);
|
|
280
|
+
} else {
|
|
281
|
+
to.insertImportDeclaration(0, c);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
if (to !== from && siblingDeps.size) {
|
|
285
|
+
const aSpec = specifierFrom(to, fromAbs, prefixes);
|
|
286
|
+
const existingA = to.getImportDeclarations().find((d) => d.getModuleSpecifierValue() === aSpec && !d.isTypeOnly());
|
|
287
|
+
if (existingA) {
|
|
288
|
+
const have = new Set(existingA.getNamedImports().map((n) => n.getName()));
|
|
289
|
+
for (const s of siblingDeps)
|
|
290
|
+
if (!have.has(s))
|
|
291
|
+
existingA.addNamedImport(s);
|
|
292
|
+
} else {
|
|
293
|
+
to.insertImportDeclaration(0, { moduleSpecifier: aSpec, namedImports: [...siblingDeps] });
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
if (sharedDeclarators)
|
|
297
|
+
decl.remove();
|
|
298
|
+
else
|
|
299
|
+
(_nullishCoalesce(varStmt, () => ( decl))).remove();
|
|
300
|
+
for (const imp of from.getImportDeclarations()) {
|
|
301
|
+
for (const ni of imp.getNamedImports()) {
|
|
302
|
+
if (!scopeUsesBinding(from, bindingNodeOf(ni)))
|
|
303
|
+
ni.remove();
|
|
304
|
+
}
|
|
305
|
+
const dflt = imp.getDefaultImport();
|
|
306
|
+
if (dflt && !scopeUsesBinding(from, dflt))
|
|
307
|
+
imp.removeDefaultImport();
|
|
308
|
+
const ns = imp.getNamespaceImport();
|
|
309
|
+
if (ns && !scopeUsesBinding(from, ns))
|
|
310
|
+
imp.removeNamespaceImport();
|
|
311
|
+
if (!imp.getNamedImports().length && !imp.getDefaultImport() && !imp.getNamespaceImport())
|
|
312
|
+
imp.remove();
|
|
313
|
+
}
|
|
314
|
+
const toSpecFor = (f) => specifierFrom(f, toAbs, prefixes);
|
|
315
|
+
for (const { rf, imp, moved, typeOnly } of rewrites) {
|
|
316
|
+
const bSpec = toSpecFor(rf);
|
|
317
|
+
const ni = imp.getNamedImports().find((n) => n.getName() === name);
|
|
318
|
+
if (ni) {
|
|
319
|
+
ni.remove();
|
|
320
|
+
if (imp.getNamedImports().length === 0 && !imp.getDefaultImport() && !imp.getNamespaceImport())
|
|
321
|
+
imp.remove();
|
|
322
|
+
}
|
|
323
|
+
const existingB = rf.getImportDeclarations().find((d) => d.getModuleSpecifierValue() === bSpec && d.isTypeOnly() === typeOnly);
|
|
324
|
+
if (existingB)
|
|
325
|
+
existingB.addNamedImport(moved);
|
|
326
|
+
else
|
|
327
|
+
rf.addImportDeclaration({ moduleSpecifier: bSpec, namedImports: [moved], isTypeOnly: typeOnly });
|
|
328
|
+
}
|
|
329
|
+
if (aStillUses)
|
|
330
|
+
from.addImportDeclaration({ moduleSpecifier: specifierFrom(from, toAbs, prefixes), namedImports: [name] });
|
|
331
|
+
return [.../* @__PURE__ */ new Set([from, to, ...refFiles])];
|
|
332
|
+
}
|
|
333
|
+
async function moveFile(src, dest, dry = false) {
|
|
334
|
+
const project = await openProject();
|
|
335
|
+
const root = _process2.default.cwd();
|
|
336
|
+
let changed;
|
|
337
|
+
try {
|
|
338
|
+
changed = moveInProject(project, _path.resolve.call(void 0, src), _path.resolve.call(void 0, dest));
|
|
339
|
+
} catch (e2) {
|
|
340
|
+
console.error(`refactor: ${src} not in tsconfig project (check include globs)`);
|
|
341
|
+
_process2.default.exit(1);
|
|
342
|
+
}
|
|
343
|
+
console.log(`move ${_path.relative.call(void 0, root, src)} \u2192 ${_path.relative.call(void 0, root, dest)}`);
|
|
344
|
+
console.log(`${changed.length} file(s) ${dry ? "would change" : "changed"}:`);
|
|
345
|
+
for (const f of changed)
|
|
346
|
+
console.log(` ${_path.relative.call(void 0, root, f.getFilePath())}`);
|
|
347
|
+
if (dry)
|
|
348
|
+
return;
|
|
349
|
+
await project.save();
|
|
350
|
+
console.log("saved. verify: tsc --noEmit");
|
|
351
|
+
}
|
|
352
|
+
async function moveSymbol(from, name, to, dry = false) {
|
|
353
|
+
const project = await openProject();
|
|
354
|
+
const root = _process2.default.cwd();
|
|
355
|
+
let changed;
|
|
356
|
+
try {
|
|
357
|
+
changed = moveSymbolInProject(project, _path.resolve.call(void 0, from), name, _path.resolve.call(void 0, to));
|
|
358
|
+
} catch (e) {
|
|
359
|
+
console.error(`refactor: ${e.message}`);
|
|
360
|
+
_process2.default.exit(1);
|
|
361
|
+
}
|
|
362
|
+
console.log(`move-symbol ${name}: ${_path.relative.call(void 0, root, from)} \u2192 ${_path.relative.call(void 0, root, to)}`);
|
|
363
|
+
console.log(`${changed.length} file(s) ${dry ? "would change" : "changed"}:`);
|
|
364
|
+
for (const f of changed)
|
|
365
|
+
console.log(` ${_path.relative.call(void 0, root, f.getFilePath())}`);
|
|
366
|
+
if (dry)
|
|
367
|
+
return;
|
|
368
|
+
await project.save();
|
|
369
|
+
console.log("saved. verify: tsc --noEmit");
|
|
370
|
+
}
|
|
371
|
+
async function renameSymbol(file, oldName, newName, dry = false) {
|
|
372
|
+
const project = await openProject();
|
|
373
|
+
const root = _process2.default.cwd();
|
|
374
|
+
let changed;
|
|
375
|
+
try {
|
|
376
|
+
changed = renameInProject(project, _path.resolve.call(void 0, file), oldName, newName);
|
|
377
|
+
} catch (e) {
|
|
378
|
+
console.error(`refactor: ${e.message}`);
|
|
379
|
+
_process2.default.exit(1);
|
|
380
|
+
}
|
|
381
|
+
console.log(`rename ${oldName} \u2192 ${newName} (in ${_path.relative.call(void 0, root, file)})`);
|
|
382
|
+
console.log(`${changed.length} file(s) ${dry ? "would change" : "changed"}:`);
|
|
383
|
+
for (const f of changed)
|
|
384
|
+
console.log(` ${_path.relative.call(void 0, root, f.getFilePath())}`);
|
|
385
|
+
if (dry)
|
|
386
|
+
return;
|
|
387
|
+
await project.save();
|
|
388
|
+
console.log("saved. verify: tsc --noEmit");
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
exports.toAlias = toAlias; exports.moveInProject = moveInProject; exports.renameInProject = renameInProject; exports.moveSymbolInProject = moveSymbolInProject; exports.moveFile = moveFile; exports.moveSymbol = moveSymbol; exports.renameSymbol = renameSymbol;
|