slicejs-cli 2.8.6 β 2.9.1
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 +347 -315
- package/client.js +526 -539
- package/commands/Print.js +167 -167
- package/commands/Validations.js +103 -103
- package/commands/build/build.js +40 -0
- package/commands/buildProduction/buildProduction.js +45 -10
- package/commands/bundle/bundle.js +235 -231
- package/commands/createComponent/VisualComponentTemplate.js +55 -55
- package/commands/createComponent/createComponent.js +126 -126
- package/commands/deleteComponent/deleteComponent.js +77 -77
- package/commands/doctor/doctor.js +369 -369
- package/commands/getComponent/getComponent.js +747 -747
- package/commands/init/init.js +261 -261
- package/commands/listComponents/listComponents.js +175 -175
- package/commands/startServer/startServer.js +260 -270
- package/commands/startServer/watchServer.js +79 -79
- package/commands/utils/PathHelper.js +68 -68
- package/commands/utils/VersionChecker.js +167 -167
- package/commands/utils/bundling/BundleGenerator.js +1331 -783
- package/commands/utils/bundling/DependencyAnalyzer.js +859 -679
- package/commands/utils/updateManager.js +437 -384
- package/package.json +46 -46
- package/post.js +25 -25
- package/refactor.md +271 -271
- package/tests/bundle-generator.test.js +38 -0
- package/tests/dependency-analyzer.test.js +24 -0
|
@@ -1,79 +1,79 @@
|
|
|
1
|
-
import chokidar from 'chokidar';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import Print from '../Print.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Configura el watcher para archivos del proyecto
|
|
7
|
-
* @param {ChildProcess} serverProcess - Proceso del servidor
|
|
8
|
-
* @returns {FSWatcher} - Watcher de chokidar
|
|
9
|
-
*/
|
|
10
|
-
export default function setupWatcher(serverProcess, onRestart) {
|
|
11
|
-
Print.info('Watch mode enabled - monitoring file changes...');
|
|
12
|
-
Print.newLine();
|
|
13
|
-
|
|
14
|
-
const watcher = chokidar.watch(['src/**/*', 'api/**/*'], {
|
|
15
|
-
ignored: [
|
|
16
|
-
/(^|[\/\\])\../, // archivos ocultos
|
|
17
|
-
'**/node_modules/**',
|
|
18
|
-
'**/dist/**',
|
|
19
|
-
'**/bundles/**',
|
|
20
|
-
'**/*.log'
|
|
21
|
-
],
|
|
22
|
-
persistent: true,
|
|
23
|
-
ignoreInitial: true,
|
|
24
|
-
awaitWriteFinish: {
|
|
25
|
-
stabilityThreshold: 100,
|
|
26
|
-
pollInterval: 50
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
let reloadTimeout;
|
|
31
|
-
|
|
32
|
-
watcher
|
|
33
|
-
.on('change', (path) => {
|
|
34
|
-
// Debounce para evitar mΓΊltiples reloads
|
|
35
|
-
clearTimeout(reloadTimeout);
|
|
36
|
-
reloadTimeout = setTimeout(() => {
|
|
37
|
-
if(onRestart) {
|
|
38
|
-
console.log(chalk.yellow('π Changes detected, restarting server...'));
|
|
39
|
-
onRestart(path);
|
|
40
|
-
} else {
|
|
41
|
-
console.log(chalk.yellow('π Changes detected, server will reload automatically... (No handler)'));
|
|
42
|
-
}
|
|
43
|
-
}, 500);
|
|
44
|
-
})
|
|
45
|
-
.on('add', (path) => {
|
|
46
|
-
// console.log(chalk.green(`β New file added: ${path}`));
|
|
47
|
-
clearTimeout(reloadTimeout);
|
|
48
|
-
reloadTimeout = setTimeout(() => {
|
|
49
|
-
if (onRestart) onRestart(path);
|
|
50
|
-
}, 500);
|
|
51
|
-
})
|
|
52
|
-
.on('unlink', (path) => {
|
|
53
|
-
// console.log(chalk.red(`β File removed: ${path}`));
|
|
54
|
-
clearTimeout(reloadTimeout);
|
|
55
|
-
reloadTimeout = setTimeout(() => {
|
|
56
|
-
if (onRestart) onRestart(path);
|
|
57
|
-
}, 500);
|
|
58
|
-
})
|
|
59
|
-
.on('error', (error) => {
|
|
60
|
-
Print.error(`Watcher error: ${error.message}`);
|
|
61
|
-
})
|
|
62
|
-
.on('ready', () => {
|
|
63
|
-
console.log(chalk.gray('π Watching for file changes...'));
|
|
64
|
-
Print.newLine();
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
return watcher;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Detiene el watcher de forma segura
|
|
72
|
-
* @param {FSWatcher} watcher - Watcher a detener
|
|
73
|
-
*/
|
|
74
|
-
export function stopWatcher(watcher) {
|
|
75
|
-
if (watcher) {
|
|
76
|
-
watcher.close();
|
|
77
|
-
console.log(chalk.gray('Watch mode stopped'));
|
|
78
|
-
}
|
|
79
|
-
}
|
|
1
|
+
import chokidar from 'chokidar';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import Print from '../Print.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Configura el watcher para archivos del proyecto
|
|
7
|
+
* @param {ChildProcess} serverProcess - Proceso del servidor
|
|
8
|
+
* @returns {FSWatcher} - Watcher de chokidar
|
|
9
|
+
*/
|
|
10
|
+
export default function setupWatcher(serverProcess, onRestart) {
|
|
11
|
+
Print.info('Watch mode enabled - monitoring file changes...');
|
|
12
|
+
Print.newLine();
|
|
13
|
+
|
|
14
|
+
const watcher = chokidar.watch(['src/**/*', 'api/**/*'], {
|
|
15
|
+
ignored: [
|
|
16
|
+
/(^|[\/\\])\../, // archivos ocultos
|
|
17
|
+
'**/node_modules/**',
|
|
18
|
+
'**/dist/**',
|
|
19
|
+
'**/bundles/**',
|
|
20
|
+
'**/*.log'
|
|
21
|
+
],
|
|
22
|
+
persistent: true,
|
|
23
|
+
ignoreInitial: true,
|
|
24
|
+
awaitWriteFinish: {
|
|
25
|
+
stabilityThreshold: 100,
|
|
26
|
+
pollInterval: 50
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
let reloadTimeout;
|
|
31
|
+
|
|
32
|
+
watcher
|
|
33
|
+
.on('change', (path) => {
|
|
34
|
+
// Debounce para evitar mΓΊltiples reloads
|
|
35
|
+
clearTimeout(reloadTimeout);
|
|
36
|
+
reloadTimeout = setTimeout(() => {
|
|
37
|
+
if(onRestart) {
|
|
38
|
+
console.log(chalk.yellow('π Changes detected, restarting server...'));
|
|
39
|
+
onRestart(path);
|
|
40
|
+
} else {
|
|
41
|
+
console.log(chalk.yellow('π Changes detected, server will reload automatically... (No handler)'));
|
|
42
|
+
}
|
|
43
|
+
}, 500);
|
|
44
|
+
})
|
|
45
|
+
.on('add', (path) => {
|
|
46
|
+
// console.log(chalk.green(`β New file added: ${path}`));
|
|
47
|
+
clearTimeout(reloadTimeout);
|
|
48
|
+
reloadTimeout = setTimeout(() => {
|
|
49
|
+
if (onRestart) onRestart(path);
|
|
50
|
+
}, 500);
|
|
51
|
+
})
|
|
52
|
+
.on('unlink', (path) => {
|
|
53
|
+
// console.log(chalk.red(`β File removed: ${path}`));
|
|
54
|
+
clearTimeout(reloadTimeout);
|
|
55
|
+
reloadTimeout = setTimeout(() => {
|
|
56
|
+
if (onRestart) onRestart(path);
|
|
57
|
+
}, 500);
|
|
58
|
+
})
|
|
59
|
+
.on('error', (error) => {
|
|
60
|
+
Print.error(`Watcher error: ${error.message}`);
|
|
61
|
+
})
|
|
62
|
+
.on('ready', () => {
|
|
63
|
+
console.log(chalk.gray('π Watching for file changes...'));
|
|
64
|
+
Print.newLine();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return watcher;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Detiene el watcher de forma segura
|
|
72
|
+
* @param {FSWatcher} watcher - Watcher a detener
|
|
73
|
+
*/
|
|
74
|
+
export function stopWatcher(watcher) {
|
|
75
|
+
if (watcher) {
|
|
76
|
+
watcher.close();
|
|
77
|
+
console.log(chalk.gray('Watch mode stopped'));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
import path from 'path'
|
|
2
|
-
import fs from 'fs-extra'
|
|
3
|
-
import { fileURLToPath } from 'url'
|
|
4
|
-
|
|
5
|
-
const sanitize = (s) => (s || '').replace(/^[/\\]+/, '')
|
|
6
|
-
const dirOf = (url) => path.dirname(fileURLToPath(url))
|
|
7
|
-
|
|
8
|
-
function candidates(moduleUrl) {
|
|
9
|
-
const dir = dirOf(moduleUrl)
|
|
10
|
-
return [
|
|
11
|
-
path.join(dir, '../../'),
|
|
12
|
-
path.join(dir, '../../../../')
|
|
13
|
-
]
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function resolveProjectRoot(moduleUrl) {
|
|
17
|
-
const initCwd = process.env.INIT_CWD
|
|
18
|
-
if (initCwd && fs.pathExistsSync(initCwd)) {
|
|
19
|
-
return initCwd
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const cwd = process.cwd()
|
|
23
|
-
if (cwd && fs.pathExistsSync(cwd)) {
|
|
24
|
-
return cwd
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const dirs = candidates(moduleUrl)
|
|
28
|
-
for (const root of dirs) {
|
|
29
|
-
const hasSrc = fs.pathExistsSync(path.join(root, 'src'))
|
|
30
|
-
const hasApi = fs.pathExistsSync(path.join(root, 'api'))
|
|
31
|
-
if (hasSrc || hasApi) return root
|
|
32
|
-
}
|
|
33
|
-
return dirs[1]
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function joinProject(moduleUrl, ...segments) {
|
|
37
|
-
const root = resolveProjectRoot(moduleUrl)
|
|
38
|
-
const clean = segments.map(sanitize)
|
|
39
|
-
return path.join(root, ...clean)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function getProjectRoot(moduleUrl) {
|
|
43
|
-
return resolveProjectRoot(moduleUrl)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function getPath(moduleUrl, folder, ...segments) {
|
|
47
|
-
return joinProject(moduleUrl, folder, ...segments)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function getSrcPath(moduleUrl, ...segments) {
|
|
51
|
-
return joinProject(moduleUrl, 'src', ...segments)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export function getApiPath(moduleUrl, ...segments) {
|
|
55
|
-
return joinProject(moduleUrl, 'api', ...segments)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function getDistPath(moduleUrl, ...segments) {
|
|
59
|
-
return joinProject(moduleUrl, 'dist', ...segments)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export function getConfigPath(moduleUrl) {
|
|
63
|
-
return joinProject(moduleUrl, 'src', 'sliceConfig.json')
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export function getComponentsJsPath(moduleUrl) {
|
|
67
|
-
return joinProject(moduleUrl, 'src', 'Components', 'components.js')
|
|
68
|
-
}
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import fs from 'fs-extra'
|
|
3
|
+
import { fileURLToPath } from 'url'
|
|
4
|
+
|
|
5
|
+
const sanitize = (s) => (s || '').replace(/^[/\\]+/, '')
|
|
6
|
+
const dirOf = (url) => path.dirname(fileURLToPath(url))
|
|
7
|
+
|
|
8
|
+
function candidates(moduleUrl) {
|
|
9
|
+
const dir = dirOf(moduleUrl)
|
|
10
|
+
return [
|
|
11
|
+
path.join(dir, '../../'),
|
|
12
|
+
path.join(dir, '../../../../')
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function resolveProjectRoot(moduleUrl) {
|
|
17
|
+
const initCwd = process.env.INIT_CWD
|
|
18
|
+
if (initCwd && fs.pathExistsSync(initCwd)) {
|
|
19
|
+
return initCwd
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const cwd = process.cwd()
|
|
23
|
+
if (cwd && fs.pathExistsSync(cwd)) {
|
|
24
|
+
return cwd
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const dirs = candidates(moduleUrl)
|
|
28
|
+
for (const root of dirs) {
|
|
29
|
+
const hasSrc = fs.pathExistsSync(path.join(root, 'src'))
|
|
30
|
+
const hasApi = fs.pathExistsSync(path.join(root, 'api'))
|
|
31
|
+
if (hasSrc || hasApi) return root
|
|
32
|
+
}
|
|
33
|
+
return dirs[1]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function joinProject(moduleUrl, ...segments) {
|
|
37
|
+
const root = resolveProjectRoot(moduleUrl)
|
|
38
|
+
const clean = segments.map(sanitize)
|
|
39
|
+
return path.join(root, ...clean)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function getProjectRoot(moduleUrl) {
|
|
43
|
+
return resolveProjectRoot(moduleUrl)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function getPath(moduleUrl, folder, ...segments) {
|
|
47
|
+
return joinProject(moduleUrl, folder, ...segments)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function getSrcPath(moduleUrl, ...segments) {
|
|
51
|
+
return joinProject(moduleUrl, 'src', ...segments)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function getApiPath(moduleUrl, ...segments) {
|
|
55
|
+
return joinProject(moduleUrl, 'api', ...segments)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function getDistPath(moduleUrl, ...segments) {
|
|
59
|
+
return joinProject(moduleUrl, 'dist', ...segments)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function getConfigPath(moduleUrl) {
|
|
63
|
+
return joinProject(moduleUrl, 'src', 'sliceConfig.json')
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function getComponentsJsPath(moduleUrl) {
|
|
67
|
+
return joinProject(moduleUrl, 'src', 'Components', 'components.js')
|
|
68
|
+
}
|
|
@@ -1,167 +1,167 @@
|
|
|
1
|
-
// commands/utils/VersionChecker.js
|
|
2
|
-
|
|
3
|
-
import fs from "fs-extra";
|
|
4
|
-
import path from "path";
|
|
5
|
-
import { fileURLToPath } from "url";
|
|
6
|
-
import Print from "../Print.js";
|
|
7
|
-
import { getProjectRoot } from "../utils/PathHelper.js";
|
|
8
|
-
|
|
9
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
-
|
|
11
|
-
class VersionChecker {
|
|
12
|
-
constructor() {
|
|
13
|
-
this.currentCliVersion = null;
|
|
14
|
-
this.currentFrameworkVersion = null;
|
|
15
|
-
this.latestCliVersion = null;
|
|
16
|
-
this.latestFrameworkVersion = null;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async getCurrentVersions() {
|
|
20
|
-
try {
|
|
21
|
-
// Get CLI version
|
|
22
|
-
const cliPackagePath = path.join(__dirname, '../../package.json');
|
|
23
|
-
const cliPackage = await fs.readJson(cliPackagePath);
|
|
24
|
-
this.currentCliVersion = cliPackage.version;
|
|
25
|
-
|
|
26
|
-
// Get Framework version from project node_modules
|
|
27
|
-
const projectRoot = getProjectRoot(import.meta.url);
|
|
28
|
-
const frameworkPackagePath = path.join(projectRoot, 'node_modules', 'slicejs-web-framework', 'package.json');
|
|
29
|
-
if (await fs.pathExists(frameworkPackagePath)) {
|
|
30
|
-
const frameworkPackage = await fs.readJson(frameworkPackagePath);
|
|
31
|
-
this.currentFrameworkVersion = frameworkPackage.version;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Get Project's CLI version
|
|
35
|
-
const projectPackagePath = path.join(__dirname, '../../../../package.json');
|
|
36
|
-
if (await fs.pathExists(projectPackagePath)) {
|
|
37
|
-
const projectPackage = await fs.readJson(projectPackagePath);
|
|
38
|
-
if (projectPackage.dependencies && projectPackage.dependencies['slicejs-cli']) {
|
|
39
|
-
// This could be different from the currently running CLI version
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
cli: this.currentCliVersion,
|
|
45
|
-
framework: this.currentFrameworkVersion
|
|
46
|
-
};
|
|
47
|
-
} catch (error) {
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async getLatestVersions() {
|
|
53
|
-
try {
|
|
54
|
-
// Check CLI version
|
|
55
|
-
const cliResponse = await fetch('https://registry.npmjs.org/slicejs-cli/latest', {
|
|
56
|
-
headers: { 'Accept': 'application/json' }
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
if (cliResponse.ok) {
|
|
60
|
-
const cliData = await cliResponse.json();
|
|
61
|
-
this.latestCliVersion = cliData.version;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Check Framework version
|
|
65
|
-
const frameworkResponse = await fetch('https://registry.npmjs.org/slicejs-web-framework/latest', {
|
|
66
|
-
headers: { 'Accept': 'application/json' }
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
if (frameworkResponse.ok) {
|
|
70
|
-
const frameworkData = await frameworkResponse.json();
|
|
71
|
-
this.latestFrameworkVersion = frameworkData.version;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return {
|
|
75
|
-
cli: this.latestCliVersion,
|
|
76
|
-
framework: this.latestFrameworkVersion
|
|
77
|
-
};
|
|
78
|
-
} catch (error) {
|
|
79
|
-
// Silent fail - don't interrupt commands for version check failures
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
compareVersions(current, latest) {
|
|
85
|
-
if (!current || !latest) return null;
|
|
86
|
-
|
|
87
|
-
const currentParts = current.split('.').map(Number);
|
|
88
|
-
const latestParts = latest.split('.').map(Number);
|
|
89
|
-
|
|
90
|
-
for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {
|
|
91
|
-
const currentPart = currentParts[i] || 0;
|
|
92
|
-
const latestPart = latestParts[i] || 0;
|
|
93
|
-
|
|
94
|
-
if (latestPart > currentPart) return 'outdated';
|
|
95
|
-
if (currentPart > latestPart) return 'newer';
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return 'current';
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
async checkForUpdates(silent = false) {
|
|
102
|
-
try {
|
|
103
|
-
const current = await this.getCurrentVersions();
|
|
104
|
-
if (!current) return;
|
|
105
|
-
|
|
106
|
-
const latest = await this.getLatestVersions();
|
|
107
|
-
if (!latest) return;
|
|
108
|
-
|
|
109
|
-
const cliStatus = this.compareVersions(current.cli, latest.cli);
|
|
110
|
-
const frameworkStatus = this.compareVersions(current.framework, latest.framework);
|
|
111
|
-
|
|
112
|
-
if (!silent && (cliStatus === 'outdated' || frameworkStatus === 'outdated')) {
|
|
113
|
-
console.log(''); // Line break
|
|
114
|
-
Print.warning('π¦ Available Updates:');
|
|
115
|
-
|
|
116
|
-
if (cliStatus === 'outdated') {
|
|
117
|
-
console.log(` π§ CLI: ${current.cli} β ${latest.cli}`);
|
|
118
|
-
console.log(` npm update slicejs-cli`);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
if (frameworkStatus === 'outdated') {
|
|
122
|
-
console.log(` β‘ Framework: ${current.framework} β ${latest.framework}`);
|
|
123
|
-
console.log(` npm update slicejs-web-framework`);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
console.log(' π Changelog: https://github.com/VKneider/slice.js/releases');
|
|
127
|
-
console.log(''); // Line break
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return {
|
|
131
|
-
cli: { current: current.cli, latest: latest.cli, status: cliStatus },
|
|
132
|
-
framework: { current: current.framework, latest: latest.framework, status: frameworkStatus }
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
} catch (error) {
|
|
136
|
-
// Silent fail - don't interrupt commands
|
|
137
|
-
return null;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
async showVersionInfo() {
|
|
142
|
-
const current = await this.getCurrentVersions();
|
|
143
|
-
const latest = await this.getLatestVersions();
|
|
144
|
-
|
|
145
|
-
console.log('\nπ Version Information:');
|
|
146
|
-
console.log('βββββββββββββββββββββββββββββββ');
|
|
147
|
-
|
|
148
|
-
if (current?.cli) {
|
|
149
|
-
const cliStatus = this.compareVersions(current.cli, latest?.cli);
|
|
150
|
-
const statusIcon = cliStatus === 'current' ? 'β
' : cliStatus === 'outdated' ? 'π' : 'π';
|
|
151
|
-
console.log(`${statusIcon} CLI: v${current.cli}${latest?.cli && latest.cli !== current.cli ? ` (latest: v${latest.cli})` : ''}`);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (current?.framework) {
|
|
155
|
-
const frameworkStatus = this.compareVersions(current.framework, latest?.framework);
|
|
156
|
-
const statusIcon = frameworkStatus === 'current' ? 'β
' : frameworkStatus === 'outdated' ? 'π' : 'π';
|
|
157
|
-
console.log(`${statusIcon} Framework: v${current.framework}${latest?.framework && latest.framework !== current.framework ? ` (latest: v${latest.framework})` : ''}`);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
console.log('βββββββββββββββββββββββββββββββ\n');
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Singleton instance
|
|
165
|
-
const versionChecker = new VersionChecker();
|
|
166
|
-
|
|
167
|
-
export default versionChecker;
|
|
1
|
+
// commands/utils/VersionChecker.js
|
|
2
|
+
|
|
3
|
+
import fs from "fs-extra";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
import Print from "../Print.js";
|
|
7
|
+
import { getProjectRoot } from "../utils/PathHelper.js";
|
|
8
|
+
|
|
9
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
|
|
11
|
+
class VersionChecker {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.currentCliVersion = null;
|
|
14
|
+
this.currentFrameworkVersion = null;
|
|
15
|
+
this.latestCliVersion = null;
|
|
16
|
+
this.latestFrameworkVersion = null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async getCurrentVersions() {
|
|
20
|
+
try {
|
|
21
|
+
// Get CLI version
|
|
22
|
+
const cliPackagePath = path.join(__dirname, '../../package.json');
|
|
23
|
+
const cliPackage = await fs.readJson(cliPackagePath);
|
|
24
|
+
this.currentCliVersion = cliPackage.version;
|
|
25
|
+
|
|
26
|
+
// Get Framework version from project node_modules
|
|
27
|
+
const projectRoot = getProjectRoot(import.meta.url);
|
|
28
|
+
const frameworkPackagePath = path.join(projectRoot, 'node_modules', 'slicejs-web-framework', 'package.json');
|
|
29
|
+
if (await fs.pathExists(frameworkPackagePath)) {
|
|
30
|
+
const frameworkPackage = await fs.readJson(frameworkPackagePath);
|
|
31
|
+
this.currentFrameworkVersion = frameworkPackage.version;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Get Project's CLI version
|
|
35
|
+
const projectPackagePath = path.join(__dirname, '../../../../package.json');
|
|
36
|
+
if (await fs.pathExists(projectPackagePath)) {
|
|
37
|
+
const projectPackage = await fs.readJson(projectPackagePath);
|
|
38
|
+
if (projectPackage.dependencies && projectPackage.dependencies['slicejs-cli']) {
|
|
39
|
+
// This could be different from the currently running CLI version
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
cli: this.currentCliVersion,
|
|
45
|
+
framework: this.currentFrameworkVersion
|
|
46
|
+
};
|
|
47
|
+
} catch (error) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async getLatestVersions() {
|
|
53
|
+
try {
|
|
54
|
+
// Check CLI version
|
|
55
|
+
const cliResponse = await fetch('https://registry.npmjs.org/slicejs-cli/latest', {
|
|
56
|
+
headers: { 'Accept': 'application/json' }
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
if (cliResponse.ok) {
|
|
60
|
+
const cliData = await cliResponse.json();
|
|
61
|
+
this.latestCliVersion = cliData.version;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Check Framework version
|
|
65
|
+
const frameworkResponse = await fetch('https://registry.npmjs.org/slicejs-web-framework/latest', {
|
|
66
|
+
headers: { 'Accept': 'application/json' }
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
if (frameworkResponse.ok) {
|
|
70
|
+
const frameworkData = await frameworkResponse.json();
|
|
71
|
+
this.latestFrameworkVersion = frameworkData.version;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
cli: this.latestCliVersion,
|
|
76
|
+
framework: this.latestFrameworkVersion
|
|
77
|
+
};
|
|
78
|
+
} catch (error) {
|
|
79
|
+
// Silent fail - don't interrupt commands for version check failures
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
compareVersions(current, latest) {
|
|
85
|
+
if (!current || !latest) return null;
|
|
86
|
+
|
|
87
|
+
const currentParts = current.split('.').map(Number);
|
|
88
|
+
const latestParts = latest.split('.').map(Number);
|
|
89
|
+
|
|
90
|
+
for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {
|
|
91
|
+
const currentPart = currentParts[i] || 0;
|
|
92
|
+
const latestPart = latestParts[i] || 0;
|
|
93
|
+
|
|
94
|
+
if (latestPart > currentPart) return 'outdated';
|
|
95
|
+
if (currentPart > latestPart) return 'newer';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return 'current';
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async checkForUpdates(silent = false) {
|
|
102
|
+
try {
|
|
103
|
+
const current = await this.getCurrentVersions();
|
|
104
|
+
if (!current) return;
|
|
105
|
+
|
|
106
|
+
const latest = await this.getLatestVersions();
|
|
107
|
+
if (!latest) return;
|
|
108
|
+
|
|
109
|
+
const cliStatus = this.compareVersions(current.cli, latest.cli);
|
|
110
|
+
const frameworkStatus = this.compareVersions(current.framework, latest.framework);
|
|
111
|
+
|
|
112
|
+
if (!silent && (cliStatus === 'outdated' || frameworkStatus === 'outdated')) {
|
|
113
|
+
console.log(''); // Line break
|
|
114
|
+
Print.warning('π¦ Available Updates:');
|
|
115
|
+
|
|
116
|
+
if (cliStatus === 'outdated') {
|
|
117
|
+
console.log(` π§ CLI: ${current.cli} β ${latest.cli}`);
|
|
118
|
+
console.log(` npm update slicejs-cli`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (frameworkStatus === 'outdated') {
|
|
122
|
+
console.log(` β‘ Framework: ${current.framework} β ${latest.framework}`);
|
|
123
|
+
console.log(` npm update slicejs-web-framework`);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
console.log(' π Changelog: https://github.com/VKneider/slice.js/releases');
|
|
127
|
+
console.log(''); // Line break
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
cli: { current: current.cli, latest: latest.cli, status: cliStatus },
|
|
132
|
+
framework: { current: current.framework, latest: latest.framework, status: frameworkStatus }
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
} catch (error) {
|
|
136
|
+
// Silent fail - don't interrupt commands
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async showVersionInfo() {
|
|
142
|
+
const current = await this.getCurrentVersions();
|
|
143
|
+
const latest = await this.getLatestVersions();
|
|
144
|
+
|
|
145
|
+
console.log('\nπ Version Information:');
|
|
146
|
+
console.log('βββββββββββββββββββββββββββββββ');
|
|
147
|
+
|
|
148
|
+
if (current?.cli) {
|
|
149
|
+
const cliStatus = this.compareVersions(current.cli, latest?.cli);
|
|
150
|
+
const statusIcon = cliStatus === 'current' ? 'β
' : cliStatus === 'outdated' ? 'π' : 'π';
|
|
151
|
+
console.log(`${statusIcon} CLI: v${current.cli}${latest?.cli && latest.cli !== current.cli ? ` (latest: v${latest.cli})` : ''}`);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (current?.framework) {
|
|
155
|
+
const frameworkStatus = this.compareVersions(current.framework, latest?.framework);
|
|
156
|
+
const statusIcon = frameworkStatus === 'current' ? 'β
' : frameworkStatus === 'outdated' ? 'π' : 'π';
|
|
157
|
+
console.log(`${statusIcon} Framework: v${current.framework}${latest?.framework && latest.framework !== current.framework ? ` (latest: v${latest.framework})` : ''}`);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
console.log('βββββββββββββββββββββββββββββββ\n');
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Singleton instance
|
|
165
|
+
const versionChecker = new VersionChecker();
|
|
166
|
+
|
|
167
|
+
export default versionChecker;
|