u2a 3.5.5 → 3.5.7

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.
@@ -1,141 +1,141 @@
1
- //seems still a bit unstable, thats why this feature is disabled by default
2
- //enable with 'u2a configure autoupgrade enable'
3
-
4
-
5
-
6
- const fs = require('fs');
7
- const path = require('path');
8
- const { readDB } = require('./config');
9
- const Logger = require('./logger');
10
- const { createApp } = require('../commands/create');
11
- const { removeApp } = require('../commands/remove');
12
- const { getSetting } = require('./settings');
13
-
14
- const logger = new Logger('upgradeLA');
15
-
16
- function isCoreUpdate(currentVersion, newVersion) {
17
- try {
18
- const [currentSecurity, currentCore, currentFeature] = currentVersion.split('.').map(Number);
19
- const [newSecurity, newCore, newFeature] = newVersion.split('.').map(Number);
20
-
21
- return (currentSecurity !== newSecurity || currentCore !== newCore);
22
- } catch (err) {
23
- logger.debug(`Error comparing versions: ${currentVersion} vs ${newVersion}`, err.message);
24
- return false;
25
- }
26
- }
27
-
28
- function extractDimensionsFromMainJs(mainJsPath) {
29
- try {
30
- if (!fs.existsSync(mainJsPath)) {
31
- logger.warn(`main.js file not found at ${mainJsPath}`);
32
- return { width: 1200, height: 800 };
33
- }
34
-
35
- const mainJsContent = fs.readFileSync(mainJsPath, 'utf8');
36
-
37
- const widthMatch = mainJsContent.match(/const\s+WINDOW_WIDTH\s*=\s*(\d+)/);
38
- const width = widthMatch ? parseInt(widthMatch[1], 10) : 1200;
39
-
40
- const heightMatch = mainJsContent.match(/const\s+WINDOW_HEIGHT\s*=\s*(\d+)/);
41
- const height = heightMatch ? parseInt(heightMatch[1], 10) : 800;
42
-
43
- logger.debug(`Extracted dimensions from main.js: ${width}x${height}`);
44
- return { width, height };
45
- } catch (err) {
46
- logger.debug(`Error extracting dimensions from main.js: ${mainJsPath}`, err.message);
47
- return { width: 1200, height: 800 };
48
- }
49
- }
50
-
51
- async function upgradeLocalApp(appName, appData) {
52
- logger.debug(`Upgrading local app: ${appName}`);
53
-
54
- try {
55
- const { url, path: appPath, icon } = appData;
56
-
57
- const mainJsPath = path.join(appPath, 'main.js');
58
- const { width, height } = extractDimensionsFromMainJs(mainJsPath);
59
-
60
- const options = {
61
- name: appName,
62
- width: width,
63
- height: height,
64
- };
65
-
66
- if (icon)
67
- options.icon = icon;
68
-
69
-
70
- await removeApp(appName, false);
71
- logger.debug(`Removed existing app: ${appName}`);
72
-
73
- await createApp(url, options);
74
- logger.debug(`Successfully upgraded: ${appName}`);
75
-
76
- return true;
77
- } catch (err) {
78
- logger.debug(`Failed to upgrade ${appName}`, err.message);
79
- return false;
80
- }
81
- }
82
-
83
- async function upgradeLocalApps(currentVersion, newVersion) {
84
- logger.debug(`Checking for local apps that need upgrading`);
85
-
86
- const autoUpgradeEnabled = getSetting('autoupgrade_localapps');
87
- if (!autoUpgradeEnabled) {
88
- logger.debug(`Automatic upgrade for local apps is disabled. Skipping upgrades.`);
89
- return { skipped: true, reason: 'disabled', upgraded: 0, failed: 0, total: 0 };
90
- }
91
-
92
- if (!isCoreUpdate(currentVersion, newVersion)) {
93
- logger.debug(`Not a core update (${currentVersion} → ${newVersion}). Skipping local app upgrades.`);
94
- return { skipped: true, reason: 'not-core-update', upgraded: 0, failed: 0, total: 0 };
95
- }
96
-
97
- try {
98
- const db = readDB();
99
- const apps = Object.keys(db);
100
- const stats = { skipped: false, upgraded: 0, failed: 0, total: apps.length };
101
-
102
- logger.debug(`Found ${apps.length} local apps to check for upgrade`);
103
-
104
- for (const appName of apps) {
105
- const appData = db[appName];
106
-
107
- if (!appData.path || !fs.existsSync(appData.path)) { //skips if no path but shouldnt happen
108
- logger.debug(`Skipping ${appName}: Not a local app or path doesn't exist`);
109
- continue;
110
- }
111
-
112
- const success = await upgradeLocalApp(appName, appData);
113
- if (success) {
114
- stats.upgraded++;
115
- } else {
116
- stats.failed++;
117
- }
118
- }
119
-
120
- logger.debug(`Local apps upgrade completed: ${stats.upgraded} upgraded, ${stats.failed} failed, ${apps.length - stats.upgraded - stats.failed} skipped`);
121
- return stats;
122
- } catch (err) {
123
- logger.debug(`Error upgrading local apps`, err.message);
124
- return { skipped: false, upgraded: 0, failed: 0, total: 0, error: err.message };
125
- }
126
- }
127
-
128
- async function upgrade(currentVersion, newVersion) {
129
- logger.debug(`Starting local apps upgrade check: ${currentVersion} → ${newVersion}`);
130
-
131
- if (currentVersion === '0.0.0') {
132
- logger.debug('New installation detected, no apps to upgrade');
133
- return { skipped: true, reason: 'new-install' };
134
- }
135
-
136
- return await upgradeLocalApps(currentVersion, newVersion);
137
- }
138
-
139
- module.exports = {
140
- upgrade
1
+ //seems still a bit unstable, thats why this feature is disabled by default
2
+ //enable with 'u2a configure autoupgrade enable'
3
+
4
+
5
+
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+ const { readDB } = require('./config');
9
+ const Logger = require('./logger');
10
+ const { createApp } = require('../commands/create');
11
+ const { removeApp } = require('../commands/remove');
12
+ const { getSetting } = require('./settings');
13
+
14
+ const logger = new Logger('upgradeLA');
15
+
16
+ function isCoreUpdate(currentVersion, newVersion) {
17
+ try {
18
+ const [currentSecurity, currentCore, currentFeature] = currentVersion.split('.').map(Number);
19
+ const [newSecurity, newCore, newFeature] = newVersion.split('.').map(Number);
20
+
21
+ return (currentSecurity !== newSecurity || currentCore !== newCore);
22
+ } catch (err) {
23
+ logger.debug(`Error comparing versions: ${currentVersion} vs ${newVersion}`, err.message);
24
+ return false;
25
+ }
26
+ }
27
+
28
+ function extractDimensionsFromMainJs(mainJsPath) {
29
+ try {
30
+ if (!fs.existsSync(mainJsPath)) {
31
+ logger.warn(`main.js file not found at ${mainJsPath}`);
32
+ return { width: 1200, height: 800 };
33
+ }
34
+
35
+ const mainJsContent = fs.readFileSync(mainJsPath, 'utf8');
36
+
37
+ const widthMatch = mainJsContent.match(/const\s+WINDOW_WIDTH\s*=\s*(\d+)/);
38
+ const width = widthMatch ? parseInt(widthMatch[1], 10) : 1200;
39
+
40
+ const heightMatch = mainJsContent.match(/const\s+WINDOW_HEIGHT\s*=\s*(\d+)/);
41
+ const height = heightMatch ? parseInt(heightMatch[1], 10) : 800;
42
+
43
+ logger.debug(`Extracted dimensions from main.js: ${width}x${height}`);
44
+ return { width, height };
45
+ } catch (err) {
46
+ logger.debug(`Error extracting dimensions from main.js: ${mainJsPath}`, err.message);
47
+ return { width: 1200, height: 800 };
48
+ }
49
+ }
50
+
51
+ async function upgradeLocalApp(appName, appData) {
52
+ logger.debug(`Upgrading local app: ${appName}`);
53
+
54
+ try {
55
+ const { url, path: appPath, icon } = appData;
56
+
57
+ const mainJsPath = path.join(appPath, 'main.js');
58
+ const { width, height } = extractDimensionsFromMainJs(mainJsPath);
59
+
60
+ const options = {
61
+ name: appName,
62
+ width: width,
63
+ height: height,
64
+ };
65
+
66
+ if (icon)
67
+ options.icon = icon;
68
+
69
+
70
+ await removeApp(appName, false);
71
+ logger.debug(`Removed existing app: ${appName}`);
72
+
73
+ await createApp(url, options);
74
+ logger.debug(`Successfully upgraded: ${appName}`);
75
+
76
+ return true;
77
+ } catch (err) {
78
+ logger.debug(`Failed to upgrade ${appName}`, err.message);
79
+ return false;
80
+ }
81
+ }
82
+
83
+ async function upgradeLocalApps(currentVersion, newVersion) {
84
+ logger.debug(`Checking for local apps that need upgrading`);
85
+
86
+ const autoUpgradeEnabled = getSetting('autoupgrade_localapps');
87
+ if (!autoUpgradeEnabled) {
88
+ logger.debug(`Automatic upgrade for local apps is disabled. Skipping upgrades.`);
89
+ return { skipped: true, reason: 'disabled', upgraded: 0, failed: 0, total: 0 };
90
+ }
91
+
92
+ if (!isCoreUpdate(currentVersion, newVersion)) {
93
+ logger.debug(`Not a core update (${currentVersion} → ${newVersion}). Skipping local app upgrades.`);
94
+ return { skipped: true, reason: 'not-core-update', upgraded: 0, failed: 0, total: 0 };
95
+ }
96
+
97
+ try {
98
+ const db = readDB();
99
+ const apps = Object.keys(db);
100
+ const stats = { skipped: false, upgraded: 0, failed: 0, total: apps.length };
101
+
102
+ logger.debug(`Found ${apps.length} local apps to check for upgrade`);
103
+
104
+ for (const appName of apps) {
105
+ const appData = db[appName];
106
+
107
+ if (!appData.path || !fs.existsSync(appData.path)) { //skips if no path but shouldnt happen
108
+ logger.debug(`Skipping ${appName}: Not a local app or path doesn't exist`);
109
+ continue;
110
+ }
111
+
112
+ const success = await upgradeLocalApp(appName, appData);
113
+ if (success) {
114
+ stats.upgraded++;
115
+ } else {
116
+ stats.failed++;
117
+ }
118
+ }
119
+
120
+ logger.debug(`Local apps upgrade completed: ${stats.upgraded} upgraded, ${stats.failed} failed, ${apps.length - stats.upgraded - stats.failed} skipped`);
121
+ return stats;
122
+ } catch (err) {
123
+ logger.debug(`Error upgrading local apps`, err.message);
124
+ return { skipped: false, upgraded: 0, failed: 0, total: 0, error: err.message };
125
+ }
126
+ }
127
+
128
+ async function upgrade(currentVersion, newVersion) {
129
+ logger.debug(`Starting local apps upgrade check: ${currentVersion} → ${newVersion}`);
130
+
131
+ if (currentVersion === '0.0.0') {
132
+ logger.debug('New installation detected, no apps to upgrade');
133
+ return { skipped: true, reason: 'new-install' };
134
+ }
135
+
136
+ return await upgradeLocalApps(currentVersion, newVersion);
137
+ }
138
+
139
+ module.exports = {
140
+ upgrade
141
141
  };
package/src/utils/url.js CHANGED
@@ -2,15 +2,18 @@ const axios = require('axios');
2
2
  const { sanitizeInput } = require('./sanitize');
3
3
 
4
4
  async function normalizeUrl(url) {
5
- if (!url.startsWith('http://') && !url.startsWith('https://')) {
6
- try {
7
- await axios.get('https://' + url);
8
- url = 'https://' + url;
9
- } catch (error) {
10
- url = 'http://' + url;
11
- }
5
+ const sanitizedUrl = sanitizeInput(url);
6
+
7
+ if (sanitizedUrl.startsWith('http://') || sanitizedUrl.startsWith('https://')) {
8
+ return sanitizedUrl;
9
+ }
10
+
11
+ try {
12
+ await axios.get('https://' + sanitizedUrl);
13
+ return 'https://' + sanitizedUrl;
14
+ } catch (error) {
15
+ return 'http://' + sanitizedUrl;
12
16
  }
13
- return sanitizeInput(url);
14
17
  }
15
18
 
16
19
  function getDomainName(url) {
@@ -25,4 +28,4 @@ function getDomainName(url) {
25
28
  module.exports = {
26
29
  normalizeUrl,
27
30
  getDomainName
28
- };
31
+ };
@@ -1,150 +1,150 @@
1
- const axios = require('axios');
2
- const { version } = require('../../package.json');
3
- const Logger = require('./logger');
4
- const { getSetting } = require('./settings');
5
- const chalk = require('chalk');
6
-
7
- const logger = new Logger('version-check');
8
-
9
- // types of updates based on pattern arount lines 90 of this file
10
- const UPDATE_TYPES = {
11
- NONE: 'none',
12
- SECURITY: 'security',
13
- CORE: 'core',
14
- FEATURE: 'feature'
15
- };
16
-
17
- async function checkVersion(silent = false, forceCheck = false) {
18
- //check if version check is enabled in settings
19
- const versionCheckEnabled = getSetting('version_check');
20
-
21
- //if version check is disabled and not forcing skip the check (btw idk why i made forcecheck)
22
- if (!versionCheckEnabled && !forceCheck) {
23
- logger.debug('Version check is disabled in settings');
24
- return {
25
- current: version,
26
- latest: null,
27
- needsUpdate: false,
28
- updateType: UPDATE_TYPES.NONE,
29
- skipped: true,
30
- reason: 'version_check disabled in settings'
31
- };
32
- }
33
-
34
- try {
35
- logger.debug('Started version check');
36
- const response = await axios.get('https://urltoapp.xyz/api/v1/getlastest', {
37
- timeout: 1000
38
- });
39
-
40
- const latestVersion = response.data.trim();
41
- logger.debug(`Version retrieved: ${latestVersion}`);
42
-
43
- const versionComparison = compareVersions(version, latestVersion);
44
- const updateType = getUpdateType(version, latestVersion);
45
- const needsUpdate = versionComparison < 0;
46
-
47
- if (!silent && needsUpdate) {
48
- logger.debug(`New update available: ${latestVersion} (${updateType})`);
49
- console.log('');
50
-
51
- const updateMessages = {
52
- [UPDATE_TYPES.SECURITY]: `CRITICAL: Security update (${latestVersion}) available!`,
53
- [UPDATE_TYPES.CORE]: `IMPORTANT: Core update (${latestVersion}) available!`,
54
- [UPDATE_TYPES.FEATURE]: `NEW: Feature update (${latestVersion}) available!`
55
- };
56
-
57
- if (updateType === UPDATE_TYPES.SECURITY) {
58
- logger.error(updateMessages[UPDATE_TYPES.SECURITY]); //using .error cuz im lazy to do other variations, sorry ! :)
59
- } else {
60
- logger.warn(updateMessages[updateType] || `A new update (${latestVersion}) is available!`);
61
- }
62
-
63
- logger.warn(`Current version: ${version}`);
64
- logger.warn(`Update u2a with: ${chalk.underline(`npm install -g u2a@${latestVersion}`)}`);
65
-
66
- if (updateType === UPDATE_TYPES.SECURITY) {
67
- logger.error('This update fixes SECURITY VULNERABILITIES and should be installed immediately!');
68
- }
69
- }
70
-
71
- return {
72
- current: version,
73
- latest: latestVersion,
74
- needsUpdate,
75
- updateType,
76
- updateDetails: needsUpdate ? getUpdateDetails(version, latestVersion) : null,
77
- skipped: false
78
- };
79
- } catch (error) {
80
- logger.debug(`Version check failed: ${error.message}`);
81
- return {
82
- current: version,
83
- latest: null,
84
- needsUpdate: false,
85
- updateType: UPDATE_TYPES.NONE,
86
- error: error.message,
87
- skipped: false
88
- };
89
- }
90
- }
91
-
92
- function compareVersions(v1, v2) {
93
- const parts1 = v1.split('.').map(Number);
94
- const parts2 = v2.split('.').map(Number);
95
-
96
- for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
97
- const part1 = parts1[i] || 0;
98
- const part2 = parts2[i] || 0;
99
-
100
- if (part1 < part2) return -1;
101
- if (part1 > part2) return 1;
102
- }
103
-
104
- return 0;
105
- }
106
-
107
- function getUpdateType(currentVersion, latestVersion) {
108
- if (currentVersion === latestVersion) {
109
- return UPDATE_TYPES.NONE;
110
- }
111
-
112
- const current = currentVersion.split('.').map(Number);
113
- const latest = latestVersion.split('.').map(Number);
114
-
115
- /*
116
- a.b.c format where:
117
- a: security version
118
- b: core version
119
- c: feature version
120
- eg, 3.4.18 -> security version: 3, core version: 4, feature version: 18
121
- */
122
-
123
- if (latest[0] > current[0]) {
124
- return UPDATE_TYPES.SECURITY;
125
- } else if (latest[1] > current[1]) {
126
- return UPDATE_TYPES.CORE;
127
- } else if (latest[2] > current[2]) {
128
- return UPDATE_TYPES.FEATURE;
129
- }
130
-
131
- return UPDATE_TYPES.NONE; //current is newer or same
132
- }
133
-
134
- function getUpdateDetails(currentVersion, latestVersion) {
135
- const current = currentVersion.split('.').map(Number);
136
- const latest = latestVersion.split('.').map(Number);
137
-
138
- return {
139
- securityChanges: latest[0] - current[0],
140
- coreChanges: latest[1] - current[1],
141
- featureChanges: latest[2] - current[2],
142
- fromVersion: currentVersion,
143
- toVersion: latestVersion
144
- }; //hard maths up here
145
- }
146
-
147
- module.exports = {
148
- checkVersion,
149
- UPDATE_TYPES
1
+ const axios = require('axios');
2
+ const { version } = require('../../package.json');
3
+ const Logger = require('./logger');
4
+ const { getSetting } = require('./settings');
5
+ const chalk = require('chalk');
6
+
7
+ const logger = new Logger('version-check');
8
+
9
+ // types of updates based on pattern arount lines 90 of this file
10
+ const UPDATE_TYPES = {
11
+ NONE: 'none',
12
+ SECURITY: 'security',
13
+ CORE: 'core',
14
+ FEATURE: 'feature'
15
+ };
16
+
17
+ async function checkVersion(silent = false, forceCheck = false) {
18
+ //check if version check is enabled in settings
19
+ const versionCheckEnabled = getSetting('version_check');
20
+
21
+ //if version check is disabled and not forcing skip the check (btw idk why i made forcecheck)
22
+ if (!versionCheckEnabled && !forceCheck) {
23
+ logger.debug('Version check is disabled in settings');
24
+ return {
25
+ current: version,
26
+ latest: null,
27
+ needsUpdate: false,
28
+ updateType: UPDATE_TYPES.NONE,
29
+ skipped: true,
30
+ reason: 'version_check disabled in settings'
31
+ };
32
+ }
33
+
34
+ try {
35
+ logger.debug('Started version check');
36
+ const response = await axios.get('https://urltoapp.xyz/api/v1/getlastest', {
37
+ timeout: 1000
38
+ });
39
+
40
+ const latestVersion = response.data.trim();
41
+ logger.debug(`Version retrieved: ${latestVersion}`);
42
+
43
+ const versionComparison = compareVersions(version, latestVersion);
44
+ const updateType = getUpdateType(version, latestVersion);
45
+ const needsUpdate = versionComparison < 0;
46
+
47
+ if (!silent && needsUpdate) {
48
+ logger.debug(`New update available: ${latestVersion} (${updateType})`);
49
+ console.log('');
50
+
51
+ const updateMessages = {
52
+ [UPDATE_TYPES.SECURITY]: `CRITICAL: Security update (${latestVersion}) available!`,
53
+ [UPDATE_TYPES.CORE]: `IMPORTANT: Core update (${latestVersion}) available!`,
54
+ [UPDATE_TYPES.FEATURE]: `NEW: Feature update (${latestVersion}) available!`
55
+ };
56
+
57
+ if (updateType === UPDATE_TYPES.SECURITY) {
58
+ logger.error(updateMessages[UPDATE_TYPES.SECURITY]); //using .error cuz im lazy to do other variations, sorry ! :)
59
+ } else {
60
+ logger.warn(updateMessages[updateType] || `A new update (${latestVersion}) is available!`);
61
+ }
62
+
63
+ logger.warn(`Current version: ${version}`);
64
+ logger.warn(`Update u2a with: ${chalk.underline(`npm install -g u2a@${latestVersion}`)}`);
65
+
66
+ if (updateType === UPDATE_TYPES.SECURITY) {
67
+ logger.error('This update fixes SECURITY VULNERABILITIES and should be installed immediately!');
68
+ }
69
+ }
70
+
71
+ return {
72
+ current: version,
73
+ latest: latestVersion,
74
+ needsUpdate,
75
+ updateType,
76
+ updateDetails: needsUpdate ? getUpdateDetails(version, latestVersion) : null,
77
+ skipped: false
78
+ };
79
+ } catch (error) {
80
+ logger.debug(`Version check failed: ${error.message}`);
81
+ return {
82
+ current: version,
83
+ latest: null,
84
+ needsUpdate: false,
85
+ updateType: UPDATE_TYPES.NONE,
86
+ error: error.message,
87
+ skipped: false
88
+ };
89
+ }
90
+ }
91
+
92
+ function compareVersions(v1, v2) {
93
+ const parts1 = v1.split('.').map(Number);
94
+ const parts2 = v2.split('.').map(Number);
95
+
96
+ for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
97
+ const part1 = parts1[i] || 0;
98
+ const part2 = parts2[i] || 0;
99
+
100
+ if (part1 < part2) return -1;
101
+ if (part1 > part2) return 1;
102
+ }
103
+
104
+ return 0;
105
+ }
106
+
107
+ function getUpdateType(currentVersion, latestVersion) {
108
+ if (currentVersion === latestVersion) {
109
+ return UPDATE_TYPES.NONE;
110
+ }
111
+
112
+ const current = currentVersion.split('.').map(Number);
113
+ const latest = latestVersion.split('.').map(Number);
114
+
115
+ /*
116
+ a.b.c format where:
117
+ a: security version
118
+ b: core version
119
+ c: feature version
120
+ eg, 3.4.18 -> security version: 3, core version: 4, feature version: 18
121
+ */
122
+
123
+ if (latest[0] > current[0]) {
124
+ return UPDATE_TYPES.SECURITY;
125
+ } else if (latest[1] > current[1]) {
126
+ return UPDATE_TYPES.CORE;
127
+ } else if (latest[2] > current[2]) {
128
+ return UPDATE_TYPES.FEATURE;
129
+ }
130
+
131
+ return UPDATE_TYPES.NONE; //current is newer or same
132
+ }
133
+
134
+ function getUpdateDetails(currentVersion, latestVersion) {
135
+ const current = currentVersion.split('.').map(Number);
136
+ const latest = latestVersion.split('.').map(Number);
137
+
138
+ return {
139
+ securityChanges: latest[0] - current[0],
140
+ coreChanges: latest[1] - current[1],
141
+ featureChanges: latest[2] - current[2],
142
+ fromVersion: currentVersion,
143
+ toVersion: latestVersion
144
+ }; //hard maths up here
145
+ }
146
+
147
+ module.exports = {
148
+ checkVersion,
149
+ UPDATE_TYPES
150
150
  };
@@ -1,22 +0,0 @@
1
- name: Node.js Package
2
-
3
- on:
4
- push:
5
- paths:
6
- - 'package.json'
7
- branches:
8
- - main
9
-
10
- jobs:
11
-
12
- publish-npm:
13
- runs-on: ubuntu-latest
14
- steps:
15
- - uses: actions/checkout@v4
16
- - uses: actions/setup-node@v4
17
- with:
18
- node-version: 20
19
- registry-url: https://registry.npmjs.org/
20
- - run: npm publish
21
- env:
22
- NODE_AUTH_TOKEN: ${{ secrets.npm_token }}