uilint 0.2.21 → 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
|
|
|
@@ -2559,6 +2680,43 @@ async function installReactUILintOverlay(opts) {
|
|
|
2559
2680
|
modifiedFiles: modified ? [absTarget] : []
|
|
2560
2681
|
};
|
|
2561
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
|
|
2718
|
+
};
|
|
2719
|
+
}
|
|
2562
2720
|
|
|
2563
2721
|
// src/utils/next-config-inject.ts
|
|
2564
2722
|
import { existsSync as existsSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync3 } from "fs";
|
|
@@ -2709,6 +2867,52 @@ async function installJsxLocPlugin(opts) {
|
|
|
2709
2867
|
}
|
|
2710
2868
|
return { configFile: configFilename, modified: false, modifiedFiles: [] };
|
|
2711
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
|
+
};
|
|
2914
|
+
}
|
|
2915
|
+
}
|
|
2712
2916
|
|
|
2713
2917
|
// src/utils/vite-config-inject.ts
|
|
2714
2918
|
import { existsSync as existsSync8, readFileSync as readFileSync8, writeFileSync as writeFileSync4 } from "fs";
|
|
@@ -2920,6 +3124,49 @@ async function installViteJsxLocPlugin(opts) {
|
|
|
2920
3124
|
}
|
|
2921
3125
|
return { configFile: configFilename, modified: false, modifiedFiles: [] };
|
|
2922
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
|
+
};
|
|
3168
|
+
}
|
|
3169
|
+
}
|
|
2923
3170
|
|
|
2924
3171
|
// src/utils/next-routes.ts
|
|
2925
3172
|
import { existsSync as existsSync9 } from "fs";
|
|
@@ -3401,6 +3648,22 @@ async function installNextUILintRoutes(opts) {
|
|
|
3401
3648
|
opts
|
|
3402
3649
|
);
|
|
3403
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
|
+
}
|
|
3404
3667
|
|
|
3405
3668
|
// src/utils/prettier.ts
|
|
3406
3669
|
import { existsSync as existsSync10, utimesSync } from "fs";
|
|
@@ -3656,6 +3919,25 @@ async function executeAction(action, options) {
|
|
|
3656
3919
|
case "install_next_routes": {
|
|
3657
3920
|
return await executeInstallNextRoutes(action, options);
|
|
3658
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
|
+
}
|
|
3659
3941
|
default: {
|
|
3660
3942
|
const _exhaustive = action;
|
|
3661
3943
|
return {
|
|
@@ -3781,6 +4063,117 @@ async function executeInstallNextRoutes(action, options) {
|
|
|
3781
4063
|
});
|
|
3782
4064
|
return { action, success: true };
|
|
3783
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
|
+
}
|
|
3784
4177
|
function deepMerge(target, source) {
|
|
3785
4178
|
const result = { ...target };
|
|
3786
4179
|
for (const key of Object.keys(source)) {
|
|
@@ -4075,6 +4468,15 @@ var genstyleguideInstaller = {
|
|
|
4075
4468
|
type: "complete",
|
|
4076
4469
|
message: "Installed /genstyleguide command"
|
|
4077
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 };
|
|
4078
4480
|
}
|
|
4079
4481
|
};
|
|
4080
4482
|
|
|
@@ -4178,6 +4580,15 @@ var skillInstaller = {
|
|
|
4178
4580
|
error: error instanceof Error ? error.message : String(error)
|
|
4179
4581
|
};
|
|
4180
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 };
|
|
4181
4592
|
}
|
|
4182
4593
|
};
|
|
4183
4594
|
|
|
@@ -4407,6 +4818,24 @@ var eslintInstaller = {
|
|
|
4407
4818
|
type: "complete",
|
|
4408
4819
|
message: `ESLint plugin installed in ${targets.length} package(s)`
|
|
4409
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 };
|
|
4410
4839
|
}
|
|
4411
4840
|
};
|
|
4412
4841
|
|
|
@@ -4485,6 +4914,27 @@ var viteOverlayInstaller = {
|
|
|
4485
4914
|
type: "complete",
|
|
4486
4915
|
message: "Vite overlay installed"
|
|
4487
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 };
|
|
4488
4938
|
}
|
|
4489
4939
|
};
|
|
4490
4940
|
|
|
@@ -4566,23 +5016,41 @@ async function installUI(options = {}, executeOptions = {}) {
|
|
|
4566
5016
|
InstallApp,
|
|
4567
5017
|
{
|
|
4568
5018
|
projectPromise,
|
|
4569
|
-
onComplete: async (selections, eslintRules, injectionPointConfig) => {
|
|
5019
|
+
onComplete: async (selections, eslintRules, injectionPointConfig, uninstallSelections) => {
|
|
4570
5020
|
const project = await projectPromise;
|
|
4571
5021
|
const choices = selectionsToUserChoices(selections, project, eslintRules, injectionPointConfig);
|
|
4572
|
-
|
|
4573
|
-
|
|
5022
|
+
const hasInstalls = choices.items.length > 0;
|
|
5023
|
+
const hasUninstalls = uninstallSelections && uninstallSelections.length > 0;
|
|
5024
|
+
if (!hasInstalls && !hasUninstalls) {
|
|
5025
|
+
console.log("\nNo changes selected");
|
|
4574
5026
|
process.exit(0);
|
|
4575
5027
|
}
|
|
4576
5028
|
const { createPlan } = await import("./plan-SIXVCXCK.js");
|
|
4577
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
|
+
}
|
|
4578
5040
|
const result = await execute(plan, {
|
|
4579
5041
|
...executeOptions,
|
|
4580
5042
|
projectPath: project.projectPath
|
|
4581
5043
|
});
|
|
4582
5044
|
if (result.success) {
|
|
4583
|
-
|
|
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
|
+
}
|
|
4584
5052
|
} else {
|
|
4585
|
-
console.log("\n\u26A0
|
|
5053
|
+
console.log("\n\u26A0 Operation completed with errors");
|
|
4586
5054
|
}
|
|
4587
5055
|
process.exit(result.success ? 0 : 1);
|
|
4588
5056
|
},
|
|
@@ -4598,4 +5066,4 @@ async function installUI(options = {}, executeOptions = {}) {
|
|
|
4598
5066
|
export {
|
|
4599
5067
|
installUI
|
|
4600
5068
|
};
|
|
4601
|
-
//# sourceMappingURL=install-ui-
|
|
5069
|
+
//# sourceMappingURL=install-ui-HTVB5HDB.js.map
|