@interopio/iocd-cli 0.0.53 → 0.0.55
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/cli.js +18 -15
- package/dist/cli.js.map +1 -1
- package/dist/schemas/iocd.cli.config.schema.json +6 -6
- package/dist/services/app.service.js +1 -1
- package/dist/services/app.service.js.map +1 -1
- package/dist/services/components/component.config.js +1 -1
- package/dist/services/components/component.config.js.map +1 -1
- package/dist/services/components/components.registry.js +17 -17
- package/dist/services/components/components.registry.js.map +1 -1
- package/dist/services/components/components.service.js +16 -15
- package/dist/services/components/components.service.js.map +1 -1
- package/dist/services/components/file.helper.js +7 -7
- package/dist/services/components/file.helper.js.map +1 -1
- package/dist/services/components/platform.utils.js +49 -41
- package/dist/services/components/platform.utils.js.map +1 -1
- package/dist/services/components/stores/github.store.js +52 -34
- package/dist/services/components/stores/github.store.js.map +1 -1
- package/dist/services/components/stores/local.store.js +19 -18
- package/dist/services/components/stores/local.store.js.map +1 -1
- package/dist/services/components/stores/s3.store.js +63 -56
- package/dist/services/components/stores/s3.store.js.map +1 -1
- package/dist/services/components/version.selector.js +3 -3
- package/dist/services/components/version.selector.js.map +1 -1
- package/dist/services/config/config.service.js +84 -45
- package/dist/services/config/config.service.js.map +1 -1
- package/dist/services/installer/electronForge.js +44 -44
- package/dist/services/installer/electronForge.js.map +1 -1
- package/dist/services/installer/installer.service.js +24 -24
- package/dist/services/installer/installer.service.js.map +1 -1
- package/dist/services/installer/macOS.helper.js +135 -77
- package/dist/services/installer/macOS.helper.js.map +1 -1
- package/dist/services/installer/prerequisites.js +10 -10
- package/dist/services/installer/windows.helper.js +53 -53
- package/dist/services/modifications/macOS.helper.js +28 -24
- package/dist/services/modifications/macOS.helper.js.map +1 -1
- package/dist/services/modifications/modifications.service.js +57 -57
- package/dist/services/modifications/windows.helper.js +54 -14
- package/dist/services/modifications/windows.helper.js.map +1 -1
- package/dist/templates/groups/apps/groups/src/App.tsx +3 -3
- package/dist/templates/groups/apps/groups/src/index.tsx +15 -13
- package/dist/templates/groups/apps/groups/vite.config.ts +4 -4
- package/dist/templates/launchpad/apps/launchpad/src/app/app.tsx +34 -29
- package/dist/templates/launchpad/apps/launchpad/src/app/constants.ts +20 -20
- package/dist/templates/launchpad/apps/launchpad/src/components/logo.tsx +5 -5
- package/dist/templates/launchpad/apps/launchpad/src/components/main-context-menu.tsx +195 -145
- package/dist/templates/launchpad/apps/launchpad/src/components/notifications-button.tsx +41 -34
- package/dist/templates/launchpad/apps/launchpad/src/main.tsx +3 -1
- package/dist/templates/launchpad/apps/launchpad/vite.config.ts +6 -7
- package/dist/templates/tests/tests/tests/sample.spec.ts +16 -16
- package/dist/templates/tests/tests/wdio.config.ts +9 -9
- package/dist/templates/workspaces/apps/workspaces/src/AddWindowButton.tsx +40 -33
- package/dist/templates/workspaces/apps/workspaces/src/AfterTabs.tsx +40 -27
- package/dist/templates/workspaces/apps/workspaces/src/App.tsx +93 -88
- package/dist/templates/workspaces/apps/workspaces/src/GroupHeaderButtons.tsx +11 -9
- package/dist/templates/workspaces/apps/workspaces/src/index.tsx +19 -14
- package/dist/templates/workspaces/apps/workspaces/src/reportWebVitals.ts +4 -4
- package/dist/templates/workspaces/apps/workspaces/src/setupTests.ts +1 -1
- package/dist/templates/workspaces/apps/workspaces/src/useAddWindowButtonVisible.tsx +36 -30
- package/dist/templates/workspaces/apps/workspaces/vite.config.ts +4 -4
- package/dist/utils/proxy.js +68 -0
- package/dist/utils/proxy.js.map +1 -0
- package/package.json +8 -7
|
@@ -8,51 +8,51 @@ const logger_1 = require("../../utils/logger");
|
|
|
8
8
|
const config_service_1 = require("../config/config.service");
|
|
9
9
|
const deep_merge_1 = require("../../utils/deep.merge");
|
|
10
10
|
const windows_helper_1 = require("./windows.helper");
|
|
11
|
-
const isMac = process.platform ===
|
|
11
|
+
const isMac = process.platform === "darwin";
|
|
12
12
|
// Conditionally import macOS helper only on macOS
|
|
13
13
|
let macOSHelper = null;
|
|
14
14
|
if (isMac) {
|
|
15
15
|
try {
|
|
16
|
-
macOSHelper = require(
|
|
16
|
+
macOSHelper = require("./macOS.helper");
|
|
17
17
|
}
|
|
18
18
|
catch (_error) {
|
|
19
19
|
// Will be handled later when needed
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
const logger = logger_1.Logger.getInstance(
|
|
22
|
+
const logger = logger_1.Logger.getInstance("modifications.service");
|
|
23
23
|
const getVars = () => {
|
|
24
24
|
return {
|
|
25
25
|
dev: [
|
|
26
26
|
{
|
|
27
|
-
name:
|
|
28
|
-
value: isMac ?
|
|
27
|
+
name: "COMPONENTS_PATH",
|
|
28
|
+
value: isMac ? "%IO_CD_ROOT_DIR%/../../.." : "%IO_CD_ROOT_DIR%/..",
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
|
-
name:
|
|
32
|
-
value: config_service_1.ConfigManager.config.version ||
|
|
31
|
+
name: "PRODUCT_VERSION",
|
|
32
|
+
value: config_service_1.ConfigManager.config.version || "1.0.0",
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
|
-
name:
|
|
36
|
-
value: config_service_1.ConfigManager.config.productName ||
|
|
35
|
+
name: "PRODUCT_NAME",
|
|
36
|
+
value: config_service_1.ConfigManager.config.productName || "io.Connect Desktop",
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
|
-
name:
|
|
40
|
-
value: config_service_1.ConfigManager.config.productSlug ||
|
|
39
|
+
name: "PRODUCT_SLUG",
|
|
40
|
+
value: config_service_1.ConfigManager.config.productSlug || "io-connect-desktop",
|
|
41
41
|
},
|
|
42
42
|
],
|
|
43
43
|
build: [
|
|
44
|
-
{ name:
|
|
44
|
+
{ name: "COMPONENTS_PATH", value: "%IO_CD_ROOT_DIR%/components" },
|
|
45
45
|
{
|
|
46
|
-
name:
|
|
47
|
-
value: config_service_1.ConfigManager.config.version ||
|
|
46
|
+
name: "PRODUCT_VERSION",
|
|
47
|
+
value: config_service_1.ConfigManager.config.version || "1.0.0",
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
|
-
name:
|
|
51
|
-
value: config_service_1.ConfigManager.config.productName ||
|
|
50
|
+
name: "PRODUCT_NAME",
|
|
51
|
+
value: config_service_1.ConfigManager.config.productName || "io.Connect Desktop",
|
|
52
52
|
},
|
|
53
53
|
{
|
|
54
|
-
name:
|
|
55
|
-
value: config_service_1.ConfigManager.config.productSlug ||
|
|
54
|
+
name: "PRODUCT_SLUG",
|
|
55
|
+
value: config_service_1.ConfigManager.config.productSlug || "io-connect-desktop",
|
|
56
56
|
},
|
|
57
57
|
],
|
|
58
58
|
};
|
|
@@ -60,24 +60,24 @@ const getVars = () => {
|
|
|
60
60
|
async function applyModifications(mode) {
|
|
61
61
|
try {
|
|
62
62
|
logger.info(`Applying modifications in ${mode} mode...`);
|
|
63
|
-
const componentsDir = (0, path_1.join)(process.cwd(),
|
|
63
|
+
const componentsDir = (0, path_1.join)(process.cwd(), "components");
|
|
64
64
|
if (!(0, fs_1.existsSync)(componentsDir)) {
|
|
65
|
-
logger.debug(
|
|
65
|
+
logger.debug("No components directory found - skipping modifications");
|
|
66
66
|
return;
|
|
67
67
|
}
|
|
68
|
-
if (process.platform ===
|
|
69
|
-
logger.debug(
|
|
68
|
+
if (process.platform === "win32") {
|
|
69
|
+
logger.debug("Running on Windows, proceeding with Windows-specific modifications");
|
|
70
70
|
await (0, windows_helper_1.modifyExe)();
|
|
71
|
-
logger.debug(
|
|
71
|
+
logger.debug("Windows-specific modifications applied successfully!");
|
|
72
72
|
}
|
|
73
73
|
// Define modification directories to process in order using new structure
|
|
74
74
|
const modificationDirs = [
|
|
75
75
|
{
|
|
76
|
-
path: (0, path_1.join)(process.cwd(),
|
|
77
|
-
name:
|
|
76
|
+
path: (0, path_1.join)(process.cwd(), "modifications", "base"),
|
|
77
|
+
name: "base modifications",
|
|
78
78
|
},
|
|
79
79
|
{
|
|
80
|
-
path: (0, path_1.join)(process.cwd(),
|
|
80
|
+
path: (0, path_1.join)(process.cwd(), "modifications", mode),
|
|
81
81
|
name: `${mode}-specific modifications`,
|
|
82
82
|
},
|
|
83
83
|
];
|
|
@@ -107,7 +107,7 @@ async function applyModifications(mode) {
|
|
|
107
107
|
continue;
|
|
108
108
|
}
|
|
109
109
|
// Handle macOS app bundle structure for iocd component
|
|
110
|
-
if (process.platform ===
|
|
110
|
+
if (process.platform === "darwin" && componentName === "iocd") {
|
|
111
111
|
await processIocdComponentOnMacOS(modComponentDir, baseTargetComponentDir, mode);
|
|
112
112
|
}
|
|
113
113
|
else {
|
|
@@ -123,7 +123,7 @@ async function applyModifications(mode) {
|
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
if (totalModificationsApplied === 0) {
|
|
126
|
-
logger.info(
|
|
126
|
+
logger.info("No modifications found to apply");
|
|
127
127
|
}
|
|
128
128
|
else {
|
|
129
129
|
logger.info(`All modifications applied successfully! (${totalModificationsApplied} component modification sets processed)`);
|
|
@@ -158,10 +158,10 @@ async function processModificationDirectory(modDir, targetDir, mode) {
|
|
|
158
158
|
async function processDirectory(modDirPath, targetDirPath, mode) {
|
|
159
159
|
logger.debug(`Processing directory ${modDirPath} with targetDir ${targetDirPath}`);
|
|
160
160
|
// Check for .replace marker in the modification directory
|
|
161
|
-
const replaceMarkerPath = (0, path_1.join)(modDirPath,
|
|
161
|
+
const replaceMarkerPath = (0, path_1.join)(modDirPath, ".replace");
|
|
162
162
|
const hasReplaceMarker = (0, fs_1.existsSync)(replaceMarkerPath);
|
|
163
163
|
// Check for .delete marker in the modification directory
|
|
164
|
-
const deleteMarkerPath = (0, path_1.join)(modDirPath,
|
|
164
|
+
const deleteMarkerPath = (0, path_1.join)(modDirPath, ".delete");
|
|
165
165
|
const hasDeleteMarker = (0, fs_1.existsSync)(deleteMarkerPath);
|
|
166
166
|
if (hasDeleteMarker) {
|
|
167
167
|
// Delete the entire target directory
|
|
@@ -183,7 +183,7 @@ async function processDirectory(modDirPath, targetDirPath, mode) {
|
|
|
183
183
|
// Copy all files except the .replace marker
|
|
184
184
|
const items = (0, fs_1.readdirSync)(modDirPath, { withFileTypes: true });
|
|
185
185
|
for (const item of items) {
|
|
186
|
-
if (item.name ===
|
|
186
|
+
if (item.name === ".replace")
|
|
187
187
|
continue;
|
|
188
188
|
const srcPath = (0, path_1.join)(modDirPath, item.name);
|
|
189
189
|
const destPath = (0, path_1.join)(targetDirPath, item.name);
|
|
@@ -210,12 +210,12 @@ async function processDirectory(modDirPath, targetDirPath, mode) {
|
|
|
210
210
|
* Process a file modification
|
|
211
211
|
*/
|
|
212
212
|
async function processFile(modFilePath, targetFilePath, fileName, mode) {
|
|
213
|
-
if (fileName.endsWith(
|
|
213
|
+
if (fileName.endsWith(".gitkeep")) {
|
|
214
214
|
// ignore .gitkeep files
|
|
215
215
|
return;
|
|
216
216
|
}
|
|
217
217
|
// Handle .delete files
|
|
218
|
-
if (fileName.endsWith(
|
|
218
|
+
if (fileName.endsWith(".delete")) {
|
|
219
219
|
const targetFile = fileName.slice(0, -7); // Remove '.delete' suffix
|
|
220
220
|
const actualTargetPath = (0, path_1.join)((0, path_1.dirname)(targetFilePath), targetFile);
|
|
221
221
|
logger.debug(`Deleting file: ${(0, path_1.relative)(process.cwd(), actualTargetPath)}`);
|
|
@@ -230,11 +230,11 @@ async function processFile(modFilePath, targetFilePath, fileName, mode) {
|
|
|
230
230
|
}
|
|
231
231
|
// Handle .json.merge files
|
|
232
232
|
// names can be like system.json.merge or system.json.merge-suffix
|
|
233
|
-
const isJSONMergeFile = fileName.endsWith(
|
|
233
|
+
const isJSONMergeFile = fileName.endsWith(".json.merge") || fileName.includes(".json.merge-");
|
|
234
234
|
if (isJSONMergeFile) {
|
|
235
235
|
// Check for platform-specific suffix (darwin or win32)
|
|
236
236
|
const currentPlatform = process.platform;
|
|
237
|
-
const supportedPlatforms = [
|
|
237
|
+
const supportedPlatforms = ["darwin", "win32"];
|
|
238
238
|
// Extract suffix after .json.merge-
|
|
239
239
|
const suffixMatch = fileName.match(/\.json\.merge-(.+)$/);
|
|
240
240
|
if (suffixMatch) {
|
|
@@ -247,8 +247,8 @@ async function processFile(modFilePath, targetFilePath, fileName, mode) {
|
|
|
247
247
|
}
|
|
248
248
|
}
|
|
249
249
|
// get the base filename without the .merge or .merge-suffix
|
|
250
|
-
const baseFileName = fileName.split(
|
|
251
|
-
const targetFile = baseFileName +
|
|
250
|
+
const baseFileName = fileName.split(".json.merge")[0];
|
|
251
|
+
const targetFile = baseFileName + ".json"; // Remove '.merge' and ensure .json
|
|
252
252
|
const actualTargetPath = (0, path_1.join)((0, path_1.dirname)(targetFilePath), targetFile);
|
|
253
253
|
await mergeJsonFile(modFilePath, actualTargetPath);
|
|
254
254
|
expandVarsSync(actualTargetPath, mode);
|
|
@@ -257,7 +257,7 @@ async function processFile(modFilePath, targetFilePath, fileName, mode) {
|
|
|
257
257
|
// Handle regular file replacement
|
|
258
258
|
ensureDirectoryExists((0, path_1.dirname)(targetFilePath));
|
|
259
259
|
(0, fs_1.copyFileSync)(modFilePath, targetFilePath);
|
|
260
|
-
if (fileName.endsWith(
|
|
260
|
+
if (fileName.endsWith(".json")) {
|
|
261
261
|
// expand vars in the final file only if json
|
|
262
262
|
expandVarsSync(targetFilePath, mode);
|
|
263
263
|
}
|
|
@@ -266,18 +266,18 @@ async function processFile(modFilePath, targetFilePath, fileName, mode) {
|
|
|
266
266
|
function expandVarsSync(filePath, mode) {
|
|
267
267
|
const vars = getVars()[mode] || [];
|
|
268
268
|
// Read the file content
|
|
269
|
-
let content = (0, fs_1.readFileSync)(filePath,
|
|
269
|
+
let content = (0, fs_1.readFileSync)(filePath, "utf-8");
|
|
270
270
|
// Expand environment variables in ${VAR_NAME} format
|
|
271
271
|
content = content.replace(/\$\{([^}]+)\}/g, (_, varName) => {
|
|
272
272
|
let varsValue = vars.find((v) => v.name === varName)?.value;
|
|
273
|
-
const value = varsValue || process.env[varName] ||
|
|
273
|
+
const value = varsValue || process.env[varName] || "";
|
|
274
274
|
// Normalize path separators to forward slashes for JSON safety
|
|
275
|
-
const finalValue = value.replace(/\\/g,
|
|
275
|
+
const finalValue = value.replace(/\\/g, "/");
|
|
276
276
|
logger.debug(`Expanded variable ${varName} to ${finalValue}`);
|
|
277
277
|
return finalValue;
|
|
278
278
|
});
|
|
279
279
|
// Write the modified content back to the file
|
|
280
|
-
(0, fs_1.writeFileSync)(filePath, content,
|
|
280
|
+
(0, fs_1.writeFileSync)(filePath, content, "utf-8");
|
|
281
281
|
}
|
|
282
282
|
/**
|
|
283
283
|
* Merge a JSON modification file with the target JSON file
|
|
@@ -286,19 +286,19 @@ async function mergeJsonFile(mergePath, targetPath) {
|
|
|
286
286
|
try {
|
|
287
287
|
logger.debug(`Merging JSON file: ${mergePath} into ${targetPath}`);
|
|
288
288
|
// Read the merge file
|
|
289
|
-
const mergeContent = (0, fs_1.readFileSync)(mergePath,
|
|
289
|
+
const mergeContent = (0, fs_1.readFileSync)(mergePath, "utf-8");
|
|
290
290
|
const mergeData = JSON.parse(mergeContent);
|
|
291
291
|
let targetData = {};
|
|
292
292
|
// Read existing target file if it exists
|
|
293
293
|
if ((0, fs_1.existsSync)(targetPath)) {
|
|
294
|
-
const targetContent = (0, fs_1.readFileSync)(targetPath,
|
|
294
|
+
const targetContent = (0, fs_1.readFileSync)(targetPath, "utf-8");
|
|
295
295
|
targetData = JSON.parse(targetContent);
|
|
296
296
|
}
|
|
297
297
|
// Deep merge the objects
|
|
298
298
|
const mergedData = (0, deep_merge_1.deepMerge)(targetData, mergeData);
|
|
299
299
|
// Write the merged result
|
|
300
300
|
ensureDirectoryExists((0, path_1.dirname)(targetPath));
|
|
301
|
-
(0, fs_1.writeFileSync)(targetPath, JSON.stringify(mergedData, null, 4),
|
|
301
|
+
(0, fs_1.writeFileSync)(targetPath, JSON.stringify(mergedData, null, 4), "utf-8");
|
|
302
302
|
logger.debug(`Merged JSON file: ${(0, path_1.relative)(process.cwd(), targetPath)}`);
|
|
303
303
|
}
|
|
304
304
|
catch (error) {
|
|
@@ -338,13 +338,13 @@ function ensureDirectoryExists(dirPath) {
|
|
|
338
338
|
*/
|
|
339
339
|
function getActualComponentPath(baseComponentPath, componentName) {
|
|
340
340
|
// Handle macOS app bundle structure for iocd component
|
|
341
|
-
if (process.platform ===
|
|
341
|
+
if (process.platform === "darwin" && componentName === "iocd") {
|
|
342
342
|
// Check for app bundle structure: iocd/{BUNDLE_NAME}/Contents/
|
|
343
343
|
const items = (0, fs_1.readdirSync)(baseComponentPath, { withFileTypes: true });
|
|
344
|
-
const appBundle = items.find(item => item.isDirectory() && item.name.endsWith(
|
|
344
|
+
const appBundle = items.find(item => item.isDirectory() && item.name.endsWith(".app"));
|
|
345
345
|
if (appBundle) {
|
|
346
346
|
const appBundlePath = (0, path_1.join)(baseComponentPath, appBundle.name);
|
|
347
|
-
const contentsPath = (0, path_1.join)(appBundlePath,
|
|
347
|
+
const contentsPath = (0, path_1.join)(appBundlePath, "Contents");
|
|
348
348
|
// Verify the Contents directory exists
|
|
349
349
|
if ((0, fs_1.existsSync)(contentsPath)) {
|
|
350
350
|
logger.debug(`Using macOS app bundle path: ${(0, path_1.relative)(process.cwd(), contentsPath)}`);
|
|
@@ -377,18 +377,18 @@ function getActualComponentPath(baseComponentPath, componentName) {
|
|
|
377
377
|
* @throws {Error} When file operations fail during the modification process
|
|
378
378
|
*/
|
|
379
379
|
async function processIocdComponentOnMacOS(modComponentDir, baseTargetComponentDir, mode) {
|
|
380
|
-
logger.info(
|
|
380
|
+
logger.info("Applying modifications for component: iocd (macOS app bundle)");
|
|
381
381
|
const appBundleName = config_service_1.ConfigManager.config.mac.appBundleName;
|
|
382
382
|
const targetAppBundlePath = (0, path_1.join)(baseTargetComponentDir, appBundleName); // where we expect the app bundle to be at the end
|
|
383
383
|
let currentAppBundlePath = targetAppBundlePath; // where the app bundle currently is
|
|
384
384
|
// Check if macOS helper is available
|
|
385
385
|
if (!macOSHelper) {
|
|
386
|
-
logger.error(
|
|
387
|
-
throw new Error(
|
|
386
|
+
logger.error("macOS helper module is required but not available");
|
|
387
|
+
throw new Error("macOS helper module is required but not available");
|
|
388
388
|
}
|
|
389
389
|
if (!(0, fs_1.existsSync)(targetAppBundlePath)) {
|
|
390
390
|
// APP BUNDLE NOT FOUND, TRY io.Connect Desktop.app as fallback
|
|
391
|
-
const fallbackAppBundlePath = (0, path_1.join)(baseTargetComponentDir,
|
|
391
|
+
const fallbackAppBundlePath = (0, path_1.join)(baseTargetComponentDir, "io.Connect Desktop.app");
|
|
392
392
|
if ((0, fs_1.existsSync)(fallbackAppBundlePath)) {
|
|
393
393
|
logger.debug(`Using fallback app bundle: ${(0, path_1.relative)(process.cwd(), fallbackAppBundlePath)}`);
|
|
394
394
|
currentAppBundlePath = fallbackAppBundlePath;
|
|
@@ -398,7 +398,7 @@ async function processIocdComponentOnMacOS(modComponentDir, baseTargetComponentD
|
|
|
398
398
|
}
|
|
399
399
|
}
|
|
400
400
|
// Strategy: Copy the entire app bundle to a temp location, modify it there, then copy back
|
|
401
|
-
const tempDir = (0, path_1.join)(process.cwd(),
|
|
401
|
+
const tempDir = (0, path_1.join)(process.cwd(), "temp");
|
|
402
402
|
const tempAppPath = (0, path_1.join)(tempDir, `${appBundleName}-temp`);
|
|
403
403
|
try {
|
|
404
404
|
// Create temp directory
|
|
@@ -412,10 +412,10 @@ async function processIocdComponentOnMacOS(modComponentDir, baseTargetComponentD
|
|
|
412
412
|
logger.debug(`Copying app bundle to temp location: ${tempAppPath}`);
|
|
413
413
|
// Copy the entire app bundle to temp (this should work since it's not constrained by permissions)
|
|
414
414
|
(0, child_process_1.execSync)(`cp -R "${currentAppBundlePath}" "${tempAppPath}"`, {
|
|
415
|
-
stdio:
|
|
415
|
+
stdio: "pipe",
|
|
416
416
|
});
|
|
417
417
|
// Apply modifications to the temp copy
|
|
418
|
-
const tempContentsPath = (0, path_1.join)(tempAppPath,
|
|
418
|
+
const tempContentsPath = (0, path_1.join)(tempAppPath, "Contents");
|
|
419
419
|
await processModificationDirectory(modComponentDir, tempContentsPath, mode); // rename the app bundle name
|
|
420
420
|
await macOSHelper.renameAppBundleContents(tempAppPath, appBundleName);
|
|
421
421
|
// Remove the original app bundle
|
|
@@ -423,8 +423,8 @@ async function processIocdComponentOnMacOS(modComponentDir, baseTargetComponentD
|
|
|
423
423
|
(0, fs_1.rmSync)(currentAppBundlePath, { recursive: true, force: true });
|
|
424
424
|
// Move the modified temp app back
|
|
425
425
|
logger.debug(`Moving modified app bundle back: ${targetAppBundlePath}`);
|
|
426
|
-
(0, child_process_1.execSync)(`mv "${tempAppPath}" "${targetAppBundlePath}"`, { stdio:
|
|
427
|
-
logger.debug(
|
|
426
|
+
(0, child_process_1.execSync)(`mv "${tempAppPath}" "${targetAppBundlePath}"`, { stdio: "pipe" });
|
|
427
|
+
logger.debug("Successfully applied modifications to macOS app bundle");
|
|
428
428
|
}
|
|
429
429
|
catch (error) {
|
|
430
430
|
logger.error(`Failed to process iocd component on macOS: ${error}`);
|
|
@@ -9,34 +9,48 @@ const path_2 = require("../../utils/path");
|
|
|
9
9
|
const child_process_1 = require("child_process");
|
|
10
10
|
const find_package_dir_1 = require("../../utils/find.package.dir");
|
|
11
11
|
const version_1 = require("../../utils/version");
|
|
12
|
+
const error_handler_1 = require("../../utils/error.handler");
|
|
12
13
|
const logger = logger_1.Logger.getInstance("modifications.windows.helper");
|
|
13
14
|
async function modifyExe() {
|
|
14
|
-
logger.info(
|
|
15
|
+
logger.info("Modifying Windows executable...");
|
|
15
16
|
restoreOriginalUnsignedExeIfNeeded();
|
|
16
|
-
const defaultIOCDPath = (0, path_1.join)(path_2.PathUtils.getComponentDir("iocd"),
|
|
17
|
+
const defaultIOCDPath = (0, path_1.join)(path_2.PathUtils.getComponentDir("iocd"), "io-connect-desktop.exe");
|
|
17
18
|
const options = config_service_1.ConfigManager.config;
|
|
18
19
|
const newExePath = renameExe(defaultIOCDPath, options.win.exe.exeName);
|
|
20
|
+
if (isFileLocked(newExePath)) {
|
|
21
|
+
throw new error_handler_1.CLIError(`Cannot modify executable because it is locked: ${newExePath}.`, {
|
|
22
|
+
suggestions: [
|
|
23
|
+
"Please close any running instances of the application and try again.",
|
|
24
|
+
],
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
logger.debug("Executable is not locked, proceeding with modifications.");
|
|
29
|
+
}
|
|
19
30
|
await changeIconAndMetadata(newExePath, options);
|
|
20
|
-
logger.info(
|
|
31
|
+
logger.info("Modification complete successfully!");
|
|
21
32
|
}
|
|
22
33
|
function restoreOriginalUnsignedExeIfNeeded() {
|
|
23
34
|
// we store the original unsigned exe before signing, because rcedit can be done on unsigned exe only (see installer/windows.helper.ts for store logic).
|
|
24
35
|
// at this point we are restoring it so we can do rcedit again if needed.
|
|
25
|
-
logger.debug(
|
|
36
|
+
logger.debug("Will check if original unsigned exe exists in _temp...");
|
|
26
37
|
const tempDir = path_2.PathUtils.getComponentDir("_temp");
|
|
27
38
|
const exeBaseName = (0, path_1.basename)(path_2.PathUtils.getIOCDExePath());
|
|
28
39
|
const tempPath = (0, path_1.join)(tempDir, exeBaseName);
|
|
29
40
|
if ((0, fs_1.existsSync)(tempPath)) {
|
|
30
|
-
logger.debug(
|
|
41
|
+
logger.debug("Restoring exe from _temp directory...");
|
|
31
42
|
(0, fs_1.copyFileSync)(tempPath, path_2.PathUtils.getIOCDExePath());
|
|
32
|
-
logger.debug(
|
|
43
|
+
logger.debug("Restored exe from _temp directory.");
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
logger.debug("No original unsigned exe found in _temp, skipping restore.");
|
|
33
47
|
}
|
|
34
48
|
}
|
|
35
49
|
/** rename io-connect-desktop.exe in the path to newName.exe; don to use regex */
|
|
36
50
|
function renameExe(path, newName) {
|
|
37
51
|
logger.debug(`Renaming executable in path: ${path} to ${newName}.exe`);
|
|
38
52
|
const dir = (0, path_1.dirname)(path);
|
|
39
|
-
const oldPath = (0, path_1.join)(dir,
|
|
53
|
+
const oldPath = (0, path_1.join)(dir, "io-connect-desktop.exe");
|
|
40
54
|
const newPath = (0, path_1.join)(dir, `${newName}`);
|
|
41
55
|
const oldExists = (0, fs_1.existsSync)(oldPath);
|
|
42
56
|
const newExists = (0, fs_1.existsSync)(newPath);
|
|
@@ -59,14 +73,23 @@ async function changeIconAndMetadata(exePath, options) {
|
|
|
59
73
|
const rceditPath = (0, path_1.join)((0, find_package_dir_1.findPackageRoot)(), "tools", "rcedit-x64.exe");
|
|
60
74
|
const args = [
|
|
61
75
|
exePath,
|
|
62
|
-
"--set-icon",
|
|
63
|
-
|
|
64
|
-
"--set-version-string",
|
|
65
|
-
"
|
|
66
|
-
|
|
67
|
-
"--set-
|
|
76
|
+
"--set-icon",
|
|
77
|
+
options.win.exe.exeIconPath,
|
|
78
|
+
"--set-version-string",
|
|
79
|
+
"CompanyName",
|
|
80
|
+
options.company,
|
|
81
|
+
"--set-version-string",
|
|
82
|
+
"FileDescription",
|
|
83
|
+
options.productDescription,
|
|
84
|
+
"--set-version-string",
|
|
85
|
+
"ProductName",
|
|
86
|
+
options.productName,
|
|
87
|
+
"--set-file-version",
|
|
88
|
+
(0, version_1.makeVersionFourDigitsIfNeeded)(options.version),
|
|
89
|
+
"--set-product-version",
|
|
90
|
+
options.version,
|
|
68
91
|
];
|
|
69
|
-
logger.debug(`Executing rcedit with args: ${args.join(
|
|
92
|
+
logger.debug(`Executing rcedit with args: ${args.join(" ")}`);
|
|
70
93
|
(0, child_process_1.execFile)(rceditPath, args, (error, stdout, stderr) => {
|
|
71
94
|
if (error) {
|
|
72
95
|
logger.error("rcedit error:", error);
|
|
@@ -80,4 +103,21 @@ async function changeIconAndMetadata(exePath, options) {
|
|
|
80
103
|
});
|
|
81
104
|
});
|
|
82
105
|
}
|
|
106
|
+
function isFileLocked(path) {
|
|
107
|
+
try {
|
|
108
|
+
logger.debug(`Checking if file is locked: ${path}`);
|
|
109
|
+
const fd = (0, fs_1.openSync)(path, "r+"); // request read/write exclusive access
|
|
110
|
+
(0, fs_1.closeSync)(fd);
|
|
111
|
+
logger.debug(`File is not locked: ${path}`);
|
|
112
|
+
return false; // success -> not locked
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
logger.debug(`Error while checking if file is locked: ${path}`, err);
|
|
116
|
+
// Common Windows lock errors:
|
|
117
|
+
if (["EPERM", "EBUSY", "EACCES"].includes(err.code)) {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
83
123
|
//# sourceMappingURL=windows.helper.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"windows.helper.js","sourceRoot":"","sources":["../../../src/services/modifications/windows.helper.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"windows.helper.js","sourceRoot":"","sources":["../../../src/services/modifications/windows.helper.ts"],"names":[],"mappings":";;AAaA,8BAyBC;AAtCD,+BAA+C;AAC/C,+CAA4C;AAE5C,2BAA+E;AAC/E,6DAAyD;AACzD,2CAA6C;AAC7C,iDAAyC;AACzC,mEAA+D;AAC/D,iDAAoE;AACpE,6DAAqD;AAErD,MAAM,MAAM,GAAG,eAAM,CAAC,WAAW,CAAC,8BAA8B,CAAC,CAAC;AAE3D,KAAK,UAAU,SAAS;IAC7B,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAE/C,kCAAkC,EAAE,CAAC;IAErC,MAAM,eAAe,GAAG,IAAA,WAAI,EAC1B,gBAAS,CAAC,eAAe,CAAC,MAAM,CAAC,EACjC,wBAAwB,CACzB,CAAC;IACF,MAAM,OAAO,GAAG,8BAAa,CAAC,MAAM,CAAC;IACrC,MAAM,UAAU,GAAG,SAAS,CAAC,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACvE,IAAI,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,wBAAQ,CAChB,kDAAkD,UAAU,GAAG,EAC/D;YACE,WAAW,EAAE;gBACX,sEAAsE;aACvE;SACF,CACF,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC3E,CAAC;IACD,MAAM,qBAAqB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACjD,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,kCAAkC;IACzC,wJAAwJ;IACxJ,yEAAyE;IACzE,MAAM,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;IACvE,MAAM,OAAO,GAAG,gBAAS,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IACnD,MAAM,WAAW,GAAG,IAAA,eAAQ,EAAC,gBAAS,CAAC,cAAc,EAAE,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAC5C,IAAI,IAAA,eAAU,EAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,MAAM,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACtD,IAAA,iBAAY,EAAC,QAAQ,EAAE,gBAAS,CAAC,cAAc,EAAE,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACrD,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC;AAED,iFAAiF;AACjF,SAAS,SAAS,CAAC,IAAY,EAAE,OAAe;IAC9C,MAAM,CAAC,KAAK,CAAC,gCAAgC,IAAI,OAAO,OAAO,MAAM,CAAC,CAAC;IACvE,MAAM,GAAG,GAAG,IAAA,cAAO,EAAC,IAAI,CAAC,CAAC;IAC1B,MAAM,OAAO,GAAG,IAAA,WAAI,EAAC,GAAG,EAAE,wBAAwB,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,IAAA,WAAI,EAAC,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IAExC,MAAM,SAAS,GAAG,IAAA,eAAU,EAAC,OAAO,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,IAAA,eAAU,EAAC,OAAO,CAAC,CAAC;IAEtC,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,CAAC,KAAK,CACV,uDAAuD,OAAO,EAAE,CACjE,CAAC;QACF,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,IAAA,eAAU,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,YAAY,OAAO,OAAO,OAAO,EAAE,CAAC,CAAC;IACpD,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CACb,mBAAmB,OAAO,iCAAiC,OAAO,EAAE,CACrE,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,qBAAqB,CAClC,OAAe,EACf,OAAkB;IAElB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,CAAC,KAAK,CAAC,8CAA8C,OAAO,EAAE,CAAC,CAAC;QACtE,MAAM,UAAU,GAAG,IAAA,WAAI,EAAC,IAAA,kCAAe,GAAE,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;QAEtE,MAAM,IAAI,GAAG;YACX,OAAO;YACP,YAAY;YACZ,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW;YAC3B,sBAAsB;YACtB,aAAa;YACb,OAAO,CAAC,OAAO;YACf,sBAAsB;YACtB,iBAAiB;YACjB,OAAO,CAAC,kBAAkB;YAC1B,sBAAsB;YACtB,aAAa;YACb,OAAO,CAAC,WAAW;YACnB,oBAAoB;YACpB,IAAA,uCAA6B,EAAC,OAAO,CAAC,OAAO,CAAC;YAC9C,uBAAuB;YACvB,OAAO,CAAC,OAAO;SAChB,CAAC;QAEF,MAAM,CAAC,KAAK,CAAC,+BAA+B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9D,IAAA,wBAAQ,EAAC,UAAU,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACnD,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;gBACrC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC;YACD,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,CAAC,KAAK,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;YACzC,CAAC;YACD,MAAM,CAAC,KAAK,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;YACvC,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,+BAA+B,IAAI,EAAE,CAAC,CAAC;QACpD,MAAM,EAAE,GAAG,IAAA,aAAQ,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,sCAAsC;QACvE,IAAA,cAAS,EAAC,EAAE,CAAC,CAAC;QACd,MAAM,CAAC,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;QAC5C,OAAO,KAAK,CAAC,CAAC,wBAAwB;IACxC,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,MAAM,CAAC,KAAK,CAAC,2CAA2C,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;QACrE,8BAA8B;QAC9B,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACpD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import React, { useContext } from
|
|
1
|
+
import React, { useContext } from "react";
|
|
2
2
|
import Group from "@interopio/groups-ui-react";
|
|
3
3
|
import "@interopio/groups-ui-react/dist/styles/groups.css";
|
|
4
|
-
import { IOConnectContext } from
|
|
4
|
+
import { IOConnectContext } from "@interopio/react-hooks";
|
|
5
5
|
|
|
6
6
|
const App = () => {
|
|
7
7
|
(window as any).io = useContext(IOConnectContext);
|
|
8
|
-
return <Group
|
|
8
|
+
return <Group />;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
export default App;
|
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import ReactDOM from
|
|
3
|
-
import App from
|
|
1
|
+
import React from "react";
|
|
2
|
+
import ReactDOM from "react-dom/client";
|
|
3
|
+
import App from "./App";
|
|
4
4
|
import { IOConnectProvider } from "@interopio/react-hooks";
|
|
5
|
-
import IODesktop from
|
|
5
|
+
import IODesktop from "@interopio/desktop";
|
|
6
6
|
|
|
7
|
-
ReactDOM.createRoot(document.getElementById(
|
|
7
|
+
ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
8
8
|
<React.StrictMode>
|
|
9
|
-
<IOConnectProvider
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
<IOConnectProvider
|
|
10
|
+
settings={{
|
|
11
|
+
desktop: {
|
|
12
|
+
factory: (config: any) => {
|
|
13
|
+
return IODesktop();
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
}}
|
|
17
|
+
>
|
|
16
18
|
<App />
|
|
17
19
|
</IOConnectProvider>
|
|
18
|
-
</React.StrictMode
|
|
20
|
+
</React.StrictMode>
|
|
19
21
|
);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { defineConfig } from
|
|
2
|
-
import react from
|
|
1
|
+
import { defineConfig } from "vite";
|
|
2
|
+
import react from "@vitejs/plugin-react";
|
|
3
3
|
|
|
4
4
|
// https://vite.dev/config/
|
|
5
5
|
export default defineConfig({
|
|
6
6
|
plugins: [react()],
|
|
7
|
-
base:
|
|
8
|
-
})
|
|
7
|
+
base: "./",
|
|
8
|
+
});
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { IOConnectProvider } from "@interopio/react-hooks";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
LaunchpadBody,
|
|
4
|
+
LaunchpadHeader,
|
|
5
|
+
LaunchpadContentsContainer,
|
|
6
|
+
PlatformPrefsProvider,
|
|
7
|
+
} from "@interopio/home-ui-react";
|
|
3
8
|
import { ioConfig } from "./constants";
|
|
4
9
|
import { ThemeProvider, IONotifications } from "@interopio/components-react";
|
|
5
10
|
import Logo from "../components/logo";
|
|
@@ -9,34 +14,34 @@ import "@interopio/workspaces-ui-react/dist/styles/workspaces.css";
|
|
|
9
14
|
import "@interopio/home-ui-react/index.css";
|
|
10
15
|
|
|
11
16
|
export function App() {
|
|
12
|
-
|
|
17
|
+
const { NotificationsProvider } = IONotifications;
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
19
|
+
return (
|
|
20
|
+
<IOConnectProvider settings={ioConfig}>
|
|
21
|
+
<PlatformPrefsProvider>
|
|
22
|
+
<ThemeProvider>
|
|
23
|
+
<NotificationsProvider>
|
|
24
|
+
<LaunchpadContentsContainer
|
|
25
|
+
components={{
|
|
26
|
+
header: {
|
|
27
|
+
BeforeSearch: () => <Logo />,
|
|
28
|
+
AfterSearch: () => (
|
|
29
|
+
<>
|
|
30
|
+
<NotificationsButton />
|
|
31
|
+
<MainContextMenu />
|
|
32
|
+
</>
|
|
33
|
+
),
|
|
34
|
+
},
|
|
35
|
+
}}
|
|
36
|
+
>
|
|
37
|
+
<LaunchpadHeader />
|
|
38
|
+
<LaunchpadBody />
|
|
39
|
+
</LaunchpadContentsContainer>
|
|
40
|
+
</NotificationsProvider>
|
|
41
|
+
</ThemeProvider>
|
|
42
|
+
</PlatformPrefsProvider>
|
|
43
|
+
</IOConnectProvider>
|
|
44
|
+
);
|
|
40
45
|
}
|
|
41
46
|
|
|
42
|
-
export default App;
|
|
47
|
+
export default App;
|
|
@@ -4,24 +4,24 @@ import IOWorkspaces from "@interopio/workspaces-api";
|
|
|
4
4
|
import { IOConnectInitSettings } from "@interopio/react-hooks";
|
|
5
5
|
|
|
6
6
|
export const ioConfig = {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
7
|
+
desktop: {
|
|
8
|
+
factory: IODesktop,
|
|
9
|
+
config: {
|
|
10
|
+
gateway: {
|
|
11
|
+
logging: {
|
|
12
|
+
level: "warn",
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
libraries: [IOWorkspaces, IOSearch],
|
|
16
|
+
appManager: "full",
|
|
17
|
+
layouts: "full",
|
|
18
|
+
activities: "trackAll",
|
|
19
|
+
channels: false,
|
|
20
|
+
metrics: false,
|
|
21
|
+
contexts: true,
|
|
22
|
+
systemLogger: {
|
|
23
|
+
level: "warn",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
27
|
} as IOConnectInitSettings;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ButtonIcon } from "@interopio/components-react";
|
|
2
2
|
|
|
3
3
|
function Logo() {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
return (
|
|
5
|
+
<div className="logo draggable">
|
|
6
|
+
<ButtonIcon variant="circle" icon="logo" size="32" />
|
|
7
|
+
</div>
|
|
8
|
+
);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export default Logo;
|