@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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +93 -70
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsonpages/cli",
3
- "version": "3.0.3",
3
+ "version": "3.0.5",
4
4
  "description": "JsonPages CLI - Sovereign Projection Engine",
5
5
  "type": "module",
6
6
  "bin": {
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 per rendere la CLI shippable
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.0');
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
- // πŸ” Logica Asset Interno:
42
- // Se l'utente non fornisce uno script, usa quello dentro packages/cli/assets/
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
- const scriptExists = await fs.pathExists(scriptPath);
47
- if (!scriptExists) {
48
- console.log(chalk.red(`❌ Error: Deterministic script not found at ${scriptPath}`));
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
- await execa('npm', ['create', 'vite@latest', '.', '--', '--template', 'react-ts'], execOpts(targetDir));
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 (Piazza pulita per il determinismo)
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 SRC (Node-only projection β€” no shell; Windows-compatible)
79
- spinner.start('Projecting source files (Node)...');
80
- const { fileCount } = await projectSrc(targetDir, scriptPath);
81
- spinner.succeed(`Source code and assets projected (${fileCount} files).`);
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 (Green Build Enforcement)
137
+ // 5. DEPENDENCY RESOLUTION
84
138
  spinner.start('Installing dependencies (this may take a minute)...');
85
139
 
86
- // 5a. Runtime Dependencies (Risolve Radix, CVA e Animations)
87
- await execa(
88
- 'npm',
89
- [
90
- 'install',
91
- 'react',
92
- 'react-dom',
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`);