@trops/dash-core 0.1.284 → 0.1.285
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 +85 -83
- package/dist/electron/index.js +368 -249
- package/dist/electron/index.js.map +1 -1
- package/package.json +1 -1
package/dist/electron/index.js
CHANGED
|
@@ -30,14 +30,15 @@ var require$$4$1 = require('url');
|
|
|
30
30
|
var require$$2$3 = require('vm');
|
|
31
31
|
var require$$1$5 = require('croner');
|
|
32
32
|
var require$$1$6 = require('node-vibrant/node');
|
|
33
|
-
var require$$
|
|
34
|
-
var require$$0$
|
|
35
|
-
var require$$3$
|
|
33
|
+
var require$$3$5 = require('http');
|
|
34
|
+
var require$$0$c = require('events');
|
|
35
|
+
var require$$3$7 = require('net');
|
|
36
36
|
var require$$4$2 = require('tls');
|
|
37
|
-
var require$$3$
|
|
38
|
-
var require$$0$
|
|
39
|
-
var require$$0$
|
|
37
|
+
var require$$3$6 = require('crypto');
|
|
38
|
+
var require$$0$a = require('zlib');
|
|
39
|
+
var require$$0$b = require('buffer');
|
|
40
40
|
var require$$1$7 = require('http2');
|
|
41
|
+
var require$$2$5 = require('node-forge');
|
|
41
42
|
|
|
42
43
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
43
44
|
|
|
@@ -1099,7 +1100,7 @@ var secureStoreController$1 = {
|
|
|
1099
1100
|
getData: getData$1,
|
|
1100
1101
|
};
|
|
1101
1102
|
|
|
1102
|
-
const path$
|
|
1103
|
+
const path$i = require$$1$2;
|
|
1103
1104
|
const {
|
|
1104
1105
|
readFileSync,
|
|
1105
1106
|
writeFileSync: writeFileSync$4,
|
|
@@ -1117,7 +1118,7 @@ const {
|
|
|
1117
1118
|
function ensureDirectoryExistence$2(filePath) {
|
|
1118
1119
|
try {
|
|
1119
1120
|
// isDirectory
|
|
1120
|
-
var dirname = path$
|
|
1121
|
+
var dirname = path$i.dirname(filePath);
|
|
1121
1122
|
// check if the directory exists...return true
|
|
1122
1123
|
// if not, we can pass in the dirname as the filepath
|
|
1123
1124
|
// and check each directory recursively.
|
|
@@ -1232,7 +1233,7 @@ function removeFilesFromDirectory(directory, excludeFiles = []) {
|
|
|
1232
1233
|
|
|
1233
1234
|
for (const file of files) {
|
|
1234
1235
|
if (!excludeFiles.includes(file)) {
|
|
1235
|
-
unlinkSync(path$
|
|
1236
|
+
unlinkSync(path$i.join(directory, file), (err) => {
|
|
1236
1237
|
if (err) throw err;
|
|
1237
1238
|
});
|
|
1238
1239
|
}
|
|
@@ -1250,7 +1251,7 @@ var file = {
|
|
|
1250
1251
|
};
|
|
1251
1252
|
|
|
1252
1253
|
const { app: app$a } = require$$0$2;
|
|
1253
|
-
const path$
|
|
1254
|
+
const path$h = require$$1$2;
|
|
1254
1255
|
const { writeFileSync: writeFileSync$3 } = require$$0$3;
|
|
1255
1256
|
const { getFileContents: getFileContents$7 } = file;
|
|
1256
1257
|
|
|
@@ -1297,7 +1298,7 @@ const workspaceController$3 = {
|
|
|
1297
1298
|
saveWorkspaceForApplication: (win, appId, workspaceObject) => {
|
|
1298
1299
|
try {
|
|
1299
1300
|
// filename to the pages file (live pages)
|
|
1300
|
-
const filename = path$
|
|
1301
|
+
const filename = path$h.join(
|
|
1301
1302
|
app$a.getPath("userData"),
|
|
1302
1303
|
appName$7,
|
|
1303
1304
|
appId,
|
|
@@ -1346,7 +1347,7 @@ const workspaceController$3 = {
|
|
|
1346
1347
|
saveMenuItemsForApplication: (win, appId, menuItems) => {
|
|
1347
1348
|
try {
|
|
1348
1349
|
// filename to the workspaces file
|
|
1349
|
-
const filename = path$
|
|
1350
|
+
const filename = path$h.join(
|
|
1350
1351
|
app$a.getPath("userData"),
|
|
1351
1352
|
appName$7,
|
|
1352
1353
|
appId,
|
|
@@ -1395,7 +1396,7 @@ const workspaceController$3 = {
|
|
|
1395
1396
|
*/
|
|
1396
1397
|
deleteWorkspaceForApplication: (win, appId, workspaceId) => {
|
|
1397
1398
|
try {
|
|
1398
|
-
const filename = path$
|
|
1399
|
+
const filename = path$h.join(
|
|
1399
1400
|
app$a.getPath("userData"),
|
|
1400
1401
|
appName$7,
|
|
1401
1402
|
appId,
|
|
@@ -1429,7 +1430,7 @@ const workspaceController$3 = {
|
|
|
1429
1430
|
|
|
1430
1431
|
listWorkspacesForApplication: (win, appId) => {
|
|
1431
1432
|
try {
|
|
1432
|
-
const filename = path$
|
|
1433
|
+
const filename = path$h.join(
|
|
1433
1434
|
app$a.getPath("userData"),
|
|
1434
1435
|
appName$7,
|
|
1435
1436
|
appId,
|
|
@@ -1457,7 +1458,7 @@ const workspaceController$3 = {
|
|
|
1457
1458
|
|
|
1458
1459
|
listMenuItemsForApplication: (win, appId) => {
|
|
1459
1460
|
try {
|
|
1460
|
-
const filename = path$
|
|
1461
|
+
const filename = path$h.join(
|
|
1461
1462
|
app$a.getPath("userData"),
|
|
1462
1463
|
appName$7,
|
|
1463
1464
|
appId,
|
|
@@ -1502,7 +1503,7 @@ const workspaceController$3 = {
|
|
|
1502
1503
|
var workspaceController_1 = workspaceController$3;
|
|
1503
1504
|
|
|
1504
1505
|
const { app: app$9 } = require$$0$2;
|
|
1505
|
-
const path$
|
|
1506
|
+
const path$g = require$$1$2;
|
|
1506
1507
|
const { writeFileSync: writeFileSync$2 } = require$$0$3;
|
|
1507
1508
|
const { getFileContents: getFileContents$6 } = file;
|
|
1508
1509
|
|
|
@@ -1522,7 +1523,7 @@ const themeController$5 = {
|
|
|
1522
1523
|
saveThemeForApplication: (win, appId, name, obj) => {
|
|
1523
1524
|
try {
|
|
1524
1525
|
// filename to the pages file (live pages)
|
|
1525
|
-
const filename = path$
|
|
1526
|
+
const filename = path$g.join(
|
|
1526
1527
|
app$9.getPath("userData"),
|
|
1527
1528
|
appName$6,
|
|
1528
1529
|
appId,
|
|
@@ -1568,7 +1569,7 @@ const themeController$5 = {
|
|
|
1568
1569
|
*/
|
|
1569
1570
|
listThemesForApplication: (win, appId) => {
|
|
1570
1571
|
try {
|
|
1571
|
-
const filename = path$
|
|
1572
|
+
const filename = path$g.join(
|
|
1572
1573
|
app$9.getPath("userData"),
|
|
1573
1574
|
appName$6,
|
|
1574
1575
|
appId,
|
|
@@ -1610,7 +1611,7 @@ const themeController$5 = {
|
|
|
1610
1611
|
*/
|
|
1611
1612
|
deleteThemeForApplication: (win, appId, themeKey) => {
|
|
1612
1613
|
try {
|
|
1613
|
-
const filename = path$
|
|
1614
|
+
const filename = path$g.join(
|
|
1614
1615
|
app$9.getPath("userData"),
|
|
1615
1616
|
appName$6,
|
|
1616
1617
|
appId,
|
|
@@ -1650,14 +1651,14 @@ var themeController_1 = themeController$5;
|
|
|
1650
1651
|
* - CSV -> JSON
|
|
1651
1652
|
*/
|
|
1652
1653
|
|
|
1653
|
-
var fs$
|
|
1654
|
+
var fs$a = require$$0$3;
|
|
1654
1655
|
var readline = require$$1$3;
|
|
1655
1656
|
const xtreamer = require$$2;
|
|
1656
1657
|
var xmlParser = require$$3$1;
|
|
1657
1658
|
var JSONStream$1 = require$$4;
|
|
1658
1659
|
const stream$2 = require$$0$4;
|
|
1659
1660
|
var csv = require$$6;
|
|
1660
|
-
const path$
|
|
1661
|
+
const path$f = require$$1$2;
|
|
1661
1662
|
const { app: app$8 } = require$$0$2;
|
|
1662
1663
|
const { ensureDirectoryExistence: ensureDirectoryExistence$1 } = file;
|
|
1663
1664
|
|
|
@@ -1706,7 +1707,7 @@ let Transform$1 = class Transform {
|
|
|
1706
1707
|
let lineObject = [];
|
|
1707
1708
|
|
|
1708
1709
|
const readInterface = readline.createInterface({
|
|
1709
|
-
input: fs$
|
|
1710
|
+
input: fs$a.createReadStream(filepath),
|
|
1710
1711
|
output: process.stdout,
|
|
1711
1712
|
console: false,
|
|
1712
1713
|
});
|
|
@@ -1741,7 +1742,7 @@ let Transform$1 = class Transform {
|
|
|
1741
1742
|
return new Promise((resolve, reject) => {
|
|
1742
1743
|
try {
|
|
1743
1744
|
const parser = JSONStream$1.parse("*");
|
|
1744
|
-
const readStream = fs$
|
|
1745
|
+
const readStream = fs$a.createReadStream(file).pipe(parser);
|
|
1745
1746
|
|
|
1746
1747
|
let count = 0;
|
|
1747
1748
|
|
|
@@ -1794,7 +1795,7 @@ let Transform$1 = class Transform {
|
|
|
1794
1795
|
parseXMLStream = (filepath, outpath, start) => {
|
|
1795
1796
|
return new Promise((resolve, reject) => {
|
|
1796
1797
|
try {
|
|
1797
|
-
const xmlFileReadStream = fs$
|
|
1798
|
+
const xmlFileReadStream = fs$a.createReadStream(filepath);
|
|
1798
1799
|
|
|
1799
1800
|
xmlFileReadStream.on("end", () => {
|
|
1800
1801
|
writeStream.write("\n]");
|
|
@@ -1805,7 +1806,7 @@ let Transform$1 = class Transform {
|
|
|
1805
1806
|
resolve("Read Finish");
|
|
1806
1807
|
});
|
|
1807
1808
|
|
|
1808
|
-
const writeStream = fs$
|
|
1809
|
+
const writeStream = fs$a.createWriteStream(outpath);
|
|
1809
1810
|
writeStream.write("[\n");
|
|
1810
1811
|
|
|
1811
1812
|
const options = {
|
|
@@ -1857,10 +1858,10 @@ let Transform$1 = class Transform {
|
|
|
1857
1858
|
) => {
|
|
1858
1859
|
return new Promise((resolve, reject) => {
|
|
1859
1860
|
try {
|
|
1860
|
-
const readStream = fs$
|
|
1861
|
+
const readStream = fs$a
|
|
1861
1862
|
.createReadStream(filepath)
|
|
1862
1863
|
.pipe(csv({ separator: delimiter }));
|
|
1863
|
-
const writeStream = fs$
|
|
1864
|
+
const writeStream = fs$a.createWriteStream(outpath);
|
|
1864
1865
|
|
|
1865
1866
|
let canParse = true;
|
|
1866
1867
|
|
|
@@ -1946,18 +1947,18 @@ let Transform$1 = class Transform {
|
|
|
1946
1947
|
}
|
|
1947
1948
|
|
|
1948
1949
|
// Validate file paths are within app data directory
|
|
1949
|
-
const appDataDir = path$
|
|
1950
|
-
const resolvedFilepath = path$
|
|
1951
|
-
const resolvedOutFilepath = path$
|
|
1950
|
+
const appDataDir = path$f.join(app$8.getPath("userData"), TRANSFORM_APP_NAME);
|
|
1951
|
+
const resolvedFilepath = path$f.resolve(filepath);
|
|
1952
|
+
const resolvedOutFilepath = path$f.resolve(outFilepath);
|
|
1952
1953
|
|
|
1953
|
-
if (!resolvedFilepath.startsWith(appDataDir + path$
|
|
1954
|
+
if (!resolvedFilepath.startsWith(appDataDir + path$f.sep)) {
|
|
1954
1955
|
return reject(
|
|
1955
1956
|
new Error(
|
|
1956
1957
|
"Input file path must be within the application data directory",
|
|
1957
1958
|
),
|
|
1958
1959
|
);
|
|
1959
1960
|
}
|
|
1960
|
-
if (!resolvedOutFilepath.startsWith(appDataDir + path$
|
|
1961
|
+
if (!resolvedOutFilepath.startsWith(appDataDir + path$f.sep)) {
|
|
1961
1962
|
return reject(
|
|
1962
1963
|
new Error(
|
|
1963
1964
|
"Output file path must be within the application data directory",
|
|
@@ -1968,14 +1969,14 @@ let Transform$1 = class Transform {
|
|
|
1968
1969
|
// JSON parser
|
|
1969
1970
|
var parser = JSONStream$1.parse("*");
|
|
1970
1971
|
|
|
1971
|
-
if (fs$
|
|
1972
|
+
if (fs$a.existsSync(resolvedFilepath)) {
|
|
1972
1973
|
console.log("file exists ", resolvedFilepath);
|
|
1973
1974
|
// create the readStream to parse the large file (json)
|
|
1974
|
-
var readStream = fs$
|
|
1975
|
+
var readStream = fs$a.createReadStream(resolvedFilepath).pipe(parser);
|
|
1975
1976
|
|
|
1976
1977
|
ensureDirectoryExistence$1(resolvedOutFilepath);
|
|
1977
1978
|
|
|
1978
|
-
var writeStream = fs$
|
|
1979
|
+
var writeStream = fs$a.createWriteStream(resolvedOutFilepath);
|
|
1979
1980
|
|
|
1980
1981
|
let sep = "";
|
|
1981
1982
|
let count = 0;
|
|
@@ -3816,8 +3817,8 @@ async function extractColorsFromImageURL$2(url, toDirectory) {
|
|
|
3816
3817
|
var color = { extractColorsFromImageURL: extractColorsFromImageURL$2 };
|
|
3817
3818
|
|
|
3818
3819
|
const { app: app$7 } = require$$0$2;
|
|
3819
|
-
var fs$
|
|
3820
|
-
const path$
|
|
3820
|
+
var fs$9 = require$$0$3;
|
|
3821
|
+
const path$e = require$$1$2;
|
|
3821
3822
|
const events$5 = events$8;
|
|
3822
3823
|
const { getFileContents: getFileContents$5, writeToFile: writeToFile$2 } = file;
|
|
3823
3824
|
|
|
@@ -3825,7 +3826,7 @@ const { getFileContents: getFileContents$5, writeToFile: writeToFile$2 } = file;
|
|
|
3825
3826
|
const ObjectsToCsv = require$$5;
|
|
3826
3827
|
const Transform = transform;
|
|
3827
3828
|
const { extractColorsFromImageURL: extractColorsFromImageURL$1 } = color;
|
|
3828
|
-
const https$
|
|
3829
|
+
const https$4 = require$$8;
|
|
3829
3830
|
const appName$5 = "Dashboard";
|
|
3830
3831
|
|
|
3831
3832
|
const dataController$1 = {
|
|
@@ -3840,7 +3841,7 @@ const dataController$1 = {
|
|
|
3840
3841
|
convertJsonToCsvFile: (win, appId, jsonObject, toFilename = "test.csv") => {
|
|
3841
3842
|
try {
|
|
3842
3843
|
// filename to the pages file (live pages)
|
|
3843
|
-
const filename = path$
|
|
3844
|
+
const filename = path$e.join(
|
|
3844
3845
|
app$7.getPath("userData"),
|
|
3845
3846
|
appName$5,
|
|
3846
3847
|
appId,
|
|
@@ -3968,17 +3969,17 @@ const dataController$1 = {
|
|
|
3968
3969
|
}
|
|
3969
3970
|
|
|
3970
3971
|
// Validate toFilepath is within the app data directory
|
|
3971
|
-
const appDataDir = path$
|
|
3972
|
-
const resolvedFilepath = path$
|
|
3973
|
-
if (!resolvedFilepath.startsWith(appDataDir + path$
|
|
3972
|
+
const appDataDir = path$e.join(app$7.getPath("userData"), appName$5);
|
|
3973
|
+
const resolvedFilepath = path$e.resolve(toFilepath);
|
|
3974
|
+
if (!resolvedFilepath.startsWith(appDataDir + path$e.sep)) {
|
|
3974
3975
|
throw new Error(
|
|
3975
3976
|
"File path must be within the application data directory",
|
|
3976
3977
|
);
|
|
3977
3978
|
}
|
|
3978
3979
|
|
|
3979
|
-
const writeStream = fs$
|
|
3980
|
+
const writeStream = fs$9.createWriteStream(resolvedFilepath);
|
|
3980
3981
|
|
|
3981
|
-
https$
|
|
3982
|
+
https$4
|
|
3982
3983
|
.get(url, (resp) => {
|
|
3983
3984
|
resp.on("data", (chunk) => {
|
|
3984
3985
|
writeStream.write(chunk);
|
|
@@ -4117,7 +4118,7 @@ const dataController$1 = {
|
|
|
4117
4118
|
try {
|
|
4118
4119
|
if (data) {
|
|
4119
4120
|
// filename to the pages file (live pages)
|
|
4120
|
-
const toFilename = path$
|
|
4121
|
+
const toFilename = path$e.join(
|
|
4121
4122
|
app$7.getPath("userData"),
|
|
4122
4123
|
appName$5,
|
|
4123
4124
|
"data",
|
|
@@ -4199,7 +4200,7 @@ const dataController$1 = {
|
|
|
4199
4200
|
try {
|
|
4200
4201
|
if (filename) {
|
|
4201
4202
|
// filename to the pages file (live pages)
|
|
4202
|
-
const fromFilename = path$
|
|
4203
|
+
const fromFilename = path$e.join(
|
|
4203
4204
|
app$7.getPath("userData"),
|
|
4204
4205
|
appName$5,
|
|
4205
4206
|
"data",
|
|
@@ -4277,7 +4278,7 @@ const dataController$1 = {
|
|
|
4277
4278
|
try {
|
|
4278
4279
|
console.log(url);
|
|
4279
4280
|
const fileExtension = ".jpg";
|
|
4280
|
-
const filename = path$
|
|
4281
|
+
const filename = path$e.join(
|
|
4281
4282
|
app$7.getPath("userData"),
|
|
4282
4283
|
appName$5,
|
|
4283
4284
|
"@algolia/dash-electron",
|
|
@@ -4303,8 +4304,8 @@ var dataController_1 = dataController$1;
|
|
|
4303
4304
|
*/
|
|
4304
4305
|
|
|
4305
4306
|
const { app: app$6 } = require$$0$2;
|
|
4306
|
-
const path$
|
|
4307
|
-
const fs$
|
|
4307
|
+
const path$d = require$$1$2;
|
|
4308
|
+
const fs$8 = require$$0$3;
|
|
4308
4309
|
const { getFileContents: getFileContents$4, writeToFile: writeToFile$1 } = file;
|
|
4309
4310
|
|
|
4310
4311
|
const configFilename$3 = "settings.json";
|
|
@@ -4312,15 +4313,15 @@ const appName$4 = "Dashboard";
|
|
|
4312
4313
|
|
|
4313
4314
|
// Helper function to recursively copy directory
|
|
4314
4315
|
function copyDirectory(source, destination) {
|
|
4315
|
-
if (!fs$
|
|
4316
|
-
fs$
|
|
4316
|
+
if (!fs$8.existsSync(destination)) {
|
|
4317
|
+
fs$8.mkdirSync(destination, { recursive: true });
|
|
4317
4318
|
}
|
|
4318
4319
|
|
|
4319
|
-
const files = fs$
|
|
4320
|
+
const files = fs$8.readdirSync(source);
|
|
4320
4321
|
for (const file of files) {
|
|
4321
|
-
const srcPath = path$
|
|
4322
|
-
const destPath = path$
|
|
4323
|
-
const stat = fs$
|
|
4322
|
+
const srcPath = path$d.join(source, file);
|
|
4323
|
+
const destPath = path$d.join(destination, file);
|
|
4324
|
+
const stat = fs$8.lstatSync(srcPath);
|
|
4324
4325
|
|
|
4325
4326
|
// Skip symlinks to prevent following links to sensitive files
|
|
4326
4327
|
if (stat.isSymbolicLink()) {
|
|
@@ -4331,7 +4332,7 @@ function copyDirectory(source, destination) {
|
|
|
4331
4332
|
if (stat.isDirectory()) {
|
|
4332
4333
|
copyDirectory(srcPath, destPath);
|
|
4333
4334
|
} else {
|
|
4334
|
-
fs$
|
|
4335
|
+
fs$8.copyFileSync(srcPath, destPath);
|
|
4335
4336
|
}
|
|
4336
4337
|
}
|
|
4337
4338
|
}
|
|
@@ -4347,7 +4348,7 @@ const settingsController$4 = {
|
|
|
4347
4348
|
try {
|
|
4348
4349
|
if (data) {
|
|
4349
4350
|
// <appId>/settings.json
|
|
4350
|
-
const filename = path$
|
|
4351
|
+
const filename = path$d.join(
|
|
4351
4352
|
app$6.getPath("userData"),
|
|
4352
4353
|
appName$4,
|
|
4353
4354
|
configFilename$3,
|
|
@@ -4383,7 +4384,7 @@ const settingsController$4 = {
|
|
|
4383
4384
|
getSettingsForApplication: (win) => {
|
|
4384
4385
|
try {
|
|
4385
4386
|
// <appId>/settings.json
|
|
4386
|
-
const filename = path$
|
|
4387
|
+
const filename = path$d.join(
|
|
4387
4388
|
app$6.getPath("userData"),
|
|
4388
4389
|
appName$4,
|
|
4389
4390
|
configFilename$3,
|
|
@@ -4414,7 +4415,7 @@ const settingsController$4 = {
|
|
|
4414
4415
|
*/
|
|
4415
4416
|
getDataDirectory: (win) => {
|
|
4416
4417
|
try {
|
|
4417
|
-
const settingsPath = path$
|
|
4418
|
+
const settingsPath = path$d.join(
|
|
4418
4419
|
app$6.getPath("userData"),
|
|
4419
4420
|
appName$4,
|
|
4420
4421
|
configFilename$3,
|
|
@@ -4422,7 +4423,7 @@ const settingsController$4 = {
|
|
|
4422
4423
|
const settings = getFileContents$4(settingsPath, {});
|
|
4423
4424
|
const userDataDir =
|
|
4424
4425
|
settings.userDataDirectory ||
|
|
4425
|
-
path$
|
|
4426
|
+
path$d.join(app$6.getPath("userData"), appName$4);
|
|
4426
4427
|
|
|
4427
4428
|
console.log("[settingsController] Data directory retrieved successfully");
|
|
4428
4429
|
// Return the data for ipcMain.handle() - modern promise-based approach
|
|
@@ -4449,17 +4450,17 @@ const settingsController$4 = {
|
|
|
4449
4450
|
setDataDirectory: (win, newPath) => {
|
|
4450
4451
|
try {
|
|
4451
4452
|
// Validate the path exists and is a directory
|
|
4452
|
-
if (!fs$
|
|
4453
|
-
fs$
|
|
4453
|
+
if (!fs$8.existsSync(newPath)) {
|
|
4454
|
+
fs$8.mkdirSync(newPath, { recursive: true });
|
|
4454
4455
|
}
|
|
4455
4456
|
|
|
4456
|
-
const stats = fs$
|
|
4457
|
+
const stats = fs$8.statSync(newPath);
|
|
4457
4458
|
if (!stats.isDirectory()) {
|
|
4458
4459
|
throw new Error("Path is not a directory");
|
|
4459
4460
|
}
|
|
4460
4461
|
|
|
4461
4462
|
// Update settings
|
|
4462
|
-
const settingsPath = path$
|
|
4463
|
+
const settingsPath = path$d.join(
|
|
4463
4464
|
app$6.getPath("userData"),
|
|
4464
4465
|
appName$4,
|
|
4465
4466
|
configFilename$3,
|
|
@@ -4493,11 +4494,11 @@ const settingsController$4 = {
|
|
|
4493
4494
|
migrateDataDirectory: (win, oldPath, newPath) => {
|
|
4494
4495
|
try {
|
|
4495
4496
|
// Resolve paths to prevent traversal
|
|
4496
|
-
const resolvedOldPath = path$
|
|
4497
|
-
const resolvedNewPath = path$
|
|
4497
|
+
const resolvedOldPath = path$d.resolve(oldPath);
|
|
4498
|
+
const resolvedNewPath = path$d.resolve(newPath);
|
|
4498
4499
|
|
|
4499
4500
|
// Validate oldPath is the current configured data directory
|
|
4500
|
-
const settingsCheckPath = path$
|
|
4501
|
+
const settingsCheckPath = path$d.join(
|
|
4501
4502
|
app$6.getPath("userData"),
|
|
4502
4503
|
appName$4,
|
|
4503
4504
|
configFilename$3,
|
|
@@ -4505,8 +4506,8 @@ const settingsController$4 = {
|
|
|
4505
4506
|
const currentSettings = getFileContents$4(settingsCheckPath, {});
|
|
4506
4507
|
const currentDataDir =
|
|
4507
4508
|
currentSettings.userDataDirectory ||
|
|
4508
|
-
path$
|
|
4509
|
-
if (resolvedOldPath !== path$
|
|
4509
|
+
path$d.join(app$6.getPath("userData"), appName$4);
|
|
4510
|
+
if (resolvedOldPath !== path$d.resolve(currentDataDir)) {
|
|
4510
4511
|
throw new Error("Source path must be the current data directory");
|
|
4511
4512
|
}
|
|
4512
4513
|
|
|
@@ -4530,19 +4531,19 @@ const settingsController$4 = {
|
|
|
4530
4531
|
}
|
|
4531
4532
|
|
|
4532
4533
|
// Validate paths
|
|
4533
|
-
if (!fs$
|
|
4534
|
+
if (!fs$8.existsSync(resolvedOldPath)) {
|
|
4534
4535
|
throw new Error("Source directory does not exist");
|
|
4535
4536
|
}
|
|
4536
4537
|
|
|
4537
|
-
if (!fs$
|
|
4538
|
-
fs$
|
|
4538
|
+
if (!fs$8.existsSync(resolvedNewPath)) {
|
|
4539
|
+
fs$8.mkdirSync(resolvedNewPath, { recursive: true });
|
|
4539
4540
|
}
|
|
4540
4541
|
|
|
4541
4542
|
// Copy files
|
|
4542
4543
|
copyDirectory(resolvedOldPath, resolvedNewPath);
|
|
4543
4544
|
|
|
4544
4545
|
// Update settings to use new path
|
|
4545
|
-
const settingsPath = path$
|
|
4546
|
+
const settingsPath = path$d.join(
|
|
4546
4547
|
app$6.getPath("userData"),
|
|
4547
4548
|
appName$4,
|
|
4548
4549
|
configFilename$3,
|
|
@@ -5174,7 +5175,7 @@ function requireProviderController () {
|
|
|
5174
5175
|
}
|
|
5175
5176
|
|
|
5176
5177
|
const { app: app$5 } = require$$0$2;
|
|
5177
|
-
const path$
|
|
5178
|
+
const path$c = require$$1$2;
|
|
5178
5179
|
const { writeFileSync: writeFileSync$1 } = require$$0$3;
|
|
5179
5180
|
const events$4 = events$8;
|
|
5180
5181
|
const { getFileContents: getFileContents$3 } = file;
|
|
@@ -5194,7 +5195,7 @@ const layoutController$1 = {
|
|
|
5194
5195
|
saveLayoutForApplication: (win, appId, layoutObject) => {
|
|
5195
5196
|
try {
|
|
5196
5197
|
// filename to the pages file (live pages)
|
|
5197
|
-
const filename = path$
|
|
5198
|
+
const filename = path$c.join(
|
|
5198
5199
|
app$5.getPath("userData"),
|
|
5199
5200
|
appName$3,
|
|
5200
5201
|
appId,
|
|
@@ -5227,7 +5228,7 @@ const layoutController$1 = {
|
|
|
5227
5228
|
*/
|
|
5228
5229
|
listLayoutsForApplication: (win, appId) => {
|
|
5229
5230
|
try {
|
|
5230
|
-
const filename = path$
|
|
5231
|
+
const filename = path$c.join(
|
|
5231
5232
|
app$5.getPath("userData"),
|
|
5232
5233
|
appName$3,
|
|
5233
5234
|
appId,
|
|
@@ -26032,8 +26033,8 @@ const {
|
|
|
26032
26033
|
const {
|
|
26033
26034
|
StreamableHTTPClientTransport,
|
|
26034
26035
|
} = streamableHttp$1;
|
|
26035
|
-
const path$
|
|
26036
|
-
const fs$
|
|
26036
|
+
const path$b = require$$1$2;
|
|
26037
|
+
const fs$7 = require$$0$3;
|
|
26037
26038
|
|
|
26038
26039
|
/**
|
|
26039
26040
|
* Cached shell PATH result (resolved once, reused for all spawns).
|
|
@@ -26082,7 +26083,7 @@ function getShellPath$1() {
|
|
|
26082
26083
|
fallbackDirs.push(`${home}/.nodenv/shims`);
|
|
26083
26084
|
try {
|
|
26084
26085
|
const nvmDir = `${home}/.nvm/versions/node`;
|
|
26085
|
-
const versions = fs$
|
|
26086
|
+
const versions = fs$7.readdirSync(nvmDir).sort();
|
|
26086
26087
|
if (versions.length > 0) {
|
|
26087
26088
|
// Find the highest compatible version (v18/v20/v22)
|
|
26088
26089
|
for (let i = versions.length - 1; i >= 0; i--) {
|
|
@@ -26218,15 +26219,15 @@ async function refreshGoogleOAuthToken(tokenRefresh) {
|
|
|
26218
26219
|
const credPath = tokenRefresh.credentialsPath.replace(/^~/, home);
|
|
26219
26220
|
const keysPath = tokenRefresh.oauthKeysPath.replace(/^~/, home);
|
|
26220
26221
|
|
|
26221
|
-
if (!fs$
|
|
26222
|
+
if (!fs$7.existsSync(credPath) || !fs$7.existsSync(keysPath)) {
|
|
26222
26223
|
console.log(
|
|
26223
26224
|
"[mcpController] Token refresh skipped: credential files not found",
|
|
26224
26225
|
);
|
|
26225
26226
|
return;
|
|
26226
26227
|
}
|
|
26227
26228
|
|
|
26228
|
-
const credentials = JSON.parse(fs$
|
|
26229
|
-
const keysFile = JSON.parse(fs$
|
|
26229
|
+
const credentials = JSON.parse(fs$7.readFileSync(credPath, "utf8"));
|
|
26230
|
+
const keysFile = JSON.parse(fs$7.readFileSync(keysPath, "utf8"));
|
|
26230
26231
|
const keyData = keysFile.installed || keysFile.web;
|
|
26231
26232
|
|
|
26232
26233
|
if (
|
|
@@ -26295,7 +26296,7 @@ async function refreshGoogleOAuthToken(tokenRefresh) {
|
|
|
26295
26296
|
credentials.refresh_token = body.refresh_token;
|
|
26296
26297
|
}
|
|
26297
26298
|
|
|
26298
|
-
fs$
|
|
26299
|
+
fs$7.writeFileSync(credPath, JSON.stringify(credentials, null, 2));
|
|
26299
26300
|
console.log("[mcpController] Google OAuth token refreshed successfully");
|
|
26300
26301
|
}
|
|
26301
26302
|
|
|
@@ -26449,7 +26450,7 @@ const mcpController$2 = {
|
|
|
26449
26450
|
}
|
|
26450
26451
|
|
|
26451
26452
|
// Interpolate {{MCP_DIR}} in args to resolve local MCP server scripts
|
|
26452
|
-
const mcpDir = path$
|
|
26453
|
+
const mcpDir = path$b.join(__dirname, "..", "mcp");
|
|
26453
26454
|
for (let i = 0; i < args.length; i++) {
|
|
26454
26455
|
if (
|
|
26455
26456
|
typeof args[i] === "string" &&
|
|
@@ -26824,20 +26825,20 @@ const mcpController$2 = {
|
|
|
26824
26825
|
*/
|
|
26825
26826
|
getCatalog: (win) => {
|
|
26826
26827
|
try {
|
|
26827
|
-
const catalogPath = path$
|
|
26828
|
+
const catalogPath = path$b.join(
|
|
26828
26829
|
__dirname,
|
|
26829
26830
|
"..",
|
|
26830
26831
|
"mcp",
|
|
26831
26832
|
"mcpServerCatalog.json",
|
|
26832
26833
|
);
|
|
26833
26834
|
|
|
26834
|
-
if (!fs$
|
|
26835
|
+
if (!fs$7.existsSync(catalogPath)) {
|
|
26835
26836
|
return {
|
|
26836
26837
|
catalog: [],
|
|
26837
26838
|
};
|
|
26838
26839
|
}
|
|
26839
26840
|
|
|
26840
|
-
const catalogData = fs$
|
|
26841
|
+
const catalogData = fs$7.readFileSync(catalogPath, "utf8");
|
|
26841
26842
|
const catalog = JSON.parse(catalogData);
|
|
26842
26843
|
|
|
26843
26844
|
return {
|
|
@@ -26899,8 +26900,8 @@ const mcpController$2 = {
|
|
|
26899
26900
|
const destPath = to.replace(/^~/, process.env.HOME || "");
|
|
26900
26901
|
const destDir = require$$1$2.dirname(destPath);
|
|
26901
26902
|
try {
|
|
26902
|
-
fs$
|
|
26903
|
-
fs$
|
|
26903
|
+
fs$7.mkdirSync(destDir, { recursive: true });
|
|
26904
|
+
fs$7.copyFileSync(sourcePath, destPath);
|
|
26904
26905
|
} catch (err) {
|
|
26905
26906
|
return {
|
|
26906
26907
|
error: true,
|
|
@@ -26936,7 +26937,7 @@ const mcpController$2 = {
|
|
|
26936
26937
|
}
|
|
26937
26938
|
|
|
26938
26939
|
// Interpolate {{MCP_DIR}} in authCommand args (same as startServer)
|
|
26939
|
-
const mcpDir = path$
|
|
26940
|
+
const mcpDir = path$b.join(__dirname, "..", "mcp");
|
|
26940
26941
|
const resolvedArgs = (authCommand.args || []).map((arg) =>
|
|
26941
26942
|
typeof arg === "string" && arg.includes("{{MCP_DIR}}")
|
|
26942
26943
|
? arg.replace(/\{\{MCP_DIR\}\}/g, mcpDir)
|
|
@@ -27072,8 +27073,8 @@ var packageId = { toPackageId: toPackageId$1, parsePackageId };
|
|
|
27072
27073
|
* - Support two-level browsing: packages (bundles) and widgets within packages
|
|
27073
27074
|
*/
|
|
27074
27075
|
|
|
27075
|
-
const path$
|
|
27076
|
-
const fs$
|
|
27076
|
+
const path$a = require$$1$2;
|
|
27077
|
+
const fs$6 = require$$0$3;
|
|
27077
27078
|
const { toPackageId } = packageId;
|
|
27078
27079
|
|
|
27079
27080
|
// Default registry API base URL
|
|
@@ -27089,7 +27090,7 @@ let cacheTimestamp = 0;
|
|
|
27089
27090
|
* Get the local test registry path for dev mode
|
|
27090
27091
|
*/
|
|
27091
27092
|
function getTestRegistryPath() {
|
|
27092
|
-
return path$
|
|
27093
|
+
return path$a.join(__dirname, "..", "registry", "test-registry-index.json");
|
|
27093
27094
|
}
|
|
27094
27095
|
|
|
27095
27096
|
/**
|
|
@@ -27125,12 +27126,12 @@ async function fetchRegistryIndex(forceRefresh = false) {
|
|
|
27125
27126
|
if (isDev()) {
|
|
27126
27127
|
// In dev mode, try local test file first
|
|
27127
27128
|
const testPath = getTestRegistryPath();
|
|
27128
|
-
if (fs$
|
|
27129
|
+
if (fs$6.existsSync(testPath)) {
|
|
27129
27130
|
console.log(
|
|
27130
27131
|
"[RegistryController] Loading test registry from:",
|
|
27131
27132
|
testPath,
|
|
27132
27133
|
);
|
|
27133
|
-
const raw = fs$
|
|
27134
|
+
const raw = fs$6.readFileSync(testPath, "utf8");
|
|
27134
27135
|
indexData = JSON.parse(raw);
|
|
27135
27136
|
} else {
|
|
27136
27137
|
// Fall back to API (supports DASH_REGISTRY_URL as full-URL override)
|
|
@@ -27448,10 +27449,10 @@ var registryController$3 = {
|
|
|
27448
27449
|
checkUpdates,
|
|
27449
27450
|
};
|
|
27450
27451
|
|
|
27451
|
-
var fs$
|
|
27452
|
+
var fs$5 = require$$0$3;
|
|
27452
27453
|
var JSONStream = require$$4;
|
|
27453
27454
|
const algoliasearch$1 = require$$2$2;
|
|
27454
|
-
const path$
|
|
27455
|
+
const path$9 = require$$3$3;
|
|
27455
27456
|
const { ensureDirectoryExistence, checkDirectory } = file;
|
|
27456
27457
|
|
|
27457
27458
|
let AlgoliaIndex$1 = class AlgoliaIndex {
|
|
@@ -27489,7 +27490,7 @@ let AlgoliaIndex$1 = class AlgoliaIndex {
|
|
|
27489
27490
|
var batchNumber = 1;
|
|
27490
27491
|
|
|
27491
27492
|
// create the readStream to parse the large file (json)
|
|
27492
|
-
var readStream = fs$
|
|
27493
|
+
var readStream = fs$5.createReadStream(filepath).pipe(parser);
|
|
27493
27494
|
|
|
27494
27495
|
var batch = [];
|
|
27495
27496
|
|
|
@@ -27503,7 +27504,7 @@ let AlgoliaIndex$1 = class AlgoliaIndex {
|
|
|
27503
27504
|
// lets write to the batch file
|
|
27504
27505
|
if (countForBatch === batchSize) {
|
|
27505
27506
|
// write to the batch file
|
|
27506
|
-
var writeStream = fs$
|
|
27507
|
+
var writeStream = fs$5.createWriteStream(
|
|
27507
27508
|
batchFilepath + "/batch_" + batchNumber + ".json",
|
|
27508
27509
|
);
|
|
27509
27510
|
writeStream.write(JSON.stringify(batch));
|
|
@@ -27554,11 +27555,11 @@ let AlgoliaIndex$1 = class AlgoliaIndex {
|
|
|
27554
27555
|
return new Promise((resolve, reject) => {
|
|
27555
27556
|
try {
|
|
27556
27557
|
checkDirectory(directoryPath);
|
|
27557
|
-
fs$
|
|
27558
|
+
fs$5.readdir(directoryPath, (err, files) => {
|
|
27558
27559
|
if (err) reject(err);
|
|
27559
27560
|
if (files) {
|
|
27560
27561
|
files.forEach((file) => {
|
|
27561
|
-
fs$
|
|
27562
|
+
fs$5.unlinkSync(path$9.join(directoryPath, file));
|
|
27562
27563
|
});
|
|
27563
27564
|
resolve();
|
|
27564
27565
|
}
|
|
@@ -27577,11 +27578,11 @@ let AlgoliaIndex$1 = class AlgoliaIndex {
|
|
|
27577
27578
|
) {
|
|
27578
27579
|
try {
|
|
27579
27580
|
// read the directory...
|
|
27580
|
-
const files = await fs$
|
|
27581
|
+
const files = await fs$5.readdirSync(batchFilepath);
|
|
27581
27582
|
let results = [];
|
|
27582
27583
|
for (const fileIndex in files) {
|
|
27583
27584
|
// for each file lets read the file and then push to algolia
|
|
27584
|
-
const pathToBatch = path$
|
|
27585
|
+
const pathToBatch = path$9.join(batchFilepath, files[fileIndex]);
|
|
27585
27586
|
const fileContents = await this.readFile(pathToBatch);
|
|
27586
27587
|
if (fileContents) {
|
|
27587
27588
|
if ("data" in fileContents && "filepath" in fileContents) {
|
|
@@ -27606,7 +27607,7 @@ let AlgoliaIndex$1 = class AlgoliaIndex {
|
|
|
27606
27607
|
|
|
27607
27608
|
async readFile(filepath) {
|
|
27608
27609
|
return await new Promise((resolve, reject) => {
|
|
27609
|
-
fs$
|
|
27610
|
+
fs$5.readFile(filepath, "utf8", (err, data) => {
|
|
27610
27611
|
if (err) {
|
|
27611
27612
|
reject(err);
|
|
27612
27613
|
}
|
|
@@ -27756,7 +27757,7 @@ var algolia = AlgoliaIndex$1;
|
|
|
27756
27757
|
const algoliasearch = require$$2$2;
|
|
27757
27758
|
const events$3 = events$8;
|
|
27758
27759
|
const AlgoliaIndex = algolia;
|
|
27759
|
-
var fs$
|
|
27760
|
+
var fs$4 = require$$0$3;
|
|
27760
27761
|
|
|
27761
27762
|
const algoliaController$1 = {
|
|
27762
27763
|
/**
|
|
@@ -27864,7 +27865,7 @@ const algoliaController$1 = {
|
|
|
27864
27865
|
// init the Algolia Index helper
|
|
27865
27866
|
const a = new AlgoliaIndex(appId, apiKey, indexName);
|
|
27866
27867
|
// create the write stream to store the hits
|
|
27867
|
-
const writeStream = fs$
|
|
27868
|
+
const writeStream = fs$4.createWriteStream(toFilename);
|
|
27868
27869
|
writeStream.write("[");
|
|
27869
27870
|
|
|
27870
27871
|
let sep = "";
|
|
@@ -28036,7 +28037,7 @@ const openaiController$1 = {
|
|
|
28036
28037
|
var openaiController_1 = openaiController$1;
|
|
28037
28038
|
|
|
28038
28039
|
const { app: app$4 } = require$$0$2;
|
|
28039
|
-
const path$
|
|
28040
|
+
const path$8 = require$$1$2;
|
|
28040
28041
|
const { writeFileSync } = require$$0$3;
|
|
28041
28042
|
const { getFileContents: getFileContents$2 } = file;
|
|
28042
28043
|
|
|
@@ -28047,7 +28048,7 @@ const menuItemsController$1 = {
|
|
|
28047
28048
|
saveMenuItemForApplication: (win, appId, menuItem) => {
|
|
28048
28049
|
try {
|
|
28049
28050
|
// filename to the pages file (live pages)
|
|
28050
|
-
const filename = path$
|
|
28051
|
+
const filename = path$8.join(
|
|
28051
28052
|
app$4.getPath("userData"),
|
|
28052
28053
|
appName$2,
|
|
28053
28054
|
appId,
|
|
@@ -28083,7 +28084,7 @@ const menuItemsController$1 = {
|
|
|
28083
28084
|
|
|
28084
28085
|
listMenuItemsForApplication: (win, appId) => {
|
|
28085
28086
|
try {
|
|
28086
|
-
const filename = path$
|
|
28087
|
+
const filename = path$8.join(
|
|
28087
28088
|
app$4.getPath("userData"),
|
|
28088
28089
|
appName$2,
|
|
28089
28090
|
appId,
|
|
@@ -28109,13 +28110,13 @@ const menuItemsController$1 = {
|
|
|
28109
28110
|
|
|
28110
28111
|
var menuItemsController_1 = menuItemsController$1;
|
|
28111
28112
|
|
|
28112
|
-
const path$
|
|
28113
|
+
const path$7 = require$$1$2;
|
|
28113
28114
|
const { app: app$3 } = require$$0$2;
|
|
28114
28115
|
|
|
28115
28116
|
const pluginController$1 = {
|
|
28116
28117
|
install: (win, packageName, filepath) => {
|
|
28117
28118
|
try {
|
|
28118
|
-
const rootPath = path$
|
|
28119
|
+
const rootPath = path$7.join(
|
|
28119
28120
|
app$3.getPath("userData"),
|
|
28120
28121
|
"plugins",
|
|
28121
28122
|
packageName,
|
|
@@ -30491,8 +30492,8 @@ var dynamicWidgetLoader$2 = {exports: {}};
|
|
|
30491
30492
|
* Runs in the Electron main process at widget install time.
|
|
30492
30493
|
*/
|
|
30493
30494
|
|
|
30494
|
-
const fs$
|
|
30495
|
-
const path$
|
|
30495
|
+
const fs$3 = require$$0$3;
|
|
30496
|
+
const path$6 = require$$1$2;
|
|
30496
30497
|
|
|
30497
30498
|
/**
|
|
30498
30499
|
* Find the widgets/ directory, handling nested ZIP extraction.
|
|
@@ -30507,26 +30508,26 @@ const path$5 = require$$1$2;
|
|
|
30507
30508
|
* @returns {string|null} Path to the widgets/ directory, or null
|
|
30508
30509
|
*/
|
|
30509
30510
|
function findWidgetsDir$1(widgetPath) {
|
|
30510
|
-
const direct = path$
|
|
30511
|
-
if (fs$
|
|
30511
|
+
const direct = path$6.join(widgetPath, "widgets");
|
|
30512
|
+
if (fs$3.existsSync(direct)) {
|
|
30512
30513
|
return direct;
|
|
30513
30514
|
}
|
|
30514
30515
|
|
|
30515
30516
|
// Check configs/widgets/ (packageZip.js nests .dash.js files here)
|
|
30516
|
-
const configsWidgets = path$
|
|
30517
|
-
if (fs$
|
|
30517
|
+
const configsWidgets = path$6.join(widgetPath, "configs", "widgets");
|
|
30518
|
+
if (fs$3.existsSync(configsWidgets)) {
|
|
30518
30519
|
return configsWidgets;
|
|
30519
30520
|
}
|
|
30520
30521
|
|
|
30521
30522
|
// Check configs/ directory (used by packageZip.js for distributed widgets)
|
|
30522
|
-
const configs = path$
|
|
30523
|
-
if (fs$
|
|
30523
|
+
const configs = path$6.join(widgetPath, "configs");
|
|
30524
|
+
if (fs$3.existsSync(configs)) {
|
|
30524
30525
|
return configs;
|
|
30525
30526
|
}
|
|
30526
30527
|
|
|
30527
30528
|
// Check one level deeper for nested ZIP extraction
|
|
30528
30529
|
try {
|
|
30529
|
-
const entries = fs$
|
|
30530
|
+
const entries = fs$3.readdirSync(widgetPath, { withFileTypes: true });
|
|
30530
30531
|
const subdirs = entries.filter(
|
|
30531
30532
|
(e) =>
|
|
30532
30533
|
e.isDirectory() &&
|
|
@@ -30536,8 +30537,8 @@ function findWidgetsDir$1(widgetPath) {
|
|
|
30536
30537
|
);
|
|
30537
30538
|
|
|
30538
30539
|
for (const subdir of subdirs) {
|
|
30539
|
-
const nested = path$
|
|
30540
|
-
if (fs$
|
|
30540
|
+
const nested = path$6.join(widgetPath, subdir.name, "widgets");
|
|
30541
|
+
if (fs$3.existsSync(nested)) {
|
|
30541
30542
|
console.log(`[WidgetCompiler] Found nested widgets/ at ${nested}`);
|
|
30542
30543
|
return nested;
|
|
30543
30544
|
}
|
|
@@ -30571,7 +30572,7 @@ async function compileWidget(widgetPath) {
|
|
|
30571
30572
|
}
|
|
30572
30573
|
|
|
30573
30574
|
// Discover .dash.js config files
|
|
30574
|
-
const files = fs$
|
|
30575
|
+
const files = fs$3.readdirSync(widgetsDir);
|
|
30575
30576
|
const dashFiles = files.filter((f) => f.endsWith(".dash.js"));
|
|
30576
30577
|
|
|
30577
30578
|
if (dashFiles.length === 0) {
|
|
@@ -30585,15 +30586,15 @@ async function compileWidget(widgetPath) {
|
|
|
30585
30586
|
// Compute relative path from the entry file (in widgetPath) to widgetsDir,
|
|
30586
30587
|
// since widgetsDir may be nested (e.g., ./weather-widget/widgets/).
|
|
30587
30588
|
const relWidgetsDir =
|
|
30588
|
-
"./" + path$
|
|
30589
|
+
"./" + path$6.relative(widgetPath, widgetsDir).split(path$6.sep).join("/");
|
|
30589
30590
|
const imports = [];
|
|
30590
30591
|
const exportParts = [];
|
|
30591
30592
|
|
|
30592
30593
|
for (const dashFile of dashFiles) {
|
|
30593
30594
|
const componentName = dashFile.replace(".dash.js", "");
|
|
30594
30595
|
const componentFile = `${componentName}.js`;
|
|
30595
|
-
const componentFilePath = path$
|
|
30596
|
-
const hasComponent = fs$
|
|
30596
|
+
const componentFilePath = path$6.join(widgetsDir, componentFile);
|
|
30597
|
+
const hasComponent = fs$3.existsSync(componentFilePath);
|
|
30597
30598
|
|
|
30598
30599
|
// Import the config (always)
|
|
30599
30600
|
imports.push(
|
|
@@ -30619,17 +30620,17 @@ async function compileWidget(widgetPath) {
|
|
|
30619
30620
|
const entryContent = [...imports, "", ...exportParts, ""].join("\n");
|
|
30620
30621
|
|
|
30621
30622
|
// Write temporary entry file in the widget root
|
|
30622
|
-
const entryPath = path$
|
|
30623
|
-
const distDir = path$
|
|
30624
|
-
const outPath = path$
|
|
30623
|
+
const entryPath = path$6.join(widgetPath, "__compile_entry.js");
|
|
30624
|
+
const distDir = path$6.join(widgetPath, "dist");
|
|
30625
|
+
const outPath = path$6.join(distDir, "index.cjs.js");
|
|
30625
30626
|
|
|
30626
30627
|
try {
|
|
30627
30628
|
// Ensure dist/ directory exists
|
|
30628
|
-
if (!fs$
|
|
30629
|
-
fs$
|
|
30629
|
+
if (!fs$3.existsSync(distDir)) {
|
|
30630
|
+
fs$3.mkdirSync(distDir, { recursive: true });
|
|
30630
30631
|
}
|
|
30631
30632
|
|
|
30632
|
-
fs$
|
|
30633
|
+
fs$3.writeFileSync(entryPath, entryContent, "utf8");
|
|
30633
30634
|
|
|
30634
30635
|
console.log(
|
|
30635
30636
|
`[WidgetCompiler] Compiling ${dashFiles.length} component(s) from ${widgetPath}`,
|
|
@@ -30670,8 +30671,8 @@ async function compileWidget(widgetPath) {
|
|
|
30670
30671
|
} finally {
|
|
30671
30672
|
// Clean up temporary entry file
|
|
30672
30673
|
try {
|
|
30673
|
-
if (fs$
|
|
30674
|
-
fs$
|
|
30674
|
+
if (fs$3.existsSync(entryPath)) {
|
|
30675
|
+
fs$3.unlinkSync(entryPath);
|
|
30675
30676
|
}
|
|
30676
30677
|
} catch (cleanupError) {
|
|
30677
30678
|
// Non-fatal
|
|
@@ -30697,8 +30698,8 @@ var widgetCompiler$1 = { compileWidget, findWidgetsDir: findWidgetsDir$1 };
|
|
|
30697
30698
|
* Integrates with ComponentManager for automatic registration
|
|
30698
30699
|
*/
|
|
30699
30700
|
|
|
30700
|
-
const fs$
|
|
30701
|
-
const path$
|
|
30701
|
+
const fs$2 = require$$0$3;
|
|
30702
|
+
const path$5 = require$$1$2;
|
|
30702
30703
|
const vm = require$$2$3;
|
|
30703
30704
|
const { findWidgetsDir } = widgetCompiler$1;
|
|
30704
30705
|
|
|
@@ -30739,14 +30740,14 @@ class DynamicWidgetLoader {
|
|
|
30739
30740
|
);
|
|
30740
30741
|
|
|
30741
30742
|
const widgetsDir =
|
|
30742
|
-
findWidgetsDir(widgetPath) || path$
|
|
30743
|
-
const componentPath = path$
|
|
30744
|
-
const configPath = path$
|
|
30743
|
+
findWidgetsDir(widgetPath) || path$5.join(widgetPath, "widgets");
|
|
30744
|
+
const componentPath = path$5.join(widgetsDir, `${componentName}.js`);
|
|
30745
|
+
const configPath = path$5.join(widgetsDir, `${componentName}.dash.js`);
|
|
30745
30746
|
|
|
30746
|
-
if (!fs$
|
|
30747
|
+
if (!fs$2.existsSync(componentPath)) {
|
|
30747
30748
|
throw new Error(`Component file not found: ${componentPath}`);
|
|
30748
30749
|
}
|
|
30749
|
-
if (!fs$
|
|
30750
|
+
if (!fs$2.existsSync(configPath)) {
|
|
30750
30751
|
throw new Error(`Config file not found: ${configPath}`);
|
|
30751
30752
|
}
|
|
30752
30753
|
|
|
@@ -30797,7 +30798,7 @@ class DynamicWidgetLoader {
|
|
|
30797
30798
|
*/
|
|
30798
30799
|
async loadConfigFile(configPath) {
|
|
30799
30800
|
try {
|
|
30800
|
-
const source = fs$
|
|
30801
|
+
const source = fs$2.readFileSync(configPath, "utf8");
|
|
30801
30802
|
|
|
30802
30803
|
let exportMatch = source.match(/export\s+default\s+({[\s\S]*});?\s*$/);
|
|
30803
30804
|
|
|
@@ -30852,7 +30853,7 @@ class DynamicWidgetLoader {
|
|
|
30852
30853
|
return [];
|
|
30853
30854
|
}
|
|
30854
30855
|
|
|
30855
|
-
const files = fs$
|
|
30856
|
+
const files = fs$2.readdirSync(widgetsDir);
|
|
30856
30857
|
const widgets = new Set();
|
|
30857
30858
|
|
|
30858
30859
|
files.forEach((file) => {
|
|
@@ -32529,8 +32530,8 @@ var widgetRegistryExports = widgetRegistry$1.exports;
|
|
|
32529
32530
|
* Handles publishing packages and generating registry URLs.
|
|
32530
32531
|
*/
|
|
32531
32532
|
|
|
32532
|
-
const fs = require$$0$3;
|
|
32533
|
-
const path$
|
|
32533
|
+
const fs$1 = require$$0$3;
|
|
32534
|
+
const path$4 = require$$1$2;
|
|
32534
32535
|
const { getStoredToken: getStoredToken$2 } = registryAuthController$1;
|
|
32535
32536
|
|
|
32536
32537
|
const REGISTRY_BASE_URL =
|
|
@@ -32556,14 +32557,14 @@ async function publishToRegistry$1(zipPath, manifest) {
|
|
|
32556
32557
|
|
|
32557
32558
|
try {
|
|
32558
32559
|
// Read the ZIP file
|
|
32559
|
-
const zipBuffer = fs.readFileSync(zipPath);
|
|
32560
|
+
const zipBuffer = fs$1.readFileSync(zipPath);
|
|
32560
32561
|
|
|
32561
32562
|
// Create FormData with the ZIP and manifest
|
|
32562
32563
|
const formData = new FormData();
|
|
32563
32564
|
formData.append(
|
|
32564
32565
|
"file",
|
|
32565
32566
|
new Blob([zipBuffer], { type: "application/zip" }),
|
|
32566
|
-
path$
|
|
32567
|
+
path$4.basename(zipPath),
|
|
32567
32568
|
);
|
|
32568
32569
|
formData.append("manifest", JSON.stringify(manifest));
|
|
32569
32570
|
|
|
@@ -32627,7 +32628,7 @@ var registryApiController$2 = {
|
|
|
32627
32628
|
* Mirrors dashboardConfigController patterns for ZIP creation, manifest generation,
|
|
32628
32629
|
* and registry interaction.
|
|
32629
32630
|
*/
|
|
32630
|
-
const path$
|
|
32631
|
+
const path$3 = require$$1$2;
|
|
32631
32632
|
const { app: app$2, dialog: dialog$1 } = require$$0$2;
|
|
32632
32633
|
const AdmZip$1 = require$$3$4;
|
|
32633
32634
|
|
|
@@ -33071,7 +33072,7 @@ async function installThemeFromRegistry$1(win, appId, packageName) {
|
|
|
33071
33072
|
// Validate entry path (security: prevent path traversal)
|
|
33072
33073
|
if (
|
|
33073
33074
|
themeEntry.entryName.includes("..") ||
|
|
33074
|
-
path$
|
|
33075
|
+
path$3.isAbsolute(themeEntry.entryName)
|
|
33075
33076
|
) {
|
|
33076
33077
|
return {
|
|
33077
33078
|
success: false,
|
|
@@ -33197,7 +33198,7 @@ var themeRegistryController$1 = {
|
|
|
33197
33198
|
*/
|
|
33198
33199
|
|
|
33199
33200
|
const { app: app$1, dialog } = require$$0$2;
|
|
33200
|
-
const path$
|
|
33201
|
+
const path$2 = require$$1$2;
|
|
33201
33202
|
const AdmZip = require$$3$4;
|
|
33202
33203
|
const { getFileContents: getFileContents$1 } = file;
|
|
33203
33204
|
const {
|
|
@@ -33240,7 +33241,7 @@ async function exportDashboardConfig$1(
|
|
|
33240
33241
|
) {
|
|
33241
33242
|
try {
|
|
33242
33243
|
// 1. Read workspace from workspaces.json
|
|
33243
|
-
const filename = path$
|
|
33244
|
+
const filename = path$2.join(
|
|
33244
33245
|
app$1.getPath("userData"),
|
|
33245
33246
|
appName$1,
|
|
33246
33247
|
appId,
|
|
@@ -33334,7 +33335,7 @@ async function exportDashboardConfig$1(
|
|
|
33334
33335
|
|
|
33335
33336
|
const { canceled, filePath } = await dialog.showSaveDialog(win, {
|
|
33336
33337
|
title: "Export Dashboard as ZIP",
|
|
33337
|
-
defaultPath: path$
|
|
33338
|
+
defaultPath: path$2.join(
|
|
33338
33339
|
app$1.getPath("desktop"),
|
|
33339
33340
|
`dashboard-${sanitizedName}.zip`,
|
|
33340
33341
|
),
|
|
@@ -33400,7 +33401,7 @@ async function selectDashboardFile$1(win) {
|
|
|
33400
33401
|
|
|
33401
33402
|
// Extract and validate
|
|
33402
33403
|
const zip = new AdmZip(zipPath);
|
|
33403
|
-
const tempDir = path$
|
|
33404
|
+
const tempDir = path$2.join(app$1.getPath("temp"), "dash-import");
|
|
33404
33405
|
const { validateZipEntries } = widgetRegistryExports;
|
|
33405
33406
|
validateZipEntries(zip, tempDir);
|
|
33406
33407
|
|
|
@@ -33510,7 +33511,7 @@ async function importDashboardConfig$1(
|
|
|
33510
33511
|
const zip = new AdmZip(zipPath);
|
|
33511
33512
|
|
|
33512
33513
|
// Validate ZIP entries for path traversal
|
|
33513
|
-
const tempDir = path$
|
|
33514
|
+
const tempDir = path$2.join(app$1.getPath("temp"), "dash-import");
|
|
33514
33515
|
const { validateZipEntries } = widgetRegistryExports;
|
|
33515
33516
|
validateZipEntries(zip, tempDir);
|
|
33516
33517
|
|
|
@@ -34109,7 +34110,7 @@ async function installDashboardFromRegistry$1(
|
|
|
34109
34110
|
const zip = new AdmZip(zipBuffer);
|
|
34110
34111
|
|
|
34111
34112
|
// 3. Validate ZIP entries
|
|
34112
|
-
const tempDir = path$
|
|
34113
|
+
const tempDir = path$2.join(app$1.getPath("temp"), "dash-registry-import");
|
|
34113
34114
|
const { validateZipEntries } = widgetRegistryExports;
|
|
34114
34115
|
validateZipEntries(zip, tempDir);
|
|
34115
34116
|
|
|
@@ -34253,7 +34254,7 @@ async function prepareDashboardForPublish$1(
|
|
|
34253
34254
|
} = dashboardConfigUtils$1;
|
|
34254
34255
|
|
|
34255
34256
|
// 1. Read workspace
|
|
34256
|
-
const filename = path$
|
|
34257
|
+
const filename = path$2.join(
|
|
34257
34258
|
app$1.getPath("userData"),
|
|
34258
34259
|
appName$1,
|
|
34259
34260
|
appId,
|
|
@@ -34433,7 +34434,7 @@ async function prepareDashboardForPublish$1(
|
|
|
34433
34434
|
const sanitizedName = manifest.name;
|
|
34434
34435
|
const { canceled, filePath } = await dialog.showSaveDialog(win, {
|
|
34435
34436
|
title: "Save Dashboard Package for Registry",
|
|
34436
|
-
defaultPath: path$
|
|
34437
|
+
defaultPath: path$2.join(
|
|
34437
34438
|
app$1.getPath("desktop"),
|
|
34438
34439
|
`dashboard-${sanitizedName}-v${manifest.version}.zip`,
|
|
34439
34440
|
),
|
|
@@ -34572,7 +34573,7 @@ async function checkDashboardUpdatesForApp$1(appId) {
|
|
|
34572
34573
|
const { fetchRegistryIndex } = registryController$3;
|
|
34573
34574
|
|
|
34574
34575
|
try {
|
|
34575
|
-
const filename = path$
|
|
34576
|
+
const filename = path$2.join(
|
|
34576
34577
|
app$1.getPath("userData"),
|
|
34577
34578
|
appName$1,
|
|
34578
34579
|
appId,
|
|
@@ -34643,7 +34644,7 @@ function getProviderSetupManifest$1(appId, requiredProviders = []) {
|
|
|
34643
34644
|
*/
|
|
34644
34645
|
function getDashboardPublishPreview$1(appId, workspaceId, widgetRegistry = null) {
|
|
34645
34646
|
try {
|
|
34646
|
-
const filename = path$
|
|
34647
|
+
const filename = path$2.join(
|
|
34647
34648
|
app$1.getPath("userData"),
|
|
34648
34649
|
appName$1,
|
|
34649
34650
|
appId,
|
|
@@ -40136,8 +40137,8 @@ var themeFromUrlErrors$1 = {
|
|
|
40136
40137
|
|
|
40137
40138
|
const css = css$1;
|
|
40138
40139
|
const { Vibrant } = require$$1$6;
|
|
40139
|
-
const https$
|
|
40140
|
-
const http$
|
|
40140
|
+
const https$3 = require$$8;
|
|
40141
|
+
const http$3 = require$$3$5;
|
|
40141
40142
|
const { URL: URL$2 } = require$$4$1;
|
|
40142
40143
|
const {
|
|
40143
40144
|
UrlUnreachableError,
|
|
@@ -40538,7 +40539,7 @@ function fetchBuffer(url, maxRedirects = 5, _redirectCount = 0) {
|
|
|
40538
40539
|
return;
|
|
40539
40540
|
}
|
|
40540
40541
|
const parsedUrl = new URL$2(url);
|
|
40541
|
-
const client = parsedUrl.protocol === "https:" ? https$
|
|
40542
|
+
const client = parsedUrl.protocol === "https:" ? https$3 : http$3;
|
|
40542
40543
|
const request = client.get(
|
|
40543
40544
|
url,
|
|
40544
40545
|
{ timeout: 10000, headers: { "User-Agent": "Dash/1.0" } },
|
|
@@ -41760,7 +41761,7 @@ let Limiter$1 = class Limiter {
|
|
|
41760
41761
|
|
|
41761
41762
|
var limiter = Limiter$1;
|
|
41762
41763
|
|
|
41763
|
-
const zlib = require$$0$
|
|
41764
|
+
const zlib = require$$0$a;
|
|
41764
41765
|
|
|
41765
41766
|
const bufferUtil = bufferUtilExports;
|
|
41766
41767
|
const Limiter = limiter;
|
|
@@ -42291,7 +42292,7 @@ var validation$2 = {exports: {}};
|
|
|
42291
42292
|
|
|
42292
42293
|
var isValidUTF8_1;
|
|
42293
42294
|
|
|
42294
|
-
const { isUtf8 } = require$$0$
|
|
42295
|
+
const { isUtf8 } = require$$0$b;
|
|
42295
42296
|
|
|
42296
42297
|
const { hasBlob } = constants;
|
|
42297
42298
|
|
|
@@ -43150,7 +43151,7 @@ let Receiver$1 = class Receiver extends Writable {
|
|
|
43150
43151
|
var receiver = Receiver$1;
|
|
43151
43152
|
|
|
43152
43153
|
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex" }] */
|
|
43153
|
-
const { randomFillSync } = require$$3$
|
|
43154
|
+
const { randomFillSync } = require$$3$6;
|
|
43154
43155
|
|
|
43155
43156
|
const PerMessageDeflate$2 = permessageDeflate;
|
|
43156
43157
|
const { EMPTY_BUFFER: EMPTY_BUFFER$1, kWebSocket: kWebSocket$2, NOOP: NOOP$1 } = constants;
|
|
@@ -44243,12 +44244,12 @@ var extension$1 = { format: format$4, parse: parse$4 };
|
|
|
44243
44244
|
|
|
44244
44245
|
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex|Readable$", "caughtErrors": "none" }] */
|
|
44245
44246
|
|
|
44246
|
-
const EventEmitter$1 = require$$0$
|
|
44247
|
-
const https$
|
|
44248
|
-
const http$
|
|
44249
|
-
const net = require$$3$
|
|
44247
|
+
const EventEmitter$1 = require$$0$c;
|
|
44248
|
+
const https$2 = require$$8;
|
|
44249
|
+
const http$2 = require$$3$5;
|
|
44250
|
+
const net = require$$3$7;
|
|
44250
44251
|
const tls = require$$4$2;
|
|
44251
|
-
const { randomBytes, createHash: createHash$1 } = require$$3$
|
|
44252
|
+
const { randomBytes, createHash: createHash$1 } = require$$3$6;
|
|
44252
44253
|
const { URL: URL$1 } = require$$4$1;
|
|
44253
44254
|
|
|
44254
44255
|
const PerMessageDeflate$1 = permessageDeflate;
|
|
@@ -44973,7 +44974,7 @@ function initAsClient(websocket, address, protocols, options) {
|
|
|
44973
44974
|
|
|
44974
44975
|
const defaultPort = isSecure ? 443 : 80;
|
|
44975
44976
|
const key = randomBytes(16).toString('base64');
|
|
44976
|
-
const request = isSecure ? https$
|
|
44977
|
+
const request = isSecure ? https$2.request : http$2.request;
|
|
44977
44978
|
const protocolSet = new Set();
|
|
44978
44979
|
let perMessageDeflate;
|
|
44979
44980
|
|
|
@@ -45854,9 +45855,9 @@ var subprotocol$1 = { parse: parse$2 };
|
|
|
45854
45855
|
|
|
45855
45856
|
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex$", "caughtErrors": "none" }] */
|
|
45856
45857
|
|
|
45857
|
-
const EventEmitter = require$$0$
|
|
45858
|
-
const http$
|
|
45859
|
-
const { createHash } = require$$3$
|
|
45858
|
+
const EventEmitter = require$$0$c;
|
|
45859
|
+
const http$1 = require$$3$5;
|
|
45860
|
+
const { createHash } = require$$3$6;
|
|
45860
45861
|
|
|
45861
45862
|
const extension = extension$1;
|
|
45862
45863
|
const PerMessageDeflate = permessageDeflate;
|
|
@@ -45945,8 +45946,8 @@ class WebSocketServer extends EventEmitter {
|
|
|
45945
45946
|
}
|
|
45946
45947
|
|
|
45947
45948
|
if (options.port != null) {
|
|
45948
|
-
this._server = http$
|
|
45949
|
-
const body = http$
|
|
45949
|
+
this._server = http$1.createServer((req, res) => {
|
|
45950
|
+
const body = http$1.STATUS_CODES[426];
|
|
45950
45951
|
|
|
45951
45952
|
res.writeHead(426, {
|
|
45952
45953
|
'Content-Length': body.length,
|
|
@@ -46354,7 +46355,7 @@ function abortHandshake(socket, code, message, headers) {
|
|
|
46354
46355
|
// call to `socket.end()` below, which triggers an `'error'` event that in
|
|
46355
46356
|
// turn causes the socket to be destroyed.
|
|
46356
46357
|
//
|
|
46357
|
-
message = message || http$
|
|
46358
|
+
message = message || http$1.STATUS_CODES[code];
|
|
46358
46359
|
headers = {
|
|
46359
46360
|
Connection: 'close',
|
|
46360
46361
|
'Content-Type': 'text/html',
|
|
@@ -46365,7 +46366,7 @@ function abortHandshake(socket, code, message, headers) {
|
|
|
46365
46366
|
socket.once('finish', socket.destroy);
|
|
46366
46367
|
|
|
46367
46368
|
socket.end(
|
|
46368
|
-
`HTTP/1.1 ${code} ${http$
|
|
46369
|
+
`HTTP/1.1 ${code} ${http$1.STATUS_CODES[code]}\r\n` +
|
|
46369
46370
|
Object.keys(headers)
|
|
46370
46371
|
.map((h) => `${h}: ${headers[h]}`)
|
|
46371
46372
|
.join('\r\n') +
|
|
@@ -60133,16 +60134,16 @@ function urnuuidSerialize (uuidComponent) {
|
|
|
60133
60134
|
return urnComponent
|
|
60134
60135
|
}
|
|
60135
60136
|
|
|
60136
|
-
const http
|
|
60137
|
+
const http = /** @type {SchemeHandler} */ ({
|
|
60137
60138
|
scheme: 'http',
|
|
60138
60139
|
domainHost: true,
|
|
60139
60140
|
parse: httpParse,
|
|
60140
60141
|
serialize: httpSerialize
|
|
60141
60142
|
});
|
|
60142
60143
|
|
|
60143
|
-
const https = /** @type {SchemeHandler} */ ({
|
|
60144
|
+
const https$1 = /** @type {SchemeHandler} */ ({
|
|
60144
60145
|
scheme: 'https',
|
|
60145
|
-
domainHost: http
|
|
60146
|
+
domainHost: http.domainHost,
|
|
60146
60147
|
parse: httpParse,
|
|
60147
60148
|
serialize: httpSerialize
|
|
60148
60149
|
});
|
|
@@ -60176,8 +60177,8 @@ const urnuuid = /** @type {SchemeHandler} */ ({
|
|
|
60176
60177
|
});
|
|
60177
60178
|
|
|
60178
60179
|
const SCHEMES$1 = /** @type {Record<SchemeName, SchemeHandler>} */ ({
|
|
60179
|
-
http
|
|
60180
|
-
https,
|
|
60180
|
+
http,
|
|
60181
|
+
https: https$1,
|
|
60181
60182
|
ws,
|
|
60182
60183
|
wss,
|
|
60183
60184
|
urn,
|
|
@@ -65793,7 +65794,7 @@ __export(src_exports, {
|
|
|
65793
65794
|
var dist = __toCommonJS(src_exports);
|
|
65794
65795
|
|
|
65795
65796
|
// src/server.ts
|
|
65796
|
-
var import_node_http = require$$
|
|
65797
|
+
var import_node_http = require$$3$5;
|
|
65797
65798
|
|
|
65798
65799
|
// src/listener.ts
|
|
65799
65800
|
var import_node_http22 = require$$1$7;
|
|
@@ -66122,7 +66123,7 @@ var buildOutgoingHttpHeaders = (headers) => {
|
|
|
66122
66123
|
var X_ALREADY_SENT = "x-hono-already-sent";
|
|
66123
66124
|
|
|
66124
66125
|
// src/globals.ts
|
|
66125
|
-
var import_node_crypto = __toESM(require$$3$
|
|
66126
|
+
var import_node_crypto = __toESM(require$$3$6);
|
|
66126
66127
|
if (typeof commonjsGlobal.crypto === "undefined") {
|
|
66127
66128
|
commonjsGlobal.crypto = import_node_crypto.default;
|
|
66128
66129
|
}
|
|
@@ -67293,6 +67294,113 @@ let StreamableHTTPServerTransport$1 = class StreamableHTTPServerTransport {
|
|
|
67293
67294
|
};
|
|
67294
67295
|
streamableHttp.StreamableHTTPServerTransport = StreamableHTTPServerTransport$1;
|
|
67295
67296
|
|
|
67297
|
+
/**
|
|
67298
|
+
* tlsCert.js
|
|
67299
|
+
*
|
|
67300
|
+
* Generates and caches a self-signed TLS certificate for the MCP Dash Server.
|
|
67301
|
+
* Uses node-forge (already in the dependency tree) to create a cert valid for
|
|
67302
|
+
* 127.0.0.1 and localhost, stored in the app's userData directory.
|
|
67303
|
+
*
|
|
67304
|
+
* Usage:
|
|
67305
|
+
* const { getOrCreateCert } = require('./tlsCert');
|
|
67306
|
+
* const { cert, key } = getOrCreateCert(certsDir);
|
|
67307
|
+
* https.createServer({ key, cert }, handler);
|
|
67308
|
+
*/
|
|
67309
|
+
|
|
67310
|
+
const fs = require$$0$3;
|
|
67311
|
+
const path$1 = require$$1$2;
|
|
67312
|
+
const forge = require$$2$5;
|
|
67313
|
+
|
|
67314
|
+
/**
|
|
67315
|
+
* Get or create a self-signed TLS certificate for localhost.
|
|
67316
|
+
* @param {string} certsDir - Directory to store cert.pem and key.pem
|
|
67317
|
+
* @returns {{ cert: string, key: string }} PEM-encoded certificate and private key
|
|
67318
|
+
*/
|
|
67319
|
+
function getOrCreateCert$1(certsDir) {
|
|
67320
|
+
const certPath = path$1.join(certsDir, "cert.pem");
|
|
67321
|
+
const keyPath = path$1.join(certsDir, "key.pem");
|
|
67322
|
+
|
|
67323
|
+
// Return existing cert if valid
|
|
67324
|
+
if (fs.existsSync(certPath) && fs.existsSync(keyPath)) {
|
|
67325
|
+
try {
|
|
67326
|
+
const cert = fs.readFileSync(certPath, "utf8");
|
|
67327
|
+
const key = fs.readFileSync(keyPath, "utf8");
|
|
67328
|
+
// Verify cert is not expired
|
|
67329
|
+
const parsed = forge.pki.certificateFromPem(cert);
|
|
67330
|
+
if (parsed.validity.notAfter > new Date()) {
|
|
67331
|
+
return { cert, key };
|
|
67332
|
+
}
|
|
67333
|
+
console.log("[tlsCert] Existing certificate expired, regenerating...");
|
|
67334
|
+
} catch (e) {
|
|
67335
|
+
console.log("[tlsCert] Existing certificate invalid, regenerating...");
|
|
67336
|
+
}
|
|
67337
|
+
}
|
|
67338
|
+
|
|
67339
|
+
console.log("[tlsCert] Generating self-signed certificate for localhost...");
|
|
67340
|
+
|
|
67341
|
+
// Generate 2048-bit RSA key pair
|
|
67342
|
+
const keys = forge.pki.rsa.generateKeyPair(2048);
|
|
67343
|
+
|
|
67344
|
+
// Create certificate
|
|
67345
|
+
const cert = forge.pki.createCertificate();
|
|
67346
|
+
cert.publicKey = keys.publicKey;
|
|
67347
|
+
cert.serialNumber = "01";
|
|
67348
|
+
|
|
67349
|
+
// Valid for 10 years
|
|
67350
|
+
cert.validity.notBefore = new Date();
|
|
67351
|
+
cert.validity.notAfter = new Date();
|
|
67352
|
+
cert.validity.notAfter.setFullYear(
|
|
67353
|
+
cert.validity.notBefore.getFullYear() + 10,
|
|
67354
|
+
);
|
|
67355
|
+
|
|
67356
|
+
// Subject and issuer (self-signed)
|
|
67357
|
+
const attrs = [
|
|
67358
|
+
{ name: "commonName", value: "Dash MCP Server" },
|
|
67359
|
+
{ name: "organizationName", value: "Dash" },
|
|
67360
|
+
];
|
|
67361
|
+
cert.setSubject(attrs);
|
|
67362
|
+
cert.setIssuer(attrs);
|
|
67363
|
+
|
|
67364
|
+
// Subject Alternative Names (SAN) — required for modern TLS clients
|
|
67365
|
+
cert.setExtensions([
|
|
67366
|
+
{ name: "basicConstraints", cA: false },
|
|
67367
|
+
{
|
|
67368
|
+
name: "keyUsage",
|
|
67369
|
+
digitalSignature: true,
|
|
67370
|
+
keyEncipherment: true,
|
|
67371
|
+
},
|
|
67372
|
+
{
|
|
67373
|
+
name: "extKeyUsage",
|
|
67374
|
+
serverAuth: true,
|
|
67375
|
+
},
|
|
67376
|
+
{
|
|
67377
|
+
name: "subjectAltName",
|
|
67378
|
+
altNames: [
|
|
67379
|
+
{ type: 7, ip: "127.0.0.1" }, // IP SAN
|
|
67380
|
+
{ type: 2, value: "localhost" }, // DNS SAN
|
|
67381
|
+
],
|
|
67382
|
+
},
|
|
67383
|
+
]);
|
|
67384
|
+
|
|
67385
|
+
// Self-sign with SHA-256
|
|
67386
|
+
cert.sign(keys.privateKey, forge.md.sha256.create());
|
|
67387
|
+
|
|
67388
|
+
// Convert to PEM
|
|
67389
|
+
const certPem = forge.pki.certificateToPem(cert);
|
|
67390
|
+
const keyPem = forge.pki.privateKeyToPem(keys.privateKey);
|
|
67391
|
+
|
|
67392
|
+
// Write to disk
|
|
67393
|
+
fs.mkdirSync(certsDir, { recursive: true });
|
|
67394
|
+
fs.writeFileSync(certPath, certPem, { mode: 0o644 });
|
|
67395
|
+
fs.writeFileSync(keyPath, keyPem, { mode: 0o600 });
|
|
67396
|
+
|
|
67397
|
+
console.log(`[tlsCert] Certificate saved to ${certsDir}`);
|
|
67398
|
+
|
|
67399
|
+
return { cert: certPem, key: keyPem };
|
|
67400
|
+
}
|
|
67401
|
+
|
|
67402
|
+
var tlsCert = { getOrCreateCert: getOrCreateCert$1 };
|
|
67403
|
+
|
|
67296
67404
|
/**
|
|
67297
67405
|
* mcpDashServerController.js
|
|
67298
67406
|
*
|
|
@@ -67303,25 +67411,27 @@ streamableHttp.StreamableHTTPServerTransport = StreamableHTTPServerTransport$1;
|
|
|
67303
67411
|
* MCP *client* that connects to external tool servers for widgets.
|
|
67304
67412
|
*
|
|
67305
67413
|
* Architecture:
|
|
67306
|
-
* - Node
|
|
67414
|
+
* - Node https server bound to 127.0.0.1 (localhost only)
|
|
67415
|
+
* - Auto-generated self-signed TLS certificate for localhost
|
|
67307
67416
|
* - StreamableHTTPServerTransport from @modelcontextprotocol/sdk
|
|
67308
67417
|
* - McpServer registers tools and resources
|
|
67309
67418
|
* - Bearer token authentication on all requests
|
|
67310
67419
|
* - Rate limiting via token bucket (60 req/min)
|
|
67311
67420
|
*/
|
|
67312
67421
|
|
|
67313
|
-
const
|
|
67314
|
-
const { randomUUID } = require$$3$
|
|
67422
|
+
const https = require$$8;
|
|
67423
|
+
const { randomUUID } = require$$3$6;
|
|
67315
67424
|
const { McpServer } = mcp;
|
|
67316
67425
|
const {
|
|
67317
67426
|
StreamableHTTPServerTransport,
|
|
67318
67427
|
} = streamableHttp;
|
|
67319
67428
|
|
|
67320
67429
|
const settingsController$3 = settingsController_1;
|
|
67430
|
+
const { getOrCreateCert } = tlsCert;
|
|
67321
67431
|
|
|
67322
67432
|
// --- State ---
|
|
67323
67433
|
let mcpServer = null;
|
|
67324
|
-
let
|
|
67434
|
+
let httpsServer = null;
|
|
67325
67435
|
let transport = null;
|
|
67326
67436
|
let startTime = null;
|
|
67327
67437
|
let connectionCount = 0;
|
|
@@ -67484,7 +67594,7 @@ const mcpDashServerController$4 = {
|
|
|
67484
67594
|
* @param {Object} options - { port?: number }
|
|
67485
67595
|
*/
|
|
67486
67596
|
startServer: async (win, options = {}) => {
|
|
67487
|
-
if (
|
|
67597
|
+
if (httpsServer) {
|
|
67488
67598
|
return {
|
|
67489
67599
|
success: false,
|
|
67490
67600
|
error: "Server is already running",
|
|
@@ -67503,74 +67613,83 @@ const mcpDashServerController$4 = {
|
|
|
67503
67613
|
version: "1.0.0",
|
|
67504
67614
|
});
|
|
67505
67615
|
|
|
67616
|
+
// Generate or load TLS certificate
|
|
67617
|
+
const { app } = require("electron");
|
|
67618
|
+
const path = require("path");
|
|
67619
|
+
const certsDir = path.join(app.getPath("userData"), "certs");
|
|
67620
|
+
const tlsCert = getOrCreateCert(certsDir);
|
|
67621
|
+
|
|
67506
67622
|
// Apply registered tools and resources
|
|
67507
67623
|
applyRegistrations(mcpServer);
|
|
67508
67624
|
|
|
67509
|
-
// Create
|
|
67510
|
-
|
|
67511
|
-
|
|
67625
|
+
// Create HTTPS server with auth and rate limiting
|
|
67626
|
+
httpsServer = https.createServer(
|
|
67627
|
+
{ key: tlsCert.key, cert: tlsCert.cert },
|
|
67628
|
+
async (req, res) => {
|
|
67629
|
+
const ip = req.socket.remoteAddress || req.connection.remoteAddress;
|
|
67512
67630
|
|
|
67513
|
-
|
|
67514
|
-
|
|
67515
|
-
|
|
67516
|
-
|
|
67517
|
-
|
|
67518
|
-
|
|
67631
|
+
// Rate limiting
|
|
67632
|
+
if (isRateLimited(ip)) {
|
|
67633
|
+
res.writeHead(429, { "Content-Type": "application/json" });
|
|
67634
|
+
res.end(JSON.stringify({ error: "Rate limit exceeded" }));
|
|
67635
|
+
return;
|
|
67636
|
+
}
|
|
67519
67637
|
|
|
67520
|
-
|
|
67521
|
-
|
|
67522
|
-
|
|
67523
|
-
|
|
67524
|
-
|
|
67525
|
-
|
|
67526
|
-
|
|
67638
|
+
// Bearer token auth
|
|
67639
|
+
const authHeader = req.headers.authorization;
|
|
67640
|
+
if (!authHeader || authHeader !== `Bearer ${token}`) {
|
|
67641
|
+
res.writeHead(401, { "Content-Type": "application/json" });
|
|
67642
|
+
res.end(JSON.stringify({ error: "Unauthorized" }));
|
|
67643
|
+
return;
|
|
67644
|
+
}
|
|
67527
67645
|
|
|
67528
|
-
|
|
67529
|
-
|
|
67530
|
-
|
|
67531
|
-
|
|
67532
|
-
|
|
67533
|
-
|
|
67534
|
-
|
|
67535
|
-
|
|
67536
|
-
|
|
67537
|
-
|
|
67538
|
-
|
|
67539
|
-
|
|
67540
|
-
|
|
67646
|
+
// Handle MCP requests on /mcp path
|
|
67647
|
+
if (req.url === "/mcp" || req.url?.startsWith("/mcp")) {
|
|
67648
|
+
try {
|
|
67649
|
+
transport = new StreamableHTTPServerTransport({
|
|
67650
|
+
sessionIdGenerator: undefined,
|
|
67651
|
+
});
|
|
67652
|
+
await mcpServer.connect(transport);
|
|
67653
|
+
connectionCount++;
|
|
67654
|
+
await transport.handleRequest(req, res);
|
|
67655
|
+
} catch (err) {
|
|
67656
|
+
console.error("[mcpDashServer] Error handling MCP request:", err);
|
|
67657
|
+
if (!res.headersSent) {
|
|
67658
|
+
res.writeHead(500, {
|
|
67659
|
+
"Content-Type": "application/json",
|
|
67660
|
+
});
|
|
67661
|
+
res.end(
|
|
67662
|
+
JSON.stringify({
|
|
67663
|
+
error: "Internal server error",
|
|
67664
|
+
}),
|
|
67665
|
+
);
|
|
67666
|
+
}
|
|
67667
|
+
}
|
|
67668
|
+
} else {
|
|
67669
|
+
// Health check endpoint
|
|
67670
|
+
if (req.url === "/health" && req.method === "GET") {
|
|
67671
|
+
res.writeHead(200, {
|
|
67541
67672
|
"Content-Type": "application/json",
|
|
67542
67673
|
});
|
|
67543
67674
|
res.end(
|
|
67544
67675
|
JSON.stringify({
|
|
67545
|
-
|
|
67676
|
+
status: "ok",
|
|
67677
|
+
server: "dash-electron-mcp",
|
|
67678
|
+
version: "1.0.0",
|
|
67546
67679
|
}),
|
|
67547
67680
|
);
|
|
67681
|
+
return;
|
|
67548
67682
|
}
|
|
67683
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
67684
|
+
res.end(JSON.stringify({ error: "Not found" }));
|
|
67549
67685
|
}
|
|
67550
|
-
}
|
|
67551
|
-
|
|
67552
|
-
if (req.url === "/health" && req.method === "GET") {
|
|
67553
|
-
res.writeHead(200, {
|
|
67554
|
-
"Content-Type": "application/json",
|
|
67555
|
-
});
|
|
67556
|
-
res.end(
|
|
67557
|
-
JSON.stringify({
|
|
67558
|
-
status: "ok",
|
|
67559
|
-
server: "dash-electron-mcp",
|
|
67560
|
-
version: "1.0.0",
|
|
67561
|
-
}),
|
|
67562
|
-
);
|
|
67563
|
-
return;
|
|
67564
|
-
}
|
|
67565
|
-
res.writeHead(404, { "Content-Type": "application/json" });
|
|
67566
|
-
res.end(JSON.stringify({ error: "Not found" }));
|
|
67567
|
-
}
|
|
67568
|
-
});
|
|
67686
|
+
},
|
|
67687
|
+
);
|
|
67569
67688
|
|
|
67570
67689
|
// Bind to localhost only
|
|
67571
67690
|
await new Promise((resolve, reject) => {
|
|
67572
|
-
|
|
67573
|
-
|
|
67691
|
+
httpsServer.on("error", (err) => {
|
|
67692
|
+
httpsServer = null;
|
|
67574
67693
|
mcpServer = null;
|
|
67575
67694
|
if (err.code === "EADDRINUSE") {
|
|
67576
67695
|
reject(
|
|
@@ -67582,7 +67701,7 @@ const mcpDashServerController$4 = {
|
|
|
67582
67701
|
reject(err);
|
|
67583
67702
|
}
|
|
67584
67703
|
});
|
|
67585
|
-
|
|
67704
|
+
httpsServer.listen(port, "127.0.0.1", () => {
|
|
67586
67705
|
resolve();
|
|
67587
67706
|
});
|
|
67588
67707
|
});
|
|
@@ -67601,17 +67720,17 @@ const mcpDashServerController$4 = {
|
|
|
67601
67720
|
});
|
|
67602
67721
|
|
|
67603
67722
|
console.log(
|
|
67604
|
-
`[mcpDashServer] Server started on
|
|
67723
|
+
`[mcpDashServer] Server started on https://127.0.0.1:${port}/mcp`,
|
|
67605
67724
|
);
|
|
67606
67725
|
|
|
67607
67726
|
return {
|
|
67608
67727
|
success: true,
|
|
67609
67728
|
port,
|
|
67610
|
-
url: `
|
|
67729
|
+
url: `https://127.0.0.1:${port}/mcp`,
|
|
67611
67730
|
};
|
|
67612
67731
|
} catch (err) {
|
|
67613
67732
|
console.error("[mcpDashServer] Failed to start server:", err);
|
|
67614
|
-
|
|
67733
|
+
httpsServer = null;
|
|
67615
67734
|
mcpServer = null;
|
|
67616
67735
|
return {
|
|
67617
67736
|
success: false,
|
|
@@ -67624,7 +67743,7 @@ const mcpDashServerController$4 = {
|
|
|
67624
67743
|
* Stop the MCP Dash server.
|
|
67625
67744
|
*/
|
|
67626
67745
|
stopServer: async (win) => {
|
|
67627
|
-
if (!
|
|
67746
|
+
if (!httpsServer) {
|
|
67628
67747
|
return { success: true, message: "Server was not running" };
|
|
67629
67748
|
}
|
|
67630
67749
|
|
|
@@ -67632,7 +67751,7 @@ const mcpDashServerController$4 = {
|
|
|
67632
67751
|
stopCleanup();
|
|
67633
67752
|
|
|
67634
67753
|
await new Promise((resolve) => {
|
|
67635
|
-
|
|
67754
|
+
httpsServer.close(() => resolve());
|
|
67636
67755
|
// Force close after 5 seconds
|
|
67637
67756
|
setTimeout(() => resolve(), 5000);
|
|
67638
67757
|
});
|
|
@@ -67645,7 +67764,7 @@ const mcpDashServerController$4 = {
|
|
|
67645
67764
|
}
|
|
67646
67765
|
}
|
|
67647
67766
|
|
|
67648
|
-
|
|
67767
|
+
httpsServer = null;
|
|
67649
67768
|
mcpServer = null;
|
|
67650
67769
|
transport = null;
|
|
67651
67770
|
startTime = null;
|
|
@@ -67683,7 +67802,7 @@ const mcpDashServerController$4 = {
|
|
|
67683
67802
|
getStatus: (win) => {
|
|
67684
67803
|
const serverSettings = getMcpServerSettings(win);
|
|
67685
67804
|
return {
|
|
67686
|
-
running: !!
|
|
67805
|
+
running: !!httpsServer,
|
|
67687
67806
|
enabled: serverSettings.enabled || false,
|
|
67688
67807
|
port: serverSettings.port || 3141,
|
|
67689
67808
|
connectionCount,
|