@jsonpages/cli 3.0.77 → 3.0.81

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/src/index.js DELETED
@@ -1,224 +0,0 @@
1
- #!/usr/bin/env node
2
- import { Command } from 'commander';
3
- import chalk from 'chalk';
4
- import fs from 'fs-extra';
5
- import path from 'path';
6
- import { execa } from 'execa';
7
- import ora from 'ora';
8
- import { fileURLToPath } from 'url';
9
-
10
- const __filename = fileURLToPath(import.meta.url);
11
- const __dirname = path.dirname(__filename);
12
- const CLI_ASSETS_DIR = path.resolve(__dirname, '../assets');
13
- const TEMPLATES_DIR = path.join(CLI_ASSETS_DIR, 'templates');
14
- const LEGACY_ALPHA_DNA_PATH = path.join(CLI_ASSETS_DIR, 'src_tenant_alpha.sh');
15
-
16
- const program = new Command();
17
-
18
- program
19
- .name('jsonpages')
20
- .description('JsonPages CLI - Sovereign Projection Engine')
21
- .version('2.0.2');
22
-
23
- async function processScriptInNode(scriptPath, targetDir) {
24
- const content = await fs.readFile(scriptPath, 'utf-8');
25
- const lines = content.split('\n');
26
-
27
- let captureMode = false;
28
- let delimiter = '';
29
- let currentFile = '';
30
- let fileBuffer = [];
31
-
32
- for (const line of lines) {
33
- const trimmed = line.trim();
34
-
35
- if (captureMode) {
36
- if (trimmed === delimiter) {
37
- const filePath = path.join(targetDir, currentFile);
38
- await fs.outputFile(filePath, fileBuffer.join('\n'));
39
- captureMode = false;
40
- fileBuffer = [];
41
- } else {
42
- fileBuffer.push(line);
43
- }
44
- continue;
45
- }
46
-
47
- if (trimmed.startsWith('mkdir -p')) {
48
- const match = trimmed.match(/"([^"]+)"/) || trimmed.match(/\s+([^\s]+)/);
49
- const dirPath = match ? match[1].replace(/"/g, '') : null;
50
- if (dirPath) {
51
- await fs.ensureDir(path.join(targetDir, dirPath));
52
- }
53
- } else if (trimmed.startsWith('cat <<')) {
54
- const match = trimmed.match(/<<\s*'([^']+)'\s*>\s*"([^"]+)"/);
55
- if (match) {
56
- delimiter = match[1];
57
- currentFile = match[2];
58
- captureMode = true;
59
- }
60
- }
61
- }
62
- }
63
-
64
- function getAvailableTemplates() {
65
- if (!fs.existsSync(TEMPLATES_DIR)) return [];
66
- return fs
67
- .readdirSync(TEMPLATES_DIR, { withFileTypes: true })
68
- .filter((entry) => entry.isDirectory())
69
- .map((entry) => entry.name)
70
- .filter((name) => fs.existsSync(path.join(TEMPLATES_DIR, name, 'src_tenant.sh')))
71
- .sort((a, b) => a.localeCompare(b));
72
- }
73
-
74
- function resolveTemplateScriptPath(templateName) {
75
- const templatePath = path.join(TEMPLATES_DIR, templateName, 'src_tenant.sh');
76
- if (fs.existsSync(templatePath)) return templatePath;
77
- if (templateName === 'alpha' && fs.existsSync(LEGACY_ALPHA_DNA_PATH)) return LEGACY_ALPHA_DNA_PATH;
78
- return templatePath;
79
- }
80
-
81
- program
82
- .command('new')
83
- .argument('<type>', 'Type of artifact (tenant)')
84
- .argument('<name>', 'Name of the new tenant')
85
- .option('--template <name>', 'Template profile (default: alpha)', 'alpha')
86
- .option('--agritourism', 'Alias for --template agritourism')
87
- .option('--script <path>', 'Override default deterministic script path')
88
- .action(async (type, name, options) => {
89
- if (type !== 'tenant') {
90
- console.log(chalk.red('Error: Only "tenant" type is supported.'));
91
- return;
92
- }
93
-
94
- const targetDir = path.join(process.cwd(), name);
95
- const availableTemplates = getAvailableTemplates();
96
- const template = options.agritourism ? 'agritourism' : options.template;
97
- const scriptPath = options.script
98
- ? path.resolve(process.cwd(), options.script)
99
- : resolveTemplateScriptPath(template);
100
-
101
- if (!options.script && !availableTemplates.includes(template) && !(template === 'alpha' && fs.existsSync(LEGACY_ALPHA_DNA_PATH))) {
102
- console.log(chalk.red(`Error: Unknown template "${template}".`));
103
- console.log(chalk.yellow(`Available templates: ${availableTemplates.length ? availableTemplates.join(', ') : '(none found)'}`));
104
- return;
105
- }
106
-
107
- if (!fs.existsSync(scriptPath)) {
108
- console.log(chalk.red(`Error: DNA script not found at ${scriptPath}`));
109
- console.log(chalk.yellow(`Debug info: template=${template}, assets=${CLI_ASSETS_DIR}`));
110
- return;
111
- }
112
-
113
- console.log(chalk.blue.bold(`\nProjecting Sovereign Tenant: ${name} (template: ${template})\n`));
114
- const spinner = ora();
115
-
116
- try {
117
- spinner.start('Setting up environment (Vite + TS)...');
118
- await fs.ensureDir(targetDir);
119
-
120
- const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
121
- await execa(npmCmd, ['create', 'vite@latest', '.', '--', '--template', 'react-ts'], { cwd: targetDir });
122
- spinner.succeed('Environment scaffolded.');
123
-
124
- spinner.start('Wiping default boilerplate...');
125
- await fs.emptyDir(path.join(targetDir, 'src'));
126
- const junk = ['App.css', 'App.tsx', 'main.tsx', 'vite-env.d.ts', 'favicon.ico', 'index.html'];
127
- for (const file of junk) {
128
- await fs.remove(path.join(targetDir, file)).catch(() => {});
129
- await fs.remove(path.join(targetDir, 'src', file)).catch(() => {});
130
- }
131
- spinner.succeed('Clean slate achieved.');
132
-
133
- spinner.start('Injecting Sovereign Configurations...');
134
- await injectInfraFiles(targetDir, name);
135
- spinner.succeed('Infrastructure configured.');
136
-
137
- spinner.start('Executing deterministic src projection...');
138
- await processScriptInNode(scriptPath, targetDir);
139
- spinner.succeed('Source code and assets projected successfully.');
140
-
141
- spinner.start('Installing dependencies (this may take a minute)...');
142
- await execa(npmCmd, ['install'], { cwd: targetDir });
143
- spinner.succeed(chalk.green.bold('Tenant Ready.'));
144
-
145
- console.log(`\n${chalk.white.bgBlue(' NEXT STEPS ')}`);
146
- console.log(` ${chalk.cyan(`cd ${name}`)}`);
147
- console.log(` ${chalk.cyan('npm run dev')} <- Start development`);
148
- console.log(` ${chalk.cyan('npm run build')} <- Validate Green Build`);
149
- console.log(`\nTemplate used: ${template}\n`);
150
- } catch (error) {
151
- spinner.fail(chalk.red('Projection failed.'));
152
- console.error(error);
153
- }
154
- });
155
-
156
- async function injectInfraFiles(targetDir, name) {
157
- const pkg = {
158
- name,
159
- private: true,
160
- version: '1.0.0',
161
- type: 'module',
162
- scripts: {
163
- dev: 'vite',
164
- build: 'tsc && vite build',
165
- preview: 'vite preview',
166
- },
167
- };
168
- await fs.writeJson(path.join(targetDir, 'package.json'), pkg, { spaces: 2 });
169
-
170
- await fs.ensureDir(path.join(targetDir, 'public', 'assets', 'images'));
171
- await fs.ensureDir(path.join(targetDir, 'src', 'data', 'config'));
172
- await fs.ensureDir(path.join(targetDir, 'src', 'data', 'pages'));
173
-
174
- const tsConfig = `
175
- {
176
- "compilerOptions": {
177
- "target": "ES2020",
178
- "useDefineForClassFields": true,
179
- "lib": ["ES2020", "DOM", "DOM.Iterable"],
180
- "module": "ESNext",
181
- "skipLibCheck": true,
182
- "moduleResolution": "bundler",
183
- "allowImportingTsExtensions": true,
184
- "resolveJsonModule": true,
185
- "isolatedModules": true,
186
- "noEmit": true,
187
- "jsx": "react-jsx",
188
- "strict": true,
189
- "noUnusedLocals": true,
190
- "noUnusedParameters": true,
191
- "noFallthroughCasesInSwitch": true,
192
- "baseUrl": ".",
193
- "paths": {
194
- "@/*": ["./src/*"]
195
- }
196
- },
197
- "include": ["src"]
198
- }`;
199
- await fs.writeFile(path.join(targetDir, 'tsconfig.json'), tsConfig.trim());
200
-
201
- const shadcnConfig = {
202
- $schema: 'https://ui.shadcn.com/schema.json',
203
- style: 'radix-nova',
204
- rsc: false,
205
- tsx: true,
206
- tailwind: {
207
- config: '',
208
- css: 'src/index.css',
209
- baseColor: 'zinc',
210
- cssVariables: true,
211
- prefix: '',
212
- },
213
- aliases: {
214
- components: '@/components',
215
- utils: '@/lib/utils',
216
- ui: '@/components/ui',
217
- lib: '@/lib',
218
- hooks: '@/hooks',
219
- },
220
- };
221
- await fs.writeJson(path.join(targetDir, 'components.json'), shadcnConfig, { spaces: 2 });
222
- }
223
-
224
- program.parse();