u2a 1.0.0

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 ADDED
@@ -0,0 +1,123 @@
1
+ # U2A (URL to App)
2
+
3
+ ![U2A Banner](https://img.shields.io/badge/U2A-URL%20to%20App-blue)
4
+ ![License](https://img.shields.io/badge/license-GPL--3.0-green)
5
+ ![Version](https://img.shields.io/badge/version-1.0.0-orange)
6
+
7
+ **Convert any website into a desktop application with a single command.**
8
+
9
+ U2A is a command-line utility that allows you to transform any web URL into a standalone desktop application using Electron. It works across Windows, macOS, and Linux platforms.
10
+
11
+ ## Features
12
+
13
+ - 🚀 Transform any website into a desktop app with one command
14
+ - 🖥️ Cross-platform support (Windows, macOS, Linux)
15
+ - 🔄 Automatic favicon retrieval for app icons
16
+ - 📋 Easy management of created applications
17
+ - 📊 Detailed logging for troubleshooting
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install -g u2a
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ### Creating an App
28
+
29
+ To create a desktop application from a website:
30
+
31
+ ```bash
32
+ u2a create <url>
33
+ ```
34
+
35
+ Example:
36
+ ```bash
37
+ u2a create github.com
38
+ ```
39
+
40
+ This will:
41
+ 1. Download the website's favicon (if available)
42
+ 2. Create an Electron wrapper application
43
+ 3. Add the application to your system menu/launcher
44
+ 4. Track the application in the U2A database
45
+
46
+ ### Listing Your Apps
47
+
48
+ To see all the applications you've created:
49
+
50
+ ```bash
51
+ u2a list
52
+ ```
53
+
54
+ This will display a list of all created applications with their details:
55
+ - Domain name
56
+ - Original URL
57
+ - Creation date
58
+ - Application directory
59
+
60
+ ### Removing an App
61
+
62
+ To remove an application:
63
+
64
+ ```bash
65
+ u2a remove <url>
66
+ ```
67
+
68
+ Example:
69
+ ```bash
70
+ u2a remove github.com
71
+ ```
72
+
73
+ This will:
74
+ 1. Remove the application from your system menu/launcher
75
+ 2. Delete the application files
76
+ 3. Remove the entry from the U2A database
77
+
78
+ ## How It Works
79
+
80
+ U2A creates a minimal Electron application that loads the specified website URL. It:
81
+
82
+ 1. Downloads the site's favicon to use as the application icon
83
+ 2. Generates a main.js file with Electron configuration
84
+ 3. Creates a package.json with necessary dependencies
85
+ 4. Installs required Node modules
86
+ 5. Adds appropriate desktop integration for your operating system
87
+ 6. Maintains a database of created applications for easy management
88
+
89
+ ## System Requirements
90
+
91
+ - Node.js 12.0 or higher
92
+ - npm 6.0 or higher
93
+ - Windows, macOS, or Linux
94
+
95
+ ## Configuration
96
+
97
+ U2A stores all configuration, application data, and logs in the `.u2a` directory in your home folder:
98
+
99
+ - `~/.u2a/apps/` - Application files
100
+ - `~/.u2a/logs/` - Log files
101
+ - `~/.u2a/db.json` - Application database
102
+
103
+ ## Troubleshooting
104
+
105
+ If you encounter any issues, check the log files in the `~/.u2a/logs/` directory. Each component has its own log file with detailed information.
106
+
107
+ Set the `DEBUG` environment variable to see additional debug messages:
108
+
109
+ ```bash
110
+ DEBUG=1 u2a create example.com
111
+ ```
112
+
113
+ ## License
114
+
115
+ This project is licensed under the GNU General Public License v3.0 - see the [LICENSE](LICENSE) file for details.
116
+
117
+ ## Author
118
+
119
+ Created by [Douxx](https://douxx.tech)
120
+
121
+ ## Disclaimer
122
+
123
+ This tool is for personal use only. Always respect the terms of service of websites you convert to desktop apps.
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "u2a",
3
+ "version": "1.0.0",
4
+ "description": "URL to App - Turn any URL into a desktop application",
5
+ "main": "src/index.js",
6
+ "bin": {
7
+ "u2a": "./src/index.js"
8
+ },
9
+ "scripts": {
10
+ "start": "node src/index.js"
11
+ },
12
+ "keywords": [
13
+ "cli",
14
+ "webapp",
15
+ "electron",
16
+ "url",
17
+ "desktop",
18
+ "build",
19
+ "application"
20
+ ],
21
+ "author": "Douxx",
22
+ "license": "GPL-3.0-only",
23
+ "dependencies": {
24
+ "axios": "^1.6.0",
25
+ "chalk": "^4.1.2",
26
+ "commander": "^10.0.0",
27
+ "electron": "^22.0.0",
28
+ "inquirer": "^8.2.5",
29
+ "open": "^8.4.0"
30
+ },
31
+ "homepage": "https://douxx.tech"
32
+ }
@@ -0,0 +1,333 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { execSync } = require('child_process');
4
+ const { normalizeUrl, getDomainName } = require('../utils/url');
5
+ const { getFavicon } = require('../utils/favicon');
6
+ const { APPS_DIR, readDB, writeDB } = require('../utils/config');
7
+ const Logger = require('../utils/logger');
8
+ const os = require('os');
9
+ const { isContext } = require('vm');
10
+
11
+ const logger = new Logger('create');
12
+
13
+ function createWindowsShortcut(appInfo) {
14
+ try {
15
+ const { domain, appDir, iconPath } = appInfo;
16
+ const startMenuPath = path.join(process.env.APPDATA, 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'U2A Apps');
17
+
18
+ if (!fs.existsSync(startMenuPath)) {
19
+ fs.mkdirSync(startMenuPath, { recursive: true });
20
+ }
21
+
22
+ const shortcutPath = path.join(startMenuPath, `${domain}.lnk`);
23
+ const targetPath = path.join(appDir, 'node_modules', '.bin', 'electron.cmd');
24
+ const workingDir = appDir;
25
+
26
+ const psScript = `
27
+ $WshShell = New-Object -comObject WScript.Shell
28
+ $Shortcut = $WshShell.CreateShortcut("${shortcutPath.replace(/\\/g, '\\\\')}")
29
+ $Shortcut.TargetPath = "${targetPath.replace(/\\/g, '\\\\')}"
30
+ $Shortcut.Arguments = "."
31
+ $Shortcut.WorkingDirectory = "${workingDir.replace(/\\/g, '\\\\')}"
32
+ $Shortcut.IconLocation = "${iconPath.replace(/\\/g, '\\\\')}"
33
+ $Shortcut.Description = "Application Web pour ${domain}"
34
+ $Shortcut.Save()
35
+ `;
36
+
37
+ const tempScriptPath = path.join(os.tmpdir(), `create_shortcut_${domain}.ps1`);
38
+ fs.writeFileSync(tempScriptPath, psScript);
39
+
40
+ execSync(`powershell -ExecutionPolicy Bypass -File "${tempScriptPath}"`, {
41
+ stdio: ['ignore', 'pipe', 'pipe'],
42
+ windowsHide: true
43
+ });
44
+
45
+ fs.unlinkSync(tempScriptPath);
46
+
47
+ logger.success(`Shortcut created in the Start Menu: ${shortcutPath}`);
48
+ return shortcutPath;
49
+ } catch (error) {
50
+ logger.error(`Error while creating the Windows shortcut`, error);
51
+ return null;
52
+ }
53
+ }
54
+
55
+
56
+ function createLinuxDesktopEntry(appInfo) {
57
+ try {
58
+ const { domain, url, appDir, iconPath } = appInfo;
59
+ const appsDir = path.join(os.homedir(), '.local', 'share', 'applications');
60
+
61
+ if (!fs.existsSync(appsDir)) {
62
+ fs.mkdirSync(appsDir, { recursive: true });
63
+ }
64
+
65
+ const desktopEntry = `[Desktop Entry]
66
+ Type=Application
67
+ Name=${domain}
68
+ Exec=${path.join(appDir, 'node_modules', '.bin', 'electron')} ${path.join(appDir, 'main.js')}
69
+ Icon=${iconPath}
70
+ Comment=Application Web pour ${url}
71
+ Categories=Network;WebBrowser;
72
+ Terminal=false
73
+ `;
74
+
75
+ const desktopFilePath = path.join(appsDir, `u2a-${domain}.desktop`);
76
+ fs.writeFileSync(desktopFilePath, desktopEntry);
77
+
78
+ fs.chmodSync(desktopFilePath, '755');
79
+
80
+ logger.success(`Desktop entry created for Linux: ${desktopFilePath}`);
81
+ return desktopFilePath;
82
+ } catch (error) {
83
+ logger.error(`Error while creating the Linux desktop entry`, error);
84
+ return null;
85
+ }
86
+ }
87
+
88
+ function createMacOSApp(appInfo) {
89
+ try {
90
+ const { domain, appDir, iconPath } = appInfo;
91
+ const appsDir = path.join(os.homedir(), 'Applications', 'U2A Apps');
92
+
93
+ if (!fs.existsSync(appsDir)) {
94
+ fs.mkdirSync(appsDir, { recursive: true });
95
+ }
96
+
97
+ const appName = `${domain}.app`;
98
+ const appPath = path.join(appsDir, appName);
99
+ const macOsPath = path.join(appPath, 'Contents', 'MacOS');
100
+ const resourcesPath = path.join(appPath, 'Contents', 'Resources');
101
+
102
+ fs.mkdirSync(path.join(appPath, 'Contents', 'MacOS'), { recursive: true });
103
+ fs.mkdirSync(resourcesPath, { recursive: true });
104
+
105
+ const infoPlist = `<?xml version="1.0" encoding="UTF-8"?>
106
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
107
+ <plist version="1.0">
108
+ <dict>
109
+ <key>CFBundleExecutable</key>
110
+ <string>AppRunner</string>
111
+ <key>CFBundleIconFile</key>
112
+ <string>icon.icns</string>
113
+ <key>CFBundleIdentifier</key>
114
+ <string>com.u2a.${domain}</string>
115
+ <key>CFBundleName</key>
116
+ <string>${domain}</string>
117
+ <key>CFBundleDisplayName</key>
118
+ <string>${domain}</string>
119
+ <key>CFBundlePackageType</key>
120
+ <string>APPL</string>
121
+ <key>CFBundleVersion</key>
122
+ <string>1.0</string>
123
+ <key>CFBundleShortVersionString</key>
124
+ <string>1.0</string>
125
+ </dict>
126
+ </plist>`;
127
+
128
+ fs.writeFileSync(path.join(appPath, 'Contents', 'Info.plist'), infoPlist);
129
+
130
+ const shellScript = `#!/bin/bash
131
+ cd "${appDir}"
132
+ "${path.join(appDir, 'node_modules', '.bin', 'electron')}" "${path.join(appDir, 'main.js')}"`;
133
+
134
+ const shellScriptPath = path.join(macOsPath, 'AppRunner');
135
+ fs.writeFileSync(shellScriptPath, shellScript);
136
+ fs.chmodSync(shellScriptPath, '755');
137
+
138
+ fs.copyFileSync(iconPath, path.join(resourcesPath, 'icon.icns'));
139
+
140
+ logger.success(`macOS application created: ${appPath}`);
141
+ return appPath;
142
+ } catch (error) {
143
+ logger.error(`Error while creating the macOS application`, error);
144
+ return null;
145
+ }
146
+ }
147
+
148
+ function addAppToOS(domain, url, appDir, iconPath) {
149
+ const appInfo = { domain, url, appDir, iconPath };
150
+ let desktopPath = null;
151
+
152
+ if (process.platform === 'win32') {
153
+ desktopPath = createWindowsShortcut(appInfo);
154
+ } else if (process.platform === 'darwin') {
155
+ desktopPath = createMacOSApp(appInfo);
156
+ } else if (process.platform === 'linux') {
157
+ desktopPath = createLinuxDesktopEntry(appInfo);
158
+ } else {
159
+ logger.warn(`Desktop integration not supported for platform ${process.platform}`);
160
+ }
161
+
162
+ return desktopPath;
163
+ }
164
+
165
+ function removeAppFromOS(domain) {
166
+ try {
167
+ if (process.platform === 'win32') {
168
+ const startMenuPath = path.join(process.env.APPDATA, 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'U2A Apps', `${domain}.lnk`);
169
+ if (fs.existsSync(startMenuPath)) {
170
+ fs.unlinkSync(startMenuPath);
171
+ logger.success(`Shortcut removed from the Start Menu: ${startMenuPath}`);
172
+ }
173
+ } else if (process.platform === 'darwin') {
174
+ const appPath = path.join(os.homedir(), 'Applications', 'U2A Apps', `${domain}.app`);
175
+ if (fs.existsSync(appPath)) {
176
+ fs.rmSync(appPath, { recursive: true, force: true });
177
+ logger.success(`macOS application removed: ${appPath}`);
178
+ }
179
+ } else if (process.platform === 'linux') {
180
+ const desktopFilePath = path.join(os.homedir(), '.local', 'share', 'applications', `u2a-${domain}.desktop`);
181
+ if (fs.existsSync(desktopFilePath)) {
182
+ fs.unlinkSync(desktopFilePath);
183
+ logger.success(`Linux desktop entry removed: ${desktopFilePath}
184
+
185
+ `);
186
+ }
187
+ }
188
+ } catch (error) {
189
+ logger.error(`Error while removing desktop integration for ${domain}`, error);
190
+ }
191
+ }
192
+
193
+ function generateMainJs(domain, url, iconPath) {
194
+ return `
195
+ const { app, BrowserWindow, Menu, shell } = require('electron');
196
+ const path = require('path');
197
+
198
+ let mainWindow;
199
+
200
+ function createWindow() {
201
+ app.setAppUserModelId("${domain}");
202
+
203
+ mainWindow = new BrowserWindow({
204
+ width: 1200,
205
+ height: 800,
206
+ title: "${domain}",
207
+ icon: "${iconPath.replace(/\\/g, '\\\\')}",
208
+ webPreferences: {
209
+ nodeIntegration: false,
210
+ contextIsolation: true
211
+ }
212
+ });
213
+
214
+ mainWindow.loadURL("${url}");
215
+
216
+ mainWindow.webContents.on('new-window', (event, url) => {
217
+ event.preventDefault();
218
+ shell.openExternal(url);
219
+ });
220
+
221
+ const template = [];
222
+
223
+ const menu = Menu.buildFromTemplate(template);
224
+ Menu.setApplicationMenu(menu);
225
+ }
226
+
227
+ if (process.platform === 'win32') {
228
+ app.setAppUserModelId(app.name);
229
+ }
230
+
231
+ app.whenReady().then(createWindow);
232
+
233
+ app.on('window-all-closed', () => {
234
+ if (process.platform !== 'darwin') {
235
+ app.quit();
236
+ }
237
+ });
238
+
239
+ app.on('activate', () => {
240
+ if (BrowserWindow.getAllWindows().length === 0) {
241
+ createWindow();
242
+ }
243
+ });
244
+ `;
245
+ }
246
+ function generatePackageJson(domain, iconPath) {
247
+ return {
248
+ name: `u2a-${domain}`,
249
+ version: '1.0.0',
250
+ description: `Web app for ${domain}`,
251
+ main: 'main.js',
252
+ scripts: {
253
+ start: 'electron .'
254
+ },
255
+ dependencies: {
256
+ electron: '^22.0.0'
257
+ },
258
+ build: {
259
+ appId: `com.u2a.${domain.replace(/\./g, '-')}`,
260
+ productName: domain,
261
+ icon: iconPath
262
+ }
263
+ };
264
+ }
265
+
266
+ async function createApp(url) {
267
+ logger.info(`Creating application for ${url}`);
268
+
269
+ try {
270
+ url = normalizeUrl(url);
271
+ const domain = getDomainName(url);
272
+
273
+ const db = readDB();
274
+ if (db.hasOwnProperty(domain)) {
275
+ logger.warn(`Application for ${domain} already exists`);
276
+ return;
277
+ }
278
+
279
+ const iconPath = await getFavicon(url);
280
+
281
+ const appDir = path.join(APPS_DIR, domain);
282
+ if (!fs.existsSync(appDir)) {
283
+ fs.mkdirSync(appDir, { recursive: true });
284
+ logger.debug(`Directory created: ${appDir}`);
285
+ }
286
+
287
+ const mainJsPath = path.join(appDir, 'main.js');
288
+ const mainJsContent = generateMainJs(domain, url, iconPath);
289
+ fs.writeFileSync(mainJsPath, mainJsContent);
290
+ logger.debug(`main.js file created`);
291
+
292
+ const packageJsonPath = path.join(appDir, 'package.json');
293
+ const packageJsonContent = generatePackageJson(domain, iconPath);
294
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJsonContent, null, 2));
295
+ logger.debug(`package.json file created`);
296
+
297
+ logger.info(`Installing dependencies for ${domain}`);
298
+
299
+ const installOptions = {
300
+ cwd: appDir,
301
+ stdio: ['ignore', 'pipe', 'pipe'],
302
+ windowsHide: true
303
+ };
304
+
305
+ const stdout = execSync('npm install --only=prod', installOptions);
306
+ logger.debug(`npm install completed: ${stdout.toString().trim()}`);
307
+
308
+ const desktopPath = addAppToOS(domain, url, appDir, iconPath);
309
+
310
+ const appData = {
311
+ url,
312
+ created: new Date().toISOString(),
313
+ path: appDir,
314
+ icon: iconPath,
315
+ desktopPath
316
+ };
317
+
318
+ db[domain] = appData;
319
+ writeDB(db);
320
+
321
+ logger.success(`Application successfully created for ${url}`);
322
+ if (desktopPath) {
323
+ logger.info(`A shortcut has been created in your system's applications directory`);
324
+ }
325
+ } catch (error) {
326
+ logger.error(`Error while creating an application for ${url}`, error);
327
+ }
328
+ }
329
+
330
+ module.exports = {
331
+ createApp,
332
+ removeAppFromOS
333
+ };
@@ -0,0 +1,33 @@
1
+ const { readDB } = require('../utils/config');
2
+ const Logger = require('../utils/logger');
3
+ const chalk = require('chalk');
4
+
5
+ const logger = new Logger('list');
6
+
7
+ function listApps() {
8
+ const apps = readDB();
9
+
10
+ if (Object.keys(apps).length === 0) {
11
+ logger.warn('No applications have been created');
12
+ logger.info('Create one with: u2a create <url>');
13
+ return;
14
+ }
15
+
16
+ logger.info('Available applications:');
17
+ console.log(chalk.gray('--------------------------------'));
18
+
19
+ Object.entries(apps).forEach(([domain, info]) => {
20
+ logger.debug(`Retrieved information for ${domain}:`, info);
21
+ console.log(chalk.green(`\n${domain}:`));
22
+ console.log(chalk.blue(` URL: ${info.url}`));
23
+ console.log(chalk.blue(` Created on: ${new Date(info.created).toLocaleString()}`));
24
+ console.log(chalk.blue(` Directory: ${info.path}`));
25
+ console.log(chalk.gray(' ----------'));
26
+ });
27
+
28
+ logger.info('To remove an application: u2a remove <domain>');
29
+ }
30
+
31
+ module.exports = {
32
+ listApps
33
+ };
@@ -0,0 +1,59 @@
1
+ const fs = require('fs');
2
+ const inquirer = require('inquirer');
3
+ const { normalizeUrl, getDomainName } = require('../utils/url');
4
+ const { readDB, writeDB, APPS_DIR } = require('../utils/config');
5
+ const Logger = require('../utils/logger');
6
+ const { removeAppFromOS } = require('./create');
7
+ const path = require('path');
8
+
9
+ const logger = new Logger('remove');
10
+
11
+ async function removeApp(url) {
12
+ try {
13
+ const domain = getDomainName(normalizeUrl(url));
14
+ const db = readDB();
15
+
16
+ if (!db.hasOwnProperty(domain)) {
17
+ logger.warn(`The application for ${domain} does not exist`);
18
+ return;
19
+ }
20
+
21
+ const { confirm } = await inquirer.prompt([
22
+ {
23
+ type: 'confirm',
24
+ name: 'confirm',
25
+ message: `Are you sure you want to remove the application for ${domain}?`,
26
+ default: false
27
+ }
28
+ ]);
29
+
30
+ if (!confirm) {
31
+ logger.info('Operation canceled');
32
+ return;
33
+ }
34
+
35
+ const appInfo = db[domain];
36
+ const appDir = appInfo.path;
37
+
38
+ removeAppFromOS(domain);
39
+ logger.info(`Removing the application ${domain}...`);
40
+
41
+ const iconPath = path.join(APPS_DIR, `${domain}.ico`);
42
+ if (fs.existsSync(iconPath)) {
43
+ fs.unlinkSync(iconPath);
44
+ logger.success(`Icon for ${domain} removed`);
45
+ }
46
+
47
+ fs.rmSync(appDir, { recursive: true, force: true });
48
+ delete db[domain];
49
+ writeDB(db);
50
+
51
+ logger.success(`The application for ${domain} has been successfully removed`);
52
+ } catch (error) {
53
+ logger.error(`Error removing the application ${url}`, error);
54
+ }
55
+ }
56
+
57
+ module.exports = {
58
+ removeApp
59
+ };
package/src/index.js ADDED
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { program } = require('commander');
4
+ const { createApp } = require('./commands/create');
5
+ const { listApps } = require('./commands/list');
6
+ const { removeApp } = require('./commands/remove');
7
+ const { version } = require('../package.json');
8
+ const { setupConfig } = require('./utils/config');
9
+
10
+ setupConfig();
11
+
12
+ program
13
+ .name('u2a')
14
+ .description('Convert websites into desktop applications')
15
+ .version(version);
16
+
17
+ program
18
+ .command('create <url>')
19
+ .description('Create a new application from a URL')
20
+ .action(createApp);
21
+
22
+ program
23
+ .command('list')
24
+ .description('List all available applications')
25
+ .action(listApps);
26
+
27
+ program
28
+ .command('remove <url>')
29
+ .description('Remove an existing application')
30
+ .action(removeApp);
31
+
32
+ program.on('command:*', () => {
33
+ console.error(`\nInvalid command: ${program.args.join(' ')}`);
34
+ console.log(`\nUse --help to see the list of available commands.`);
35
+ process.exit(1);
36
+ });
37
+
38
+ program.parse(process.argv);
39
+
40
+ if (process.argv.length <= 2) {
41
+ program.help();
42
+ }
@@ -0,0 +1,48 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const os = require('os');
4
+
5
+ const CONFIG_DIR = path.join(os.homedir(), '.u2a');
6
+ const APPS_DIR = path.join(CONFIG_DIR, 'apps');
7
+ const LOGS_DIR = path.join(CONFIG_DIR, 'logs');
8
+ const DB_PATH = path.join(CONFIG_DIR, 'db.json');
9
+
10
+ function setupConfig() {
11
+ if (!fs.existsSync(CONFIG_DIR)) {
12
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
13
+ }
14
+ if (!fs.existsSync(APPS_DIR)) {
15
+ fs.mkdirSync(APPS_DIR, { recursive: true });
16
+ }
17
+ if (!fs.existsSync(LOGS_DIR)) {
18
+ fs.mkdirSync(LOGS_DIR, { recursive: true });
19
+ }
20
+ if (!fs.existsSync(DB_PATH)) {
21
+ fs.writeFileSync(DB_PATH, JSON.stringify({}, null, 2));
22
+ }
23
+ }
24
+
25
+ function readDB() {
26
+ return JSON.parse(fs.readFileSync(DB_PATH, 'utf-8'));
27
+ }
28
+
29
+ function writeDB(data) {
30
+ fs.writeFileSync(DB_PATH, JSON.stringify(data, null, 2));
31
+ }
32
+
33
+ function addAppToDB(domain, appData) {
34
+ const db = readDB();
35
+ db[domain] = appData;
36
+ writeDB(db);
37
+ logger.debug(`Application recorded in the database:`, domain);
38
+ }
39
+
40
+ module.exports = {
41
+ CONFIG_DIR,
42
+ APPS_DIR,
43
+ LOGS_DIR,
44
+ setupConfig,
45
+ readDB,
46
+ writeDB,
47
+ addAppToDB
48
+ };
Binary file