@dimina-kit/devtools 0.3.1-dev.20260518054451 → 0.3.1-dev.20260518114324
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 +120 -0
- package/dist/main/app/app.js +8 -0
- package/dist/main/index.bundle.js +322 -85
- package/dist/main/ipc/projects.d.ts +3 -1
- package/dist/main/ipc/projects.js +88 -4
- package/dist/main/ipc/settings.js +8 -6
- package/dist/main/services/projects/builtin-templates.d.ts +3 -0
- package/dist/main/services/projects/builtin-templates.js +24 -0
- package/dist/main/services/projects/create-project-service.d.ts +7 -0
- package/dist/main/services/projects/create-project-service.js +84 -0
- package/dist/main/services/projects/index.d.ts +7 -0
- package/dist/main/services/projects/index.js +9 -0
- package/dist/main/services/projects/local-provider.d.ts +3 -0
- package/dist/main/services/projects/local-provider.js +25 -0
- package/dist/main/services/projects/templates.d.ts +21 -0
- package/dist/main/services/projects/templates.js +39 -0
- package/dist/main/services/projects/thumbnail.d.ts +6 -2
- package/dist/main/services/projects/thumbnail.js +13 -8
- package/dist/main/services/projects/types.d.ts +118 -0
- package/dist/main/services/projects/types.js +19 -0
- package/dist/main/services/settings/index.d.ts +7 -0
- package/dist/main/services/settings/index.js +4 -0
- package/dist/main/services/workbench-context.d.ts +35 -0
- package/dist/main/services/workbench-context.js +9 -0
- package/dist/main/services/workspace/workspace-service.d.ts +8 -8
- package/dist/main/services/workspace/workspace-service.js +65 -13
- package/dist/main/windows/main-window/create.js +1 -1
- package/dist/renderer/assets/index-Czz_bp6b.js +46 -0
- package/dist/renderer/assets/{input-AH9UDYmj.js → input-DqVQNCx_.js} +2 -2
- package/dist/renderer/assets/{ipc-transport-DNgBM6Qz.js → ipc-transport-CCHrCtDr.js} +2 -2
- package/dist/renderer/assets/ipc-transport-DqbRdZNO.css +1 -0
- package/dist/renderer/assets/{popover-D1hoVYiY.js → popover-BRg4XI_w.js} +2 -2
- package/dist/renderer/assets/{select-BgDHRj6r.js → select-CvILHHZU.js} +2 -2
- package/dist/renderer/assets/{settings-m-tcmZy_.js → settings-BFNfnYvU.js} +2 -2
- package/dist/renderer/assets/{settings-api-DBKlNKV3.js → settings-api-DOAgmBst.js} +2 -2
- package/dist/renderer/assets/{workbenchSettings-CGacu-pI.js → workbenchSettings-DjVMgMMH.js} +2 -2
- package/dist/renderer/entries/main/index.html +5 -5
- package/dist/renderer/entries/popover/index.html +5 -5
- package/dist/renderer/entries/settings/index.html +5 -5
- package/dist/renderer/entries/workbench-settings/index.html +4 -4
- package/dist/shared/ipc-channels.d.ts +14 -1
- package/dist/shared/ipc-channels.js +8 -0
- package/dist/shared/ipc-schemas.d.ts +1 -0
- package/dist/shared/ipc-schemas.js +1 -0
- package/dist/shared/types.d.ts +80 -0
- package/package.json +7 -2
- package/templates/blank/app.js +6 -0
- package/templates/blank/app.json +11 -0
- package/templates/blank/app.wxss +5 -0
- package/templates/blank/pages/index/index.js +6 -0
- package/templates/blank/pages/index/index.json +3 -0
- package/templates/blank/pages/index/index.wxml +3 -0
- package/templates/blank/pages/index/index.wxss +11 -0
- package/templates/blank/project.config.json +13 -0
- package/templates/blank/sitemap.json +9 -0
- package/templates/taro-todo/app.js +1 -0
- package/templates/taro-todo/app.json +1 -0
- package/templates/taro-todo/app.wxss +1 -0
- package/templates/taro-todo/base.wxml +851 -0
- package/templates/taro-todo/common.js +1 -0
- package/templates/taro-todo/comp.js +1 -0
- package/templates/taro-todo/comp.json +1 -0
- package/templates/taro-todo/comp.wxml +2 -0
- package/templates/taro-todo/custom-wrapper.js +1 -0
- package/templates/taro-todo/custom-wrapper.json +1 -0
- package/templates/taro-todo/custom-wrapper.wxml +4 -0
- package/templates/taro-todo/pages/index/index.js +2 -0
- package/templates/taro-todo/pages/index/index.json +1 -0
- package/templates/taro-todo/pages/index/index.wxml +2 -0
- package/templates/taro-todo/pages/index/index.wxss +1 -0
- package/templates/taro-todo/project.config.json +44 -0
- package/templates/taro-todo/runtime.js +1 -0
- package/templates/taro-todo/taro.js +2 -0
- package/templates/taro-todo/utils.wxs +39 -0
- package/templates/taro-todo/vendors.js +2 -0
- package/dist/renderer/assets/index-BFdItKBK.js +0 -46
- package/dist/renderer/assets/ipc-transport-Dvmd5JZj.css +0 -1
|
@@ -17,7 +17,8 @@ var DEFAULTS = {
|
|
|
17
17
|
compile: {
|
|
18
18
|
watch: true
|
|
19
19
|
},
|
|
20
|
-
theme: "system"
|
|
20
|
+
theme: "system",
|
|
21
|
+
lastCreateBaseDir: null
|
|
21
22
|
};
|
|
22
23
|
function getSettingsFile() {
|
|
23
24
|
return path.join(app.getPath("userData"), "dimina-workbench-settings.json");
|
|
@@ -38,7 +39,8 @@ function loadWorkbenchSettings() {
|
|
|
38
39
|
compile: {
|
|
39
40
|
watch: data.compile?.watch ?? DEFAULTS.compile.watch
|
|
40
41
|
},
|
|
41
|
-
theme
|
|
42
|
+
theme,
|
|
43
|
+
lastCreateBaseDir: typeof data.lastCreateBaseDir === "string" ? data.lastCreateBaseDir : DEFAULTS.lastCreateBaseDir
|
|
42
44
|
};
|
|
43
45
|
} catch {
|
|
44
46
|
return {
|
|
@@ -73,9 +75,9 @@ function setupCdpPort() {
|
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
// src/main/app/app.ts
|
|
76
|
-
import { app as
|
|
77
|
-
import
|
|
78
|
-
import
|
|
78
|
+
import { app as app13, BrowserWindow as BrowserWindow3, nativeImage } from "electron";
|
|
79
|
+
import fs7 from "fs";
|
|
80
|
+
import path12 from "path";
|
|
79
81
|
|
|
80
82
|
// src/main/utils/paths.ts
|
|
81
83
|
import fs2 from "fs";
|
|
@@ -200,7 +202,7 @@ function configureSimulatorSession(simulatorPreloadPath) {
|
|
|
200
202
|
headers["access-control-allow-headers"] = ["*"];
|
|
201
203
|
headers["access-control-allow-methods"] = ["*"];
|
|
202
204
|
headers["Cross-Origin-Opener-Policy"] = ["same-origin"];
|
|
203
|
-
headers["Cross-Origin-Embedder-Policy"] = ["
|
|
205
|
+
headers["Cross-Origin-Embedder-Policy"] = ["credentialless"];
|
|
204
206
|
callback({ responseHeaders: headers });
|
|
205
207
|
});
|
|
206
208
|
}
|
|
@@ -448,7 +450,15 @@ var ProjectChannel = {
|
|
|
448
450
|
var ProjectsChannel = {
|
|
449
451
|
List: "projects:list",
|
|
450
452
|
Add: "projects:add",
|
|
451
|
-
Remove: "projects:remove"
|
|
453
|
+
Remove: "projects:remove",
|
|
454
|
+
/** Phase 3: merged + sanitized template catalog for the create-project dialog. */
|
|
455
|
+
ListTemplates: "projects:listTemplates",
|
|
456
|
+
/** Phase 3: host-supplied create-project dialog hook (returns input or null). */
|
|
457
|
+
OpenCreateDialog: "projects:openCreateDialog",
|
|
458
|
+
/** Phase 3: server-side scaffold + register (delegates to create-project-service). */
|
|
459
|
+
Create: "projects:create",
|
|
460
|
+
/** Default values used to pre-fill the create-project dialog (baseDir). */
|
|
461
|
+
GetCreateDefaults: "projects:getCreateDefaults"
|
|
452
462
|
};
|
|
453
463
|
var DialogChannel = {
|
|
454
464
|
OpenDirectory: "dialog:openDirectory"
|
|
@@ -960,9 +970,6 @@ function validateProjectDir(dirPath) {
|
|
|
960
970
|
}
|
|
961
971
|
return null;
|
|
962
972
|
}
|
|
963
|
-
function hasProject(dirPath) {
|
|
964
|
-
return load().some((p) => p.path === dirPath);
|
|
965
|
-
}
|
|
966
973
|
function addProject(dirPath) {
|
|
967
974
|
const projects = load();
|
|
968
975
|
let name = path7.basename(dirPath);
|
|
@@ -1059,37 +1066,12 @@ function updateProjectSettings(projectPath, patch) {
|
|
|
1059
1066
|
);
|
|
1060
1067
|
}
|
|
1061
1068
|
|
|
1062
|
-
// src/main/services/projects/
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
return path8.join(app7.getPath("userData"), "thumbnails");
|
|
1069
|
-
}
|
|
1070
|
-
function hashProjectPath(projectPath) {
|
|
1071
|
-
return createHash("sha256").update(projectPath).digest("hex").slice(0, 16);
|
|
1072
|
-
}
|
|
1073
|
-
function getThumbnailPath(projectPath) {
|
|
1074
|
-
return path8.join(getThumbnailDir(), `${hashProjectPath(projectPath)}.png`);
|
|
1075
|
-
}
|
|
1076
|
-
function saveThumbnail(projectPath, image) {
|
|
1077
|
-
const png = image.toPNG();
|
|
1078
|
-
const dir = getThumbnailDir();
|
|
1079
|
-
fs4.mkdirSync(dir, { recursive: true });
|
|
1080
|
-
const filePath = getThumbnailPath(projectPath);
|
|
1081
|
-
fs4.writeFileSync(filePath, png);
|
|
1082
|
-
return `data:image/png;base64,${png.toString("base64")}`;
|
|
1083
|
-
}
|
|
1084
|
-
function loadThumbnail(projectPath) {
|
|
1085
|
-
const filePath = getThumbnailPath(projectPath);
|
|
1086
|
-
try {
|
|
1087
|
-
const buf = fs4.readFileSync(filePath);
|
|
1088
|
-
return `data:image/png;base64,${buf.toString("base64")}`;
|
|
1089
|
-
} catch {
|
|
1090
|
-
return null;
|
|
1091
|
-
}
|
|
1092
|
-
}
|
|
1069
|
+
// src/main/services/projects/types.ts
|
|
1070
|
+
var DEFAULT_COMPILE_CONFIG = {
|
|
1071
|
+
startPage: "",
|
|
1072
|
+
scene: DEFAULT_SCENE,
|
|
1073
|
+
queryParams: []
|
|
1074
|
+
};
|
|
1093
1075
|
|
|
1094
1076
|
// src/main/services/workspace/workspace-service.ts
|
|
1095
1077
|
function createWorkspaceService(ctx) {
|
|
@@ -1129,17 +1111,31 @@ function createWorkspaceService(ctx) {
|
|
|
1129
1111
|
);
|
|
1130
1112
|
}
|
|
1131
1113
|
}
|
|
1132
|
-
|
|
1114
|
+
const provider = ctx.projectsProvider ?? {
|
|
1133
1115
|
listProjects: () => listProjects(),
|
|
1134
|
-
addProject: (
|
|
1135
|
-
removeProject: (
|
|
1136
|
-
|
|
1137
|
-
|
|
1116
|
+
addProject: (p) => addProject(p),
|
|
1117
|
+
removeProject: (p) => removeProject(p),
|
|
1118
|
+
validateProjectDir: (p) => validateProjectDir(p),
|
|
1119
|
+
updateLastOpened: (p) => updateLastOpened(p),
|
|
1120
|
+
getCompileConfig: (p) => getCompileConfig(p),
|
|
1121
|
+
saveCompileConfig: (p, c) => saveCompileConfig(p, c)
|
|
1122
|
+
};
|
|
1123
|
+
return {
|
|
1124
|
+
listProjects: async () => provider.listProjects(),
|
|
1125
|
+
addProject: async (dirPath) => provider.addProject(dirPath),
|
|
1126
|
+
removeProject: async (dirPath) => {
|
|
1127
|
+
await provider.removeProject(dirPath);
|
|
1128
|
+
},
|
|
1129
|
+
hasProject: async (dirPath) => {
|
|
1130
|
+
const projects = await provider.listProjects();
|
|
1131
|
+
return projects.some((p) => p.path === dirPath);
|
|
1132
|
+
},
|
|
1133
|
+
validateProjectDir: async (dirPath) => provider.validateProjectDir ? provider.validateProjectDir(dirPath) : null,
|
|
1138
1134
|
async openProject(projectPath) {
|
|
1139
1135
|
clearSimulatorServicewechatReferer();
|
|
1140
1136
|
await disposeSession();
|
|
1141
1137
|
currentProjectPath = "";
|
|
1142
|
-
const dirError = validateProjectDir(projectPath);
|
|
1138
|
+
const dirError = provider.validateProjectDir ? await provider.validateProjectDir(projectPath) : null;
|
|
1143
1139
|
if (dirError) {
|
|
1144
1140
|
sendStatus("error", dirError);
|
|
1145
1141
|
return { success: false, error: dirError };
|
|
@@ -1162,7 +1158,9 @@ function createWorkspaceService(ctx) {
|
|
|
1162
1158
|
}
|
|
1163
1159
|
currentSession = session2;
|
|
1164
1160
|
currentProjectPath = projectPath;
|
|
1165
|
-
bestEffort("updateLastOpened", () =>
|
|
1161
|
+
bestEffort("updateLastOpened", () => {
|
|
1162
|
+
if (provider.updateLastOpened) provider.updateLastOpened(projectPath);
|
|
1163
|
+
});
|
|
1166
1164
|
bestEffort("sendStatus", () => sendStatus("ready", "\u7F16\u8BD1\u5B8C\u6210"));
|
|
1167
1165
|
bestEffort("applyReferer", () => applyRefererFromSession(session2));
|
|
1168
1166
|
return {
|
|
@@ -1187,22 +1185,127 @@ function createWorkspaceService(ctx) {
|
|
|
1187
1185
|
if (!wc || wc.isDestroyed()) return null;
|
|
1188
1186
|
try {
|
|
1189
1187
|
const image = await wc.capturePage();
|
|
1190
|
-
|
|
1188
|
+
const dataUrl = `data:image/png;base64,${image.toPNG().toString("base64")}`;
|
|
1189
|
+
if (provider.saveThumbnail) {
|
|
1190
|
+
await provider.saveThumbnail(projectPath, dataUrl);
|
|
1191
|
+
}
|
|
1192
|
+
return dataUrl;
|
|
1191
1193
|
} catch {
|
|
1192
1194
|
return null;
|
|
1193
1195
|
}
|
|
1194
1196
|
},
|
|
1195
|
-
getThumbnail(projectPath) {
|
|
1196
|
-
|
|
1197
|
+
async getThumbnail(projectPath) {
|
|
1198
|
+
if (provider.getThumbnail) {
|
|
1199
|
+
return await provider.getThumbnail(projectPath) ?? null;
|
|
1200
|
+
}
|
|
1201
|
+
return null;
|
|
1197
1202
|
},
|
|
1203
|
+
// `getProjectPages` reads the project's own `app.json` from disk and is
|
|
1204
|
+
// independent of the project registry — it stays on the repo helper.
|
|
1198
1205
|
getProjectPages: (projectPath) => getProjectPages(projectPath),
|
|
1199
|
-
getCompileConfig: (projectPath) => getCompileConfig(projectPath),
|
|
1200
|
-
saveCompileConfig: (projectPath, config) =>
|
|
1206
|
+
getCompileConfig: async (projectPath) => provider.getCompileConfig ? await provider.getCompileConfig(projectPath) : DEFAULT_COMPILE_CONFIG,
|
|
1207
|
+
saveCompileConfig: async (projectPath, config) => {
|
|
1208
|
+
if (provider.saveCompileConfig) {
|
|
1209
|
+
await provider.saveCompileConfig(projectPath, config);
|
|
1210
|
+
}
|
|
1211
|
+
},
|
|
1212
|
+
// Per-project settings (uploadWithSourceMap etc.) live in the project's
|
|
1213
|
+
// own `project.config.json`, not the registry — keep direct repo calls.
|
|
1201
1214
|
getProjectSettings: (projectPath) => getProjectSettings(projectPath),
|
|
1202
1215
|
updateProjectSettings: (projectPath, patch) => updateProjectSettings(projectPath, patch)
|
|
1203
1216
|
};
|
|
1204
1217
|
}
|
|
1205
1218
|
|
|
1219
|
+
// src/main/services/projects/thumbnail.ts
|
|
1220
|
+
import { createHash } from "crypto";
|
|
1221
|
+
import fs4 from "fs";
|
|
1222
|
+
import path8 from "path";
|
|
1223
|
+
import { app as app7 } from "electron";
|
|
1224
|
+
function getThumbnailDir() {
|
|
1225
|
+
return path8.join(app7.getPath("userData"), "thumbnails");
|
|
1226
|
+
}
|
|
1227
|
+
function hashProjectPath(projectPath) {
|
|
1228
|
+
return createHash("sha256").update(projectPath).digest("hex").slice(0, 16);
|
|
1229
|
+
}
|
|
1230
|
+
function getThumbnailPath(projectPath) {
|
|
1231
|
+
return path8.join(getThumbnailDir(), `${hashProjectPath(projectPath)}.png`);
|
|
1232
|
+
}
|
|
1233
|
+
var DATA_URL_PNG_PREFIX = "data:image/png;base64,";
|
|
1234
|
+
function saveThumbnailFromDataUrl(projectPath, imageDataUrl) {
|
|
1235
|
+
if (!imageDataUrl.startsWith(DATA_URL_PNG_PREFIX)) return;
|
|
1236
|
+
const png = Buffer.from(imageDataUrl.slice(DATA_URL_PNG_PREFIX.length), "base64");
|
|
1237
|
+
fs4.mkdirSync(getThumbnailDir(), { recursive: true });
|
|
1238
|
+
fs4.writeFileSync(getThumbnailPath(projectPath), png);
|
|
1239
|
+
}
|
|
1240
|
+
function loadThumbnail(projectPath) {
|
|
1241
|
+
const filePath = getThumbnailPath(projectPath);
|
|
1242
|
+
try {
|
|
1243
|
+
const buf = fs4.readFileSync(filePath);
|
|
1244
|
+
return `${DATA_URL_PNG_PREFIX}${buf.toString("base64")}`;
|
|
1245
|
+
} catch {
|
|
1246
|
+
return null;
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
// src/main/services/projects/local-provider.ts
|
|
1251
|
+
function createLocalProjectsProvider() {
|
|
1252
|
+
return {
|
|
1253
|
+
listProjects: () => listProjects(),
|
|
1254
|
+
addProject: (dirPath) => addProject(dirPath),
|
|
1255
|
+
removeProject: (dirPath) => removeProject(dirPath),
|
|
1256
|
+
validateProjectDir: (dirPath) => validateProjectDir(dirPath),
|
|
1257
|
+
updateLastOpened: (dirPath) => updateLastOpened(dirPath),
|
|
1258
|
+
getCompileConfig: (dirPath) => getCompileConfig(dirPath),
|
|
1259
|
+
saveCompileConfig: (dirPath, cfg) => saveCompileConfig(dirPath, cfg),
|
|
1260
|
+
saveThumbnail: (dirPath, dataUrl) => saveThumbnailFromDataUrl(dirPath, dataUrl),
|
|
1261
|
+
getThumbnail: (dirPath) => loadThumbnail(dirPath)
|
|
1262
|
+
};
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
// src/main/services/projects/templates.ts
|
|
1266
|
+
function resolveTemplates(builtin, injected, mode) {
|
|
1267
|
+
let kept;
|
|
1268
|
+
if (mode === "none") {
|
|
1269
|
+
kept = [];
|
|
1270
|
+
} else if (mode === "all") {
|
|
1271
|
+
kept = [...builtin];
|
|
1272
|
+
} else {
|
|
1273
|
+
const byId = new Map(builtin.map((t) => [t.id, t]));
|
|
1274
|
+
kept = [];
|
|
1275
|
+
for (const id of mode) {
|
|
1276
|
+
const t = byId.get(id);
|
|
1277
|
+
if (t) kept.push(t);
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
const injectedIds = new Set(injected.map((t) => t.id));
|
|
1281
|
+
const remaining = kept.filter((t) => !injectedIds.has(t.id));
|
|
1282
|
+
return [...injected, ...remaining];
|
|
1283
|
+
}
|
|
1284
|
+
function sanitizeTemplates(templates) {
|
|
1285
|
+
return templates.map((t) => {
|
|
1286
|
+
const { generate: _generate, ...rest } = t;
|
|
1287
|
+
return rest;
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
// src/main/services/projects/builtin-templates.ts
|
|
1292
|
+
import path9 from "node:path";
|
|
1293
|
+
var TEMPLATES_DIR = path9.join(devtoolsPackageRoot, "templates");
|
|
1294
|
+
var BUILTIN_TEMPLATES = [
|
|
1295
|
+
{
|
|
1296
|
+
id: "blank",
|
|
1297
|
+
name: "Blank",
|
|
1298
|
+
description: "\u6700\u5C0F\u9AA8\u67B6\uFF1Aapp.* + \u4E00\u4E2A index \u9875\u9762",
|
|
1299
|
+
source: { type: "directory", path: path9.join(TEMPLATES_DIR, "blank") }
|
|
1300
|
+
},
|
|
1301
|
+
{
|
|
1302
|
+
id: "taro-todo",
|
|
1303
|
+
name: "Taro Todo",
|
|
1304
|
+
description: "Taro \u7F16\u8BD1\u4EA7\u7269\u7684 Todo \u793A\u4F8B",
|
|
1305
|
+
source: { type: "directory", path: path9.join(TEMPLATES_DIR, "taro-todo") }
|
|
1306
|
+
}
|
|
1307
|
+
];
|
|
1308
|
+
|
|
1206
1309
|
// src/main/services/workbench-context.ts
|
|
1207
1310
|
function hasBuiltinPanel(ctx, panelId) {
|
|
1208
1311
|
return ctx.panels.includes(panelId);
|
|
@@ -1229,6 +1332,13 @@ function createWorkbenchContext(opts) {
|
|
|
1229
1332
|
ctx.windows = createWindowService(ctx.mainWindow);
|
|
1230
1333
|
ctx.views = createViewManager(ctx);
|
|
1231
1334
|
ctx.notify = createRendererNotifier(ctx);
|
|
1335
|
+
ctx.projectsProvider = opts.projectsProvider ?? createLocalProjectsProvider();
|
|
1336
|
+
ctx.projectTemplates = resolveTemplates(
|
|
1337
|
+
BUILTIN_TEMPLATES,
|
|
1338
|
+
opts.projectTemplates ?? [],
|
|
1339
|
+
opts.builtinTemplates ?? "all"
|
|
1340
|
+
);
|
|
1341
|
+
ctx.customCreateProjectDialog = opts.customCreateProjectDialog;
|
|
1232
1342
|
ctx.workspace = createWorkspaceService(ctx);
|
|
1233
1343
|
ctx.senderPolicy = createWorkbenchSenderPolicy(ctx);
|
|
1234
1344
|
return ctx;
|
|
@@ -1471,7 +1581,8 @@ var WorkbenchSettingsSaveSchema = z.tuple([
|
|
|
1471
1581
|
compile: z.looseObject({
|
|
1472
1582
|
watch: z.boolean()
|
|
1473
1583
|
}),
|
|
1474
|
-
theme: z.enum(["system", "light", "dark"])
|
|
1584
|
+
theme: z.enum(["system", "light", "dark"]),
|
|
1585
|
+
lastCreateBaseDir: z.union([z.string(), z.null()])
|
|
1475
1586
|
})
|
|
1476
1587
|
]);
|
|
1477
1588
|
var WorkbenchSettingsSetThemeSchema = z.tuple([
|
|
@@ -1593,7 +1704,74 @@ var popoverModule = {
|
|
|
1593
1704
|
};
|
|
1594
1705
|
|
|
1595
1706
|
// src/main/ipc/projects.ts
|
|
1596
|
-
import { dialog } from "electron";
|
|
1707
|
+
import { app as app8, dialog } from "electron";
|
|
1708
|
+
import path11 from "path";
|
|
1709
|
+
|
|
1710
|
+
// src/main/services/projects/create-project-service.ts
|
|
1711
|
+
import fs6 from "node:fs";
|
|
1712
|
+
import path10 from "node:path";
|
|
1713
|
+
var DEFAULT_TEMPLATE_ID = "blank";
|
|
1714
|
+
async function createProject(input, ctx) {
|
|
1715
|
+
const name = (input.name ?? "").trim();
|
|
1716
|
+
if (name.length === 0) {
|
|
1717
|
+
throw new Error("Project name cannot be empty");
|
|
1718
|
+
}
|
|
1719
|
+
const target = input.path;
|
|
1720
|
+
if (!target || typeof target !== "string") {
|
|
1721
|
+
throw new Error("Project path is required");
|
|
1722
|
+
}
|
|
1723
|
+
if (fs6.existsSync(target)) {
|
|
1724
|
+
const stat = fs6.statSync(target);
|
|
1725
|
+
if (!stat.isDirectory()) {
|
|
1726
|
+
throw new Error(`Project path exists and is not a directory: ${target}`);
|
|
1727
|
+
}
|
|
1728
|
+
const entries = fs6.readdirSync(target);
|
|
1729
|
+
if (entries.length > 0) {
|
|
1730
|
+
throw new Error(
|
|
1731
|
+
`Project path is not empty (refusing to overwrite): ${target}`
|
|
1732
|
+
);
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
const templateId = input.templateId ?? DEFAULT_TEMPLATE_ID;
|
|
1736
|
+
const template = ctx.templates.find((t) => t.id === templateId);
|
|
1737
|
+
if (!template) {
|
|
1738
|
+
throw new Error(`Template not found: ${templateId}`);
|
|
1739
|
+
}
|
|
1740
|
+
if (!template.source && !template.generate) {
|
|
1741
|
+
throw new Error(
|
|
1742
|
+
`Template '${templateId}' has neither a source directory nor a generate function`
|
|
1743
|
+
);
|
|
1744
|
+
}
|
|
1745
|
+
fs6.mkdirSync(target, { recursive: true });
|
|
1746
|
+
if (template.generate) {
|
|
1747
|
+
await template.generate(target, { name });
|
|
1748
|
+
} else if (template.source) {
|
|
1749
|
+
if (!fs6.existsSync(template.source.path)) {
|
|
1750
|
+
throw new Error(
|
|
1751
|
+
`Template source missing on disk: ${template.source.path}`
|
|
1752
|
+
);
|
|
1753
|
+
}
|
|
1754
|
+
fs6.cpSync(template.source.path, target, {
|
|
1755
|
+
recursive: true,
|
|
1756
|
+
force: true
|
|
1757
|
+
});
|
|
1758
|
+
}
|
|
1759
|
+
const cfgPath = path10.join(target, "project.config.json");
|
|
1760
|
+
let cfg = {};
|
|
1761
|
+
if (fs6.existsSync(cfgPath)) {
|
|
1762
|
+
try {
|
|
1763
|
+
cfg = JSON.parse(fs6.readFileSync(cfgPath, "utf-8"));
|
|
1764
|
+
} catch {
|
|
1765
|
+
cfg = {};
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
cfg.projectname = name;
|
|
1769
|
+
fs6.writeFileSync(cfgPath, JSON.stringify(cfg, null, 2));
|
|
1770
|
+
const created = await ctx.projectsProvider.addProject(target);
|
|
1771
|
+
return created;
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
// src/main/ipc/projects.ts
|
|
1597
1775
|
function registerProjectsIpc(ctx) {
|
|
1598
1776
|
return new IpcRegistry(ctx.senderPolicy).handle(ProjectsChannel.List, () => {
|
|
1599
1777
|
return ctx.workspace.listProjects();
|
|
@@ -1605,7 +1783,7 @@ function registerProjectsIpc(ctx) {
|
|
|
1605
1783
|
return result.canceled ? null : result.filePaths[0];
|
|
1606
1784
|
}).handle(ProjectsChannel.Add, async (_event, ...args) => {
|
|
1607
1785
|
const [dirPath] = validate(ProjectsChannel.Add, ProjectsAddSchema, args);
|
|
1608
|
-
const dirError = ctx.workspace.validateProjectDir(dirPath);
|
|
1786
|
+
const dirError = await ctx.workspace.validateProjectDir(dirPath);
|
|
1609
1787
|
if (dirError) {
|
|
1610
1788
|
await dialog.showMessageBox(ctx.mainWindow, {
|
|
1611
1789
|
type: "error",
|
|
@@ -1616,8 +1794,8 @@ function registerProjectsIpc(ctx) {
|
|
|
1616
1794
|
});
|
|
1617
1795
|
throw new Error(dirError);
|
|
1618
1796
|
}
|
|
1619
|
-
const duplicate = ctx.workspace.hasProject(dirPath);
|
|
1620
|
-
const project = ctx.workspace.addProject(dirPath);
|
|
1797
|
+
const duplicate = await ctx.workspace.hasProject(dirPath);
|
|
1798
|
+
const project = await ctx.workspace.addProject(dirPath);
|
|
1621
1799
|
if (duplicate) {
|
|
1622
1800
|
await dialog.showMessageBox(ctx.mainWindow, {
|
|
1623
1801
|
type: "info",
|
|
@@ -1631,8 +1809,60 @@ function registerProjectsIpc(ctx) {
|
|
|
1631
1809
|
}).handle(ProjectsChannel.Remove, (_event, ...args) => {
|
|
1632
1810
|
const [dirPath] = validate(ProjectsChannel.Remove, ProjectsRemoveSchema, args);
|
|
1633
1811
|
return ctx.workspace.removeProject(dirPath);
|
|
1812
|
+
}).handle(ProjectsChannel.ListTemplates, () => {
|
|
1813
|
+
return sanitizeTemplates(ctx.projectTemplates ?? []);
|
|
1814
|
+
}).handle(ProjectsChannel.OpenCreateDialog, async () => {
|
|
1815
|
+
if (!ctx.customCreateProjectDialog) return null;
|
|
1816
|
+
const sanitized = sanitizeTemplates(ctx.projectTemplates ?? []);
|
|
1817
|
+
return await ctx.customCreateProjectDialog({
|
|
1818
|
+
parentWindow: ctx.mainWindow,
|
|
1819
|
+
templates: sanitized
|
|
1820
|
+
});
|
|
1821
|
+
}).handle(ProjectsChannel.Create, async (_event, ...args) => {
|
|
1822
|
+
const [raw] = args;
|
|
1823
|
+
if (!raw || typeof raw !== "object") {
|
|
1824
|
+
throw new Error("projects:create expects a CreateProjectInput object");
|
|
1825
|
+
}
|
|
1826
|
+
const input = raw;
|
|
1827
|
+
let project;
|
|
1828
|
+
try {
|
|
1829
|
+
project = await createProject(input, {
|
|
1830
|
+
templates: ctx.projectTemplates ?? [],
|
|
1831
|
+
projectsProvider: ctx.projectsProvider
|
|
1832
|
+
});
|
|
1833
|
+
} catch (err) {
|
|
1834
|
+
await dialog.showMessageBox(ctx.mainWindow, {
|
|
1835
|
+
type: "error",
|
|
1836
|
+
title: "\u521B\u5EFA\u9879\u76EE\u5931\u8D25",
|
|
1837
|
+
message: "\u65E0\u6CD5\u521B\u5EFA\u9879\u76EE",
|
|
1838
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
1839
|
+
buttons: ["\u786E\u5B9A"]
|
|
1840
|
+
});
|
|
1841
|
+
throw err;
|
|
1842
|
+
}
|
|
1843
|
+
try {
|
|
1844
|
+
const settings = loadWorkbenchSettings();
|
|
1845
|
+
const newBase = path11.dirname(input.path);
|
|
1846
|
+
if (newBase && settings.lastCreateBaseDir !== newBase) {
|
|
1847
|
+
saveWorkbenchSettings({ ...settings, lastCreateBaseDir: newBase });
|
|
1848
|
+
}
|
|
1849
|
+
} catch (err) {
|
|
1850
|
+
console.warn("[projects:create] failed to persist lastCreateBaseDir", err);
|
|
1851
|
+
}
|
|
1852
|
+
return project;
|
|
1853
|
+
}).handle(ProjectsChannel.GetCreateDefaults, () => {
|
|
1854
|
+
const settings = loadWorkbenchSettings();
|
|
1855
|
+
const baseDir = settings.lastCreateBaseDir ?? safeAppPath("documents") ?? safeAppPath("home") ?? "";
|
|
1856
|
+
return { baseDir };
|
|
1634
1857
|
});
|
|
1635
1858
|
}
|
|
1859
|
+
function safeAppPath(name) {
|
|
1860
|
+
try {
|
|
1861
|
+
return app8.getPath(name);
|
|
1862
|
+
} catch {
|
|
1863
|
+
return null;
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1636
1866
|
var projectsModule = {
|
|
1637
1867
|
setup: (ctx) => registerProjectsIpc(ctx)
|
|
1638
1868
|
};
|
|
@@ -1682,7 +1912,7 @@ var sessionModule = {
|
|
|
1682
1912
|
};
|
|
1683
1913
|
|
|
1684
1914
|
// src/main/ipc/settings.ts
|
|
1685
|
-
import { app as
|
|
1915
|
+
import { app as app9 } from "electron";
|
|
1686
1916
|
function registerSettingsIpc(ctx) {
|
|
1687
1917
|
return new IpcRegistry(ctx.senderPolicy).handle(WorkbenchSettingsChannel.Get, () => {
|
|
1688
1918
|
return loadWorkbenchSettings();
|
|
@@ -1704,8 +1934,8 @@ function registerSettingsIpc(ctx) {
|
|
|
1704
1934
|
applyTheme(theme);
|
|
1705
1935
|
}).handle(WorkbenchSettingsChannel.GetCdpStatus, () => {
|
|
1706
1936
|
const settings = loadWorkbenchSettings();
|
|
1707
|
-
const switchValue =
|
|
1708
|
-
const implicitDevDefault = !
|
|
1937
|
+
const switchValue = app9.commandLine.getSwitchValue("remote-debugging-port");
|
|
1938
|
+
const implicitDevDefault = !app9.isPackaged && !settings.cdp.enabled && switchValue === "9222";
|
|
1709
1939
|
return {
|
|
1710
1940
|
configured: settings.cdp.enabled,
|
|
1711
1941
|
port: settings.cdp.port,
|
|
@@ -1728,26 +1958,25 @@ function registerSettingsIpc(ctx) {
|
|
|
1728
1958
|
const [visible] = validate(SettingsChannel.SetVisible, SettingsSetVisibleSchema, args);
|
|
1729
1959
|
if (visible) {
|
|
1730
1960
|
await ctx.views.showSettings();
|
|
1961
|
+
const projectPath = ctx.workspace.getProjectPath();
|
|
1731
1962
|
ctx.notify.settingsInit({
|
|
1732
|
-
projectPath
|
|
1733
|
-
config: ctx.workspace.getCompileConfig(
|
|
1734
|
-
projectSettings: ctx.workspace.getProjectSettings(
|
|
1963
|
+
projectPath,
|
|
1964
|
+
config: await ctx.workspace.getCompileConfig(projectPath),
|
|
1965
|
+
projectSettings: ctx.workspace.getProjectSettings(projectPath)
|
|
1735
1966
|
});
|
|
1736
1967
|
} else {
|
|
1737
1968
|
ctx.views.hideSettings();
|
|
1738
1969
|
ctx.notify.settingsClosed();
|
|
1739
1970
|
}
|
|
1740
|
-
}).on(SettingsChannel.ConfigChanged, (_, ...args) => {
|
|
1971
|
+
}).on(SettingsChannel.ConfigChanged, async (_, ...args) => {
|
|
1741
1972
|
const [config] = validate(
|
|
1742
1973
|
SettingsChannel.ConfigChanged,
|
|
1743
1974
|
SettingsConfigChangedSchema,
|
|
1744
1975
|
args
|
|
1745
1976
|
);
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
config
|
|
1750
|
-
);
|
|
1977
|
+
const projectPath = ctx.workspace.getProjectPath();
|
|
1978
|
+
if (projectPath) {
|
|
1979
|
+
await ctx.workspace.saveCompileConfig(projectPath, config);
|
|
1751
1980
|
}
|
|
1752
1981
|
ctx.notify.settingsChanged(config);
|
|
1753
1982
|
}).on(SettingsChannel.ProjectSettingsChanged, (_, ...args) => {
|
|
@@ -2959,7 +3188,7 @@ function startMcpServer(resolvedCdpPort, mcpPort) {
|
|
|
2959
3188
|
}
|
|
2960
3189
|
|
|
2961
3190
|
// src/main/services/simulator-storage/index.ts
|
|
2962
|
-
import { app as
|
|
3191
|
+
import { app as app10, webContents as wcStatic } from "electron";
|
|
2963
3192
|
function isSimulatorWebview(wc) {
|
|
2964
3193
|
if (wc.isDestroyed()) return false;
|
|
2965
3194
|
if (wc.getType() !== "webview") return false;
|
|
@@ -3209,9 +3438,9 @@ function setupSimulatorStorage(host, options) {
|
|
|
3209
3438
|
wcSubs.delete(wc);
|
|
3210
3439
|
});
|
|
3211
3440
|
};
|
|
3212
|
-
|
|
3441
|
+
app10.on("web-contents-created", onWcCreated);
|
|
3213
3442
|
registry.add(() => {
|
|
3214
|
-
|
|
3443
|
+
app10.removeListener("web-contents-created", onWcCreated);
|
|
3215
3444
|
});
|
|
3216
3445
|
registry.add(async () => {
|
|
3217
3446
|
const subs = Array.from(wcSubs.values());
|
|
@@ -3272,7 +3501,7 @@ async function clearElementInspection() {
|
|
|
3272
3501
|
}
|
|
3273
3502
|
|
|
3274
3503
|
// src/main/services/update/update-manager.ts
|
|
3275
|
-
import { app as
|
|
3504
|
+
import { app as app11, shell as shell3 } from "electron";
|
|
3276
3505
|
var UpdateManager = class {
|
|
3277
3506
|
checker;
|
|
3278
3507
|
mainWindow;
|
|
@@ -3285,7 +3514,7 @@ var UpdateManager = class {
|
|
|
3285
3514
|
constructor(opts) {
|
|
3286
3515
|
this.checker = opts.checker;
|
|
3287
3516
|
this.mainWindow = opts.mainWindow;
|
|
3288
|
-
this.getCurrentVersion = opts.getCurrentVersion ?? (() =>
|
|
3517
|
+
this.getCurrentVersion = opts.getCurrentVersion ?? (() => app11.getVersion());
|
|
3289
3518
|
this.ipc = new IpcRegistry(opts.senderPolicy);
|
|
3290
3519
|
this.registerIpc();
|
|
3291
3520
|
this.startPeriodicCheck(opts.checkInterval ?? 60 * 60 * 1e3, opts.initialDelay ?? 5e3);
|
|
@@ -3326,7 +3555,7 @@ var UpdateManager = class {
|
|
|
3326
3555
|
install() {
|
|
3327
3556
|
if (this.downloadedPath) {
|
|
3328
3557
|
shell3.openPath(this.downloadedPath);
|
|
3329
|
-
|
|
3558
|
+
app11.quit();
|
|
3330
3559
|
}
|
|
3331
3560
|
}
|
|
3332
3561
|
/**
|
|
@@ -3359,7 +3588,7 @@ var UpdateManager = class {
|
|
|
3359
3588
|
};
|
|
3360
3589
|
|
|
3361
3590
|
// src/main/services/update/github-release-checker.ts
|
|
3362
|
-
import { app as
|
|
3591
|
+
import { app as app12 } from "electron";
|
|
3363
3592
|
|
|
3364
3593
|
// src/main/app/app.ts
|
|
3365
3594
|
var DEFAULT_MODULES = {
|
|
@@ -3408,7 +3637,7 @@ async function disposeContext(ctx) {
|
|
|
3408
3637
|
function createConfiguredMainWindow(config, rendererDir2) {
|
|
3409
3638
|
const mainWindow = createMainWindow({
|
|
3410
3639
|
title: config.appName ?? "Dimina DevTools",
|
|
3411
|
-
indexHtml:
|
|
3640
|
+
indexHtml: path12.join(rendererDir2, "entries/main/index.html"),
|
|
3412
3641
|
width: config.window?.width,
|
|
3413
3642
|
height: config.window?.height,
|
|
3414
3643
|
minWidth: config.window?.minWidth,
|
|
@@ -3435,7 +3664,15 @@ function createContext(config, mainWindow, rendererDir2) {
|
|
|
3435
3664
|
appName: config.appName,
|
|
3436
3665
|
apiNamespaces: config.apiNamespaces,
|
|
3437
3666
|
brandingProvider: config.brandingProvider,
|
|
3438
|
-
toolbarActions: config.toolbarActions
|
|
3667
|
+
toolbarActions: config.toolbarActions,
|
|
3668
|
+
// The host-supplied ProjectsProvider / template types in `shared/types`
|
|
3669
|
+
// are structurally compatible with the main-process equivalents —
|
|
3670
|
+
// these casts are safe; we re-narrow at the workspace-service /
|
|
3671
|
+
// create-project-service boundary.
|
|
3672
|
+
projectsProvider: config.projectsProvider,
|
|
3673
|
+
projectTemplates: config.projectTemplates,
|
|
3674
|
+
builtinTemplates: config.builtinTemplates,
|
|
3675
|
+
customCreateProjectDialog: config.customCreateProjectDialog
|
|
3439
3676
|
});
|
|
3440
3677
|
}
|
|
3441
3678
|
function registerBuiltinModules(config, context) {
|
|
@@ -3463,7 +3700,7 @@ async function setupAutomation(instance) {
|
|
|
3463
3700
|
function setupMcp() {
|
|
3464
3701
|
const settings = loadWorkbenchSettings();
|
|
3465
3702
|
if (!settings.mcp.enabled) return null;
|
|
3466
|
-
const cdpPortSwitch =
|
|
3703
|
+
const cdpPortSwitch = app13.commandLine.getSwitchValue("remote-debugging-port");
|
|
3467
3704
|
const cdpPort2 = cdpPortSwitch ? parseInt(cdpPortSwitch, 10) : settings.cdp.port;
|
|
3468
3705
|
return startMcpServer(cdpPort2, settings.mcp.port);
|
|
3469
3706
|
}
|
|
@@ -3484,12 +3721,12 @@ function wireAppWindowEvents(config, instance) {
|
|
|
3484
3721
|
});
|
|
3485
3722
|
}
|
|
3486
3723
|
function enableDevRendererAutoReload(rendererDir2) {
|
|
3487
|
-
if (
|
|
3724
|
+
if (app13.isPackaged) {
|
|
3488
3725
|
return toDisposable(() => {
|
|
3489
3726
|
});
|
|
3490
3727
|
}
|
|
3491
3728
|
let reloadTimer = null;
|
|
3492
|
-
const watcher =
|
|
3729
|
+
const watcher = fs7.watch(rendererDir2, { recursive: true }, () => {
|
|
3493
3730
|
if (reloadTimer) clearTimeout(reloadTimer);
|
|
3494
3731
|
reloadTimer = setTimeout(() => {
|
|
3495
3732
|
for (const win of BrowserWindow3.getAllWindows()) {
|
|
@@ -3511,7 +3748,7 @@ function createWorkbenchApp(config = {}) {
|
|
|
3511
3748
|
setupCdpPort();
|
|
3512
3749
|
async function setup() {
|
|
3513
3750
|
if (setupPromise) return setupPromise;
|
|
3514
|
-
setupPromise =
|
|
3751
|
+
setupPromise = app13.whenReady().then(async () => {
|
|
3515
3752
|
applyTheme(loadWorkbenchSettings().theme);
|
|
3516
3753
|
const rendererDir2 = config.rendererDir ?? rendererDir;
|
|
3517
3754
|
const mainWindow = createConfiguredMainWindow(config, rendererDir2);
|
|
@@ -3575,7 +3812,7 @@ function createWorkbenchApp(config = {}) {
|
|
|
3575
3812
|
|
|
3576
3813
|
// src/main/windows/settings-window/create.ts
|
|
3577
3814
|
import { BrowserWindow as BrowserWindow4 } from "electron";
|
|
3578
|
-
import
|
|
3815
|
+
import path13 from "path";
|
|
3579
3816
|
async function createSettingsWindow(parent, rendererDir2) {
|
|
3580
3817
|
const win = new BrowserWindow4({
|
|
3581
3818
|
width: 420,
|
|
@@ -3593,7 +3830,7 @@ async function createSettingsWindow(parent, rendererDir2) {
|
|
|
3593
3830
|
}
|
|
3594
3831
|
});
|
|
3595
3832
|
applyNavigationHardening(win.webContents, rendererDir2);
|
|
3596
|
-
await win.loadFile(
|
|
3833
|
+
await win.loadFile(path13.join(rendererDir2, "entries/workbench-settings/index.html"));
|
|
3597
3834
|
return win;
|
|
3598
3835
|
}
|
|
3599
3836
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { WorkbenchContext } from '../services/workbench-context.js';
|
|
2
2
|
import type { WorkbenchModule } from '../services/module.js';
|
|
3
3
|
import type { Disposable } from '../utils/disposable.js';
|
|
4
|
-
|
|
4
|
+
type ProjectsIpcCtx = Pick<WorkbenchContext, 'workspace' | 'mainWindow' | 'senderPolicy' | 'projectsProvider' | 'projectTemplates' | 'customCreateProjectDialog'>;
|
|
5
|
+
export declare function registerProjectsIpc(ctx: ProjectsIpcCtx): Disposable;
|
|
5
6
|
export declare const projectsModule: WorkbenchModule;
|
|
7
|
+
export {};
|
|
6
8
|
//# sourceMappingURL=projects.d.ts.map
|