@trops/dash-core 0.1.130 → 0.1.131
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/dist/electron/index.js +598 -192
- package/dist/electron/index.js.map +1 -1
- package/package.json +1 -1
package/dist/electron/index.js
CHANGED
|
@@ -3,31 +3,31 @@
|
|
|
3
3
|
var require$$0$1 = require('electron');
|
|
4
4
|
var require$$1 = require('electron-store');
|
|
5
5
|
var require$$1$1 = require('path');
|
|
6
|
-
var require$$2 = require('fs');
|
|
6
|
+
var require$$0$2 = require('fs');
|
|
7
7
|
var require$$5$1 = require('objects-to-csv');
|
|
8
8
|
var require$$1$2 = require('readline');
|
|
9
|
-
var require$$2
|
|
9
|
+
var require$$2 = require('xtreamer');
|
|
10
10
|
var require$$3 = require('xml2js');
|
|
11
11
|
var require$$4 = require('JSONStream');
|
|
12
12
|
var require$$5 = require('stream');
|
|
13
13
|
var require$$6 = require('csv-parser');
|
|
14
|
-
var require$$0$
|
|
15
|
-
var require$$2$
|
|
14
|
+
var require$$0$3 = require('image-downloader');
|
|
15
|
+
var require$$2$1 = require('get-pixels');
|
|
16
16
|
var require$$3$1 = require('extract-colors');
|
|
17
17
|
var require$$8 = require('https');
|
|
18
|
-
var require$$0$
|
|
18
|
+
var require$$0$4 = require('@modelcontextprotocol/sdk/client/index.js');
|
|
19
19
|
var require$$1$3 = require('@modelcontextprotocol/sdk/client/stdio.js');
|
|
20
|
-
var require$$2$
|
|
20
|
+
var require$$2$2 = require('@modelcontextprotocol/sdk/client/streamableHttp.js');
|
|
21
21
|
var require$$5$2 = require('child_process');
|
|
22
|
-
var require$$2$
|
|
22
|
+
var require$$2$3 = require('algoliasearch');
|
|
23
23
|
var require$$3$2 = require('node:path');
|
|
24
|
-
var require$$0$
|
|
24
|
+
var require$$0$5 = require('openai');
|
|
25
25
|
require('live-plugin-manager');
|
|
26
|
-
var require$$0$
|
|
26
|
+
var require$$0$6 = require('@anthropic-ai/sdk');
|
|
27
27
|
var require$$3$3 = require('adm-zip');
|
|
28
|
-
var require$$2$
|
|
28
|
+
var require$$2$5 = require('os');
|
|
29
29
|
var require$$4$1 = require('url');
|
|
30
|
-
var require$$2$
|
|
30
|
+
var require$$2$4 = require('vm');
|
|
31
31
|
|
|
32
32
|
function getDefaultExportFromCjs (x) {
|
|
33
33
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
@@ -139,6 +139,10 @@ const THEME_DELETE$1 = "theme-delete";
|
|
|
139
139
|
const THEME_DELETE_COMPLETE = "theme-delete-complete";
|
|
140
140
|
const THEME_DELETE_ERROR = "theme-delete-error";
|
|
141
141
|
|
|
142
|
+
const THEME_PUBLISH$1 = "theme-publish";
|
|
143
|
+
const THEME_INSTALL_FROM_REGISTRY$1 = "theme-install-from-registry";
|
|
144
|
+
const THEME_PUBLISH_PREVIEW$1 = "theme-publish-preview";
|
|
145
|
+
|
|
142
146
|
var themeEvents$1 = {
|
|
143
147
|
THEME_LIST: THEME_LIST$1,
|
|
144
148
|
THEME_LIST_COMPLETE,
|
|
@@ -149,6 +153,9 @@ var themeEvents$1 = {
|
|
|
149
153
|
THEME_DELETE: THEME_DELETE$1,
|
|
150
154
|
THEME_DELETE_COMPLETE,
|
|
151
155
|
THEME_DELETE_ERROR,
|
|
156
|
+
THEME_PUBLISH: THEME_PUBLISH$1,
|
|
157
|
+
THEME_INSTALL_FROM_REGISTRY: THEME_INSTALL_FROM_REGISTRY$1,
|
|
158
|
+
THEME_PUBLISH_PREVIEW: THEME_PUBLISH_PREVIEW$1,
|
|
152
159
|
};
|
|
153
160
|
|
|
154
161
|
const DATA_JSON_TO_CSV_FILE$1 = "data-json-to-csv-file";
|
|
@@ -424,6 +431,7 @@ const REGISTRY_SEARCH = "registry:search";
|
|
|
424
431
|
const REGISTRY_GET_PACKAGE = "registry:get-package";
|
|
425
432
|
const REGISTRY_CHECK_UPDATES = "registry:check-updates";
|
|
426
433
|
const REGISTRY_SEARCH_DASHBOARDS = "registry:search-dashboards";
|
|
434
|
+
const REGISTRY_SEARCH_THEMES = "registry:search-themes";
|
|
427
435
|
|
|
428
436
|
var registryEvents$1 = {
|
|
429
437
|
REGISTRY_FETCH_INDEX,
|
|
@@ -431,6 +439,7 @@ var registryEvents$1 = {
|
|
|
431
439
|
REGISTRY_GET_PACKAGE,
|
|
432
440
|
REGISTRY_CHECK_UPDATES,
|
|
433
441
|
REGISTRY_SEARCH_DASHBOARDS,
|
|
442
|
+
REGISTRY_SEARCH_THEMES,
|
|
434
443
|
};
|
|
435
444
|
|
|
436
445
|
/**
|
|
@@ -785,14 +794,14 @@ var events$8 = {
|
|
|
785
794
|
* Open a dialog window for choosing files
|
|
786
795
|
*/
|
|
787
796
|
|
|
788
|
-
const { dialog: dialog$
|
|
797
|
+
const { dialog: dialog$2 } = require$$0$1;
|
|
789
798
|
const events$7 = events$8;
|
|
790
799
|
|
|
791
800
|
const showDialog$1 = async (win, message, allowFile, extensions = ["*"]) => {
|
|
792
801
|
const properties =
|
|
793
802
|
allowFile === true ? ["openFile"] : ["openDirectory", "createDirectory"];
|
|
794
803
|
const filters = allowFile === true ? [{ name: "Data", extensions }] : [];
|
|
795
|
-
const result = await dialog$
|
|
804
|
+
const result = await dialog$2.showOpenDialog({ properties, filters });
|
|
796
805
|
if (result.canceled || !result.filePaths[0]) return null;
|
|
797
806
|
return result.filePaths[0];
|
|
798
807
|
};
|
|
@@ -870,7 +879,7 @@ var secureStoreController$1 = {
|
|
|
870
879
|
getData: getData$1,
|
|
871
880
|
};
|
|
872
881
|
|
|
873
|
-
const path$
|
|
882
|
+
const path$h = require$$1$1;
|
|
874
883
|
const {
|
|
875
884
|
readFileSync,
|
|
876
885
|
writeFileSync: writeFileSync$4,
|
|
@@ -883,12 +892,12 @@ const {
|
|
|
883
892
|
unlinkSync,
|
|
884
893
|
readdirSync,
|
|
885
894
|
lstatSync,
|
|
886
|
-
} = require$$2;
|
|
895
|
+
} = require$$0$2;
|
|
887
896
|
|
|
888
897
|
function ensureDirectoryExistence$2(filePath) {
|
|
889
898
|
try {
|
|
890
899
|
// isDirectory
|
|
891
|
-
var dirname = path$
|
|
900
|
+
var dirname = path$h.dirname(filePath);
|
|
892
901
|
// check if the directory exists...return true
|
|
893
902
|
// if not, we can pass in the dirname as the filepath
|
|
894
903
|
// and check each directory recursively.
|
|
@@ -1003,7 +1012,7 @@ function removeFilesFromDirectory(directory, excludeFiles = []) {
|
|
|
1003
1012
|
|
|
1004
1013
|
for (const file of files) {
|
|
1005
1014
|
if (!excludeFiles.includes(file)) {
|
|
1006
|
-
unlinkSync(path$
|
|
1015
|
+
unlinkSync(path$h.join(directory, file), (err) => {
|
|
1007
1016
|
if (err) throw err;
|
|
1008
1017
|
});
|
|
1009
1018
|
}
|
|
@@ -1020,9 +1029,9 @@ var file = {
|
|
|
1020
1029
|
checkDirectory: checkDirectory$1,
|
|
1021
1030
|
};
|
|
1022
1031
|
|
|
1023
|
-
const { app: app$
|
|
1024
|
-
const path$
|
|
1025
|
-
const { writeFileSync: writeFileSync$3 } = require$$2;
|
|
1032
|
+
const { app: app$a } = require$$0$1;
|
|
1033
|
+
const path$g = require$$1$1;
|
|
1034
|
+
const { writeFileSync: writeFileSync$3 } = require$$0$2;
|
|
1026
1035
|
const { getFileContents: getFileContents$7 } = file;
|
|
1027
1036
|
|
|
1028
1037
|
const configFilename$5 = "workspaces.json";
|
|
@@ -1068,8 +1077,8 @@ const workspaceController$1 = {
|
|
|
1068
1077
|
saveWorkspaceForApplication: (win, appId, workspaceObject) => {
|
|
1069
1078
|
try {
|
|
1070
1079
|
// filename to the pages file (live pages)
|
|
1071
|
-
const filename = path$
|
|
1072
|
-
app$
|
|
1080
|
+
const filename = path$g.join(
|
|
1081
|
+
app$a.getPath("userData"),
|
|
1073
1082
|
appName$7,
|
|
1074
1083
|
appId,
|
|
1075
1084
|
configFilename$5,
|
|
@@ -1117,8 +1126,8 @@ const workspaceController$1 = {
|
|
|
1117
1126
|
saveMenuItemsForApplication: (win, appId, menuItems) => {
|
|
1118
1127
|
try {
|
|
1119
1128
|
// filename to the workspaces file
|
|
1120
|
-
const filename = path$
|
|
1121
|
-
app$
|
|
1129
|
+
const filename = path$g.join(
|
|
1130
|
+
app$a.getPath("userData"),
|
|
1122
1131
|
appName$7,
|
|
1123
1132
|
appId,
|
|
1124
1133
|
configFilename$5,
|
|
@@ -1166,8 +1175,8 @@ const workspaceController$1 = {
|
|
|
1166
1175
|
*/
|
|
1167
1176
|
deleteWorkspaceForApplication: (win, appId, workspaceId) => {
|
|
1168
1177
|
try {
|
|
1169
|
-
const filename = path$
|
|
1170
|
-
app$
|
|
1178
|
+
const filename = path$g.join(
|
|
1179
|
+
app$a.getPath("userData"),
|
|
1171
1180
|
appName$7,
|
|
1172
1181
|
appId,
|
|
1173
1182
|
configFilename$5,
|
|
@@ -1200,8 +1209,8 @@ const workspaceController$1 = {
|
|
|
1200
1209
|
|
|
1201
1210
|
listWorkspacesForApplication: (win, appId) => {
|
|
1202
1211
|
try {
|
|
1203
|
-
const filename = path$
|
|
1204
|
-
app$
|
|
1212
|
+
const filename = path$g.join(
|
|
1213
|
+
app$a.getPath("userData"),
|
|
1205
1214
|
appName$7,
|
|
1206
1215
|
appId,
|
|
1207
1216
|
configFilename$5,
|
|
@@ -1228,8 +1237,8 @@ const workspaceController$1 = {
|
|
|
1228
1237
|
|
|
1229
1238
|
listMenuItemsForApplication: (win, appId) => {
|
|
1230
1239
|
try {
|
|
1231
|
-
const filename = path$
|
|
1232
|
-
app$
|
|
1240
|
+
const filename = path$g.join(
|
|
1241
|
+
app$a.getPath("userData"),
|
|
1233
1242
|
appName$7,
|
|
1234
1243
|
appId,
|
|
1235
1244
|
configFilename$5,
|
|
@@ -1272,15 +1281,15 @@ const workspaceController$1 = {
|
|
|
1272
1281
|
|
|
1273
1282
|
var workspaceController_1 = workspaceController$1;
|
|
1274
1283
|
|
|
1275
|
-
const { app: app$
|
|
1276
|
-
const path$
|
|
1277
|
-
const { writeFileSync: writeFileSync$2 } = require$$2;
|
|
1284
|
+
const { app: app$9 } = require$$0$1;
|
|
1285
|
+
const path$f = require$$1$1;
|
|
1286
|
+
const { writeFileSync: writeFileSync$2 } = require$$0$2;
|
|
1278
1287
|
const { getFileContents: getFileContents$6 } = file;
|
|
1279
1288
|
|
|
1280
1289
|
const configFilename$4 = "themes.json";
|
|
1281
1290
|
const appName$6 = "Dashboard";
|
|
1282
1291
|
|
|
1283
|
-
const themeController$
|
|
1292
|
+
const themeController$2 = {
|
|
1284
1293
|
/**
|
|
1285
1294
|
* saveTheme
|
|
1286
1295
|
* Create a new Theme that can be used in the application
|
|
@@ -1293,8 +1302,8 @@ const themeController$1 = {
|
|
|
1293
1302
|
saveThemeForApplication: (win, appId, name, obj) => {
|
|
1294
1303
|
try {
|
|
1295
1304
|
// filename to the pages file (live pages)
|
|
1296
|
-
const filename = path$
|
|
1297
|
-
app$
|
|
1305
|
+
const filename = path$f.join(
|
|
1306
|
+
app$9.getPath("userData"),
|
|
1298
1307
|
appName$6,
|
|
1299
1308
|
appId,
|
|
1300
1309
|
configFilename$4,
|
|
@@ -1339,8 +1348,8 @@ const themeController$1 = {
|
|
|
1339
1348
|
*/
|
|
1340
1349
|
listThemesForApplication: (win, appId) => {
|
|
1341
1350
|
try {
|
|
1342
|
-
const filename = path$
|
|
1343
|
-
app$
|
|
1351
|
+
const filename = path$f.join(
|
|
1352
|
+
app$9.getPath("userData"),
|
|
1344
1353
|
appName$6,
|
|
1345
1354
|
appId,
|
|
1346
1355
|
configFilename$4,
|
|
@@ -1381,8 +1390,8 @@ const themeController$1 = {
|
|
|
1381
1390
|
*/
|
|
1382
1391
|
deleteThemeForApplication: (win, appId, themeKey) => {
|
|
1383
1392
|
try {
|
|
1384
|
-
const filename = path$
|
|
1385
|
-
app$
|
|
1393
|
+
const filename = path$f.join(
|
|
1394
|
+
app$9.getPath("userData"),
|
|
1386
1395
|
appName$6,
|
|
1387
1396
|
appId,
|
|
1388
1397
|
configFilename$4,
|
|
@@ -1411,7 +1420,7 @@ const themeController$1 = {
|
|
|
1411
1420
|
},
|
|
1412
1421
|
};
|
|
1413
1422
|
|
|
1414
|
-
var themeController_1 = themeController$
|
|
1423
|
+
var themeController_1 = themeController$2;
|
|
1415
1424
|
|
|
1416
1425
|
/**
|
|
1417
1426
|
* Utils/tranaform
|
|
@@ -1421,15 +1430,15 @@ var themeController_1 = themeController$1;
|
|
|
1421
1430
|
* - CSV -> JSON
|
|
1422
1431
|
*/
|
|
1423
1432
|
|
|
1424
|
-
var fs$9 = require$$2;
|
|
1433
|
+
var fs$9 = require$$0$2;
|
|
1425
1434
|
var readline = require$$1$2;
|
|
1426
|
-
const xtreamer = require$$2
|
|
1435
|
+
const xtreamer = require$$2;
|
|
1427
1436
|
var xmlParser = require$$3;
|
|
1428
1437
|
var JSONStream$1 = require$$4;
|
|
1429
1438
|
const stream = require$$5;
|
|
1430
1439
|
var csv = require$$6;
|
|
1431
|
-
const path$
|
|
1432
|
-
const { app: app$
|
|
1440
|
+
const path$e = require$$1$1;
|
|
1441
|
+
const { app: app$8 } = require$$0$1;
|
|
1433
1442
|
const { ensureDirectoryExistence: ensureDirectoryExistence$1 } = file;
|
|
1434
1443
|
|
|
1435
1444
|
const TRANSFORM_APP_NAME = "Dashboard";
|
|
@@ -1717,18 +1726,18 @@ let Transform$1 = class Transform {
|
|
|
1717
1726
|
}
|
|
1718
1727
|
|
|
1719
1728
|
// Validate file paths are within app data directory
|
|
1720
|
-
const appDataDir = path$
|
|
1721
|
-
const resolvedFilepath = path$
|
|
1722
|
-
const resolvedOutFilepath = path$
|
|
1729
|
+
const appDataDir = path$e.join(app$8.getPath("userData"), TRANSFORM_APP_NAME);
|
|
1730
|
+
const resolvedFilepath = path$e.resolve(filepath);
|
|
1731
|
+
const resolvedOutFilepath = path$e.resolve(outFilepath);
|
|
1723
1732
|
|
|
1724
|
-
if (!resolvedFilepath.startsWith(appDataDir + path$
|
|
1733
|
+
if (!resolvedFilepath.startsWith(appDataDir + path$e.sep)) {
|
|
1725
1734
|
return reject(
|
|
1726
1735
|
new Error(
|
|
1727
1736
|
"Input file path must be within the application data directory",
|
|
1728
1737
|
),
|
|
1729
1738
|
);
|
|
1730
1739
|
}
|
|
1731
|
-
if (!resolvedOutFilepath.startsWith(appDataDir + path$
|
|
1740
|
+
if (!resolvedOutFilepath.startsWith(appDataDir + path$e.sep)) {
|
|
1732
1741
|
return reject(
|
|
1733
1742
|
new Error(
|
|
1734
1743
|
"Output file path must be within the application data directory",
|
|
@@ -3542,9 +3551,9 @@ var ntc_1 = ntc$1;
|
|
|
3542
3551
|
* - extractColorsFromImageURL
|
|
3543
3552
|
*/
|
|
3544
3553
|
|
|
3545
|
-
const download = require$$0$
|
|
3546
|
-
const getPixels = require$$2$
|
|
3547
|
-
const { extractColors } = require$$3$1;
|
|
3554
|
+
const download = require$$0$3;
|
|
3555
|
+
const getPixels = require$$2$1;
|
|
3556
|
+
const { extractColors: extractColors$1 } = require$$3$1;
|
|
3548
3557
|
const ntc = ntc_1;
|
|
3549
3558
|
|
|
3550
3559
|
async function extractColorsFromImageURL$2(url, toDirectory) {
|
|
@@ -3565,7 +3574,7 @@ async function extractColorsFromImageURL$2(url, toDirectory) {
|
|
|
3565
3574
|
const data = [...pixels.data];
|
|
3566
3575
|
const [width, height] = pixels.shape;
|
|
3567
3576
|
|
|
3568
|
-
extractColors({ data, width, height })
|
|
3577
|
+
extractColors$1({ data, width, height })
|
|
3569
3578
|
.then((result) => {
|
|
3570
3579
|
console.log(result);
|
|
3571
3580
|
const n = new ntc();
|
|
@@ -3586,9 +3595,9 @@ async function extractColorsFromImageURL$2(url, toDirectory) {
|
|
|
3586
3595
|
|
|
3587
3596
|
var color = { extractColorsFromImageURL: extractColorsFromImageURL$2 };
|
|
3588
3597
|
|
|
3589
|
-
const { app: app$
|
|
3590
|
-
var fs$8 = require$$2;
|
|
3591
|
-
const path$
|
|
3598
|
+
const { app: app$7 } = require$$0$1;
|
|
3599
|
+
var fs$8 = require$$0$2;
|
|
3600
|
+
const path$d = require$$1$1;
|
|
3592
3601
|
const events$5 = events$8;
|
|
3593
3602
|
const { getFileContents: getFileContents$5, writeToFile: writeToFile$2 } = file;
|
|
3594
3603
|
|
|
@@ -3611,8 +3620,8 @@ const dataController$1 = {
|
|
|
3611
3620
|
convertJsonToCsvFile: (win, appId, jsonObject, toFilename = "test.csv") => {
|
|
3612
3621
|
try {
|
|
3613
3622
|
// filename to the pages file (live pages)
|
|
3614
|
-
const filename = path$
|
|
3615
|
-
app$
|
|
3623
|
+
const filename = path$d.join(
|
|
3624
|
+
app$7.getPath("userData"),
|
|
3616
3625
|
appName$5,
|
|
3617
3626
|
appId,
|
|
3618
3627
|
"data",
|
|
@@ -3739,9 +3748,9 @@ const dataController$1 = {
|
|
|
3739
3748
|
}
|
|
3740
3749
|
|
|
3741
3750
|
// Validate toFilepath is within the app data directory
|
|
3742
|
-
const appDataDir = path$
|
|
3743
|
-
const resolvedFilepath = path$
|
|
3744
|
-
if (!resolvedFilepath.startsWith(appDataDir + path$
|
|
3751
|
+
const appDataDir = path$d.join(app$7.getPath("userData"), appName$5);
|
|
3752
|
+
const resolvedFilepath = path$d.resolve(toFilepath);
|
|
3753
|
+
if (!resolvedFilepath.startsWith(appDataDir + path$d.sep)) {
|
|
3745
3754
|
throw new Error(
|
|
3746
3755
|
"File path must be within the application data directory",
|
|
3747
3756
|
);
|
|
@@ -3888,8 +3897,8 @@ const dataController$1 = {
|
|
|
3888
3897
|
try {
|
|
3889
3898
|
if (data) {
|
|
3890
3899
|
// filename to the pages file (live pages)
|
|
3891
|
-
const toFilename = path$
|
|
3892
|
-
app$
|
|
3900
|
+
const toFilename = path$d.join(
|
|
3901
|
+
app$7.getPath("userData"),
|
|
3893
3902
|
appName$5,
|
|
3894
3903
|
"data",
|
|
3895
3904
|
filename,
|
|
@@ -3970,8 +3979,8 @@ const dataController$1 = {
|
|
|
3970
3979
|
try {
|
|
3971
3980
|
if (filename) {
|
|
3972
3981
|
// filename to the pages file (live pages)
|
|
3973
|
-
const fromFilename = path$
|
|
3974
|
-
app$
|
|
3982
|
+
const fromFilename = path$d.join(
|
|
3983
|
+
app$7.getPath("userData"),
|
|
3975
3984
|
appName$5,
|
|
3976
3985
|
"data",
|
|
3977
3986
|
filename,
|
|
@@ -4048,8 +4057,8 @@ const dataController$1 = {
|
|
|
4048
4057
|
try {
|
|
4049
4058
|
console.log(url);
|
|
4050
4059
|
const fileExtension = ".jpg";
|
|
4051
|
-
const filename = path$
|
|
4052
|
-
app$
|
|
4060
|
+
const filename = path$d.join(
|
|
4061
|
+
app$7.getPath("userData"),
|
|
4053
4062
|
appName$5,
|
|
4054
4063
|
"@algolia/dash-electron",
|
|
4055
4064
|
"data",
|
|
@@ -4073,9 +4082,9 @@ var dataController_1 = dataController$1;
|
|
|
4073
4082
|
* settingsController
|
|
4074
4083
|
*/
|
|
4075
4084
|
|
|
4076
|
-
const { app: app$
|
|
4077
|
-
const path$
|
|
4078
|
-
const fs$7 = require$$2;
|
|
4085
|
+
const { app: app$6 } = require$$0$1;
|
|
4086
|
+
const path$c = require$$1$1;
|
|
4087
|
+
const fs$7 = require$$0$2;
|
|
4079
4088
|
const { getFileContents: getFileContents$4, writeToFile: writeToFile$1 } = file;
|
|
4080
4089
|
|
|
4081
4090
|
const configFilename$3 = "settings.json";
|
|
@@ -4089,8 +4098,8 @@ function copyDirectory(source, destination) {
|
|
|
4089
4098
|
|
|
4090
4099
|
const files = fs$7.readdirSync(source);
|
|
4091
4100
|
for (const file of files) {
|
|
4092
|
-
const srcPath = path$
|
|
4093
|
-
const destPath = path$
|
|
4101
|
+
const srcPath = path$c.join(source, file);
|
|
4102
|
+
const destPath = path$c.join(destination, file);
|
|
4094
4103
|
const stat = fs$7.lstatSync(srcPath);
|
|
4095
4104
|
|
|
4096
4105
|
// Skip symlinks to prevent following links to sensitive files
|
|
@@ -4118,8 +4127,8 @@ const settingsController$1 = {
|
|
|
4118
4127
|
try {
|
|
4119
4128
|
if (data) {
|
|
4120
4129
|
// <appId>/settings.json
|
|
4121
|
-
const filename = path$
|
|
4122
|
-
app$
|
|
4130
|
+
const filename = path$c.join(
|
|
4131
|
+
app$6.getPath("userData"),
|
|
4123
4132
|
appName$4,
|
|
4124
4133
|
configFilename$3,
|
|
4125
4134
|
);
|
|
@@ -4154,8 +4163,8 @@ const settingsController$1 = {
|
|
|
4154
4163
|
getSettingsForApplication: (win) => {
|
|
4155
4164
|
try {
|
|
4156
4165
|
// <appId>/settings.json
|
|
4157
|
-
const filename = path$
|
|
4158
|
-
app$
|
|
4166
|
+
const filename = path$c.join(
|
|
4167
|
+
app$6.getPath("userData"),
|
|
4159
4168
|
appName$4,
|
|
4160
4169
|
configFilename$3,
|
|
4161
4170
|
);
|
|
@@ -4185,15 +4194,15 @@ const settingsController$1 = {
|
|
|
4185
4194
|
*/
|
|
4186
4195
|
getDataDirectory: (win) => {
|
|
4187
4196
|
try {
|
|
4188
|
-
const settingsPath = path$
|
|
4189
|
-
app$
|
|
4197
|
+
const settingsPath = path$c.join(
|
|
4198
|
+
app$6.getPath("userData"),
|
|
4190
4199
|
appName$4,
|
|
4191
4200
|
configFilename$3,
|
|
4192
4201
|
);
|
|
4193
4202
|
const settings = getFileContents$4(settingsPath, {});
|
|
4194
4203
|
const userDataDir =
|
|
4195
4204
|
settings.userDataDirectory ||
|
|
4196
|
-
path$
|
|
4205
|
+
path$c.join(app$6.getPath("userData"), appName$4);
|
|
4197
4206
|
|
|
4198
4207
|
console.log("[settingsController] Data directory retrieved successfully");
|
|
4199
4208
|
// Return the data for ipcMain.handle() - modern promise-based approach
|
|
@@ -4230,8 +4239,8 @@ const settingsController$1 = {
|
|
|
4230
4239
|
}
|
|
4231
4240
|
|
|
4232
4241
|
// Update settings
|
|
4233
|
-
const settingsPath = path$
|
|
4234
|
-
app$
|
|
4242
|
+
const settingsPath = path$c.join(
|
|
4243
|
+
app$6.getPath("userData"),
|
|
4235
4244
|
appName$4,
|
|
4236
4245
|
configFilename$3,
|
|
4237
4246
|
);
|
|
@@ -4264,20 +4273,20 @@ const settingsController$1 = {
|
|
|
4264
4273
|
migrateDataDirectory: (win, oldPath, newPath) => {
|
|
4265
4274
|
try {
|
|
4266
4275
|
// Resolve paths to prevent traversal
|
|
4267
|
-
const resolvedOldPath = path$
|
|
4268
|
-
const resolvedNewPath = path$
|
|
4276
|
+
const resolvedOldPath = path$c.resolve(oldPath);
|
|
4277
|
+
const resolvedNewPath = path$c.resolve(newPath);
|
|
4269
4278
|
|
|
4270
4279
|
// Validate oldPath is the current configured data directory
|
|
4271
|
-
const settingsCheckPath = path$
|
|
4272
|
-
app$
|
|
4280
|
+
const settingsCheckPath = path$c.join(
|
|
4281
|
+
app$6.getPath("userData"),
|
|
4273
4282
|
appName$4,
|
|
4274
4283
|
configFilename$3,
|
|
4275
4284
|
);
|
|
4276
4285
|
const currentSettings = getFileContents$4(settingsCheckPath, {});
|
|
4277
4286
|
const currentDataDir =
|
|
4278
4287
|
currentSettings.userDataDirectory ||
|
|
4279
|
-
path$
|
|
4280
|
-
if (resolvedOldPath !== path$
|
|
4288
|
+
path$c.join(app$6.getPath("userData"), appName$4);
|
|
4289
|
+
if (resolvedOldPath !== path$c.resolve(currentDataDir)) {
|
|
4281
4290
|
throw new Error("Source path must be the current data directory");
|
|
4282
4291
|
}
|
|
4283
4292
|
|
|
@@ -4313,8 +4322,8 @@ const settingsController$1 = {
|
|
|
4313
4322
|
copyDirectory(resolvedOldPath, resolvedNewPath);
|
|
4314
4323
|
|
|
4315
4324
|
// Update settings to use new path
|
|
4316
|
-
const settingsPath = path$
|
|
4317
|
-
app$
|
|
4325
|
+
const settingsPath = path$c.join(
|
|
4326
|
+
app$6.getPath("userData"),
|
|
4318
4327
|
appName$4,
|
|
4319
4328
|
configFilename$3,
|
|
4320
4329
|
);
|
|
@@ -4598,7 +4607,7 @@ function requireProviderController () {
|
|
|
4598
4607
|
hasRequiredProviderController = 1;
|
|
4599
4608
|
const { app, safeStorage } = require$$0$1;
|
|
4600
4609
|
const path = require$$1$1;
|
|
4601
|
-
const { writeFileSync, readFileSync, existsSync } = require$$2;
|
|
4610
|
+
const { writeFileSync, readFileSync, existsSync } = require$$0$2;
|
|
4602
4611
|
const {
|
|
4603
4612
|
ensureDirectoryExistence,
|
|
4604
4613
|
getFileContents,
|
|
@@ -4927,9 +4936,9 @@ function requireProviderController () {
|
|
|
4927
4936
|
return providerController_1;
|
|
4928
4937
|
}
|
|
4929
4938
|
|
|
4930
|
-
const { app: app$
|
|
4931
|
-
const path$
|
|
4932
|
-
const { writeFileSync: writeFileSync$1 } = require$$2;
|
|
4939
|
+
const { app: app$5 } = require$$0$1;
|
|
4940
|
+
const path$b = require$$1$1;
|
|
4941
|
+
const { writeFileSync: writeFileSync$1 } = require$$0$2;
|
|
4933
4942
|
const events$4 = events$8;
|
|
4934
4943
|
const { getFileContents: getFileContents$3 } = file;
|
|
4935
4944
|
|
|
@@ -4948,8 +4957,8 @@ const layoutController$1 = {
|
|
|
4948
4957
|
saveLayoutForApplication: (win, appId, layoutObject) => {
|
|
4949
4958
|
try {
|
|
4950
4959
|
// filename to the pages file (live pages)
|
|
4951
|
-
const filename = path$
|
|
4952
|
-
app$
|
|
4960
|
+
const filename = path$b.join(
|
|
4961
|
+
app$5.getPath("userData"),
|
|
4953
4962
|
appName$3,
|
|
4954
4963
|
appId,
|
|
4955
4964
|
configFilename$2,
|
|
@@ -4981,8 +4990,8 @@ const layoutController$1 = {
|
|
|
4981
4990
|
*/
|
|
4982
4991
|
listLayoutsForApplication: (win, appId) => {
|
|
4983
4992
|
try {
|
|
4984
|
-
const filename = path$
|
|
4985
|
-
app$
|
|
4993
|
+
const filename = path$b.join(
|
|
4994
|
+
app$5.getPath("userData"),
|
|
4986
4995
|
appName$3,
|
|
4987
4996
|
appId,
|
|
4988
4997
|
configFilename$2,
|
|
@@ -5017,15 +5026,15 @@ var mcpController$3 = {exports: {}};
|
|
|
5017
5026
|
* Uses @modelcontextprotocol/sdk for protocol handling.
|
|
5018
5027
|
*/
|
|
5019
5028
|
|
|
5020
|
-
const { Client } = require$$0$
|
|
5029
|
+
const { Client } = require$$0$4;
|
|
5021
5030
|
const {
|
|
5022
5031
|
StdioClientTransport,
|
|
5023
5032
|
} = require$$1$3;
|
|
5024
5033
|
const {
|
|
5025
5034
|
StreamableHTTPClientTransport,
|
|
5026
|
-
} = require$$2$
|
|
5027
|
-
const path$
|
|
5028
|
-
const fs$6 = require$$2;
|
|
5035
|
+
} = require$$2$2;
|
|
5036
|
+
const path$a = require$$1$1;
|
|
5037
|
+
const fs$6 = require$$0$2;
|
|
5029
5038
|
|
|
5030
5039
|
/**
|
|
5031
5040
|
* Cached shell PATH result (resolved once, reused for all spawns).
|
|
@@ -5441,7 +5450,7 @@ const mcpController$2 = {
|
|
|
5441
5450
|
}
|
|
5442
5451
|
|
|
5443
5452
|
// Interpolate {{MCP_DIR}} in args to resolve local MCP server scripts
|
|
5444
|
-
const mcpDir = path$
|
|
5453
|
+
const mcpDir = path$a.join(__dirname, "..", "mcp");
|
|
5445
5454
|
for (let i = 0; i < args.length; i++) {
|
|
5446
5455
|
if (
|
|
5447
5456
|
typeof args[i] === "string" &&
|
|
@@ -5816,7 +5825,7 @@ const mcpController$2 = {
|
|
|
5816
5825
|
*/
|
|
5817
5826
|
getCatalog: (win) => {
|
|
5818
5827
|
try {
|
|
5819
|
-
const catalogPath = path$
|
|
5828
|
+
const catalogPath = path$a.join(
|
|
5820
5829
|
__dirname,
|
|
5821
5830
|
"..",
|
|
5822
5831
|
"mcp",
|
|
@@ -5928,7 +5937,7 @@ const mcpController$2 = {
|
|
|
5928
5937
|
}
|
|
5929
5938
|
|
|
5930
5939
|
// Interpolate {{MCP_DIR}} in authCommand args (same as startServer)
|
|
5931
|
-
const mcpDir = path$
|
|
5940
|
+
const mcpDir = path$a.join(__dirname, "..", "mcp");
|
|
5932
5941
|
const resolvedArgs = (authCommand.args || []).map((arg) =>
|
|
5933
5942
|
typeof arg === "string" && arg.includes("{{MCP_DIR}}")
|
|
5934
5943
|
? arg.replace(/\{\{MCP_DIR\}\}/g, mcpDir)
|
|
@@ -6024,8 +6033,8 @@ var mcpControllerExports = mcpController$3.exports;
|
|
|
6024
6033
|
* - Support two-level browsing: packages (bundles) and widgets within packages
|
|
6025
6034
|
*/
|
|
6026
6035
|
|
|
6027
|
-
const path$
|
|
6028
|
-
const fs$5 = require$$2;
|
|
6036
|
+
const path$9 = require$$1$1;
|
|
6037
|
+
const fs$5 = require$$0$2;
|
|
6029
6038
|
|
|
6030
6039
|
// Default registry API base URL
|
|
6031
6040
|
const DEFAULT_REGISTRY_API_URL = "https://main.d919rwhuzp7rj.amplifyapp.com";
|
|
@@ -6040,7 +6049,7 @@ let cacheTimestamp = 0;
|
|
|
6040
6049
|
* Get the local test registry path for dev mode
|
|
6041
6050
|
*/
|
|
6042
6051
|
function getTestRegistryPath() {
|
|
6043
|
-
return path$
|
|
6052
|
+
return path$9.join(__dirname, "..", "registry", "test-registry-index.json");
|
|
6044
6053
|
}
|
|
6045
6054
|
|
|
6046
6055
|
/**
|
|
@@ -6326,18 +6335,31 @@ async function searchDashboards(query = "", filters = {}) {
|
|
|
6326
6335
|
return searchRegistry$1(query, { ...filters, type: "dashboard" });
|
|
6327
6336
|
}
|
|
6328
6337
|
|
|
6329
|
-
|
|
6338
|
+
/**
|
|
6339
|
+
* Search the registry for theme packages only.
|
|
6340
|
+
* Convenience wrapper around searchRegistry with type: "theme".
|
|
6341
|
+
*
|
|
6342
|
+
* @param {string} query - Search query string
|
|
6343
|
+
* @param {Object} filters - Optional filters (category, author, tag)
|
|
6344
|
+
* @returns {Promise<Object>} { packages: [...], totalWidgets: number }
|
|
6345
|
+
*/
|
|
6346
|
+
async function searchThemes(query = "", filters = {}) {
|
|
6347
|
+
return searchRegistry$1(query, { ...filters, type: "theme" });
|
|
6348
|
+
}
|
|
6349
|
+
|
|
6350
|
+
var registryController$2 = {
|
|
6330
6351
|
fetchRegistryIndex,
|
|
6331
6352
|
searchRegistry: searchRegistry$1,
|
|
6332
6353
|
searchDashboards,
|
|
6354
|
+
searchThemes,
|
|
6333
6355
|
getPackage: getPackage$1,
|
|
6334
6356
|
checkUpdates,
|
|
6335
6357
|
};
|
|
6336
6358
|
|
|
6337
|
-
var fs$4 = require$$2;
|
|
6359
|
+
var fs$4 = require$$0$2;
|
|
6338
6360
|
var JSONStream = require$$4;
|
|
6339
|
-
const algoliasearch$1 = require$$2$
|
|
6340
|
-
const path$
|
|
6361
|
+
const algoliasearch$1 = require$$2$3;
|
|
6362
|
+
const path$8 = require$$3$2;
|
|
6341
6363
|
const { ensureDirectoryExistence, checkDirectory } = file;
|
|
6342
6364
|
|
|
6343
6365
|
let AlgoliaIndex$1 = class AlgoliaIndex {
|
|
@@ -6444,7 +6466,7 @@ let AlgoliaIndex$1 = class AlgoliaIndex {
|
|
|
6444
6466
|
if (err) reject(err);
|
|
6445
6467
|
if (files) {
|
|
6446
6468
|
files.forEach((file) => {
|
|
6447
|
-
fs$4.unlinkSync(path$
|
|
6469
|
+
fs$4.unlinkSync(path$8.join(directoryPath, file));
|
|
6448
6470
|
});
|
|
6449
6471
|
resolve();
|
|
6450
6472
|
}
|
|
@@ -6467,7 +6489,7 @@ let AlgoliaIndex$1 = class AlgoliaIndex {
|
|
|
6467
6489
|
let results = [];
|
|
6468
6490
|
for (const fileIndex in files) {
|
|
6469
6491
|
// for each file lets read the file and then push to algolia
|
|
6470
|
-
const pathToBatch = path$
|
|
6492
|
+
const pathToBatch = path$8.join(batchFilepath, files[fileIndex]);
|
|
6471
6493
|
const fileContents = await this.readFile(pathToBatch);
|
|
6472
6494
|
if (fileContents) {
|
|
6473
6495
|
if ("data" in fileContents && "filepath" in fileContents) {
|
|
@@ -6639,10 +6661,10 @@ var algolia = AlgoliaIndex$1;
|
|
|
6639
6661
|
* the controller methods as seen below.
|
|
6640
6662
|
*/
|
|
6641
6663
|
|
|
6642
|
-
const algoliasearch = require$$2$
|
|
6664
|
+
const algoliasearch = require$$2$3;
|
|
6643
6665
|
const events$3 = events$8;
|
|
6644
6666
|
const AlgoliaIndex = algolia;
|
|
6645
|
-
var fs$3 = require$$2;
|
|
6667
|
+
var fs$3 = require$$0$2;
|
|
6646
6668
|
|
|
6647
6669
|
const algoliaController$1 = {
|
|
6648
6670
|
/**
|
|
@@ -6880,7 +6902,7 @@ const algoliaController$1 = {
|
|
|
6880
6902
|
|
|
6881
6903
|
var algoliaController_1 = algoliaController$1;
|
|
6882
6904
|
|
|
6883
|
-
const OpenAI = require$$0$
|
|
6905
|
+
const OpenAI = require$$0$5;
|
|
6884
6906
|
const events$2 = events$8;
|
|
6885
6907
|
|
|
6886
6908
|
const openaiController$1 = {
|
|
@@ -6921,9 +6943,9 @@ const openaiController$1 = {
|
|
|
6921
6943
|
|
|
6922
6944
|
var openaiController_1 = openaiController$1;
|
|
6923
6945
|
|
|
6924
|
-
const { app: app$
|
|
6925
|
-
const path$
|
|
6926
|
-
const { writeFileSync } = require$$2;
|
|
6946
|
+
const { app: app$4 } = require$$0$1;
|
|
6947
|
+
const path$7 = require$$1$1;
|
|
6948
|
+
const { writeFileSync } = require$$0$2;
|
|
6927
6949
|
const { getFileContents: getFileContents$2 } = file;
|
|
6928
6950
|
|
|
6929
6951
|
const configFilename$1 = "menuItems.json";
|
|
@@ -6933,8 +6955,8 @@ const menuItemsController$1 = {
|
|
|
6933
6955
|
saveMenuItemForApplication: (win, appId, menuItem) => {
|
|
6934
6956
|
try {
|
|
6935
6957
|
// filename to the pages file (live pages)
|
|
6936
|
-
const filename = path$
|
|
6937
|
-
app$
|
|
6958
|
+
const filename = path$7.join(
|
|
6959
|
+
app$4.getPath("userData"),
|
|
6938
6960
|
appName$2,
|
|
6939
6961
|
appId,
|
|
6940
6962
|
configFilename$1,
|
|
@@ -6969,8 +6991,8 @@ const menuItemsController$1 = {
|
|
|
6969
6991
|
|
|
6970
6992
|
listMenuItemsForApplication: (win, appId) => {
|
|
6971
6993
|
try {
|
|
6972
|
-
const filename = path$
|
|
6973
|
-
app$
|
|
6994
|
+
const filename = path$7.join(
|
|
6995
|
+
app$4.getPath("userData"),
|
|
6974
6996
|
appName$2,
|
|
6975
6997
|
appId,
|
|
6976
6998
|
configFilename$1,
|
|
@@ -6995,14 +7017,14 @@ const menuItemsController$1 = {
|
|
|
6995
7017
|
|
|
6996
7018
|
var menuItemsController_1 = menuItemsController$1;
|
|
6997
7019
|
|
|
6998
|
-
const path$
|
|
6999
|
-
const { app: app$
|
|
7020
|
+
const path$6 = require$$1$1;
|
|
7021
|
+
const { app: app$3 } = require$$0$1;
|
|
7000
7022
|
|
|
7001
7023
|
const pluginController$1 = {
|
|
7002
7024
|
install: (win, packageName, filepath) => {
|
|
7003
7025
|
try {
|
|
7004
|
-
const rootPath = path$
|
|
7005
|
-
app$
|
|
7026
|
+
const rootPath = path$6.join(
|
|
7027
|
+
app$3.getPath("userData"),
|
|
7006
7028
|
"plugins",
|
|
7007
7029
|
packageName,
|
|
7008
7030
|
);
|
|
@@ -7457,7 +7479,7 @@ var cliController_1 = cliController$2;
|
|
|
7457
7479
|
* per-request, receiving the full messages array each time.
|
|
7458
7480
|
*/
|
|
7459
7481
|
|
|
7460
|
-
const Anthropic = require$$0$
|
|
7482
|
+
const Anthropic = require$$0$6;
|
|
7461
7483
|
const mcpController$1 = mcpControllerExports;
|
|
7462
7484
|
const cliController$1 = cliController_1;
|
|
7463
7485
|
const {
|
|
@@ -8897,8 +8919,8 @@ var dynamicWidgetLoader$2 = {exports: {}};
|
|
|
8897
8919
|
* Runs in the Electron main process at widget install time.
|
|
8898
8920
|
*/
|
|
8899
8921
|
|
|
8900
|
-
const fs$2 = require$$2;
|
|
8901
|
-
const path$
|
|
8922
|
+
const fs$2 = require$$0$2;
|
|
8923
|
+
const path$5 = require$$1$1;
|
|
8902
8924
|
|
|
8903
8925
|
/**
|
|
8904
8926
|
* Find the widgets/ directory, handling nested ZIP extraction.
|
|
@@ -8913,13 +8935,13 @@ const path$4 = require$$1$1;
|
|
|
8913
8935
|
* @returns {string|null} Path to the widgets/ directory, or null
|
|
8914
8936
|
*/
|
|
8915
8937
|
function findWidgetsDir$1(widgetPath) {
|
|
8916
|
-
const direct = path$
|
|
8938
|
+
const direct = path$5.join(widgetPath, "widgets");
|
|
8917
8939
|
if (fs$2.existsSync(direct)) {
|
|
8918
8940
|
return direct;
|
|
8919
8941
|
}
|
|
8920
8942
|
|
|
8921
8943
|
// Check configs/ directory (used by packageZip.js for distributed widgets)
|
|
8922
|
-
const configs = path$
|
|
8944
|
+
const configs = path$5.join(widgetPath, "configs");
|
|
8923
8945
|
if (fs$2.existsSync(configs)) {
|
|
8924
8946
|
return configs;
|
|
8925
8947
|
}
|
|
@@ -8936,7 +8958,7 @@ function findWidgetsDir$1(widgetPath) {
|
|
|
8936
8958
|
);
|
|
8937
8959
|
|
|
8938
8960
|
for (const subdir of subdirs) {
|
|
8939
|
-
const nested = path$
|
|
8961
|
+
const nested = path$5.join(widgetPath, subdir.name, "widgets");
|
|
8940
8962
|
if (fs$2.existsSync(nested)) {
|
|
8941
8963
|
console.log(`[WidgetCompiler] Found nested widgets/ at ${nested}`);
|
|
8942
8964
|
return nested;
|
|
@@ -8985,14 +9007,14 @@ async function compileWidget(widgetPath) {
|
|
|
8985
9007
|
// Compute relative path from the entry file (in widgetPath) to widgetsDir,
|
|
8986
9008
|
// since widgetsDir may be nested (e.g., ./weather-widget/widgets/).
|
|
8987
9009
|
const relWidgetsDir =
|
|
8988
|
-
"./" + path$
|
|
9010
|
+
"./" + path$5.relative(widgetPath, widgetsDir).split(path$5.sep).join("/");
|
|
8989
9011
|
const imports = [];
|
|
8990
9012
|
const exportParts = [];
|
|
8991
9013
|
|
|
8992
9014
|
for (const dashFile of dashFiles) {
|
|
8993
9015
|
const componentName = dashFile.replace(".dash.js", "");
|
|
8994
9016
|
const componentFile = `${componentName}.js`;
|
|
8995
|
-
const componentFilePath = path$
|
|
9017
|
+
const componentFilePath = path$5.join(widgetsDir, componentFile);
|
|
8996
9018
|
const hasComponent = fs$2.existsSync(componentFilePath);
|
|
8997
9019
|
|
|
8998
9020
|
// Import the config (always)
|
|
@@ -9019,9 +9041,9 @@ async function compileWidget(widgetPath) {
|
|
|
9019
9041
|
const entryContent = [...imports, "", ...exportParts, ""].join("\n");
|
|
9020
9042
|
|
|
9021
9043
|
// Write temporary entry file in the widget root
|
|
9022
|
-
const entryPath = path$
|
|
9023
|
-
const distDir = path$
|
|
9024
|
-
const outPath = path$
|
|
9044
|
+
const entryPath = path$5.join(widgetPath, "__compile_entry.js");
|
|
9045
|
+
const distDir = path$5.join(widgetPath, "dist");
|
|
9046
|
+
const outPath = path$5.join(distDir, "index.cjs.js");
|
|
9025
9047
|
|
|
9026
9048
|
try {
|
|
9027
9049
|
// Ensure dist/ directory exists
|
|
@@ -9097,9 +9119,9 @@ var widgetCompiler$1 = { compileWidget, findWidgetsDir: findWidgetsDir$1 };
|
|
|
9097
9119
|
* Integrates with ComponentManager for automatic registration
|
|
9098
9120
|
*/
|
|
9099
9121
|
|
|
9100
|
-
const fs$1 = require$$2;
|
|
9101
|
-
const path$
|
|
9102
|
-
const vm = require$$2$
|
|
9122
|
+
const fs$1 = require$$0$2;
|
|
9123
|
+
const path$4 = require$$1$1;
|
|
9124
|
+
const vm = require$$2$4;
|
|
9103
9125
|
const { findWidgetsDir } = widgetCompiler$1;
|
|
9104
9126
|
|
|
9105
9127
|
class DynamicWidgetLoader {
|
|
@@ -9139,9 +9161,9 @@ class DynamicWidgetLoader {
|
|
|
9139
9161
|
);
|
|
9140
9162
|
|
|
9141
9163
|
const widgetsDir =
|
|
9142
|
-
findWidgetsDir(widgetPath) || path$
|
|
9143
|
-
const componentPath = path$
|
|
9144
|
-
const configPath = path$
|
|
9164
|
+
findWidgetsDir(widgetPath) || path$4.join(widgetPath, "widgets");
|
|
9165
|
+
const componentPath = path$4.join(widgetsDir, `${componentName}.js`);
|
|
9166
|
+
const configPath = path$4.join(widgetsDir, `${componentName}.dash.js`);
|
|
9145
9167
|
|
|
9146
9168
|
if (!fs$1.existsSync(componentPath)) {
|
|
9147
9169
|
throw new Error(`Component file not found: ${componentPath}`);
|
|
@@ -9300,9 +9322,9 @@ var dynamicWidgetLoaderExports = dynamicWidgetLoader$2.exports;
|
|
|
9300
9322
|
*/
|
|
9301
9323
|
|
|
9302
9324
|
(function (module) {
|
|
9303
|
-
const fs = require$$2;
|
|
9325
|
+
const fs = require$$0$2;
|
|
9304
9326
|
const path = require$$1$1;
|
|
9305
|
-
const os = require$$2$
|
|
9327
|
+
const os = require$$2$5;
|
|
9306
9328
|
const AdmZip = require$$3$3;
|
|
9307
9329
|
const { fileURLToPath } = require$$4$1;
|
|
9308
9330
|
const { app, ipcMain, BrowserWindow } = require$$0$1;
|
|
@@ -10381,7 +10403,7 @@ function getStoredToken$1() {
|
|
|
10381
10403
|
*
|
|
10382
10404
|
* @returns {Object} { authenticated: boolean, userId?: string }
|
|
10383
10405
|
*/
|
|
10384
|
-
function getAuthStatus() {
|
|
10406
|
+
function getAuthStatus$1() {
|
|
10385
10407
|
const stored = getStoredToken$1();
|
|
10386
10408
|
if (!stored) {
|
|
10387
10409
|
return { authenticated: false };
|
|
@@ -10573,7 +10595,7 @@ var registryAuthController$1 = {
|
|
|
10573
10595
|
initiateDeviceFlow: initiateDeviceFlow$1,
|
|
10574
10596
|
pollForToken: pollForToken$1,
|
|
10575
10597
|
getStoredToken: getStoredToken$1,
|
|
10576
|
-
getAuthStatus,
|
|
10598
|
+
getAuthStatus: getAuthStatus$1,
|
|
10577
10599
|
getRegistryProfile: getRegistryProfile$1,
|
|
10578
10600
|
updateRegistryProfile: updateRegistryProfile$1,
|
|
10579
10601
|
getRegistryPackages: getRegistryPackages$1,
|
|
@@ -10589,8 +10611,8 @@ var registryAuthController$1 = {
|
|
|
10589
10611
|
* Handles publishing packages and generating registry URLs.
|
|
10590
10612
|
*/
|
|
10591
10613
|
|
|
10592
|
-
const fs = require$$2;
|
|
10593
|
-
const path$
|
|
10614
|
+
const fs = require$$0$2;
|
|
10615
|
+
const path$3 = require$$1$1;
|
|
10594
10616
|
const { getStoredToken } = registryAuthController$1;
|
|
10595
10617
|
|
|
10596
10618
|
const REGISTRY_BASE_URL =
|
|
@@ -10622,7 +10644,7 @@ async function publishToRegistry$1(zipPath, manifest) {
|
|
|
10622
10644
|
formData.append(
|
|
10623
10645
|
"file",
|
|
10624
10646
|
new Blob([zipBuffer], { type: "application/zip" }),
|
|
10625
|
-
path$
|
|
10647
|
+
path$3.basename(zipPath),
|
|
10626
10648
|
);
|
|
10627
10649
|
formData.append("manifest", JSON.stringify(manifest));
|
|
10628
10650
|
|
|
@@ -10673,7 +10695,7 @@ function getRegistryUrl$1(scope, name) {
|
|
|
10673
10695
|
return `${REGISTRY_BASE_URL}/package/${scope}/${name}`;
|
|
10674
10696
|
}
|
|
10675
10697
|
|
|
10676
|
-
var registryApiController$
|
|
10698
|
+
var registryApiController$2 = {
|
|
10677
10699
|
publishToRegistry: publishToRegistry$1,
|
|
10678
10700
|
getRegistryUrl: getRegistryUrl$1,
|
|
10679
10701
|
REGISTRY_BASE_URL,
|
|
@@ -10694,9 +10716,9 @@ var registryApiController$1 = {
|
|
|
10694
10716
|
* applies event wiring. (Import is implemented in DASH-13.)
|
|
10695
10717
|
*/
|
|
10696
10718
|
|
|
10697
|
-
const { app: app$
|
|
10698
|
-
const path$
|
|
10699
|
-
const AdmZip = require$$3$3;
|
|
10719
|
+
const { app: app$2, dialog: dialog$1 } = require$$0$1;
|
|
10720
|
+
const path$2 = require$$1$1;
|
|
10721
|
+
const AdmZip$1 = require$$3$3;
|
|
10700
10722
|
const { getFileContents: getFileContents$1 } = file;
|
|
10701
10723
|
const {
|
|
10702
10724
|
validateDashboardConfig,
|
|
@@ -10710,7 +10732,7 @@ const {
|
|
|
10710
10732
|
buildProviderRequirements,
|
|
10711
10733
|
applyEventWiringToLayout,
|
|
10712
10734
|
} = dashboardConfigUtils$1;
|
|
10713
|
-
const { searchRegistry, getPackage } = registryController$
|
|
10735
|
+
const { searchRegistry, getPackage } = registryController$2;
|
|
10714
10736
|
|
|
10715
10737
|
const configFilename = "workspaces.json";
|
|
10716
10738
|
const appName$1 = "Dashboard";
|
|
@@ -10736,8 +10758,8 @@ async function exportDashboardConfig$1(
|
|
|
10736
10758
|
) {
|
|
10737
10759
|
try {
|
|
10738
10760
|
// 1. Read workspace from workspaces.json
|
|
10739
|
-
const filename = path$
|
|
10740
|
-
app$
|
|
10761
|
+
const filename = path$2.join(
|
|
10762
|
+
app$2.getPath("userData"),
|
|
10741
10763
|
appName$1,
|
|
10742
10764
|
appId,
|
|
10743
10765
|
configFilename,
|
|
@@ -10802,10 +10824,10 @@ async function exportDashboardConfig$1(
|
|
|
10802
10824
|
.replace(/\s+/g, "-")
|
|
10803
10825
|
.toLowerCase();
|
|
10804
10826
|
|
|
10805
|
-
const { canceled, filePath } = await dialog.showSaveDialog(win, {
|
|
10827
|
+
const { canceled, filePath } = await dialog$1.showSaveDialog(win, {
|
|
10806
10828
|
title: "Export Dashboard as ZIP",
|
|
10807
|
-
defaultPath: path$
|
|
10808
|
-
app$
|
|
10829
|
+
defaultPath: path$2.join(
|
|
10830
|
+
app$2.getPath("desktop"),
|
|
10809
10831
|
`dashboard-${sanitizedName}.zip`,
|
|
10810
10832
|
),
|
|
10811
10833
|
filters: [{ name: "ZIP Archive", extensions: ["zip"] }],
|
|
@@ -10816,7 +10838,7 @@ async function exportDashboardConfig$1(
|
|
|
10816
10838
|
}
|
|
10817
10839
|
|
|
10818
10840
|
// 6. Create ZIP with the config
|
|
10819
|
-
const zip = new AdmZip();
|
|
10841
|
+
const zip = new AdmZip$1();
|
|
10820
10842
|
const configJson = JSON.stringify(dashboardConfig, null, 2);
|
|
10821
10843
|
zip.addFile(
|
|
10822
10844
|
`${sanitizedName}.dashboard.json`,
|
|
@@ -10856,7 +10878,7 @@ async function exportDashboardConfig$1(
|
|
|
10856
10878
|
*/
|
|
10857
10879
|
async function selectDashboardFile$1(win) {
|
|
10858
10880
|
try {
|
|
10859
|
-
const { canceled, filePaths } = await dialog.showOpenDialog(win, {
|
|
10881
|
+
const { canceled, filePaths } = await dialog$1.showOpenDialog(win, {
|
|
10860
10882
|
title: "Import Dashboard Configuration",
|
|
10861
10883
|
filters: [{ name: "ZIP Archive", extensions: ["zip"] }],
|
|
10862
10884
|
properties: ["openFile"],
|
|
@@ -10869,8 +10891,8 @@ async function selectDashboardFile$1(win) {
|
|
|
10869
10891
|
const zipPath = filePaths[0];
|
|
10870
10892
|
|
|
10871
10893
|
// Extract and validate
|
|
10872
|
-
const zip = new AdmZip(zipPath);
|
|
10873
|
-
const tempDir = path$
|
|
10894
|
+
const zip = new AdmZip$1(zipPath);
|
|
10895
|
+
const tempDir = path$2.join(app$2.getPath("temp"), "dash-import");
|
|
10874
10896
|
const { validateZipEntries } = widgetRegistryExports;
|
|
10875
10897
|
validateZipEntries(zip, tempDir);
|
|
10876
10898
|
|
|
@@ -10963,7 +10985,7 @@ async function importDashboardConfig$1(
|
|
|
10963
10985
|
zipPath = options.filePath;
|
|
10964
10986
|
} else {
|
|
10965
10987
|
// Show file picker
|
|
10966
|
-
const { canceled, filePaths } = await dialog.showOpenDialog(win, {
|
|
10988
|
+
const { canceled, filePaths } = await dialog$1.showOpenDialog(win, {
|
|
10967
10989
|
title: "Import Dashboard Configuration",
|
|
10968
10990
|
filters: [{ name: "ZIP Archive", extensions: ["zip"] }],
|
|
10969
10991
|
properties: ["openFile"],
|
|
@@ -10977,10 +10999,10 @@ async function importDashboardConfig$1(
|
|
|
10977
10999
|
}
|
|
10978
11000
|
|
|
10979
11001
|
// 2. Extract and validate .dashboard.json from ZIP
|
|
10980
|
-
const zip = new AdmZip(zipPath);
|
|
11002
|
+
const zip = new AdmZip$1(zipPath);
|
|
10981
11003
|
|
|
10982
11004
|
// Validate ZIP entries for path traversal
|
|
10983
|
-
const tempDir = path$
|
|
11005
|
+
const tempDir = path$2.join(app$2.getPath("temp"), "dash-import");
|
|
10984
11006
|
const { validateZipEntries } = widgetRegistryExports;
|
|
10985
11007
|
validateZipEntries(zip, tempDir);
|
|
10986
11008
|
|
|
@@ -11263,10 +11285,10 @@ async function installDashboardFromRegistry$1(
|
|
|
11263
11285
|
}
|
|
11264
11286
|
|
|
11265
11287
|
const buffer = await response.arrayBuffer();
|
|
11266
|
-
const zip = new AdmZip(Buffer.from(buffer));
|
|
11288
|
+
const zip = new AdmZip$1(Buffer.from(buffer));
|
|
11267
11289
|
|
|
11268
11290
|
// 3. Validate ZIP entries
|
|
11269
|
-
const tempDir = path$
|
|
11291
|
+
const tempDir = path$2.join(app$2.getPath("temp"), "dash-registry-import");
|
|
11270
11292
|
const { validateZipEntries } = widgetRegistryExports;
|
|
11271
11293
|
validateZipEntries(zip, tempDir);
|
|
11272
11294
|
|
|
@@ -11341,7 +11363,7 @@ async function checkCompatibility$1(dashboardWidgets, widgetRegistry = null) {
|
|
|
11341
11363
|
const {
|
|
11342
11364
|
checkDashboardCompatibility,
|
|
11343
11365
|
} = dashboardConfigUtils$1;
|
|
11344
|
-
const { fetchRegistryIndex } = registryController$
|
|
11366
|
+
const { fetchRegistryIndex } = registryController$2;
|
|
11345
11367
|
|
|
11346
11368
|
const installedWidgets = widgetRegistry ? widgetRegistry.getWidgets() : [];
|
|
11347
11369
|
|
|
@@ -11398,8 +11420,8 @@ async function prepareDashboardForPublish$1(
|
|
|
11398
11420
|
} = dashboardConfigUtils$1;
|
|
11399
11421
|
|
|
11400
11422
|
// 1. Read workspace
|
|
11401
|
-
const filename = path$
|
|
11402
|
-
app$
|
|
11423
|
+
const filename = path$2.join(
|
|
11424
|
+
app$2.getPath("userData"),
|
|
11403
11425
|
appName$1,
|
|
11404
11426
|
appId,
|
|
11405
11427
|
configFilename,
|
|
@@ -11470,7 +11492,7 @@ async function prepareDashboardForPublish$1(
|
|
|
11470
11492
|
}
|
|
11471
11493
|
|
|
11472
11494
|
// 5. Check which widgets exist in the registry (soft warning, not blocking)
|
|
11473
|
-
const { fetchRegistryIndex } = registryController$
|
|
11495
|
+
const { fetchRegistryIndex } = registryController$2;
|
|
11474
11496
|
let registryPackages = [];
|
|
11475
11497
|
let registryCheckFailed = false;
|
|
11476
11498
|
try {
|
|
@@ -11511,10 +11533,10 @@ async function prepareDashboardForPublish$1(
|
|
|
11511
11533
|
|
|
11512
11534
|
// 7. Show save dialog for the publish package
|
|
11513
11535
|
const sanitizedName = manifest.name;
|
|
11514
|
-
const { canceled, filePath } = await dialog.showSaveDialog(win, {
|
|
11536
|
+
const { canceled, filePath } = await dialog$1.showSaveDialog(win, {
|
|
11515
11537
|
title: "Save Dashboard Package for Registry",
|
|
11516
|
-
defaultPath: path$
|
|
11517
|
-
app$
|
|
11538
|
+
defaultPath: path$2.join(
|
|
11539
|
+
app$2.getPath("desktop"),
|
|
11518
11540
|
`dashboard-${sanitizedName}-v${manifest.version}.zip`,
|
|
11519
11541
|
),
|
|
11520
11542
|
filters: [{ name: "ZIP Archive", extensions: ["zip"] }],
|
|
@@ -11525,7 +11547,7 @@ async function prepareDashboardForPublish$1(
|
|
|
11525
11547
|
}
|
|
11526
11548
|
|
|
11527
11549
|
// 8. Create ZIP with manifest and dashboard config
|
|
11528
|
-
const zip = new AdmZip();
|
|
11550
|
+
const zip = new AdmZip$1();
|
|
11529
11551
|
zip.addFile(
|
|
11530
11552
|
"manifest.json",
|
|
11531
11553
|
Buffer.from(JSON.stringify(manifest, null, 2), "utf-8"),
|
|
@@ -11544,7 +11566,7 @@ async function prepareDashboardForPublish$1(
|
|
|
11544
11566
|
let registrySubmission = null;
|
|
11545
11567
|
try {
|
|
11546
11568
|
const { getAuthStatus } = registryAuthController$1;
|
|
11547
|
-
const { publishToRegistry } = registryApiController$
|
|
11569
|
+
const { publishToRegistry } = registryApiController$2;
|
|
11548
11570
|
const authStatus = getAuthStatus();
|
|
11549
11571
|
|
|
11550
11572
|
if (authStatus.authenticated) {
|
|
@@ -11604,7 +11626,7 @@ async function getDashboardPreview$1(packageName, widgetRegistry = null) {
|
|
|
11604
11626
|
buildDashboardPreview,
|
|
11605
11627
|
checkDashboardCompatibility,
|
|
11606
11628
|
} = dashboardConfigUtils$1;
|
|
11607
|
-
const { getPackage, fetchRegistryIndex } = registryController$
|
|
11629
|
+
const { getPackage, fetchRegistryIndex } = registryController$2;
|
|
11608
11630
|
|
|
11609
11631
|
const pkg = await getPackage(packageName);
|
|
11610
11632
|
if (!pkg) {
|
|
@@ -11649,11 +11671,11 @@ async function getDashboardPreview$1(packageName, widgetRegistry = null) {
|
|
|
11649
11671
|
*/
|
|
11650
11672
|
async function checkDashboardUpdatesForApp$1(appId) {
|
|
11651
11673
|
const { checkDashboardUpdates } = dashboardConfigUtils$1;
|
|
11652
|
-
const { fetchRegistryIndex } = registryController$
|
|
11674
|
+
const { fetchRegistryIndex } = registryController$2;
|
|
11653
11675
|
|
|
11654
11676
|
try {
|
|
11655
|
-
const filename = path$
|
|
11656
|
-
app$
|
|
11677
|
+
const filename = path$2.join(
|
|
11678
|
+
app$2.getPath("userData"),
|
|
11657
11679
|
appName$1,
|
|
11658
11680
|
appId,
|
|
11659
11681
|
configFilename,
|
|
@@ -11723,8 +11745,8 @@ function getProviderSetupManifest$1(appId, requiredProviders = []) {
|
|
|
11723
11745
|
*/
|
|
11724
11746
|
function getDashboardPublishPreview$1(appId, workspaceId, widgetRegistry = null) {
|
|
11725
11747
|
try {
|
|
11726
|
-
const filename = path$
|
|
11727
|
-
app$
|
|
11748
|
+
const filename = path$2.join(
|
|
11749
|
+
app$2.getPath("userData"),
|
|
11728
11750
|
appName$1,
|
|
11729
11751
|
appId,
|
|
11730
11752
|
configFilename,
|
|
@@ -12016,6 +12038,348 @@ const notificationController$2 = {
|
|
|
12016
12038
|
|
|
12017
12039
|
var notificationController_1 = notificationController$2;
|
|
12018
12040
|
|
|
12041
|
+
/**
|
|
12042
|
+
* themeRegistryController.js
|
|
12043
|
+
*
|
|
12044
|
+
* Handles publishing themes to and installing themes from the Dash registry.
|
|
12045
|
+
* Mirrors dashboardConfigController patterns for ZIP creation, manifest generation,
|
|
12046
|
+
* and registry interaction.
|
|
12047
|
+
*/
|
|
12048
|
+
const path$1 = require$$1$1;
|
|
12049
|
+
const { app: app$1, dialog } = require$$0$1;
|
|
12050
|
+
const AdmZip = require$$3$3;
|
|
12051
|
+
|
|
12052
|
+
const themeController$1 = themeController_1;
|
|
12053
|
+
const registryController$1 = registryController$2;
|
|
12054
|
+
const registryApiController$1 = registryApiController$2;
|
|
12055
|
+
const { getAuthStatus } = registryAuthController$1;
|
|
12056
|
+
|
|
12057
|
+
/**
|
|
12058
|
+
* Sanitize a name for use as a filename (lowercase, hyphens only).
|
|
12059
|
+
*/
|
|
12060
|
+
function sanitizeName(name) {
|
|
12061
|
+
return (name || "theme")
|
|
12062
|
+
.toLowerCase()
|
|
12063
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
12064
|
+
.replace(/^-|-$/g, "");
|
|
12065
|
+
}
|
|
12066
|
+
|
|
12067
|
+
/**
|
|
12068
|
+
* Generate a registry manifest for a theme package.
|
|
12069
|
+
*
|
|
12070
|
+
* @param {Object} themeData - The raw theme object
|
|
12071
|
+
* @param {string} themeKey - The theme key/name
|
|
12072
|
+
* @param {Object} options - Publish options { authorName, description, tags, scope }
|
|
12073
|
+
* @returns {Object} Registry manifest
|
|
12074
|
+
*/
|
|
12075
|
+
function generateThemeRegistryManifest(themeData, themeKey, options = {}) {
|
|
12076
|
+
const sanitizedName = sanitizeName(themeKey);
|
|
12077
|
+
const colors = extractColors(themeData);
|
|
12078
|
+
|
|
12079
|
+
return {
|
|
12080
|
+
scope: options.scope || "",
|
|
12081
|
+
name: sanitizedName,
|
|
12082
|
+
displayName: themeKey,
|
|
12083
|
+
author: options.authorName || "",
|
|
12084
|
+
description: options.description || "",
|
|
12085
|
+
version: "1.0.0",
|
|
12086
|
+
type: "theme",
|
|
12087
|
+
category: "general",
|
|
12088
|
+
tags: options.tags || [],
|
|
12089
|
+
icon: "palette",
|
|
12090
|
+
colors,
|
|
12091
|
+
appOrigin: options.appOrigin || "",
|
|
12092
|
+
publishedAt: new Date().toISOString(),
|
|
12093
|
+
};
|
|
12094
|
+
}
|
|
12095
|
+
|
|
12096
|
+
/**
|
|
12097
|
+
* Extract primary/secondary/tertiary/neutral colors from a theme object.
|
|
12098
|
+
* Theme objects store colors in various structures; this normalizes them.
|
|
12099
|
+
*/
|
|
12100
|
+
function extractColors(themeData) {
|
|
12101
|
+
const colors = {
|
|
12102
|
+
primary: "",
|
|
12103
|
+
secondary: "",
|
|
12104
|
+
tertiary: "",
|
|
12105
|
+
neutral: "",
|
|
12106
|
+
};
|
|
12107
|
+
|
|
12108
|
+
if (!themeData) return colors;
|
|
12109
|
+
|
|
12110
|
+
// Direct color fields
|
|
12111
|
+
if (themeData.primary) colors.primary = themeData.primary;
|
|
12112
|
+
if (themeData.secondary) colors.secondary = themeData.secondary;
|
|
12113
|
+
if (themeData.tertiary) colors.tertiary = themeData.tertiary;
|
|
12114
|
+
if (themeData.neutral) colors.neutral = themeData.neutral;
|
|
12115
|
+
|
|
12116
|
+
// Nested under "colors" key
|
|
12117
|
+
if (themeData.colors) {
|
|
12118
|
+
if (themeData.colors.primary) colors.primary = themeData.colors.primary;
|
|
12119
|
+
if (themeData.colors.secondary)
|
|
12120
|
+
colors.secondary = themeData.colors.secondary;
|
|
12121
|
+
if (themeData.colors.tertiary) colors.tertiary = themeData.colors.tertiary;
|
|
12122
|
+
if (themeData.colors.neutral) colors.neutral = themeData.colors.neutral;
|
|
12123
|
+
}
|
|
12124
|
+
|
|
12125
|
+
return colors;
|
|
12126
|
+
}
|
|
12127
|
+
|
|
12128
|
+
/**
|
|
12129
|
+
* Prepare a theme for publishing to the registry.
|
|
12130
|
+
*
|
|
12131
|
+
* Reads the theme from themes.json, generates a manifest, creates a ZIP,
|
|
12132
|
+
* and publishes via the registry API.
|
|
12133
|
+
*
|
|
12134
|
+
* @param {BrowserWindow} win - The sender window
|
|
12135
|
+
* @param {string} appId - Application identifier
|
|
12136
|
+
* @param {string} themeKey - Key of the theme to publish
|
|
12137
|
+
* @param {Object} options - { authorName, description, tags }
|
|
12138
|
+
* @returns {Object} Result with success, manifest, registryResult
|
|
12139
|
+
*/
|
|
12140
|
+
async function prepareThemeForPublish$1(win, appId, themeKey, options = {}) {
|
|
12141
|
+
try {
|
|
12142
|
+
// Read the theme data
|
|
12143
|
+
const themesResult = themeController$1.listThemesForApplication(win, appId);
|
|
12144
|
+
if (themesResult.error) {
|
|
12145
|
+
return { success: false, error: "Failed to read themes: " + themesResult.message };
|
|
12146
|
+
}
|
|
12147
|
+
|
|
12148
|
+
const themeData = themesResult.themes[themeKey];
|
|
12149
|
+
if (!themeData) {
|
|
12150
|
+
return { success: false, error: `Theme "${themeKey}" not found` };
|
|
12151
|
+
}
|
|
12152
|
+
|
|
12153
|
+
// Get auth status for scope
|
|
12154
|
+
const auth = getAuthStatus();
|
|
12155
|
+
const scope = auth.profile?.username || options.scope || "";
|
|
12156
|
+
if (!scope) {
|
|
12157
|
+
return {
|
|
12158
|
+
success: false,
|
|
12159
|
+
error: "Not authenticated with registry",
|
|
12160
|
+
authRequired: true,
|
|
12161
|
+
};
|
|
12162
|
+
}
|
|
12163
|
+
|
|
12164
|
+
// Generate manifest
|
|
12165
|
+
const manifest = generateThemeRegistryManifest(themeData, themeKey, {
|
|
12166
|
+
...options,
|
|
12167
|
+
scope,
|
|
12168
|
+
appOrigin: appId,
|
|
12169
|
+
});
|
|
12170
|
+
|
|
12171
|
+
// Validate colors
|
|
12172
|
+
if (!manifest.colors.primary || !manifest.colors.secondary || !manifest.colors.tertiary) {
|
|
12173
|
+
return {
|
|
12174
|
+
success: false,
|
|
12175
|
+
error: "Theme must have primary, secondary, and tertiary colors defined",
|
|
12176
|
+
};
|
|
12177
|
+
}
|
|
12178
|
+
|
|
12179
|
+
// Show save dialog
|
|
12180
|
+
const sanitizedName = sanitizeName(themeKey);
|
|
12181
|
+
const defaultFilename = `theme-${sanitizedName}-v${manifest.version}.zip`;
|
|
12182
|
+
|
|
12183
|
+
const saveResult = await dialog.showSaveDialog(win, {
|
|
12184
|
+
title: "Save Theme Package",
|
|
12185
|
+
defaultPath: defaultFilename,
|
|
12186
|
+
filters: [{ name: "ZIP Files", extensions: ["zip"] }],
|
|
12187
|
+
});
|
|
12188
|
+
|
|
12189
|
+
if (saveResult.canceled || !saveResult.filePath) {
|
|
12190
|
+
return { success: false, error: "Save canceled" };
|
|
12191
|
+
}
|
|
12192
|
+
|
|
12193
|
+
const filePath = saveResult.filePath;
|
|
12194
|
+
|
|
12195
|
+
// Create ZIP with manifest.json + {name}.theme.json
|
|
12196
|
+
const zip = new AdmZip();
|
|
12197
|
+
zip.addFile(
|
|
12198
|
+
"manifest.json",
|
|
12199
|
+
Buffer.from(JSON.stringify(manifest, null, 2), "utf-8"),
|
|
12200
|
+
);
|
|
12201
|
+
zip.addFile(
|
|
12202
|
+
`${sanitizedName}.theme.json`,
|
|
12203
|
+
Buffer.from(JSON.stringify(themeData, null, 2), "utf-8"),
|
|
12204
|
+
);
|
|
12205
|
+
zip.writeZip(filePath);
|
|
12206
|
+
|
|
12207
|
+
console.log("[ThemeRegistryController] ZIP created at:", filePath);
|
|
12208
|
+
|
|
12209
|
+
// Attempt to publish to registry
|
|
12210
|
+
let registryResult = null;
|
|
12211
|
+
if (auth.authenticated) {
|
|
12212
|
+
registryResult = await registryApiController$1.publishToRegistry(
|
|
12213
|
+
filePath,
|
|
12214
|
+
manifest,
|
|
12215
|
+
);
|
|
12216
|
+
console.log("[ThemeRegistryController] Registry publish result:", registryResult);
|
|
12217
|
+
}
|
|
12218
|
+
|
|
12219
|
+
return {
|
|
12220
|
+
success: true,
|
|
12221
|
+
manifest,
|
|
12222
|
+
filePath,
|
|
12223
|
+
registryResult,
|
|
12224
|
+
};
|
|
12225
|
+
} catch (err) {
|
|
12226
|
+
console.error("[ThemeRegistryController] Error preparing theme for publish:", err);
|
|
12227
|
+
return { success: false, error: err.message };
|
|
12228
|
+
}
|
|
12229
|
+
}
|
|
12230
|
+
|
|
12231
|
+
/**
|
|
12232
|
+
* Install a theme from the registry.
|
|
12233
|
+
*
|
|
12234
|
+
* Looks up the theme package, downloads the ZIP, extracts the .theme.json,
|
|
12235
|
+
* and saves it via themeController.
|
|
12236
|
+
*
|
|
12237
|
+
* @param {BrowserWindow} win - The sender window
|
|
12238
|
+
* @param {string} appId - Application identifier
|
|
12239
|
+
* @param {string} packageName - Registry package name (e.g., "username/ocean-depth")
|
|
12240
|
+
* @returns {Object} Result with success, themeKey, theme
|
|
12241
|
+
*/
|
|
12242
|
+
async function installThemeFromRegistry$1(win, appId, packageName) {
|
|
12243
|
+
try {
|
|
12244
|
+
// Look up the package
|
|
12245
|
+
const pkg = await registryController$1.getPackage(packageName);
|
|
12246
|
+
if (!pkg) {
|
|
12247
|
+
return { success: false, error: `Theme package "${packageName}" not found in registry` };
|
|
12248
|
+
}
|
|
12249
|
+
|
|
12250
|
+
// Resolve download URL
|
|
12251
|
+
let downloadUrl = pkg.downloadUrl;
|
|
12252
|
+
if (!downloadUrl) {
|
|
12253
|
+
return { success: false, error: "Package has no download URL" };
|
|
12254
|
+
}
|
|
12255
|
+
|
|
12256
|
+
// Resolve template variables
|
|
12257
|
+
downloadUrl = downloadUrl
|
|
12258
|
+
.replace("{version}", pkg.version || "1.0.0")
|
|
12259
|
+
.replace("{name}", pkg.name || "");
|
|
12260
|
+
|
|
12261
|
+
// Enforce HTTPS
|
|
12262
|
+
if (!downloadUrl.startsWith("https://")) {
|
|
12263
|
+
return { success: false, error: "Download URL must use HTTPS" };
|
|
12264
|
+
}
|
|
12265
|
+
|
|
12266
|
+
console.log("[ThemeRegistryController] Downloading theme from:", downloadUrl);
|
|
12267
|
+
|
|
12268
|
+
// Download the ZIP
|
|
12269
|
+
const response = await fetch(downloadUrl);
|
|
12270
|
+
if (!response.ok) {
|
|
12271
|
+
return {
|
|
12272
|
+
success: false,
|
|
12273
|
+
error: `Failed to download theme: ${response.status} ${response.statusText}`,
|
|
12274
|
+
};
|
|
12275
|
+
}
|
|
12276
|
+
|
|
12277
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
12278
|
+
const zipBuffer = Buffer.from(arrayBuffer);
|
|
12279
|
+
|
|
12280
|
+
// Extract .theme.json from ZIP
|
|
12281
|
+
const zip = new AdmZip(zipBuffer);
|
|
12282
|
+
const entries = zip.getEntries();
|
|
12283
|
+
|
|
12284
|
+
const themeEntry = entries.find((entry) =>
|
|
12285
|
+
entry.entryName.endsWith(".theme.json"),
|
|
12286
|
+
);
|
|
12287
|
+
|
|
12288
|
+
if (!themeEntry) {
|
|
12289
|
+
return { success: false, error: "ZIP does not contain a .theme.json file" };
|
|
12290
|
+
}
|
|
12291
|
+
|
|
12292
|
+
// Validate entry path (security: prevent path traversal)
|
|
12293
|
+
if (themeEntry.entryName.includes("..") || path$1.isAbsolute(themeEntry.entryName)) {
|
|
12294
|
+
return { success: false, error: "Invalid file path in ZIP" };
|
|
12295
|
+
}
|
|
12296
|
+
|
|
12297
|
+
// Parse theme data
|
|
12298
|
+
const themeJson = themeEntry.getData().toString("utf-8");
|
|
12299
|
+
let themeData;
|
|
12300
|
+
try {
|
|
12301
|
+
themeData = JSON.parse(themeJson);
|
|
12302
|
+
} catch (parseErr) {
|
|
12303
|
+
return { success: false, error: "Invalid JSON in theme file: " + parseErr.message };
|
|
12304
|
+
}
|
|
12305
|
+
|
|
12306
|
+
// Add registry metadata
|
|
12307
|
+
themeData._registryMeta = {
|
|
12308
|
+
source: "registry",
|
|
12309
|
+
packageName,
|
|
12310
|
+
installedAt: new Date().toISOString(),
|
|
12311
|
+
};
|
|
12312
|
+
|
|
12313
|
+
// Determine theme key from package display name or name
|
|
12314
|
+
const themeKey = pkg.displayName || pkg.name;
|
|
12315
|
+
|
|
12316
|
+
// Save via themeController
|
|
12317
|
+
const saveResult = themeController$1.saveThemeForApplication(
|
|
12318
|
+
win,
|
|
12319
|
+
appId,
|
|
12320
|
+
themeKey,
|
|
12321
|
+
themeData,
|
|
12322
|
+
);
|
|
12323
|
+
|
|
12324
|
+
if (saveResult.error) {
|
|
12325
|
+
return { success: false, error: "Failed to save theme: " + saveResult.message };
|
|
12326
|
+
}
|
|
12327
|
+
|
|
12328
|
+
console.log("[ThemeRegistryController] Theme installed:", themeKey);
|
|
12329
|
+
|
|
12330
|
+
return {
|
|
12331
|
+
success: true,
|
|
12332
|
+
themeKey,
|
|
12333
|
+
theme: themeData,
|
|
12334
|
+
themes: saveResult.themes,
|
|
12335
|
+
};
|
|
12336
|
+
} catch (err) {
|
|
12337
|
+
console.error("[ThemeRegistryController] Error installing theme:", err);
|
|
12338
|
+
return { success: false, error: err.message };
|
|
12339
|
+
}
|
|
12340
|
+
}
|
|
12341
|
+
|
|
12342
|
+
/**
|
|
12343
|
+
* Get a preview of theme data for the publish modal.
|
|
12344
|
+
*
|
|
12345
|
+
* @param {string} appId - Application identifier
|
|
12346
|
+
* @param {string} themeKey - Theme key
|
|
12347
|
+
* @returns {Object} Preview data with theme name, colors, etc.
|
|
12348
|
+
*/
|
|
12349
|
+
function getThemePublishPreview$1(appId, themeKey) {
|
|
12350
|
+
try {
|
|
12351
|
+
const themesResult = themeController$1.listThemesForApplication(null, appId);
|
|
12352
|
+
if (themesResult.error) {
|
|
12353
|
+
return { success: false, error: "Failed to read themes: " + themesResult.message };
|
|
12354
|
+
}
|
|
12355
|
+
|
|
12356
|
+
const themeData = themesResult.themes[themeKey];
|
|
12357
|
+
if (!themeData) {
|
|
12358
|
+
return { success: false, error: `Theme "${themeKey}" not found` };
|
|
12359
|
+
}
|
|
12360
|
+
|
|
12361
|
+
const colors = extractColors(themeData);
|
|
12362
|
+
|
|
12363
|
+
return {
|
|
12364
|
+
success: true,
|
|
12365
|
+
themeName: themeKey,
|
|
12366
|
+
colors,
|
|
12367
|
+
hasRegistryMeta: !!themeData._registryMeta,
|
|
12368
|
+
};
|
|
12369
|
+
} catch (err) {
|
|
12370
|
+
console.error("[ThemeRegistryController] Error getting preview:", err);
|
|
12371
|
+
return { success: false, error: err.message };
|
|
12372
|
+
}
|
|
12373
|
+
}
|
|
12374
|
+
|
|
12375
|
+
var themeRegistryController$1 = {
|
|
12376
|
+
prepareThemeForPublish: prepareThemeForPublish$1,
|
|
12377
|
+
installThemeFromRegistry: installThemeFromRegistry$1,
|
|
12378
|
+
getThemePublishPreview: getThemePublishPreview$1,
|
|
12379
|
+
generateThemeRegistryManifest,
|
|
12380
|
+
extractColors,
|
|
12381
|
+
};
|
|
12382
|
+
|
|
12019
12383
|
/**
|
|
12020
12384
|
* clientFactories.js
|
|
12021
12385
|
*
|
|
@@ -12030,7 +12394,7 @@ const clientCache$1 = requireClientCache();
|
|
|
12030
12394
|
|
|
12031
12395
|
// --- Algolia ---
|
|
12032
12396
|
clientCache$1.registerFactory("algolia", (credentials) => {
|
|
12033
|
-
const algoliasearch = require$$2$
|
|
12397
|
+
const algoliasearch = require$$2$3;
|
|
12034
12398
|
return algoliasearch(
|
|
12035
12399
|
credentials.appId,
|
|
12036
12400
|
credentials.apiKey || credentials.key,
|
|
@@ -12039,7 +12403,7 @@ clientCache$1.registerFactory("algolia", (credentials) => {
|
|
|
12039
12403
|
|
|
12040
12404
|
// --- OpenAI ---
|
|
12041
12405
|
clientCache$1.registerFactory("openai", (credentials) => {
|
|
12042
|
-
const OpenAI = require$$0$
|
|
12406
|
+
const OpenAI = require$$0$5;
|
|
12043
12407
|
return new OpenAI({ apiKey: credentials.apiKey });
|
|
12044
12408
|
});
|
|
12045
12409
|
|
|
@@ -12419,7 +12783,7 @@ const {
|
|
|
12419
12783
|
const {
|
|
12420
12784
|
publishToRegistry,
|
|
12421
12785
|
getRegistryUrl,
|
|
12422
|
-
} = registryApiController$
|
|
12786
|
+
} = registryApiController$2;
|
|
12423
12787
|
const {
|
|
12424
12788
|
getRecentDashboards,
|
|
12425
12789
|
addRecentDashboard,
|
|
@@ -12436,6 +12800,11 @@ const {
|
|
|
12436
12800
|
enrichPackagesWithRatings,
|
|
12437
12801
|
} = dashboardRatingsController;
|
|
12438
12802
|
const notificationController$1 = notificationController_1;
|
|
12803
|
+
const {
|
|
12804
|
+
prepareThemeForPublish,
|
|
12805
|
+
installThemeFromRegistry,
|
|
12806
|
+
getThemePublishPreview,
|
|
12807
|
+
} = themeRegistryController$1;
|
|
12439
12808
|
|
|
12440
12809
|
var controller = {
|
|
12441
12810
|
showDialog,
|
|
@@ -12511,6 +12880,9 @@ var controller = {
|
|
|
12511
12880
|
saveSessionState,
|
|
12512
12881
|
clearSessionState,
|
|
12513
12882
|
notificationController: notificationController$1,
|
|
12883
|
+
prepareThemeForPublish,
|
|
12884
|
+
installThemeFromRegistry,
|
|
12885
|
+
getThemePublishPreview,
|
|
12514
12886
|
};
|
|
12515
12887
|
|
|
12516
12888
|
const { ipcRenderer: ipcRenderer$m } = require$$0$1;
|
|
@@ -13505,6 +13877,25 @@ const registryApi$2 = {
|
|
|
13505
13877
|
throw error;
|
|
13506
13878
|
}
|
|
13507
13879
|
},
|
|
13880
|
+
|
|
13881
|
+
/**
|
|
13882
|
+
* Search the registry for theme packages only
|
|
13883
|
+
* @param {string} query - Search query
|
|
13884
|
+
* @param {Object} filters - Optional filters { category, author, tag }
|
|
13885
|
+
* @returns {Promise<Object>} { packages: [...], totalWidgets: number }
|
|
13886
|
+
*/
|
|
13887
|
+
searchThemes: async (query = "", filters = {}) => {
|
|
13888
|
+
try {
|
|
13889
|
+
return await ipcRenderer$d.invoke(
|
|
13890
|
+
"registry:search-themes",
|
|
13891
|
+
query,
|
|
13892
|
+
filters,
|
|
13893
|
+
);
|
|
13894
|
+
} catch (error) {
|
|
13895
|
+
console.error("[RegistryApi] Error searching themes:", error);
|
|
13896
|
+
throw error;
|
|
13897
|
+
}
|
|
13898
|
+
},
|
|
13508
13899
|
};
|
|
13509
13900
|
|
|
13510
13901
|
var registryApi_1 = registryApi$2;
|
|
@@ -13517,7 +13908,14 @@ var registryApi_1 = registryApi$2;
|
|
|
13517
13908
|
|
|
13518
13909
|
const { ipcRenderer: ipcRenderer$c } = require$$0$1;
|
|
13519
13910
|
|
|
13520
|
-
const {
|
|
13911
|
+
const {
|
|
13912
|
+
THEME_LIST,
|
|
13913
|
+
THEME_SAVE,
|
|
13914
|
+
THEME_DELETE,
|
|
13915
|
+
THEME_PUBLISH,
|
|
13916
|
+
THEME_INSTALL_FROM_REGISTRY,
|
|
13917
|
+
THEME_PUBLISH_PREVIEW,
|
|
13918
|
+
} = events$8;
|
|
13521
13919
|
|
|
13522
13920
|
const themeApi$2 = {
|
|
13523
13921
|
listThemesForApplication: (appId) =>
|
|
@@ -13526,6 +13924,12 @@ const themeApi$2 = {
|
|
|
13526
13924
|
ipcRenderer$c.invoke(THEME_SAVE, { appId, themeName, themeObject }),
|
|
13527
13925
|
deleteThemeForApplication: (appId, themeKey) =>
|
|
13528
13926
|
ipcRenderer$c.invoke(THEME_DELETE, { appId, themeKey }),
|
|
13927
|
+
publishTheme: (appId, themeKey, options) =>
|
|
13928
|
+
ipcRenderer$c.invoke(THEME_PUBLISH, { appId, themeKey, options }),
|
|
13929
|
+
installThemeFromRegistry: (appId, packageName) =>
|
|
13930
|
+
ipcRenderer$c.invoke(THEME_INSTALL_FROM_REGISTRY, { appId, packageName }),
|
|
13931
|
+
getThemePublishPreview: (appId, themeKey) =>
|
|
13932
|
+
ipcRenderer$c.invoke(THEME_PUBLISH_PREVIEW, { appId, themeKey }),
|
|
13529
13933
|
};
|
|
13530
13934
|
|
|
13531
13935
|
var themeApi_1 = themeApi$2;
|
|
@@ -14468,7 +14872,7 @@ const settingsController = settingsController_1;
|
|
|
14468
14872
|
const providerController = requireProviderController();
|
|
14469
14873
|
const layoutController = layoutController_1;
|
|
14470
14874
|
const mcpController = mcpControllerExports;
|
|
14471
|
-
const registryController = registryController$
|
|
14875
|
+
const registryController = registryController$2;
|
|
14472
14876
|
const algoliaController = algoliaController_1;
|
|
14473
14877
|
const openaiController = openaiController_1;
|
|
14474
14878
|
const menuItemsController = menuItemsController_1;
|
|
@@ -14477,8 +14881,9 @@ const llmController = llmController_1;
|
|
|
14477
14881
|
const cliController = cliController_1;
|
|
14478
14882
|
const dashboardConfigController = dashboardConfigController$1;
|
|
14479
14883
|
const registryAuthController = registryAuthController$1;
|
|
14480
|
-
const registryApiController = registryApiController$
|
|
14884
|
+
const registryApiController = registryApiController$2;
|
|
14481
14885
|
const notificationController = notificationController_1;
|
|
14886
|
+
const themeRegistryController = themeRegistryController$1;
|
|
14482
14887
|
|
|
14483
14888
|
// --- Utils ---
|
|
14484
14889
|
const clientCache = requireClientCache();
|
|
@@ -14547,6 +14952,7 @@ var electron = {
|
|
|
14547
14952
|
registryAuthController,
|
|
14548
14953
|
registryApiController,
|
|
14549
14954
|
notificationController,
|
|
14955
|
+
themeRegistryController,
|
|
14550
14956
|
|
|
14551
14957
|
// Controller functions (flat) — spread for convenient destructuring
|
|
14552
14958
|
...controllers,
|