uilint 0.2.20 → 0.2.22
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.
|
@@ -137,8 +137,11 @@ function ProjectSelector({
|
|
|
137
137
|
// src/commands/install/components/MultiSelect.tsx
|
|
138
138
|
import { useState as useState3, useCallback } from "react";
|
|
139
139
|
import { Box as Box2, Text as Text3, useInput as useInput2, useApp as useApp2 } from "ink";
|
|
140
|
-
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
141
|
-
function StatusIndicator({ status, isSelected }) {
|
|
140
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
141
|
+
function StatusIndicator({ status, isSelected, isMarkedForUninstall }) {
|
|
142
|
+
if (isMarkedForUninstall) {
|
|
143
|
+
return /* @__PURE__ */ jsx3(Text3, { color: "red", children: "\u2717" });
|
|
144
|
+
}
|
|
142
145
|
if (status === "installed") {
|
|
143
146
|
return /* @__PURE__ */ jsx3(Text3, { color: "green", children: "\u2713" });
|
|
144
147
|
}
|
|
@@ -153,7 +156,10 @@ function StatusIndicator({ status, isSelected }) {
|
|
|
153
156
|
}
|
|
154
157
|
return /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "\u25CB" });
|
|
155
158
|
}
|
|
156
|
-
function StatusLabel({ status }) {
|
|
159
|
+
function StatusLabel({ status, isMarkedForUninstall }) {
|
|
160
|
+
if (isMarkedForUninstall) {
|
|
161
|
+
return /* @__PURE__ */ jsx3(Text3, { color: "red", dimColor: true, children: "uninstall" });
|
|
162
|
+
}
|
|
157
163
|
if (status === "installed") {
|
|
158
164
|
return /* @__PURE__ */ jsx3(Text3, { color: "green", dimColor: true, children: "installed" });
|
|
159
165
|
}
|
|
@@ -177,6 +183,7 @@ function ConfigSelector({
|
|
|
177
183
|
items.filter((item) => item.status !== "installed" && !item.disabled).map((item) => item.id)
|
|
178
184
|
);
|
|
179
185
|
});
|
|
186
|
+
const [markedForUninstall, setMarkedForUninstall] = useState3(/* @__PURE__ */ new Set());
|
|
180
187
|
const categories = Array.from(new Set(items.map((item) => item.category)));
|
|
181
188
|
const itemsByCategory = /* @__PURE__ */ new Map();
|
|
182
189
|
for (const cat of categories) {
|
|
@@ -185,8 +192,19 @@ function ConfigSelector({
|
|
|
185
192
|
const flatItems = items;
|
|
186
193
|
const handleToggle = useCallback(() => {
|
|
187
194
|
const item = flatItems[cursor];
|
|
188
|
-
|
|
189
|
-
if (
|
|
195
|
+
if (!item || item.disabled) return;
|
|
196
|
+
if (item.status === "installed") {
|
|
197
|
+
setMarkedForUninstall((prev) => {
|
|
198
|
+
const next = new Set(prev);
|
|
199
|
+
if (next.has(item.id)) {
|
|
200
|
+
next.delete(item.id);
|
|
201
|
+
} else {
|
|
202
|
+
next.add(item.id);
|
|
203
|
+
}
|
|
204
|
+
return next;
|
|
205
|
+
});
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
190
208
|
setSelected((prev) => {
|
|
191
209
|
const next = new Set(prev);
|
|
192
210
|
if (next.has(item.id)) {
|
|
@@ -205,7 +223,7 @@ function ConfigSelector({
|
|
|
205
223
|
} else if (input === " ") {
|
|
206
224
|
handleToggle();
|
|
207
225
|
} else if (key.return) {
|
|
208
|
-
onSubmit(Array.from(selected));
|
|
226
|
+
onSubmit(Array.from(selected), Array.from(markedForUninstall));
|
|
209
227
|
} else if (input === "q" || key.escape) {
|
|
210
228
|
onCancel?.();
|
|
211
229
|
exit();
|
|
@@ -215,8 +233,10 @@ function ConfigSelector({
|
|
|
215
233
|
items.filter((item) => item.status !== "installed" && !item.disabled).map((item) => item.id)
|
|
216
234
|
)
|
|
217
235
|
);
|
|
236
|
+
setMarkedForUninstall(/* @__PURE__ */ new Set());
|
|
218
237
|
} else if (input === "n") {
|
|
219
238
|
setSelected(/* @__PURE__ */ new Set());
|
|
239
|
+
setMarkedForUninstall(/* @__PURE__ */ new Set());
|
|
220
240
|
}
|
|
221
241
|
});
|
|
222
242
|
let globalIndex = 0;
|
|
@@ -234,20 +254,21 @@ function ConfigSelector({
|
|
|
234
254
|
const itemIndex = globalIndex++;
|
|
235
255
|
const isCursor = itemIndex === cursor;
|
|
236
256
|
const isItemSelected = selected.has(item.id);
|
|
237
|
-
const
|
|
257
|
+
const isItemMarkedForUninstall = markedForUninstall.has(item.id);
|
|
258
|
+
const isDisabled = item.disabled === true;
|
|
238
259
|
return /* @__PURE__ */ jsxs2(Box2, { paddingLeft: 2, children: [
|
|
239
260
|
/* @__PURE__ */ jsx3(Text3, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u203A " : " " }),
|
|
240
|
-
/* @__PURE__ */ jsx3(Box2, { width: 2, children: /* @__PURE__ */ jsx3(StatusIndicator, { status: item.status, isSelected: isItemSelected }) }),
|
|
261
|
+
/* @__PURE__ */ jsx3(Box2, { width: 2, children: /* @__PURE__ */ jsx3(StatusIndicator, { status: item.status, isSelected: isItemSelected, isMarkedForUninstall: isItemMarkedForUninstall }) }),
|
|
241
262
|
/* @__PURE__ */ jsx3(Box2, { width: 28, children: /* @__PURE__ */ jsx3(
|
|
242
263
|
Text3,
|
|
243
264
|
{
|
|
244
|
-
color: isDisabled ? void 0 : isCursor ? "cyan" : void 0,
|
|
245
|
-
dimColor: isDisabled,
|
|
265
|
+
color: isItemMarkedForUninstall ? "red" : isDisabled ? void 0 : isCursor ? "cyan" : void 0,
|
|
266
|
+
dimColor: isDisabled && !isItemMarkedForUninstall,
|
|
246
267
|
children: item.label
|
|
247
268
|
}
|
|
248
269
|
) }),
|
|
249
270
|
/* @__PURE__ */ jsx3(Box2, { width: 20, children: /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: item.hint || "" }) }),
|
|
250
|
-
/* @__PURE__ */ jsx3(StatusLabel, { status: item.status })
|
|
271
|
+
/* @__PURE__ */ jsx3(StatusLabel, { status: item.status, isMarkedForUninstall: isItemMarkedForUninstall })
|
|
251
272
|
] }, item.id);
|
|
252
273
|
})
|
|
253
274
|
] }, category);
|
|
@@ -273,10 +294,11 @@ function ConfigSelector({
|
|
|
273
294
|
] }) }),
|
|
274
295
|
/* @__PURE__ */ jsx3(Box2, { marginTop: 1, children: /* @__PURE__ */ jsxs2(Text3, { children: [
|
|
275
296
|
/* @__PURE__ */ jsx3(Text3, { color: "cyan", children: selected.size }),
|
|
276
|
-
/* @__PURE__ */
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
"
|
|
297
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: " to install" }),
|
|
298
|
+
markedForUninstall.size > 0 && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
299
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: ", " }),
|
|
300
|
+
/* @__PURE__ */ jsx3(Text3, { color: "red", children: markedForUninstall.size }),
|
|
301
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: " to uninstall" })
|
|
280
302
|
] })
|
|
281
303
|
] }) })
|
|
282
304
|
] });
|
|
@@ -892,6 +914,32 @@ var nextOverlayInstaller = {
|
|
|
892
914
|
type: "complete",
|
|
893
915
|
message: "Next.js overlay installed"
|
|
894
916
|
};
|
|
917
|
+
},
|
|
918
|
+
planUninstall(targets, project) {
|
|
919
|
+
const actions = [];
|
|
920
|
+
if (targets.length === 0) return { actions };
|
|
921
|
+
const target = targets[0];
|
|
922
|
+
const appInfo = project.nextApps.find(
|
|
923
|
+
(app) => app.projectPath === target.path
|
|
924
|
+
);
|
|
925
|
+
if (!appInfo) return { actions };
|
|
926
|
+
const { projectPath, detection } = appInfo;
|
|
927
|
+
actions.push({
|
|
928
|
+
type: "remove_react",
|
|
929
|
+
projectPath,
|
|
930
|
+
appRoot: detection.appRoot,
|
|
931
|
+
mode: "next"
|
|
932
|
+
});
|
|
933
|
+
actions.push({
|
|
934
|
+
type: "remove_next_config",
|
|
935
|
+
projectPath
|
|
936
|
+
});
|
|
937
|
+
actions.push({
|
|
938
|
+
type: "remove_next_routes",
|
|
939
|
+
projectPath,
|
|
940
|
+
appRoot: detection.appRoot
|
|
941
|
+
});
|
|
942
|
+
return { actions };
|
|
895
943
|
}
|
|
896
944
|
};
|
|
897
945
|
|
|
@@ -1029,6 +1077,7 @@ function InstallApp({
|
|
|
1029
1077
|
const [selections, setSelections] = useState6([]);
|
|
1030
1078
|
const [configItems, setConfigItems] = useState6([]);
|
|
1031
1079
|
const [selectedFeatureIds, setSelectedFeatureIds] = useState6([]);
|
|
1080
|
+
const [uninstallFeatureIds, setUninstallFeatureIds] = useState6([]);
|
|
1032
1081
|
const [error, setError] = useState6(null);
|
|
1033
1082
|
const [injectionPoints, setInjectionPoints] = useState6([]);
|
|
1034
1083
|
const [selectedInjectionPoint, setSelectedInjectionPoint] = useState6(void 0);
|
|
@@ -1086,8 +1135,9 @@ function InstallApp({
|
|
|
1086
1135
|
setPhase("select-project");
|
|
1087
1136
|
}
|
|
1088
1137
|
};
|
|
1089
|
-
const handleFeatureSubmit = (selectedIds) => {
|
|
1138
|
+
const handleFeatureSubmit = (selectedIds, uninstallIds) => {
|
|
1090
1139
|
setSelectedFeatureIds(selectedIds);
|
|
1140
|
+
setUninstallFeatureIds(uninstallIds);
|
|
1091
1141
|
const nextSelected = selectedIds.some((id) => id.startsWith("next:"));
|
|
1092
1142
|
if (nextSelected && project && selectedProject) {
|
|
1093
1143
|
const appInfo = project.nextApps.find(
|
|
@@ -1143,6 +1193,7 @@ function InstallApp({
|
|
|
1143
1193
|
};
|
|
1144
1194
|
const finishInstallation = (selectedIds, eslintRules, injectionConfig) => {
|
|
1145
1195
|
const selectedSet = new Set(selectedIds);
|
|
1196
|
+
const uninstallSet = new Set(uninstallFeatureIds);
|
|
1146
1197
|
const updatedSelections = selections.map((sel) => {
|
|
1147
1198
|
const selectedTargets = sel.targets.filter(
|
|
1148
1199
|
(t) => selectedSet.has(`${sel.installer.id}:${t.id}`)
|
|
@@ -1153,8 +1204,18 @@ function InstallApp({
|
|
|
1153
1204
|
selected: selectedTargets.length > 0
|
|
1154
1205
|
};
|
|
1155
1206
|
});
|
|
1207
|
+
const uninstallSelections = selections.map((sel) => {
|
|
1208
|
+
const uninstallTargets = sel.targets.filter(
|
|
1209
|
+
(t) => uninstallSet.has(`${sel.installer.id}:${t.id}`)
|
|
1210
|
+
);
|
|
1211
|
+
return {
|
|
1212
|
+
...sel,
|
|
1213
|
+
targets: uninstallTargets,
|
|
1214
|
+
selected: uninstallTargets.length > 0
|
|
1215
|
+
};
|
|
1216
|
+
}).filter((sel) => sel.selected);
|
|
1156
1217
|
setSelections(updatedSelections);
|
|
1157
|
-
onComplete(updatedSelections, eslintRules, injectionConfig);
|
|
1218
|
+
onComplete(updatedSelections, eslintRules, injectionConfig, uninstallSelections.length > 0 ? uninstallSelections : void 0);
|
|
1158
1219
|
};
|
|
1159
1220
|
const handleCancel = () => {
|
|
1160
1221
|
exit();
|
|
@@ -2038,6 +2099,65 @@ async function installEslintPlugin(opts) {
|
|
|
2038
2099
|
configured: getUilintEslintConfigInfoFromSource(updated).configured
|
|
2039
2100
|
};
|
|
2040
2101
|
}
|
|
2102
|
+
async function uninstallEslintPlugin(options) {
|
|
2103
|
+
const { projectPath } = options;
|
|
2104
|
+
const configPath = findEslintConfigFile(projectPath);
|
|
2105
|
+
if (!configPath) {
|
|
2106
|
+
return {
|
|
2107
|
+
success: true,
|
|
2108
|
+
// Nothing to uninstall
|
|
2109
|
+
modifiedFiles: []
|
|
2110
|
+
};
|
|
2111
|
+
}
|
|
2112
|
+
try {
|
|
2113
|
+
const original = readFileSync4(configPath, "utf-8");
|
|
2114
|
+
let updated = original.replace(
|
|
2115
|
+
/^import\s+\{[^}]*\}\s+from\s+["'][^"']*\.uilint\/rules[^"']*["'];?\s*$/gm,
|
|
2116
|
+
""
|
|
2117
|
+
);
|
|
2118
|
+
updated = updated.replace(
|
|
2119
|
+
/^import\s+\w+\s+from\s+["'][^"']*\.uilint\/rules[^"']*["'];?\s*$/gm,
|
|
2120
|
+
""
|
|
2121
|
+
);
|
|
2122
|
+
updated = updated.replace(
|
|
2123
|
+
/^import\s+\{[^}]*\}\s+from\s+["']uilint-eslint["'];?\s*$/gm,
|
|
2124
|
+
""
|
|
2125
|
+
);
|
|
2126
|
+
updated = updated.replace(
|
|
2127
|
+
/^const\s+\{[^}]*createRule[^}]*\}\s*=\s*require\s*\(\s*["']uilint-eslint["']\s*\)\s*;?\s*$/gm,
|
|
2128
|
+
""
|
|
2129
|
+
);
|
|
2130
|
+
updated = updated.replace(
|
|
2131
|
+
/["']uilint\/[^"']+["']\s*:\s*["'][^"']+["']\s*,?\s*/g,
|
|
2132
|
+
""
|
|
2133
|
+
);
|
|
2134
|
+
updated = updated.replace(
|
|
2135
|
+
/["']uilint\/[^"']+["']\s*:\s*\[[^\]]*\]\s*,?\s*/g,
|
|
2136
|
+
""
|
|
2137
|
+
);
|
|
2138
|
+
updated = updated.replace(
|
|
2139
|
+
/\{\s*plugins:\s*\{\s*uilint:\s*\{[^}]*\}[^}]*\}[^}]*rules:\s*\{[^}]*\}[^}]*\}\s*,?\s*/gs,
|
|
2140
|
+
""
|
|
2141
|
+
);
|
|
2142
|
+
updated = updated.replace(/\n{3,}/g, "\n\n");
|
|
2143
|
+
if (updated !== original) {
|
|
2144
|
+
writeFileSync(configPath, updated, "utf-8");
|
|
2145
|
+
return {
|
|
2146
|
+
success: true,
|
|
2147
|
+
modifiedFiles: [configPath]
|
|
2148
|
+
};
|
|
2149
|
+
}
|
|
2150
|
+
return {
|
|
2151
|
+
success: true,
|
|
2152
|
+
modifiedFiles: []
|
|
2153
|
+
};
|
|
2154
|
+
} catch (error) {
|
|
2155
|
+
return {
|
|
2156
|
+
success: false,
|
|
2157
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2158
|
+
};
|
|
2159
|
+
}
|
|
2160
|
+
}
|
|
2041
2161
|
|
|
2042
2162
|
// src/commands/install/analyze.ts
|
|
2043
2163
|
async function analyze(projectPath = process.cwd()) {
|
|
@@ -2127,7 +2247,8 @@ import {
|
|
|
2127
2247
|
writeFileSync as writeFileSync5,
|
|
2128
2248
|
readFileSync as readFileSync9,
|
|
2129
2249
|
unlinkSync,
|
|
2130
|
-
chmodSync
|
|
2250
|
+
chmodSync,
|
|
2251
|
+
rmSync
|
|
2131
2252
|
} from "fs";
|
|
2132
2253
|
import { dirname as dirname5 } from "path";
|
|
2133
2254
|
|
|
@@ -2458,11 +2579,17 @@ async function installReactUILintOverlay(opts) {
|
|
|
2458
2579
|
opts.projectPath,
|
|
2459
2580
|
opts.appRoot
|
|
2460
2581
|
);
|
|
2582
|
+
const modifiedFiles = [];
|
|
2583
|
+
if (result.modified) {
|
|
2584
|
+
modifiedFiles.push(join6(opts.projectPath, result.providersFile));
|
|
2585
|
+
modifiedFiles.push(join6(opts.projectPath, result.layoutFile));
|
|
2586
|
+
}
|
|
2461
2587
|
return {
|
|
2462
2588
|
targetFile: result.providersFile,
|
|
2463
2589
|
modified: result.modified,
|
|
2464
2590
|
createdFile: result.providersFile,
|
|
2465
|
-
layoutModified: result.layoutFile
|
|
2591
|
+
layoutModified: result.layoutFile,
|
|
2592
|
+
modifiedFiles
|
|
2466
2593
|
};
|
|
2467
2594
|
}
|
|
2468
2595
|
if (opts.targetFile) {
|
|
@@ -2488,7 +2615,8 @@ async function installReactUILintOverlay(opts) {
|
|
|
2488
2615
|
return {
|
|
2489
2616
|
targetFile: relTarget,
|
|
2490
2617
|
modified: false,
|
|
2491
|
-
alreadyConfigured: true
|
|
2618
|
+
alreadyConfigured: true,
|
|
2619
|
+
modifiedFiles: []
|
|
2492
2620
|
};
|
|
2493
2621
|
}
|
|
2494
2622
|
let changed2 = false;
|
|
@@ -2504,7 +2632,8 @@ async function installReactUILintOverlay(opts) {
|
|
|
2504
2632
|
return {
|
|
2505
2633
|
targetFile: relTarget,
|
|
2506
2634
|
modified: modified2,
|
|
2507
|
-
alreadyConfigured: false
|
|
2635
|
+
alreadyConfigured: false,
|
|
2636
|
+
modifiedFiles: modified2 ? [absTarget2] : []
|
|
2508
2637
|
};
|
|
2509
2638
|
}
|
|
2510
2639
|
const candidates = getDefaultCandidates(opts.projectPath, opts.appRoot);
|
|
@@ -2547,7 +2676,45 @@ async function installReactUILintOverlay(opts) {
|
|
|
2547
2676
|
return {
|
|
2548
2677
|
targetFile: chosen,
|
|
2549
2678
|
modified,
|
|
2550
|
-
alreadyConfigured: alreadyConfigured && !modified
|
|
2679
|
+
alreadyConfigured: alreadyConfigured && !modified,
|
|
2680
|
+
modifiedFiles: modified ? [absTarget] : []
|
|
2681
|
+
};
|
|
2682
|
+
}
|
|
2683
|
+
async function uninstallReactUILintOverlay(options) {
|
|
2684
|
+
const { projectPath, appRoot, mode = "next" } = options;
|
|
2685
|
+
const candidates = getDefaultCandidates(projectPath, appRoot);
|
|
2686
|
+
const modifiedFiles = [];
|
|
2687
|
+
for (const candidate of candidates) {
|
|
2688
|
+
const absPath = join6(projectPath, candidate);
|
|
2689
|
+
if (!existsSync6(absPath)) continue;
|
|
2690
|
+
try {
|
|
2691
|
+
const original = readFileSync6(absPath, "utf-8");
|
|
2692
|
+
let updated = original.replace(
|
|
2693
|
+
/^import\s+["']uilint-react\/devtools["'];?\s*$/gm,
|
|
2694
|
+
""
|
|
2695
|
+
);
|
|
2696
|
+
updated = updated.replace(
|
|
2697
|
+
/^import\s+\{[^}]*UILintProvider[^}]*\}\s+from\s+["']uilint-react["'];?\s*$/gm,
|
|
2698
|
+
""
|
|
2699
|
+
);
|
|
2700
|
+
updated = updated.replace(/<uilint-devtools\s*\/>/g, "");
|
|
2701
|
+
updated = updated.replace(/<uilint-devtools><\/uilint-devtools>/g, "");
|
|
2702
|
+
updated = updated.replace(/<uilint-devtools\s*>\s*<\/uilint-devtools>/g, "");
|
|
2703
|
+
updated = updated.replace(
|
|
2704
|
+
/<UILintProvider[^>]*>([\s\S]*?)<\/UILintProvider>/g,
|
|
2705
|
+
"$1"
|
|
2706
|
+
);
|
|
2707
|
+
updated = updated.replace(/\n{3,}/g, "\n\n");
|
|
2708
|
+
if (updated !== original) {
|
|
2709
|
+
writeFileSync2(absPath, updated, "utf-8");
|
|
2710
|
+
modifiedFiles.push(absPath);
|
|
2711
|
+
}
|
|
2712
|
+
} catch {
|
|
2713
|
+
}
|
|
2714
|
+
}
|
|
2715
|
+
return {
|
|
2716
|
+
success: true,
|
|
2717
|
+
modifiedFiles
|
|
2551
2718
|
};
|
|
2552
2719
|
}
|
|
2553
2720
|
|
|
@@ -2669,7 +2836,7 @@ function wrapCjsModuleExports(program) {
|
|
|
2669
2836
|
async function installJsxLocPlugin(opts) {
|
|
2670
2837
|
const configPath = findNextConfigFile(opts.projectPath);
|
|
2671
2838
|
if (!configPath) {
|
|
2672
|
-
return { configFile: null, modified: false };
|
|
2839
|
+
return { configFile: null, modified: false, modifiedFiles: [] };
|
|
2673
2840
|
}
|
|
2674
2841
|
const configFilename = getNextConfigFilename(configPath);
|
|
2675
2842
|
const original = readFileSync7(configPath, "utf-8");
|
|
@@ -2677,7 +2844,7 @@ async function installJsxLocPlugin(opts) {
|
|
|
2677
2844
|
try {
|
|
2678
2845
|
mod = parseModule4(original);
|
|
2679
2846
|
} catch {
|
|
2680
|
-
return { configFile: configFilename, modified: false };
|
|
2847
|
+
return { configFile: configFilename, modified: false, modifiedFiles: [] };
|
|
2681
2848
|
}
|
|
2682
2849
|
const program = mod.$ast;
|
|
2683
2850
|
const isCjs = configPath.endsWith(".cjs");
|
|
@@ -2696,9 +2863,55 @@ async function installJsxLocPlugin(opts) {
|
|
|
2696
2863
|
const updated = changed ? generateCode3(mod).code : original;
|
|
2697
2864
|
if (updated !== original) {
|
|
2698
2865
|
writeFileSync3(configPath, updated, "utf-8");
|
|
2699
|
-
return { configFile: configFilename, modified: true };
|
|
2866
|
+
return { configFile: configFilename, modified: true, modifiedFiles: [configPath] };
|
|
2867
|
+
}
|
|
2868
|
+
return { configFile: configFilename, modified: false, modifiedFiles: [] };
|
|
2869
|
+
}
|
|
2870
|
+
async function uninstallJsxLocPlugin(options) {
|
|
2871
|
+
const { projectPath } = options;
|
|
2872
|
+
const configPath = findNextConfigFile(projectPath);
|
|
2873
|
+
if (!configPath) {
|
|
2874
|
+
return {
|
|
2875
|
+
success: true,
|
|
2876
|
+
modifiedFiles: []
|
|
2877
|
+
};
|
|
2878
|
+
}
|
|
2879
|
+
try {
|
|
2880
|
+
const original = readFileSync7(configPath, "utf-8");
|
|
2881
|
+
let updated = original.replace(
|
|
2882
|
+
/^import\s+\{[^}]*withJsxLoc[^}]*\}\s+from\s+["']jsx-loc-plugin\/next["'];?\s*$/gm,
|
|
2883
|
+
""
|
|
2884
|
+
);
|
|
2885
|
+
updated = updated.replace(
|
|
2886
|
+
/^const\s+\{[^}]*withJsxLoc[^}]*\}\s*=\s*require\s*\(\s*["']jsx-loc-plugin\/next["']\s*\)\s*;?\s*$/gm,
|
|
2887
|
+
""
|
|
2888
|
+
);
|
|
2889
|
+
updated = updated.replace(
|
|
2890
|
+
/export\s+default\s+withJsxLoc\s*\(\s*([\s\S]*?)\s*\)\s*;?/g,
|
|
2891
|
+
"export default $1;"
|
|
2892
|
+
);
|
|
2893
|
+
updated = updated.replace(
|
|
2894
|
+
/module\.exports\s*=\s*withJsxLoc\s*\(\s*([\s\S]*?)\s*\)\s*;?/g,
|
|
2895
|
+
"module.exports = $1;"
|
|
2896
|
+
);
|
|
2897
|
+
updated = updated.replace(/\n{3,}/g, "\n\n");
|
|
2898
|
+
if (updated !== original) {
|
|
2899
|
+
writeFileSync3(configPath, updated, "utf-8");
|
|
2900
|
+
return {
|
|
2901
|
+
success: true,
|
|
2902
|
+
modifiedFiles: [configPath]
|
|
2903
|
+
};
|
|
2904
|
+
}
|
|
2905
|
+
return {
|
|
2906
|
+
success: true,
|
|
2907
|
+
modifiedFiles: []
|
|
2908
|
+
};
|
|
2909
|
+
} catch (error) {
|
|
2910
|
+
return {
|
|
2911
|
+
success: false,
|
|
2912
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2913
|
+
};
|
|
2700
2914
|
}
|
|
2701
|
-
return { configFile: configFilename, modified: false };
|
|
2702
2915
|
}
|
|
2703
2916
|
|
|
2704
2917
|
// src/utils/vite-config-inject.ts
|
|
@@ -2882,7 +3095,7 @@ function ensurePluginsContainsJsxLoc(configObj) {
|
|
|
2882
3095
|
}
|
|
2883
3096
|
async function installViteJsxLocPlugin(opts) {
|
|
2884
3097
|
const configPath = findViteConfigFile2(opts.projectPath);
|
|
2885
|
-
if (!configPath) return { configFile: null, modified: false };
|
|
3098
|
+
if (!configPath) return { configFile: null, modified: false, modifiedFiles: [] };
|
|
2886
3099
|
const configFilename = getViteConfigFilename(configPath);
|
|
2887
3100
|
const original = readFileSync8(configPath, "utf-8");
|
|
2888
3101
|
const isCjs = configPath.endsWith(".cjs");
|
|
@@ -2890,10 +3103,10 @@ async function installViteJsxLocPlugin(opts) {
|
|
|
2890
3103
|
try {
|
|
2891
3104
|
mod = parseModule5(original);
|
|
2892
3105
|
} catch {
|
|
2893
|
-
return { configFile: configFilename, modified: false };
|
|
3106
|
+
return { configFile: configFilename, modified: false, modifiedFiles: [] };
|
|
2894
3107
|
}
|
|
2895
3108
|
const found = findExportedConfigObjectExpression(mod);
|
|
2896
|
-
if (!found) return { configFile: configFilename, modified: false };
|
|
3109
|
+
if (!found) return { configFile: configFilename, modified: false, modifiedFiles: [] };
|
|
2897
3110
|
let changed = false;
|
|
2898
3111
|
if (isCjs) {
|
|
2899
3112
|
const reqRes = ensureCjsJsxLocRequire(found.program);
|
|
@@ -2907,9 +3120,52 @@ async function installViteJsxLocPlugin(opts) {
|
|
|
2907
3120
|
const updated = changed ? generateCode4(mod).code : original;
|
|
2908
3121
|
if (updated !== original) {
|
|
2909
3122
|
writeFileSync4(configPath, updated, "utf-8");
|
|
2910
|
-
return { configFile: configFilename, modified: true };
|
|
3123
|
+
return { configFile: configFilename, modified: true, modifiedFiles: [configPath] };
|
|
3124
|
+
}
|
|
3125
|
+
return { configFile: configFilename, modified: false, modifiedFiles: [] };
|
|
3126
|
+
}
|
|
3127
|
+
async function uninstallViteJsxLocPlugin(options) {
|
|
3128
|
+
const { projectPath } = options;
|
|
3129
|
+
const configPath = findViteConfigFile2(projectPath);
|
|
3130
|
+
if (!configPath) {
|
|
3131
|
+
return {
|
|
3132
|
+
success: true,
|
|
3133
|
+
modifiedFiles: []
|
|
3134
|
+
};
|
|
3135
|
+
}
|
|
3136
|
+
try {
|
|
3137
|
+
const original = readFileSync8(configPath, "utf-8");
|
|
3138
|
+
let updated = original.replace(
|
|
3139
|
+
/^import\s+\{[^}]*jsxLoc[^}]*\}\s+from\s+["']jsx-loc-plugin\/vite["'];?\s*$/gm,
|
|
3140
|
+
""
|
|
3141
|
+
);
|
|
3142
|
+
updated = updated.replace(
|
|
3143
|
+
/^import\s+jsxLoc\s+from\s+["']jsx-loc-plugin\/vite["'];?\s*$/gm,
|
|
3144
|
+
""
|
|
3145
|
+
);
|
|
3146
|
+
updated = updated.replace(
|
|
3147
|
+
/^const\s+\{[^}]*jsxLoc[^}]*\}\s*=\s*require\s*\(\s*["']jsx-loc-plugin\/vite["']\s*\)\s*;?\s*$/gm,
|
|
3148
|
+
""
|
|
3149
|
+
);
|
|
3150
|
+
updated = updated.replace(/jsxLoc\s*\(\s*\)\s*,?\s*/g, "");
|
|
3151
|
+
updated = updated.replace(/\n{3,}/g, "\n\n");
|
|
3152
|
+
if (updated !== original) {
|
|
3153
|
+
writeFileSync4(configPath, updated, "utf-8");
|
|
3154
|
+
return {
|
|
3155
|
+
success: true,
|
|
3156
|
+
modifiedFiles: [configPath]
|
|
3157
|
+
};
|
|
3158
|
+
}
|
|
3159
|
+
return {
|
|
3160
|
+
success: true,
|
|
3161
|
+
modifiedFiles: []
|
|
3162
|
+
};
|
|
3163
|
+
} catch (error) {
|
|
3164
|
+
return {
|
|
3165
|
+
success: false,
|
|
3166
|
+
error: error instanceof Error ? error.message : String(error)
|
|
3167
|
+
};
|
|
2911
3168
|
}
|
|
2912
|
-
return { configFile: configFilename, modified: false };
|
|
2913
3169
|
}
|
|
2914
3170
|
|
|
2915
3171
|
// src/utils/next-routes.ts
|
|
@@ -3392,9 +3648,25 @@ async function installNextUILintRoutes(opts) {
|
|
|
3392
3648
|
opts
|
|
3393
3649
|
);
|
|
3394
3650
|
}
|
|
3651
|
+
async function uninstallNextUILintRoutes(options) {
|
|
3652
|
+
const { projectPath, appRoot } = options;
|
|
3653
|
+
const { rm } = await import("fs/promises");
|
|
3654
|
+
const baseAbs = join9(projectPath, appRoot, "api", ".uilint");
|
|
3655
|
+
try {
|
|
3656
|
+
if (existsSync9(baseAbs)) {
|
|
3657
|
+
await rm(baseAbs, { recursive: true, force: true });
|
|
3658
|
+
}
|
|
3659
|
+
return { success: true };
|
|
3660
|
+
} catch (error) {
|
|
3661
|
+
return {
|
|
3662
|
+
success: false,
|
|
3663
|
+
error: error instanceof Error ? error.message : String(error)
|
|
3664
|
+
};
|
|
3665
|
+
}
|
|
3666
|
+
}
|
|
3395
3667
|
|
|
3396
3668
|
// src/utils/prettier.ts
|
|
3397
|
-
import { existsSync as existsSync10 } from "fs";
|
|
3669
|
+
import { existsSync as existsSync10, utimesSync } from "fs";
|
|
3398
3670
|
import { spawn } from "child_process";
|
|
3399
3671
|
import { join as join10, dirname as dirname4 } from "path";
|
|
3400
3672
|
function getPrettierPath(projectPath) {
|
|
@@ -3531,6 +3803,17 @@ async function formatFilesWithPrettier(filePaths, projectPath) {
|
|
|
3531
3803
|
});
|
|
3532
3804
|
});
|
|
3533
3805
|
}
|
|
3806
|
+
function touchFiles(filePaths) {
|
|
3807
|
+
const now = /* @__PURE__ */ new Date();
|
|
3808
|
+
for (const filePath of filePaths) {
|
|
3809
|
+
try {
|
|
3810
|
+
if (existsSync10(filePath)) {
|
|
3811
|
+
utimesSync(filePath, now, now);
|
|
3812
|
+
}
|
|
3813
|
+
} catch {
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3816
|
+
}
|
|
3534
3817
|
|
|
3535
3818
|
// src/commands/install/execute.ts
|
|
3536
3819
|
async function executeAction(action, options) {
|
|
@@ -3636,6 +3919,25 @@ async function executeAction(action, options) {
|
|
|
3636
3919
|
case "install_next_routes": {
|
|
3637
3920
|
return await executeInstallNextRoutes(action, options);
|
|
3638
3921
|
}
|
|
3922
|
+
// Uninstall actions
|
|
3923
|
+
case "remove_eslint": {
|
|
3924
|
+
return await executeRemoveEslint(action, options);
|
|
3925
|
+
}
|
|
3926
|
+
case "remove_react": {
|
|
3927
|
+
return await executeRemoveReact(action, options);
|
|
3928
|
+
}
|
|
3929
|
+
case "remove_next_config": {
|
|
3930
|
+
return await executeRemoveNextConfig(action, options);
|
|
3931
|
+
}
|
|
3932
|
+
case "remove_vite_config": {
|
|
3933
|
+
return await executeRemoveViteConfig(action, options);
|
|
3934
|
+
}
|
|
3935
|
+
case "remove_next_routes": {
|
|
3936
|
+
return await executeRemoveNextRoutes(action, options);
|
|
3937
|
+
}
|
|
3938
|
+
case "remove_directory": {
|
|
3939
|
+
return await executeRemoveDirectory(action, options);
|
|
3940
|
+
}
|
|
3639
3941
|
default: {
|
|
3640
3942
|
const _exhaustive = action;
|
|
3641
3943
|
return {
|
|
@@ -3701,7 +4003,8 @@ async function executeInjectReact(action, options) {
|
|
|
3701
4003
|
return {
|
|
3702
4004
|
action,
|
|
3703
4005
|
success,
|
|
3704
|
-
error: success ? void 0 : "Failed to configure React overlay"
|
|
4006
|
+
error: success ? void 0 : "Failed to configure React overlay",
|
|
4007
|
+
modifiedFiles: result.modifiedFiles
|
|
3705
4008
|
};
|
|
3706
4009
|
}
|
|
3707
4010
|
async function executeInjectViteConfig(action, options) {
|
|
@@ -3720,7 +4023,8 @@ async function executeInjectViteConfig(action, options) {
|
|
|
3720
4023
|
return {
|
|
3721
4024
|
action,
|
|
3722
4025
|
success: result.modified || result.configFile !== null,
|
|
3723
|
-
error: result.configFile === null ? "No vite.config found" : void 0
|
|
4026
|
+
error: result.configFile === null ? "No vite.config found" : void 0,
|
|
4027
|
+
modifiedFiles: result.modifiedFiles
|
|
3724
4028
|
};
|
|
3725
4029
|
}
|
|
3726
4030
|
async function executeInjectNextConfig(action, options) {
|
|
@@ -3739,7 +4043,8 @@ async function executeInjectNextConfig(action, options) {
|
|
|
3739
4043
|
return {
|
|
3740
4044
|
action,
|
|
3741
4045
|
success: result.modified || result.configFile !== null,
|
|
3742
|
-
error: result.configFile === null ? "No next.config found" : void 0
|
|
4046
|
+
error: result.configFile === null ? "No next.config found" : void 0,
|
|
4047
|
+
modifiedFiles: result.modifiedFiles
|
|
3743
4048
|
};
|
|
3744
4049
|
}
|
|
3745
4050
|
async function executeInstallNextRoutes(action, options) {
|
|
@@ -3758,6 +4063,117 @@ async function executeInstallNextRoutes(action, options) {
|
|
|
3758
4063
|
});
|
|
3759
4064
|
return { action, success: true };
|
|
3760
4065
|
}
|
|
4066
|
+
async function executeRemoveEslint(action, options) {
|
|
4067
|
+
const { dryRun = false } = options;
|
|
4068
|
+
if (dryRun) {
|
|
4069
|
+
return {
|
|
4070
|
+
action,
|
|
4071
|
+
success: true,
|
|
4072
|
+
wouldDo: `Remove uilint ESLint rules from: ${action.configPath}`
|
|
4073
|
+
};
|
|
4074
|
+
}
|
|
4075
|
+
const result = await uninstallEslintPlugin({
|
|
4076
|
+
projectPath: action.packagePath
|
|
4077
|
+
});
|
|
4078
|
+
return {
|
|
4079
|
+
action,
|
|
4080
|
+
success: result.success,
|
|
4081
|
+
error: result.error,
|
|
4082
|
+
modifiedFiles: result.modifiedFiles
|
|
4083
|
+
};
|
|
4084
|
+
}
|
|
4085
|
+
async function executeRemoveReact(action, options) {
|
|
4086
|
+
const { dryRun = false } = options;
|
|
4087
|
+
if (dryRun) {
|
|
4088
|
+
return {
|
|
4089
|
+
action,
|
|
4090
|
+
success: true,
|
|
4091
|
+
wouldDo: `Remove <uilint-devtools /> from: ${action.projectPath}`
|
|
4092
|
+
};
|
|
4093
|
+
}
|
|
4094
|
+
const result = await uninstallReactUILintOverlay({
|
|
4095
|
+
projectPath: action.projectPath,
|
|
4096
|
+
appRoot: action.appRoot,
|
|
4097
|
+
mode: action.mode
|
|
4098
|
+
});
|
|
4099
|
+
return {
|
|
4100
|
+
action,
|
|
4101
|
+
success: result.success,
|
|
4102
|
+
error: result.error,
|
|
4103
|
+
modifiedFiles: result.modifiedFiles
|
|
4104
|
+
};
|
|
4105
|
+
}
|
|
4106
|
+
async function executeRemoveNextConfig(action, options) {
|
|
4107
|
+
const { dryRun = false } = options;
|
|
4108
|
+
if (dryRun) {
|
|
4109
|
+
return {
|
|
4110
|
+
action,
|
|
4111
|
+
success: true,
|
|
4112
|
+
wouldDo: `Remove jsx-loc-plugin from next.config: ${action.projectPath}`
|
|
4113
|
+
};
|
|
4114
|
+
}
|
|
4115
|
+
const result = await uninstallJsxLocPlugin({
|
|
4116
|
+
projectPath: action.projectPath
|
|
4117
|
+
});
|
|
4118
|
+
return {
|
|
4119
|
+
action,
|
|
4120
|
+
success: result.success,
|
|
4121
|
+
error: result.error,
|
|
4122
|
+
modifiedFiles: result.modifiedFiles
|
|
4123
|
+
};
|
|
4124
|
+
}
|
|
4125
|
+
async function executeRemoveViteConfig(action, options) {
|
|
4126
|
+
const { dryRun = false } = options;
|
|
4127
|
+
if (dryRun) {
|
|
4128
|
+
return {
|
|
4129
|
+
action,
|
|
4130
|
+
success: true,
|
|
4131
|
+
wouldDo: `Remove jsx-loc-plugin from vite.config: ${action.projectPath}`
|
|
4132
|
+
};
|
|
4133
|
+
}
|
|
4134
|
+
const result = await uninstallViteJsxLocPlugin({
|
|
4135
|
+
projectPath: action.projectPath
|
|
4136
|
+
});
|
|
4137
|
+
return {
|
|
4138
|
+
action,
|
|
4139
|
+
success: result.success,
|
|
4140
|
+
error: result.error,
|
|
4141
|
+
modifiedFiles: result.modifiedFiles
|
|
4142
|
+
};
|
|
4143
|
+
}
|
|
4144
|
+
async function executeRemoveNextRoutes(action, options) {
|
|
4145
|
+
const { dryRun = false } = options;
|
|
4146
|
+
if (dryRun) {
|
|
4147
|
+
return {
|
|
4148
|
+
action,
|
|
4149
|
+
success: true,
|
|
4150
|
+
wouldDo: `Remove Next.js API routes: ${action.projectPath}`
|
|
4151
|
+
};
|
|
4152
|
+
}
|
|
4153
|
+
const result = await uninstallNextUILintRoutes({
|
|
4154
|
+
projectPath: action.projectPath,
|
|
4155
|
+
appRoot: action.appRoot
|
|
4156
|
+
});
|
|
4157
|
+
return {
|
|
4158
|
+
action,
|
|
4159
|
+
success: result.success,
|
|
4160
|
+
error: result.error
|
|
4161
|
+
};
|
|
4162
|
+
}
|
|
4163
|
+
async function executeRemoveDirectory(action, options) {
|
|
4164
|
+
const { dryRun = false } = options;
|
|
4165
|
+
if (dryRun) {
|
|
4166
|
+
return {
|
|
4167
|
+
action,
|
|
4168
|
+
success: true,
|
|
4169
|
+
wouldDo: `Remove directory: ${action.path}`
|
|
4170
|
+
};
|
|
4171
|
+
}
|
|
4172
|
+
if (existsSync11(action.path)) {
|
|
4173
|
+
rmSync(action.path, { recursive: true, force: true });
|
|
4174
|
+
}
|
|
4175
|
+
return { action, success: true };
|
|
4176
|
+
}
|
|
3761
4177
|
function deepMerge(target, source) {
|
|
3762
4178
|
const result = { ...target };
|
|
3763
4179
|
for (const key of Object.keys(source)) {
|
|
@@ -3873,6 +4289,14 @@ function collectFormattableFiles(actionsPerformed) {
|
|
|
3873
4289
|
files.push(filePath);
|
|
3874
4290
|
}
|
|
3875
4291
|
}
|
|
4292
|
+
if (result.modifiedFiles) {
|
|
4293
|
+
for (const modifiedPath of result.modifiedFiles) {
|
|
4294
|
+
const ext = modifiedPath.slice(modifiedPath.lastIndexOf(".")).toLowerCase();
|
|
4295
|
+
if (formattableExtensions.has(ext) && !files.includes(modifiedPath)) {
|
|
4296
|
+
files.push(modifiedPath);
|
|
4297
|
+
}
|
|
4298
|
+
}
|
|
4299
|
+
}
|
|
3876
4300
|
}
|
|
3877
4301
|
return files;
|
|
3878
4302
|
}
|
|
@@ -3941,6 +4365,8 @@ async function execute(plan, options = {}) {
|
|
|
3941
4365
|
() => {
|
|
3942
4366
|
}
|
|
3943
4367
|
);
|
|
4368
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
4369
|
+
touchFiles(filesToFormat);
|
|
3944
4370
|
}
|
|
3945
4371
|
}
|
|
3946
4372
|
}
|
|
@@ -4042,6 +4468,15 @@ var genstyleguideInstaller = {
|
|
|
4042
4468
|
type: "complete",
|
|
4043
4469
|
message: "Installed /genstyleguide command"
|
|
4044
4470
|
};
|
|
4471
|
+
},
|
|
4472
|
+
planUninstall(targets, project) {
|
|
4473
|
+
const actions = [];
|
|
4474
|
+
const commandPath = join11(project.cursorDir.path, "commands", "genstyleguide.md");
|
|
4475
|
+
actions.push({
|
|
4476
|
+
type: "delete_file",
|
|
4477
|
+
path: commandPath
|
|
4478
|
+
});
|
|
4479
|
+
return { actions };
|
|
4045
4480
|
}
|
|
4046
4481
|
};
|
|
4047
4482
|
|
|
@@ -4145,6 +4580,15 @@ var skillInstaller = {
|
|
|
4145
4580
|
error: error instanceof Error ? error.message : String(error)
|
|
4146
4581
|
};
|
|
4147
4582
|
}
|
|
4583
|
+
},
|
|
4584
|
+
planUninstall(targets, project) {
|
|
4585
|
+
const actions = [];
|
|
4586
|
+
const skillDir = join12(project.cursorDir.path, "skills", "ui-consistency-enforcer");
|
|
4587
|
+
actions.push({
|
|
4588
|
+
type: "remove_directory",
|
|
4589
|
+
path: skillDir
|
|
4590
|
+
});
|
|
4591
|
+
return { actions };
|
|
4148
4592
|
}
|
|
4149
4593
|
};
|
|
4150
4594
|
|
|
@@ -4374,6 +4818,24 @@ var eslintInstaller = {
|
|
|
4374
4818
|
type: "complete",
|
|
4375
4819
|
message: `ESLint plugin installed in ${targets.length} package(s)`
|
|
4376
4820
|
};
|
|
4821
|
+
},
|
|
4822
|
+
planUninstall(targets, project) {
|
|
4823
|
+
const actions = [];
|
|
4824
|
+
for (const target of targets) {
|
|
4825
|
+
const pkgInfo = project.packages.find((p) => p.path === target.path);
|
|
4826
|
+
if (!pkgInfo || !pkgInfo.eslintConfigPath) continue;
|
|
4827
|
+
actions.push({
|
|
4828
|
+
type: "remove_eslint",
|
|
4829
|
+
packagePath: target.path,
|
|
4830
|
+
configPath: pkgInfo.eslintConfigPath
|
|
4831
|
+
});
|
|
4832
|
+
const rulesDir = join13(target.path, ".uilint", "rules");
|
|
4833
|
+
actions.push({
|
|
4834
|
+
type: "remove_directory",
|
|
4835
|
+
path: rulesDir
|
|
4836
|
+
});
|
|
4837
|
+
}
|
|
4838
|
+
return { actions };
|
|
4377
4839
|
}
|
|
4378
4840
|
};
|
|
4379
4841
|
|
|
@@ -4452,6 +4914,27 @@ var viteOverlayInstaller = {
|
|
|
4452
4914
|
type: "complete",
|
|
4453
4915
|
message: "Vite overlay installed"
|
|
4454
4916
|
};
|
|
4917
|
+
},
|
|
4918
|
+
planUninstall(targets, project) {
|
|
4919
|
+
const actions = [];
|
|
4920
|
+
if (targets.length === 0) return { actions };
|
|
4921
|
+
const target = targets[0];
|
|
4922
|
+
const appInfo = project.viteApps.find(
|
|
4923
|
+
(app) => app.projectPath === target.path
|
|
4924
|
+
);
|
|
4925
|
+
if (!appInfo) return { actions };
|
|
4926
|
+
const { projectPath, detection } = appInfo;
|
|
4927
|
+
actions.push({
|
|
4928
|
+
type: "remove_react",
|
|
4929
|
+
projectPath,
|
|
4930
|
+
appRoot: detection.entryRoot,
|
|
4931
|
+
mode: "vite"
|
|
4932
|
+
});
|
|
4933
|
+
actions.push({
|
|
4934
|
+
type: "remove_vite_config",
|
|
4935
|
+
projectPath
|
|
4936
|
+
});
|
|
4937
|
+
return { actions };
|
|
4455
4938
|
}
|
|
4456
4939
|
};
|
|
4457
4940
|
|
|
@@ -4533,23 +5016,41 @@ async function installUI(options = {}, executeOptions = {}) {
|
|
|
4533
5016
|
InstallApp,
|
|
4534
5017
|
{
|
|
4535
5018
|
projectPromise,
|
|
4536
|
-
onComplete: async (selections, eslintRules, injectionPointConfig) => {
|
|
5019
|
+
onComplete: async (selections, eslintRules, injectionPointConfig, uninstallSelections) => {
|
|
4537
5020
|
const project = await projectPromise;
|
|
4538
5021
|
const choices = selectionsToUserChoices(selections, project, eslintRules, injectionPointConfig);
|
|
4539
|
-
|
|
4540
|
-
|
|
5022
|
+
const hasInstalls = choices.items.length > 0;
|
|
5023
|
+
const hasUninstalls = uninstallSelections && uninstallSelections.length > 0;
|
|
5024
|
+
if (!hasInstalls && !hasUninstalls) {
|
|
5025
|
+
console.log("\nNo changes selected");
|
|
4541
5026
|
process.exit(0);
|
|
4542
5027
|
}
|
|
4543
5028
|
const { createPlan } = await import("./plan-SIXVCXCK.js");
|
|
4544
5029
|
const plan = createPlan(project, choices, { force: options.force });
|
|
5030
|
+
if (hasUninstalls && uninstallSelections) {
|
|
5031
|
+
for (const selection of uninstallSelections) {
|
|
5032
|
+
if (!selection.selected || selection.targets.length === 0) continue;
|
|
5033
|
+
const { installer, targets } = selection;
|
|
5034
|
+
if (installer.planUninstall) {
|
|
5035
|
+
const uninstallPlan = installer.planUninstall(targets, project);
|
|
5036
|
+
plan.actions = [...uninstallPlan.actions, ...plan.actions];
|
|
5037
|
+
}
|
|
5038
|
+
}
|
|
5039
|
+
}
|
|
4545
5040
|
const result = await execute(plan, {
|
|
4546
5041
|
...executeOptions,
|
|
4547
5042
|
projectPath: project.projectPath
|
|
4548
5043
|
});
|
|
4549
5044
|
if (result.success) {
|
|
4550
|
-
|
|
5045
|
+
if (hasInstalls && hasUninstalls) {
|
|
5046
|
+
console.log("\n\u2713 Changes applied successfully!");
|
|
5047
|
+
} else if (hasUninstalls) {
|
|
5048
|
+
console.log("\n\u2713 Uninstallation completed successfully!");
|
|
5049
|
+
} else {
|
|
5050
|
+
console.log("\n\u2713 Installation completed successfully!");
|
|
5051
|
+
}
|
|
4551
5052
|
} else {
|
|
4552
|
-
console.log("\n\u26A0
|
|
5053
|
+
console.log("\n\u26A0 Operation completed with errors");
|
|
4553
5054
|
}
|
|
4554
5055
|
process.exit(result.success ? 0 : 1);
|
|
4555
5056
|
},
|
|
@@ -4565,4 +5066,4 @@ async function installUI(options = {}, executeOptions = {}) {
|
|
|
4565
5066
|
export {
|
|
4566
5067
|
installUI
|
|
4567
5068
|
};
|
|
4568
|
-
//# sourceMappingURL=install-ui-
|
|
5069
|
+
//# sourceMappingURL=install-ui-HTVB5HDB.js.map
|