vladx 1.0.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/bin/vladpm +9 -0
- package/bin/vladx +10 -0
- package/examples/esempio.vx +79 -0
- package/package.json +23 -0
- package/src/cli/cli.js +191 -0
- package/src/index.js +32 -0
- package/src/interpreter/interpreter.js +455 -0
- package/src/lexer/lexer.js +284 -0
- package/src/lexer/tokens.js +116 -0
- package/src/parser/ast.js +265 -0
- package/src/parser/parser.js +476 -0
- package/src/pm/cli.js +130 -0
- package/src/pm/commands/config.js +76 -0
- package/src/pm/commands/init.js +129 -0
- package/src/pm/commands/install.js +185 -0
- package/src/pm/commands/list.js +70 -0
- package/src/pm/commands/login.js +124 -0
- package/src/pm/commands/publish.js +115 -0
- package/src/pm/commands/search.js +55 -0
- package/src/pm/commands/uninstall.js +68 -0
- package/src/pm/utils/api.js +135 -0
- package/src/pm/utils/config.js +117 -0
- package/src/repl/repl.js +179 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VladPM - init command
|
|
3
|
+
* Inizializza un nuovo progetto VladX
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const readline = require('readline');
|
|
9
|
+
const { VLADX_JSON, saveVladxJson, saveVladxLock } = require('../utils/config.js');
|
|
10
|
+
|
|
11
|
+
const COLORS = {
|
|
12
|
+
reset: '\x1b[0m',
|
|
13
|
+
bright: '\x1b[1m',
|
|
14
|
+
green: '\x1b[32m',
|
|
15
|
+
cyan: '\x1b[36m',
|
|
16
|
+
yellow: '\x1b[33m'
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
function colorize(text, color) {
|
|
20
|
+
return `${COLORS[color]}${text}${COLORS.reset}`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function prompt(question) {
|
|
24
|
+
const rl = readline.createInterface({
|
|
25
|
+
input: process.stdin,
|
|
26
|
+
output: process.stdout
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
return new Promise(resolve => {
|
|
30
|
+
rl.question(question, answer => {
|
|
31
|
+
rl.close();
|
|
32
|
+
resolve(answer);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async function execute(args) {
|
|
38
|
+
const cwd = process.cwd();
|
|
39
|
+
const existingJson = path.join(cwd, VLADX_JSON);
|
|
40
|
+
|
|
41
|
+
if (fs.existsSync(existingJson) && !args.includes('-y') && !args.includes('--yes')) {
|
|
42
|
+
const overwrite = await prompt(colorize('vladx.json già esiste. Sovrascrivere? (s/N): ', 'yellow'));
|
|
43
|
+
if (overwrite.toLowerCase() !== 's' && overwrite.toLowerCase() !== 'si') {
|
|
44
|
+
console.log('Operazione annullata.');
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
console.log(colorize('\n📦 Inizializzazione nuovo progetto VladX\n', 'bright'));
|
|
50
|
+
|
|
51
|
+
let packageData;
|
|
52
|
+
|
|
53
|
+
if (args.includes('-y') || args.includes('--yes')) {
|
|
54
|
+
// Default values
|
|
55
|
+
const dirName = path.basename(cwd);
|
|
56
|
+
packageData = {
|
|
57
|
+
name: dirName,
|
|
58
|
+
version: '1.0.0',
|
|
59
|
+
description: '',
|
|
60
|
+
main: 'index.vx',
|
|
61
|
+
scripts: {
|
|
62
|
+
start: 'vladx index.vx',
|
|
63
|
+
test: 'vladx test.vx'
|
|
64
|
+
},
|
|
65
|
+
keywords: [],
|
|
66
|
+
author: '',
|
|
67
|
+
license: 'MIT',
|
|
68
|
+
dependencies: {}
|
|
69
|
+
};
|
|
70
|
+
} else {
|
|
71
|
+
const dirName = path.basename(cwd);
|
|
72
|
+
|
|
73
|
+
const name = await prompt(`Nome pacchetto: (${dirName}) `) || dirName;
|
|
74
|
+
const version = await prompt('Versione: (1.0.0) ') || '1.0.0';
|
|
75
|
+
const description = await prompt('Descrizione: ') || '';
|
|
76
|
+
const main = await prompt('Entry point: (index.vx) ') || 'index.vx';
|
|
77
|
+
const author = await prompt('Autore: ') || '';
|
|
78
|
+
const license = await prompt('Licenza: (MIT) ') || 'MIT';
|
|
79
|
+
const keywordsStr = await prompt('Keywords (separate da virgola): ') || '';
|
|
80
|
+
const keywords = keywordsStr ? keywordsStr.split(',').map(k => k.trim()).filter(k => k) : [];
|
|
81
|
+
|
|
82
|
+
packageData = {
|
|
83
|
+
name,
|
|
84
|
+
version,
|
|
85
|
+
description,
|
|
86
|
+
main,
|
|
87
|
+
scripts: {
|
|
88
|
+
start: `vladx ${main}`,
|
|
89
|
+
test: 'vladx test.vx'
|
|
90
|
+
},
|
|
91
|
+
keywords,
|
|
92
|
+
author,
|
|
93
|
+
license,
|
|
94
|
+
dependencies: {}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Save vladx.json
|
|
99
|
+
saveVladxJson(packageData);
|
|
100
|
+
console.log(colorize(`\n✓ Creato ${VLADX_JSON}`, 'green'));
|
|
101
|
+
|
|
102
|
+
// Create empty vladx-lock.json
|
|
103
|
+
saveVladxLock({
|
|
104
|
+
lockfileVersion: 1,
|
|
105
|
+
requires: true,
|
|
106
|
+
dependencies: {}
|
|
107
|
+
});
|
|
108
|
+
console.log(colorize('✓ Creato vladx-lock.json', 'green'));
|
|
109
|
+
|
|
110
|
+
// Create main file if it doesn't exist
|
|
111
|
+
const mainFile = path.join(cwd, packageData.main);
|
|
112
|
+
if (!fs.existsSync(mainFile)) {
|
|
113
|
+
fs.writeFileSync(mainFile, `// ${packageData.name} - Entry Point
|
|
114
|
+
// Scrivi il tuo codice VladX qui
|
|
115
|
+
|
|
116
|
+
stampa("Ciao da ${packageData.name}!");
|
|
117
|
+
`);
|
|
118
|
+
console.log(colorize(`✓ Creato ${packageData.main}`, 'green'));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
console.log(colorize('\n✨ Progetto inizializzato con successo!\n', 'cyan'));
|
|
122
|
+
console.log('Prossimi passi:');
|
|
123
|
+
console.log(` 1. Modifica ${colorize(packageData.main, 'bright')}`);
|
|
124
|
+
console.log(` 2. Esegui con ${colorize('vladx ' + packageData.main, 'bright')}`);
|
|
125
|
+
console.log(` 3. Pubblica con ${colorize('vladpm publish', 'bright')}`);
|
|
126
|
+
console.log();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
module.exports = { execute };
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VladPM - install command
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const zlib = require('zlib');
|
|
8
|
+
const api = require('../utils/api.js');
|
|
9
|
+
const {
|
|
10
|
+
getVladxJson,
|
|
11
|
+
saveVladxJson,
|
|
12
|
+
getVladxLock,
|
|
13
|
+
saveVladxLock,
|
|
14
|
+
ensureModulesDir,
|
|
15
|
+
getModulesDir
|
|
16
|
+
} = require('../utils/config.js');
|
|
17
|
+
|
|
18
|
+
const COLORS = {
|
|
19
|
+
reset: '\x1b[0m',
|
|
20
|
+
bright: '\x1b[1m',
|
|
21
|
+
green: '\x1b[32m',
|
|
22
|
+
red: '\x1b[31m',
|
|
23
|
+
cyan: '\x1b[36m',
|
|
24
|
+
yellow: '\x1b[33m',
|
|
25
|
+
dim: '\x1b[2m'
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
function colorize(text, color) {
|
|
29
|
+
return `${COLORS[color]}${text}${COLORS.reset}`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function installPackage(name, version = 'latest', save = true) {
|
|
33
|
+
console.log(colorize(` ⬇ ${name}${version !== 'latest' ? '@' + version : ''}`, 'dim'));
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
// Fetch package info
|
|
37
|
+
const result = await api.getPackage(name);
|
|
38
|
+
const pkg = result.data;
|
|
39
|
+
|
|
40
|
+
if (!pkg) {
|
|
41
|
+
throw new Error(`Pacchetto "${name}" non trovato`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Get version to install
|
|
45
|
+
const versionToInstall = version === 'latest'
|
|
46
|
+
? pkg.latestVersion || pkg.version
|
|
47
|
+
: version;
|
|
48
|
+
|
|
49
|
+
// Get package tarball
|
|
50
|
+
const versionData = await api.getPackageVersion(name, versionToInstall);
|
|
51
|
+
|
|
52
|
+
if (!versionData.data || !versionData.data.tarball) {
|
|
53
|
+
throw new Error(`Versione ${versionToInstall} non trovata per ${name}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Decompress tarball
|
|
57
|
+
const compressed = Buffer.from(versionData.data.tarball, 'base64');
|
|
58
|
+
const decompressed = zlib.gunzipSync(compressed);
|
|
59
|
+
const packageContent = JSON.parse(decompressed.toString());
|
|
60
|
+
|
|
61
|
+
// Create package directory
|
|
62
|
+
const modulesDir = ensureModulesDir();
|
|
63
|
+
const packageDir = path.join(modulesDir, name);
|
|
64
|
+
|
|
65
|
+
if (fs.existsSync(packageDir)) {
|
|
66
|
+
fs.rmSync(packageDir, { recursive: true });
|
|
67
|
+
}
|
|
68
|
+
fs.mkdirSync(packageDir, { recursive: true });
|
|
69
|
+
|
|
70
|
+
// Extract files
|
|
71
|
+
for (const file of packageContent.files || []) {
|
|
72
|
+
const filePath = path.join(packageDir, file.path);
|
|
73
|
+
const dirPath = path.dirname(filePath);
|
|
74
|
+
|
|
75
|
+
if (!fs.existsSync(dirPath)) {
|
|
76
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
fs.writeFileSync(filePath, file.content);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Create package vladx.json in module folder
|
|
83
|
+
const moduleVladx = {
|
|
84
|
+
name: packageContent.name,
|
|
85
|
+
version: packageContent.version,
|
|
86
|
+
description: packageContent.description,
|
|
87
|
+
main: packageContent.main,
|
|
88
|
+
dependencies: packageContent.dependencies
|
|
89
|
+
};
|
|
90
|
+
fs.writeFileSync(
|
|
91
|
+
path.join(packageDir, 'vladx.json'),
|
|
92
|
+
JSON.stringify(moduleVladx, null, 2)
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
// Update vladx.json if --save
|
|
96
|
+
if (save) {
|
|
97
|
+
const vladxJson = getVladxJson() || { dependencies: {} };
|
|
98
|
+
if (!vladxJson.dependencies) vladxJson.dependencies = {};
|
|
99
|
+
vladxJson.dependencies[name] = `^${versionToInstall}`;
|
|
100
|
+
saveVladxJson(vladxJson);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Update lock file
|
|
104
|
+
const lock = getVladxLock();
|
|
105
|
+
if (!lock.dependencies) lock.dependencies = {};
|
|
106
|
+
lock.dependencies[name] = {
|
|
107
|
+
version: versionToInstall,
|
|
108
|
+
resolved: `${name}@${versionToInstall}`,
|
|
109
|
+
integrity: Buffer.from(compressed).toString('base64').slice(0, 64)
|
|
110
|
+
};
|
|
111
|
+
saveVladxLock(lock);
|
|
112
|
+
|
|
113
|
+
console.log(colorize(` ✓ ${name}@${versionToInstall}`, 'green'));
|
|
114
|
+
|
|
115
|
+
// Install dependencies
|
|
116
|
+
if (packageContent.dependencies) {
|
|
117
|
+
for (const [depName, depVersion] of Object.entries(packageContent.dependencies)) {
|
|
118
|
+
await installPackage(depName, depVersion.replace(/[\^~]/, ''), false);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return { name, version: versionToInstall };
|
|
123
|
+
} catch (error) {
|
|
124
|
+
console.log(colorize(` ✗ ${name}: ${error.message}`, 'red'));
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async function execute(args) {
|
|
130
|
+
console.log(colorize('\n📦 Installazione pacchetti\n', 'bright'));
|
|
131
|
+
|
|
132
|
+
if (args.length === 0) {
|
|
133
|
+
// Install all from vladx.json
|
|
134
|
+
const vladxJson = getVladxJson();
|
|
135
|
+
if (!vladxJson) {
|
|
136
|
+
console.log(colorize('✗ vladx.json non trovato.', 'red'));
|
|
137
|
+
console.log(`Usa ${colorize('vladpm init', 'bright')} per inizializzare.`);
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const deps = vladxJson.dependencies || {};
|
|
142
|
+
const depCount = Object.keys(deps).length;
|
|
143
|
+
|
|
144
|
+
if (depCount === 0) {
|
|
145
|
+
console.log('Nessuna dipendenza da installare.');
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
console.log(`Installazione di ${depCount} dipendenze...\n`);
|
|
150
|
+
|
|
151
|
+
let installed = 0;
|
|
152
|
+
let failed = 0;
|
|
153
|
+
|
|
154
|
+
for (const [name, version] of Object.entries(deps)) {
|
|
155
|
+
try {
|
|
156
|
+
await installPackage(name, version.replace(/[\^~]/, ''), false);
|
|
157
|
+
installed++;
|
|
158
|
+
} catch (e) {
|
|
159
|
+
failed++;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
console.log(`\n${colorize(`✓ ${installed} pacchetti installati`, 'green')}`);
|
|
164
|
+
if (failed > 0) {
|
|
165
|
+
console.log(colorize(`✗ ${failed} pacchetti falliti`, 'red'));
|
|
166
|
+
}
|
|
167
|
+
} else {
|
|
168
|
+
// Install specific packages
|
|
169
|
+
const saveDev = args.includes('--save-dev') || args.includes('-D');
|
|
170
|
+
const packages = args.filter(a => !a.startsWith('-'));
|
|
171
|
+
|
|
172
|
+
for (const pkg of packages) {
|
|
173
|
+
const [name, version] = pkg.split('@');
|
|
174
|
+
try {
|
|
175
|
+
await installPackage(name, version || 'latest', true);
|
|
176
|
+
} catch (e) {
|
|
177
|
+
// Error already logged
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
console.log();
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
module.exports = { execute, installPackage };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VladPM - list command
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const { getVladxJson, getModulesDir } = require('../utils/config.js');
|
|
8
|
+
|
|
9
|
+
const COLORS = {
|
|
10
|
+
reset: '\x1b[0m',
|
|
11
|
+
bright: '\x1b[1m',
|
|
12
|
+
green: '\x1b[32m',
|
|
13
|
+
cyan: '\x1b[36m',
|
|
14
|
+
dim: '\x1b[2m',
|
|
15
|
+
yellow: '\x1b[33m'
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
function colorize(text, color) {
|
|
19
|
+
return `${COLORS[color]}${text}${COLORS.reset}`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function execute(args) {
|
|
23
|
+
const modulesDir = getModulesDir();
|
|
24
|
+
const vladxJson = getVladxJson();
|
|
25
|
+
|
|
26
|
+
console.log(colorize('\n📦 Pacchetti installati\n', 'bright'));
|
|
27
|
+
|
|
28
|
+
if (!fs.existsSync(modulesDir)) {
|
|
29
|
+
console.log(colorize('Nessun pacchetto installato.', 'dim'));
|
|
30
|
+
console.log(`Usa ${colorize('vladpm install <pacchetto>', 'bright')} per installare.\n`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const packages = fs.readdirSync(modulesDir, { withFileTypes: true })
|
|
35
|
+
.filter(d => d.isDirectory())
|
|
36
|
+
.map(d => d.name);
|
|
37
|
+
|
|
38
|
+
if (packages.length === 0) {
|
|
39
|
+
console.log(colorize('Nessun pacchetto installato.', 'dim'));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const deps = vladxJson?.dependencies || {};
|
|
44
|
+
|
|
45
|
+
for (const name of packages) {
|
|
46
|
+
const pkgPath = path.join(modulesDir, name, 'vladx.json');
|
|
47
|
+
let version = '?';
|
|
48
|
+
let description = '';
|
|
49
|
+
|
|
50
|
+
if (fs.existsSync(pkgPath)) {
|
|
51
|
+
try {
|
|
52
|
+
const pkgJson = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
53
|
+
version = pkgJson.version || '?';
|
|
54
|
+
description = pkgJson.description || '';
|
|
55
|
+
} catch (e) {
|
|
56
|
+
// Ignore
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const inDeps = deps[name] ? colorize(' (dipendenza)', 'dim') : '';
|
|
61
|
+
console.log(` ${colorize(name, 'cyan')}@${version}${inDeps}`);
|
|
62
|
+
if (description && args.includes('-l')) {
|
|
63
|
+
console.log(colorize(` ${description}`, 'dim'));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
console.log(colorize(`\nTotale: ${packages.length} pacchetti\n`, 'dim'));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
module.exports = { execute };
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VladPM - login command
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const readline = require('readline');
|
|
6
|
+
const api = require('../utils/api.js');
|
|
7
|
+
const { setToken, clearToken, getConfig, getRegistry } = require('../utils/config.js');
|
|
8
|
+
|
|
9
|
+
const COLORS = {
|
|
10
|
+
reset: '\x1b[0m',
|
|
11
|
+
bright: '\x1b[1m',
|
|
12
|
+
green: '\x1b[32m',
|
|
13
|
+
red: '\x1b[31m',
|
|
14
|
+
cyan: '\x1b[36m',
|
|
15
|
+
yellow: '\x1b[33m'
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
function colorize(text, color) {
|
|
19
|
+
return `${COLORS[color]}${text}${COLORS.reset}`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function prompt(question, hidden = false) {
|
|
23
|
+
return new Promise(resolve => {
|
|
24
|
+
const rl = readline.createInterface({
|
|
25
|
+
input: process.stdin,
|
|
26
|
+
output: process.stdout
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
if (hidden) {
|
|
30
|
+
process.stdout.write(question);
|
|
31
|
+
const stdin = process.stdin;
|
|
32
|
+
stdin.setRawMode(true);
|
|
33
|
+
stdin.resume();
|
|
34
|
+
stdin.setEncoding('utf8');
|
|
35
|
+
|
|
36
|
+
let password = '';
|
|
37
|
+
const handler = (char) => {
|
|
38
|
+
if (char === '\n' || char === '\r' || char === '\u0004') {
|
|
39
|
+
stdin.setRawMode(false);
|
|
40
|
+
stdin.removeListener('data', handler);
|
|
41
|
+
console.log();
|
|
42
|
+
rl.close();
|
|
43
|
+
resolve(password);
|
|
44
|
+
} else if (char === '\u0003') {
|
|
45
|
+
process.exit();
|
|
46
|
+
} else if (char === '\u007F' || char === '\b') {
|
|
47
|
+
if (password.length > 0) {
|
|
48
|
+
password = password.slice(0, -1);
|
|
49
|
+
process.stdout.write('\b \b');
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
password += char;
|
|
53
|
+
process.stdout.write('*');
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
stdin.on('data', handler);
|
|
57
|
+
} else {
|
|
58
|
+
rl.question(question, answer => {
|
|
59
|
+
rl.close();
|
|
60
|
+
resolve(answer);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async function execute(args) {
|
|
67
|
+
console.log(colorize('\n🔐 Login a VladPM Registry\n', 'bright'));
|
|
68
|
+
console.log(`Registry: ${colorize(getRegistry(), 'cyan')}\n`);
|
|
69
|
+
|
|
70
|
+
const isRegister = args.includes('--register') || args.includes('-r');
|
|
71
|
+
|
|
72
|
+
if (isRegister) {
|
|
73
|
+
// Registration flow
|
|
74
|
+
const username = await prompt('Username: ');
|
|
75
|
+
const email = await prompt('Email: ');
|
|
76
|
+
const password = await prompt('Password: ', true);
|
|
77
|
+
const confirmPassword = await prompt('Conferma Password: ', true);
|
|
78
|
+
|
|
79
|
+
if (password !== confirmPassword) {
|
|
80
|
+
console.log(colorize('\n✗ Le password non corrispondono', 'red'));
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
const result = await api.register(username, email, password);
|
|
86
|
+
console.log(colorize(`\n✓ Registrazione completata! Benvenuto ${username}`, 'green'));
|
|
87
|
+
|
|
88
|
+
// Auto-login after registration
|
|
89
|
+
const loginResult = await api.login(username, password);
|
|
90
|
+
setToken(loginResult.data.token, username);
|
|
91
|
+
console.log(colorize('✓ Login automatico eseguito', 'green'));
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.log(colorize(`\n✗ Registrazione fallita: ${error.message}`, 'red'));
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
} else {
|
|
97
|
+
// Login flow
|
|
98
|
+
const username = await prompt('Username: ');
|
|
99
|
+
const password = await prompt('Password: ', true);
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
const result = await api.login(username, password);
|
|
103
|
+
setToken(result.data.token, username);
|
|
104
|
+
console.log(colorize(`\n✓ Login effettuato come ${username}`, 'green'));
|
|
105
|
+
} catch (error) {
|
|
106
|
+
console.log(colorize(`\n✗ Login fallito: ${error.message}`, 'red'));
|
|
107
|
+
console.log(`\nNon hai un account? Usa ${colorize('vladpm login --register', 'bright')}`);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async function logout() {
|
|
114
|
+
const config = getConfig();
|
|
115
|
+
if (config.token) {
|
|
116
|
+
const username = config.username || 'utente';
|
|
117
|
+
clearToken();
|
|
118
|
+
console.log(colorize(`✓ Logout effettuato (${username})`, 'green'));
|
|
119
|
+
} else {
|
|
120
|
+
console.log(colorize('Non sei loggato.', 'yellow'));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
module.exports = { execute, logout };
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VladPM - publish command
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const zlib = require('zlib');
|
|
8
|
+
const api = require('../utils/api.js');
|
|
9
|
+
const { getVladxJson, getToken } = require('../utils/config.js');
|
|
10
|
+
|
|
11
|
+
const COLORS = {
|
|
12
|
+
reset: '\x1b[0m',
|
|
13
|
+
bright: '\x1b[1m',
|
|
14
|
+
green: '\x1b[32m',
|
|
15
|
+
red: '\x1b[31m',
|
|
16
|
+
cyan: '\x1b[36m',
|
|
17
|
+
yellow: '\x1b[33m'
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
function colorize(text, color) {
|
|
21
|
+
return `${COLORS[color]}${text}${COLORS.reset}`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getAllFiles(dir, baseDir = dir, files = []) {
|
|
25
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
26
|
+
|
|
27
|
+
for (const entry of entries) {
|
|
28
|
+
const fullPath = path.join(dir, entry.name);
|
|
29
|
+
const relativePath = path.relative(baseDir, fullPath);
|
|
30
|
+
|
|
31
|
+
// Skip node_modules, vladx_modules, and hidden files
|
|
32
|
+
if (entry.name.startsWith('.') ||
|
|
33
|
+
entry.name === 'node_modules' ||
|
|
34
|
+
entry.name === 'vladx_modules') {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (entry.isDirectory()) {
|
|
39
|
+
getAllFiles(fullPath, baseDir, files);
|
|
40
|
+
} else {
|
|
41
|
+
files.push({
|
|
42
|
+
path: relativePath,
|
|
43
|
+
content: fs.readFileSync(fullPath, 'utf8')
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return files;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function execute(args) {
|
|
52
|
+
console.log(colorize('\n📦 Pubblicazione pacchetto\n', 'bright'));
|
|
53
|
+
|
|
54
|
+
// Check if logged in
|
|
55
|
+
const token = getToken();
|
|
56
|
+
if (!token) {
|
|
57
|
+
console.log(colorize('✗ Devi effettuare il login prima di pubblicare.', 'red'));
|
|
58
|
+
console.log(`Usa ${colorize('vladpm login', 'bright')} per accedere.`);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Read vladx.json
|
|
63
|
+
const vladxJson = getVladxJson();
|
|
64
|
+
if (!vladxJson) {
|
|
65
|
+
console.log(colorize('✗ vladx.json non trovato.', 'red'));
|
|
66
|
+
console.log(`Usa ${colorize('vladpm init', 'bright')} per inizializzare il progetto.`);
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
console.log(`Nome: ${colorize(vladxJson.name, 'cyan')}`);
|
|
71
|
+
console.log(`Versione: ${colorize(vladxJson.version, 'cyan')}`);
|
|
72
|
+
|
|
73
|
+
// Collect all files
|
|
74
|
+
const files = getAllFiles(process.cwd());
|
|
75
|
+
console.log(`File: ${files.length}`);
|
|
76
|
+
|
|
77
|
+
// Create package data
|
|
78
|
+
const packageData = {
|
|
79
|
+
name: vladxJson.name,
|
|
80
|
+
version: vladxJson.version,
|
|
81
|
+
description: vladxJson.description || '',
|
|
82
|
+
main: vladxJson.main || 'index.vx',
|
|
83
|
+
keywords: vladxJson.keywords || [],
|
|
84
|
+
author: vladxJson.author || '',
|
|
85
|
+
license: vladxJson.license || 'MIT',
|
|
86
|
+
dependencies: vladxJson.dependencies || {},
|
|
87
|
+
files: files
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// Compress
|
|
91
|
+
const compressed = zlib.gzipSync(JSON.stringify(packageData));
|
|
92
|
+
const base64Data = compressed.toString('base64');
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
console.log('\nPubblicazione in corso...');
|
|
96
|
+
await api.publishPackage({
|
|
97
|
+
name: vladxJson.name,
|
|
98
|
+
version: vladxJson.version,
|
|
99
|
+
description: vladxJson.description,
|
|
100
|
+
main: vladxJson.main,
|
|
101
|
+
keywords: vladxJson.keywords,
|
|
102
|
+
author: vladxJson.author,
|
|
103
|
+
license: vladxJson.license,
|
|
104
|
+
dependencies: vladxJson.dependencies,
|
|
105
|
+
tarball: base64Data
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
console.log(colorize(`\n✓ Pubblicato ${vladxJson.name}@${vladxJson.version}`, 'green'));
|
|
109
|
+
} catch (error) {
|
|
110
|
+
console.log(colorize(`\n✗ Pubblicazione fallita: ${error.message}`, 'red'));
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
module.exports = { execute };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VladPM - search command
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const api = require('../utils/api.js');
|
|
6
|
+
|
|
7
|
+
const COLORS = {
|
|
8
|
+
reset: '\x1b[0m',
|
|
9
|
+
bright: '\x1b[1m',
|
|
10
|
+
green: '\x1b[32m',
|
|
11
|
+
red: '\x1b[31m',
|
|
12
|
+
cyan: '\x1b[36m',
|
|
13
|
+
dim: '\x1b[2m'
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
function colorize(text, color) {
|
|
17
|
+
return `${COLORS[color]}${text}${COLORS.reset}`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function execute(args) {
|
|
21
|
+
const query = args.filter(a => !a.startsWith('-')).join(' ');
|
|
22
|
+
|
|
23
|
+
if (!query) {
|
|
24
|
+
console.log(colorize('✗ Specificare una query di ricerca.', 'red'));
|
|
25
|
+
console.log('Uso: vladpm search <query>');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
console.log(colorize(`\n🔍 Ricerca: "${query}"\n`, 'bright'));
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
const result = await api.searchPackages(query);
|
|
33
|
+
const packages = result.data.packages || result.data || [];
|
|
34
|
+
|
|
35
|
+
if (packages.length === 0) {
|
|
36
|
+
console.log(colorize('Nessun pacchetto trovato.', 'dim'));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
console.log(`Trovati ${packages.length} pacchetti:\n`);
|
|
41
|
+
|
|
42
|
+
for (const pkg of packages) {
|
|
43
|
+
console.log(`${colorize(pkg.name, 'cyan')}@${pkg.version || pkg.latestVersion}`);
|
|
44
|
+
if (pkg.description) {
|
|
45
|
+
console.log(colorize(` ${pkg.description}`, 'dim'));
|
|
46
|
+
}
|
|
47
|
+
console.log();
|
|
48
|
+
}
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.log(colorize(`✗ Ricerca fallita: ${error.message}`, 'red'));
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
module.exports = { execute };
|