@jsonpages/cli 3.0.3 β 3.0.5
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/package.json +1 -1
- package/src/index.js +93 -70
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -6,24 +6,74 @@ import path from 'path';
|
|
|
6
6
|
import { execa } from 'execa';
|
|
7
7
|
import ora from 'ora';
|
|
8
8
|
import { fileURLToPath } from 'url';
|
|
9
|
-
import { projectSrc } from './projection.js';
|
|
10
9
|
|
|
11
|
-
// π‘οΈ Risoluzione path
|
|
10
|
+
// π‘οΈ Risoluzione path ESM
|
|
12
11
|
const __filename = fileURLToPath(import.meta.url);
|
|
13
12
|
const __dirname = path.dirname(__filename);
|
|
14
13
|
|
|
15
|
-
/** Cross-platform: on Windows, npm/yalc are .cmd; execa needs shell to resolve them. */
|
|
16
|
-
const execOpts = (cwd) => ({
|
|
17
|
-
cwd,
|
|
18
|
-
...(process.platform === 'win32' && { shell: true }),
|
|
19
|
-
});
|
|
20
|
-
|
|
21
14
|
const program = new Command();
|
|
22
15
|
|
|
23
16
|
program
|
|
24
17
|
.name('jsonpages')
|
|
25
18
|
.description('JsonPages CLI - Sovereign Projection Engine')
|
|
26
|
-
.version('2.2
|
|
19
|
+
.version('2.0.2'); // Bump version
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* π§ THE UNIVERSAL INTERPRETER
|
|
23
|
+
* Legge lo script bash "DNA" e lo esegue usando le API di Node.js.
|
|
24
|
+
* Rende la CLI compatibile con Windows (PowerShell/CMD) senza bisogno di Bash.
|
|
25
|
+
*/
|
|
26
|
+
async function processScriptInNode(scriptPath, targetDir) {
|
|
27
|
+
const content = await fs.readFile(scriptPath, 'utf-8');
|
|
28
|
+
const lines = content.split('\n');
|
|
29
|
+
|
|
30
|
+
let captureMode = false;
|
|
31
|
+
let delimiter = '';
|
|
32
|
+
let currentFile = '';
|
|
33
|
+
let fileBuffer = [];
|
|
34
|
+
|
|
35
|
+
for (const line of lines) {
|
|
36
|
+
const trimmed = line.trim();
|
|
37
|
+
|
|
38
|
+
// 1. ModalitΓ Cattura (Siamo dentro un cat << 'DELIMITER')
|
|
39
|
+
if (captureMode) {
|
|
40
|
+
if (trimmed === delimiter) {
|
|
41
|
+
// Fine del blocco: Scriviamo su disco
|
|
42
|
+
const filePath = path.join(targetDir, currentFile);
|
|
43
|
+
await fs.outputFile(filePath, fileBuffer.join('\n'));
|
|
44
|
+
captureMode = false;
|
|
45
|
+
fileBuffer = [];
|
|
46
|
+
} else {
|
|
47
|
+
fileBuffer.push(line); // Preserva l'indentazione originale
|
|
48
|
+
}
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 2. Parsing Comandi Bash -> Node Operations
|
|
53
|
+
|
|
54
|
+
// Rileva: mkdir -p "path"
|
|
55
|
+
if (trimmed.startsWith('mkdir -p')) {
|
|
56
|
+
const match = trimmed.match(/"([^"]+)"/) || trimmed.match(/\s+([^\s]+)/);
|
|
57
|
+
// Supporta sia mkdir -p "foo/bar" che mkdir -p foo/bar
|
|
58
|
+
const dirPath = match ? match[1].replace(/"/g, '') : null;
|
|
59
|
+
if (dirPath) {
|
|
60
|
+
await fs.ensureDir(path.join(targetDir, dirPath));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Rileva: cat << 'DELIMITER' > "path"
|
|
65
|
+
else if (trimmed.startsWith('cat <<')) {
|
|
66
|
+
// Regex robusta per catturare il delimitatore e il path del file
|
|
67
|
+
const match = trimmed.match(/<<\s*'([^']+)'\s*>\s*"([^"]+)"/);
|
|
68
|
+
if (match) {
|
|
69
|
+
delimiter = match[1];
|
|
70
|
+
currentFile = match[2];
|
|
71
|
+
captureMode = true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Ignora echo, set -e, commenti #, ecc.
|
|
75
|
+
}
|
|
76
|
+
}
|
|
27
77
|
|
|
28
78
|
program
|
|
29
79
|
.command('new')
|
|
@@ -38,15 +88,14 @@ program
|
|
|
38
88
|
|
|
39
89
|
const targetDir = path.join(process.cwd(), name);
|
|
40
90
|
|
|
41
|
-
// π
|
|
42
|
-
//
|
|
91
|
+
// π Asset Resolution
|
|
92
|
+
// Cerca lo script nella cartella assets installata col pacchetto
|
|
43
93
|
const defaultScriptPath = path.resolve(__dirname, '../assets/src_tenant_alpha.sh');
|
|
44
94
|
const scriptPath = options.script ? path.resolve(process.cwd(), options.script) : defaultScriptPath;
|
|
45
95
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
console.log(chalk.
|
|
49
|
-
console.log(chalk.yellow(`Expected internal asset at: ${defaultScriptPath}`));
|
|
96
|
+
if (!fs.existsSync(scriptPath)) {
|
|
97
|
+
console.log(chalk.red(`β Error: DNA script not found at ${scriptPath}`));
|
|
98
|
+
console.log(chalk.yellow(`Debug info: __dirname is ${__dirname}`));
|
|
50
99
|
return;
|
|
51
100
|
}
|
|
52
101
|
|
|
@@ -57,10 +106,14 @@ program
|
|
|
57
106
|
// 1. SCAFFOLDING INFRA
|
|
58
107
|
spinner.start('Setting up environment (Vite + TS)...');
|
|
59
108
|
await fs.ensureDir(targetDir);
|
|
60
|
-
|
|
109
|
+
|
|
110
|
+
// Windows fix: npm.cmd invece di npm
|
|
111
|
+
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
112
|
+
|
|
113
|
+
await execa(npmCmd, ['create', 'vite@latest', '.', '--', '--template', 'react-ts'], { cwd: targetDir });
|
|
61
114
|
spinner.succeed('Environment scaffolded.');
|
|
62
115
|
|
|
63
|
-
// 2. CLEANUP
|
|
116
|
+
// 2. CLEANUP
|
|
64
117
|
spinner.start('Wiping default boilerplate...');
|
|
65
118
|
await fs.emptyDir(path.join(targetDir, 'src'));
|
|
66
119
|
const junk = ['App.css', 'App.tsx', 'main.tsx', 'vite-env.d.ts', 'favicon.ico', 'index.html'];
|
|
@@ -75,65 +128,35 @@ program
|
|
|
75
128
|
await injectInfraFiles(targetDir, name);
|
|
76
129
|
spinner.succeed('Infrastructure configured.');
|
|
77
130
|
|
|
78
|
-
// 4. DETERMINISTIC
|
|
79
|
-
spinner.start('
|
|
80
|
-
|
|
81
|
-
|
|
131
|
+
// 4. DETERMINISTIC PROJECTION (Node-based Interpreter)
|
|
132
|
+
spinner.start('Executing deterministic src projection...');
|
|
133
|
+
// Invece di execa('./script.sh'), usiamo il nostro interprete
|
|
134
|
+
await processScriptInNode(scriptPath, targetDir);
|
|
135
|
+
spinner.succeed('Source code and assets projected successfully.');
|
|
82
136
|
|
|
83
|
-
// 5. DEPENDENCY RESOLUTION
|
|
137
|
+
// 5. DEPENDENCY RESOLUTION
|
|
84
138
|
spinner.start('Installing dependencies (this may take a minute)...');
|
|
85
139
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
'
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
'zod',
|
|
94
|
-
'react-router-dom',
|
|
95
|
-
'lucide-react',
|
|
96
|
-
'radix-ui',
|
|
97
|
-
'@base-ui/react',
|
|
98
|
-
'class-variance-authority',
|
|
99
|
-
'tailwind-merge',
|
|
100
|
-
'clsx',
|
|
101
|
-
'tw-animate-css',
|
|
102
|
-
'file-saver',
|
|
103
|
-
'jszip',
|
|
104
|
-
],
|
|
105
|
-
execOpts(targetDir)
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
// 5b. Dev Dependencies
|
|
109
|
-
await execa(
|
|
110
|
-
'npm',
|
|
111
|
-
[
|
|
112
|
-
'install',
|
|
113
|
-
'-D',
|
|
114
|
-
'vite',
|
|
115
|
-
'@vitejs/plugin-react',
|
|
116
|
-
'typescript',
|
|
117
|
-
'@tailwindcss/vite',
|
|
118
|
-
'tailwindcss',
|
|
119
|
-
'@types/node',
|
|
120
|
-
'@types/react',
|
|
121
|
-
'@types/react-dom',
|
|
122
|
-
'@types/file-saver',
|
|
123
|
-
],
|
|
124
|
-
execOpts(targetDir)
|
|
125
|
-
);
|
|
126
|
-
|
|
127
|
-
// 5c. Linking Core via yalc
|
|
128
|
-
spinner.text = 'Linking @jsonpages/core via yalc...';
|
|
129
|
-
try {
|
|
130
|
-
await execa('yalc', ['add', '@jsonpages/core'], execOpts(targetDir));
|
|
131
|
-
} catch (e) {
|
|
132
|
-
spinner.warn(chalk.yellow('Yalc link failed. Ensure "@jsonpages/core" is published in yalc.'));
|
|
133
|
-
}
|
|
140
|
+
const deps = [
|
|
141
|
+
'react', 'react-dom', 'zod', 'react-router-dom',
|
|
142
|
+
'lucide-react', 'radix-ui',
|
|
143
|
+
'tailwind-merge', 'clsx',
|
|
144
|
+
'file-saver', 'jszip',
|
|
145
|
+
'@jsonpages/core@^1.0.0',
|
|
146
|
+
];
|
|
134
147
|
|
|
148
|
+
const devDeps = [
|
|
149
|
+
'vite', '@vitejs/plugin-react', 'typescript',
|
|
150
|
+
'@tailwindcss/vite', 'tailwindcss',
|
|
151
|
+
'@types/node', '@types/react', '@types/react-dom', '@types/file-saver'
|
|
152
|
+
];
|
|
153
|
+
|
|
154
|
+
await execa(npmCmd, ['install', ...deps], { cwd: targetDir });
|
|
155
|
+
await execa(npmCmd, ['install', '-D', ...devDeps], { cwd: targetDir });
|
|
156
|
+
|
|
135
157
|
spinner.succeed(chalk.green.bold('β¨ Tenant Ready!'));
|
|
136
158
|
|
|
159
|
+
console.log(chalk.gray(' (Ensure @jsonpages/core is published: npm view @jsonpages/core)'));
|
|
137
160
|
console.log(`\n${chalk.white.bgBlue(' NEXT STEPS ')}`);
|
|
138
161
|
console.log(` ${chalk.cyan(`cd ${name}`)}`);
|
|
139
162
|
console.log(` ${chalk.cyan(`npm run dev`)} <- Start development`);
|