@idealyst/cli 1.0.31 ā 1.0.33
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/dist/generators/api.js +33 -0
- package/dist/generators/api.js.map +1 -0
- package/dist/generators/index.js +50 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/generators/native.js +99 -0
- package/dist/generators/native.js.map +1 -0
- package/dist/generators/shared.js +30 -0
- package/dist/generators/shared.js.map +1 -0
- package/dist/generators/utils.js +521 -0
- package/dist/generators/utils.js.map +1 -0
- package/dist/generators/web.js +46 -0
- package/dist/generators/web.js.map +1 -0
- package/dist/generators/workspace.js +29 -0
- package/dist/generators/workspace.js.map +1 -0
- package/dist/index.js +81 -785
- package/dist/index.js.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +1 -2
- package/templates/workspace/.devcontainer/devcontainer.json +4 -14
- package/templates/workspace/.devcontainer/docker-compose.yml +74 -0
- package/templates/workspace/.devcontainer/post-create.sh +1 -44
- package/templates/workspace/DOCKER.md +0 -398
- package/templates/workspace/Dockerfile +5 -27
package/dist/index.js
CHANGED
|
@@ -1,752 +1,47 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// Check if workspace already covers this path with a wildcard
|
|
28
|
-
const workspaceDir = path.dirname(workspacePath);
|
|
29
|
-
const wildcardPattern = `${workspaceDir}/*`;
|
|
30
|
-
const isAlreadyCovered = packageJson.workspaces.some((ws) => ws === wildcardPattern || ws === workspacePath);
|
|
31
|
-
// Add the new project to workspaces if not already present or covered
|
|
32
|
-
if (!isAlreadyCovered) {
|
|
33
|
-
packageJson.workspaces.push(workspacePath);
|
|
34
|
-
await fs.writeJSON(packageJsonPath, packageJson, { spaces: 2 });
|
|
35
|
-
console.log(chalk.green(`ā
Added ${workspacePath} to workspace configuration`));
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
console.log(chalk.blue(`š¦ Project ${workspacePath} already covered by existing workspace configuration`));
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
catch (error) {
|
|
43
|
-
// Silently ignore if we can't read/write package.json
|
|
44
|
-
console.log(chalk.yellow(`ā ļø Could not update workspace configuration: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
async function copyTemplate(templatePath, destPath, data) {
|
|
49
|
-
const spinner = ora(`Copying template files...`).start();
|
|
50
|
-
try {
|
|
51
|
-
await fs.ensureDir(destPath);
|
|
52
|
-
await fs.copy(templatePath, destPath, {
|
|
53
|
-
filter: (src) => {
|
|
54
|
-
const relativePath = path.relative(templatePath, src);
|
|
55
|
-
// Skip App-with-trpc.tsx as it's only copied when tRPC is enabled
|
|
56
|
-
return !relativePath.includes('node_modules') &&
|
|
57
|
-
!relativePath.includes('.git') &&
|
|
58
|
-
!relativePath.endsWith('App-with-trpc.tsx');
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
// Process template files
|
|
62
|
-
await processTemplateFiles(destPath, data);
|
|
63
|
-
spinner.succeed('Template files copied successfully');
|
|
64
|
-
}
|
|
65
|
-
catch (error) {
|
|
66
|
-
spinner.fail('Failed to copy template files');
|
|
67
|
-
throw error;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
async function processTemplateFiles(dir, data) {
|
|
71
|
-
const files = await fs.readdir(dir);
|
|
72
|
-
for (const file of files) {
|
|
73
|
-
const filePath = path.join(dir, file);
|
|
74
|
-
const stat = await fs.stat(filePath);
|
|
75
|
-
if (stat.isDirectory()) {
|
|
76
|
-
await processTemplateFiles(filePath, data);
|
|
77
|
-
}
|
|
78
|
-
else if (file.endsWith('.json') || file.endsWith('.js') || file.endsWith('.ts') || file.endsWith('.tsx') || file.endsWith('.md')) {
|
|
79
|
-
await processTemplateFile(filePath, data);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
async function processTemplateFile(filePath, data) {
|
|
84
|
-
try {
|
|
85
|
-
let content = await fs.readFile(filePath, 'utf8');
|
|
86
|
-
// Replace template variables
|
|
87
|
-
content = content.replace(/\{\{projectName\}\}/g, data.projectName);
|
|
88
|
-
content = content.replace(/\{\{packageName\}\}/g, data.packageName);
|
|
89
|
-
content = content.replace(/\{\{version\}\}/g, data.version);
|
|
90
|
-
content = content.replace(/\{\{description\}\}/g, data.description);
|
|
91
|
-
// Handle appName (with fallback to projectName if not provided)
|
|
92
|
-
const appName = data.appName || data.projectName;
|
|
93
|
-
content = content.replace(/\{\{appName\}\}/g, appName);
|
|
94
|
-
await fs.writeFile(filePath, content);
|
|
95
|
-
}
|
|
96
|
-
catch (error) {
|
|
97
|
-
// Skip files that can't be processed
|
|
98
|
-
console.warn(chalk.yellow(`Warning: Could not process template file ${filePath}`));
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
async function installDependencies(projectPath, skipInstall = false) {
|
|
102
|
-
if (skipInstall) {
|
|
103
|
-
console.log(chalk.yellow('Skipping dependency installation'));
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
const spinner = ora('Installing dependencies...').start();
|
|
107
|
-
try {
|
|
108
|
-
await runCommand('yarn', ['install'], { cwd: projectPath });
|
|
109
|
-
spinner.succeed('Dependencies installed successfully');
|
|
110
|
-
}
|
|
111
|
-
catch (error) {
|
|
112
|
-
spinner.fail('Failed to install dependencies with yarn');
|
|
113
|
-
console.log(chalk.yellow('You can install dependencies manually by running:'));
|
|
114
|
-
console.log(chalk.white(' cd ' + path.basename(projectPath)));
|
|
115
|
-
console.log(chalk.white(' yarn install'));
|
|
116
|
-
console.log(chalk.white(' # or alternatively:'));
|
|
117
|
-
console.log(chalk.white(' npm install'));
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
function runCommand(command, args, options) {
|
|
121
|
-
return new Promise((resolve, reject) => {
|
|
122
|
-
const timeoutMs = options.timeout || 300000; // 5 minutes default timeout
|
|
123
|
-
const process = spawn(command, args, {
|
|
124
|
-
cwd: options.cwd,
|
|
125
|
-
stdio: ['pipe', 'inherit', 'inherit'], // Pipe stdin to prevent hanging on prompts
|
|
126
|
-
shell: true
|
|
127
|
-
});
|
|
128
|
-
// Set up timeout
|
|
129
|
-
const timeoutId = setTimeout(() => {
|
|
130
|
-
process.kill('SIGTERM');
|
|
131
|
-
reject(new Error(`Command timed out after ${timeoutMs / 1000} seconds`));
|
|
132
|
-
}, timeoutMs);
|
|
133
|
-
// Close stdin immediately to prevent hanging on interactive prompts
|
|
134
|
-
if (process.stdin) {
|
|
135
|
-
process.stdin.end();
|
|
136
|
-
}
|
|
137
|
-
process.on('close', (code) => {
|
|
138
|
-
clearTimeout(timeoutId);
|
|
139
|
-
if (code === 0) {
|
|
140
|
-
resolve();
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
reject(new Error(`Command failed with code ${code}`));
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
process.on('error', (error) => {
|
|
147
|
-
clearTimeout(timeoutId);
|
|
148
|
-
reject(error);
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
function getTemplateData(projectName, description, appName, workspaceScope) {
|
|
153
|
-
let packageName = createPackageName(projectName);
|
|
154
|
-
// If we have a workspace scope, prefix the package name with it
|
|
155
|
-
if (workspaceScope) {
|
|
156
|
-
packageName = `@${workspaceScope}/${packageName}`;
|
|
157
|
-
}
|
|
158
|
-
return {
|
|
159
|
-
projectName,
|
|
160
|
-
packageName,
|
|
161
|
-
version: '1.0.0',
|
|
162
|
-
description: description || `A new Idealyst project: ${projectName}`,
|
|
163
|
-
appName
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
164
27
|
};
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
if (await fs.pathExists(packageJsonPath)) {
|
|
172
|
-
try {
|
|
173
|
-
const packageJson = await fs.readJSON(packageJsonPath);
|
|
174
|
-
return !!(packageJson.workspaces && Array.isArray(packageJson.workspaces));
|
|
175
|
-
}
|
|
176
|
-
catch (error) {
|
|
177
|
-
return false;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
return false;
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Gets the workspace name from the workspace root's package.json
|
|
184
|
-
*/
|
|
185
|
-
async function getWorkspaceName(directory) {
|
|
186
|
-
const packageJsonPath = path.join(directory, 'package.json');
|
|
187
|
-
if (await fs.pathExists(packageJsonPath)) {
|
|
188
|
-
try {
|
|
189
|
-
const packageJson = await fs.readJSON(packageJsonPath);
|
|
190
|
-
return packageJson.name || null;
|
|
191
|
-
}
|
|
192
|
-
catch (error) {
|
|
193
|
-
return null;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
return null;
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Resolves the correct project path for individual projects (native, web, shared).
|
|
200
|
-
* Individual projects can ONLY be created within an existing workspace.
|
|
201
|
-
* This enforces proper monorepo structure and prevents scattered individual projects.
|
|
202
|
-
*/
|
|
203
|
-
async function resolveProjectPath(projectName, directory) {
|
|
204
|
-
// Check if we're in a workspace directory
|
|
205
|
-
const isWorkspace = await isWorkspaceRoot(directory);
|
|
206
|
-
if (!isWorkspace) {
|
|
207
|
-
throw new Error(`Individual projects can only be created within a workspace.\n` +
|
|
208
|
-
`Please first create a workspace with: idealyst init my-workspace\n` +
|
|
209
|
-
`Then navigate to the workspace directory and create your project.`);
|
|
210
|
-
}
|
|
211
|
-
// Get the workspace name to use as scope
|
|
212
|
-
const workspaceScope = await getWorkspaceName(directory);
|
|
213
|
-
// Create project in workspace's packages/ folder
|
|
214
|
-
const packagesDir = path.join(directory, 'packages');
|
|
215
|
-
await fs.ensureDir(packagesDir);
|
|
216
|
-
return {
|
|
217
|
-
projectPath: path.join(packagesDir, projectName),
|
|
218
|
-
workspacePath: `packages/${projectName}`,
|
|
219
|
-
workspaceScope
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
220
34
|
};
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
'--pm', 'yarn',
|
|
232
|
-
'--skip-git-init'
|
|
233
|
-
];
|
|
234
|
-
// Add title if displayName is provided
|
|
235
|
-
if (displayName) {
|
|
236
|
-
args.push('--title', displayName);
|
|
237
|
-
}
|
|
238
|
-
// Skip install if requested (we'll handle it separately for workspace integration)
|
|
239
|
-
if (skipInstall) {
|
|
240
|
-
args.push('--skip-install');
|
|
241
|
-
}
|
|
242
|
-
spinner.text = 'Initializing React Native project (this may take a few minutes)...';
|
|
243
|
-
// Run React Native initialization with timeout
|
|
244
|
-
await runCommand(cliCommand, args, {
|
|
245
|
-
cwd: directory,
|
|
246
|
-
timeout: 600000 // 10 minutes timeout for React Native init
|
|
247
|
-
});
|
|
248
|
-
spinner.succeed('React Native project initialized successfully');
|
|
249
|
-
}
|
|
250
|
-
catch (error) {
|
|
251
|
-
spinner.fail('Failed to initialize React Native project');
|
|
252
|
-
if (error instanceof Error && error.message.includes('timed out')) {
|
|
253
|
-
console.log(chalk.red('ā React Native initialization timed out'));
|
|
254
|
-
console.log(chalk.yellow('This can happen due to:'));
|
|
255
|
-
console.log(chalk.white(' ⢠Slow internet connection'));
|
|
256
|
-
console.log(chalk.white(' ⢠Network issues downloading dependencies'));
|
|
257
|
-
console.log(chalk.white(' ⢠React Native CLI hanging on prompts'));
|
|
258
|
-
}
|
|
259
|
-
console.log(chalk.yellow('\nš” Alternative approaches:'));
|
|
260
|
-
console.log(chalk.white('1. Try manually creating the project:'));
|
|
261
|
-
console.log(chalk.white(` npx react-native@latest init ${projectName} --pm yarn --skip-git-init`));
|
|
262
|
-
console.log(chalk.white('\n2. Use Expo (faster alternative):'));
|
|
263
|
-
console.log(chalk.white(` npx create-expo-app@latest ${projectName} --template blank-typescript`));
|
|
264
|
-
console.log(chalk.white('\n3. Ensure prerequisites:'));
|
|
265
|
-
console.log(chalk.white(' npm install -g react-native-cli'));
|
|
266
|
-
console.log(chalk.white(' npm install -g @react-native-community/cli'));
|
|
267
|
-
throw error;
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
async function overlayIdealystFiles(templatePath, projectPath, data) {
|
|
271
|
-
const spinner = ora('Applying Idealyst Framework files...').start();
|
|
272
|
-
try {
|
|
273
|
-
// Copy Idealyst-specific files over the React Native project
|
|
274
|
-
await fs.copy(templatePath, projectPath, {
|
|
275
|
-
overwrite: true,
|
|
276
|
-
filter: (src) => {
|
|
277
|
-
const relativePath = path.relative(templatePath, src);
|
|
278
|
-
// Skip package.json as we'll merge it separately
|
|
279
|
-
// Skip App-with-trpc.tsx as it's only copied when tRPC is enabled
|
|
280
|
-
return !relativePath.includes('node_modules') &&
|
|
281
|
-
!relativePath.includes('.git') &&
|
|
282
|
-
!relativePath.endsWith('package.json') &&
|
|
283
|
-
!relativePath.endsWith('App-with-trpc.tsx');
|
|
284
|
-
}
|
|
285
|
-
});
|
|
286
|
-
// Process template files
|
|
287
|
-
await processTemplateFiles(projectPath, data);
|
|
288
|
-
// Merge package.json dependencies
|
|
289
|
-
await mergePackageJsonDependencies(templatePath, projectPath);
|
|
290
|
-
spinner.succeed('Idealyst Framework files applied successfully');
|
|
291
|
-
}
|
|
292
|
-
catch (error) {
|
|
293
|
-
spinner.fail('Failed to apply Idealyst Framework files');
|
|
294
|
-
throw error;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
async function mergePackageJsonDependencies(templatePath, projectPath) {
|
|
298
|
-
const templatePackageJsonPath = path.join(templatePath, 'package.json');
|
|
299
|
-
const projectPackageJsonPath = path.join(projectPath, 'package.json');
|
|
300
|
-
try {
|
|
301
|
-
// Read both package.json files
|
|
302
|
-
const templatePackageJson = await fs.readJSON(templatePackageJsonPath);
|
|
303
|
-
const projectPackageJson = await fs.readJSON(projectPackageJsonPath);
|
|
304
|
-
// Merge dependencies
|
|
305
|
-
const idealystDependencies = {
|
|
306
|
-
'@idealyst/components': '^1.0.3',
|
|
307
|
-
'@idealyst/navigation': '^1.0.3',
|
|
308
|
-
'@idealyst/theme': '^1.0.3',
|
|
309
|
-
'@react-native-vector-icons/common': '^12.0.1',
|
|
310
|
-
'@react-native-vector-icons/material-design-icons': '^12.0.1',
|
|
311
|
-
'@react-navigation/bottom-tabs': '^7.4.2',
|
|
312
|
-
'@react-navigation/drawer': '^7.5.3',
|
|
313
|
-
'@react-navigation/native': '^7.1.14',
|
|
314
|
-
'@react-navigation/native-stack': '^7.3.21',
|
|
315
|
-
'@tanstack/react-query': '^5.83.0',
|
|
316
|
-
'@trpc/client': '^11.4.3',
|
|
317
|
-
'@trpc/react-query': '^11.4.3',
|
|
318
|
-
'@trpc/server': '^11.4.3',
|
|
319
|
-
'react-native-edge-to-edge': '^1.6.2',
|
|
320
|
-
'react-native-gesture-handler': '^2.27.1',
|
|
321
|
-
'react-native-nitro-modules': '^0.26.3',
|
|
322
|
-
'react-native-reanimated': '^3.18.0',
|
|
323
|
-
'react-native-safe-area-context': '^5.5.1',
|
|
324
|
-
'react-native-screens': '^4.11.1',
|
|
325
|
-
'react-native-unistyles': '^3.0.4',
|
|
326
|
-
'react-native-vector-icons': '^10.2.0'
|
|
327
|
-
};
|
|
328
|
-
// Merge the dependencies
|
|
329
|
-
projectPackageJson.dependencies = {
|
|
330
|
-
...projectPackageJson.dependencies,
|
|
331
|
-
...idealystDependencies
|
|
332
|
-
};
|
|
333
|
-
// Write back the merged package.json
|
|
334
|
-
await fs.writeJSON(projectPackageJsonPath, projectPackageJson, { spaces: 2 });
|
|
335
|
-
console.log(chalk.green('ā
Merged Idealyst dependencies into package.json'));
|
|
336
|
-
}
|
|
337
|
-
catch (error) {
|
|
338
|
-
console.warn(chalk.yellow('ā ļø Could not merge package.json dependencies'));
|
|
339
|
-
throw error;
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
async function promptForProjectName() {
|
|
343
|
-
const { projectName } = await inquirer.prompt([
|
|
344
|
-
{
|
|
345
|
-
type: 'input',
|
|
346
|
-
name: 'projectName',
|
|
347
|
-
message: 'What is your project name?',
|
|
348
|
-
validate: (input) => {
|
|
349
|
-
if (!input || input.trim().length === 0) {
|
|
350
|
-
return 'Project name is required';
|
|
351
|
-
}
|
|
352
|
-
const lowerName = input.toLowerCase();
|
|
353
|
-
if (!validateProjectName(lowerName)) {
|
|
354
|
-
return 'Project name must be a valid npm package name (lowercase, no spaces)';
|
|
355
|
-
}
|
|
356
|
-
return true;
|
|
357
|
-
},
|
|
358
|
-
filter: (input) => input.toLowerCase().trim()
|
|
359
|
-
}
|
|
360
|
-
]);
|
|
361
|
-
return projectName;
|
|
362
|
-
}
|
|
363
|
-
async function promptForProjectType() {
|
|
364
|
-
const { projectType } = await inquirer.prompt([
|
|
365
|
-
{
|
|
366
|
-
type: 'list',
|
|
367
|
-
name: 'projectType',
|
|
368
|
-
message: 'What type of project would you like to create?',
|
|
369
|
-
choices: [
|
|
370
|
-
{ name: 'React Native App', value: 'native' },
|
|
371
|
-
{ name: 'React Web App', value: 'web' },
|
|
372
|
-
{ name: 'Shared Library', value: 'shared' },
|
|
373
|
-
{ name: 'API Server (tRPC + Prisma + Zod)', value: 'api' }
|
|
374
|
-
],
|
|
375
|
-
default: 'native'
|
|
376
|
-
}
|
|
377
|
-
]);
|
|
378
|
-
return projectType;
|
|
379
|
-
}
|
|
380
|
-
async function promptForAppName(projectName) {
|
|
381
|
-
const { appName } = await inquirer.prompt([
|
|
382
|
-
{
|
|
383
|
-
type: 'input',
|
|
384
|
-
name: 'appName',
|
|
385
|
-
message: 'What is the display name for your app? (used for native app titles)',
|
|
386
|
-
default: projectName.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(' '),
|
|
387
|
-
validate: (input) => {
|
|
388
|
-
if (!input || input.trim().length === 0) {
|
|
389
|
-
return 'App name is required';
|
|
390
|
-
}
|
|
391
|
-
return true;
|
|
392
|
-
},
|
|
393
|
-
filter: (input) => input.trim()
|
|
394
|
-
}
|
|
395
|
-
]);
|
|
396
|
-
return appName;
|
|
397
|
-
}
|
|
398
|
-
async function promptForTrpcIntegration() {
|
|
399
|
-
const { withTrpc } = await inquirer.prompt([
|
|
400
|
-
{
|
|
401
|
-
type: 'confirm',
|
|
402
|
-
name: 'withTrpc',
|
|
403
|
-
message: 'Would you like to include tRPC client setup and boilerplate?',
|
|
404
|
-
default: false
|
|
405
|
-
}
|
|
406
|
-
]);
|
|
407
|
-
return withTrpc;
|
|
408
|
-
}
|
|
409
|
-
async function copyTrpcFiles(templatePath, projectPath, data) {
|
|
410
|
-
const spinner = ora('Adding tRPC client utilities...').start();
|
|
411
|
-
try {
|
|
412
|
-
const trpcUtilsSource = path.join(templatePath, 'src', 'utils', 'trpc.ts');
|
|
413
|
-
const trpcUtilsTarget = path.join(projectPath, 'src', 'utils', 'trpc.ts');
|
|
414
|
-
// Ensure utils directory exists
|
|
415
|
-
await fs.ensureDir(path.join(projectPath, 'src', 'utils'));
|
|
416
|
-
// Copy and process the tRPC utils file
|
|
417
|
-
await fs.copy(trpcUtilsSource, trpcUtilsTarget);
|
|
418
|
-
await processTemplateFile(trpcUtilsTarget, data);
|
|
419
|
-
spinner.succeed('tRPC client utilities added');
|
|
420
|
-
}
|
|
421
|
-
catch (error) {
|
|
422
|
-
spinner.fail('Failed to add tRPC client utilities');
|
|
423
|
-
console.warn(chalk.yellow('ā ļø tRPC utilities could not be copied, but the project was created successfully'));
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
async function copyTrpcAppComponent(templatePath, projectPath, data) {
|
|
427
|
-
const spinner = ora('Setting up tRPC App component...').start();
|
|
428
|
-
try {
|
|
429
|
-
const trpcAppSource = path.join(templatePath, 'src', 'App-with-trpc.tsx');
|
|
430
|
-
const appTarget = path.join(projectPath, 'src', 'App.tsx');
|
|
431
|
-
// Copy the tRPC-enabled App component over the default one
|
|
432
|
-
await fs.copy(trpcAppSource, appTarget, { overwrite: true });
|
|
433
|
-
await processTemplateFile(appTarget, data);
|
|
434
|
-
spinner.succeed('tRPC App component configured');
|
|
435
|
-
}
|
|
436
|
-
catch (error) {
|
|
437
|
-
spinner.fail('Failed to configure tRPC App component');
|
|
438
|
-
console.warn(chalk.yellow('ā ļø tRPC App component could not be configured, but the project was created successfully'));
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
async function removeTrpcDependencies(projectPath) {
|
|
442
|
-
try {
|
|
443
|
-
const packageJsonPath = path.join(projectPath, 'package.json');
|
|
444
|
-
const packageJson = await fs.readJSON(packageJsonPath);
|
|
445
|
-
// Remove tRPC-related dependencies
|
|
446
|
-
const trpcDeps = [
|
|
447
|
-
'@tanstack/react-query',
|
|
448
|
-
'@trpc/client',
|
|
449
|
-
'@trpc/react-query',
|
|
450
|
-
'@trpc/server'
|
|
451
|
-
];
|
|
452
|
-
trpcDeps.forEach(dep => {
|
|
453
|
-
if (packageJson.dependencies && packageJson.dependencies[dep]) {
|
|
454
|
-
delete packageJson.dependencies[dep];
|
|
455
|
-
}
|
|
456
|
-
});
|
|
457
|
-
await fs.writeJSON(packageJsonPath, packageJson, { spaces: 2 });
|
|
458
|
-
}
|
|
459
|
-
catch (error) {
|
|
460
|
-
console.warn(chalk.yellow('ā ļø Could not remove tRPC dependencies from package.json'));
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
async function configureAndroidVectorIcons(projectPath) {
|
|
464
|
-
const buildGradlePath = path.join(projectPath, 'android', 'app', 'build.gradle');
|
|
465
|
-
try {
|
|
466
|
-
if (await fs.pathExists(buildGradlePath)) {
|
|
467
|
-
let content = await fs.readFile(buildGradlePath, 'utf8');
|
|
468
|
-
// Check if the vector icons line is already present
|
|
469
|
-
if (content.includes('react-native-vector-icons/fonts.gradle')) {
|
|
470
|
-
console.log(chalk.yellow('Vector icons configuration already exists in build.gradle'));
|
|
471
|
-
return;
|
|
472
|
-
}
|
|
473
|
-
// Find the line with jscFlavor definition and add the vector icons line after it
|
|
474
|
-
const jscFlavorRegex = /def jscFlavor = ['"][^'"]*['"]/;
|
|
475
|
-
const match = content.match(jscFlavorRegex);
|
|
476
|
-
if (match) {
|
|
477
|
-
const insertionPoint = content.indexOf(match[0]) + match[0].length;
|
|
478
|
-
const beforeInsertion = content.substring(0, insertionPoint);
|
|
479
|
-
const afterInsertion = content.substring(insertionPoint);
|
|
480
|
-
const vectorIconsLine = '\napply from: file("../../node_modules/react-native-vector-icons/fonts.gradle")';
|
|
481
|
-
content = beforeInsertion + vectorIconsLine + afterInsertion;
|
|
482
|
-
await fs.writeFile(buildGradlePath, content);
|
|
483
|
-
console.log(chalk.green('ā
Added react-native-vector-icons configuration to Android build.gradle'));
|
|
484
|
-
}
|
|
485
|
-
else {
|
|
486
|
-
console.log(chalk.yellow('ā ļø Could not find jscFlavor line in build.gradle, vector icons configuration not added'));
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
else {
|
|
490
|
-
console.log(chalk.yellow('ā ļø Android build.gradle not found, skipping vector icons configuration'));
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
catch (error) {
|
|
494
|
-
console.log(chalk.yellow(`ā ļø Could not configure vector icons in build.gradle: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
var utils = /*#__PURE__*/Object.freeze({
|
|
499
|
-
__proto__: null,
|
|
500
|
-
configureAndroidVectorIcons: configureAndroidVectorIcons,
|
|
501
|
-
copyTemplate: copyTemplate,
|
|
502
|
-
copyTrpcAppComponent: copyTrpcAppComponent,
|
|
503
|
-
copyTrpcFiles: copyTrpcFiles,
|
|
504
|
-
createPackageName: createPackageName,
|
|
505
|
-
getTemplateData: getTemplateData,
|
|
506
|
-
getWorkspaceName: getWorkspaceName,
|
|
507
|
-
initializeReactNativeProject: initializeReactNativeProject,
|
|
508
|
-
installDependencies: installDependencies,
|
|
509
|
-
isWorkspaceRoot: isWorkspaceRoot,
|
|
510
|
-
mergePackageJsonDependencies: mergePackageJsonDependencies,
|
|
511
|
-
overlayIdealystFiles: overlayIdealystFiles,
|
|
512
|
-
processTemplateFile: processTemplateFile,
|
|
513
|
-
processTemplateFiles: processTemplateFiles,
|
|
514
|
-
promptForAppName: promptForAppName,
|
|
515
|
-
promptForProjectName: promptForProjectName,
|
|
516
|
-
promptForProjectType: promptForProjectType,
|
|
517
|
-
promptForTrpcIntegration: promptForTrpcIntegration,
|
|
518
|
-
removeTrpcDependencies: removeTrpcDependencies,
|
|
519
|
-
resolveProjectPath: resolveProjectPath,
|
|
520
|
-
runCommand: runCommand,
|
|
521
|
-
updateWorkspacePackageJson: updateWorkspacePackageJson,
|
|
522
|
-
validateProjectName: validateProjectName
|
|
523
|
-
});
|
|
524
|
-
|
|
525
|
-
const __filename$4 = fileURLToPath(import.meta.url);
|
|
526
|
-
const __dirname$4 = path.dirname(__filename$4);
|
|
527
|
-
async function generateNativeProject(options) {
|
|
528
|
-
const { name, directory, skipInstall, appName, withTrpc } = options;
|
|
529
|
-
if (!validateProjectName(name)) {
|
|
530
|
-
throw new Error(`Invalid project name: ${name}`);
|
|
531
|
-
}
|
|
532
|
-
const displayName = appName || name.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(' ');
|
|
533
|
-
console.log(chalk.blue(`š± Creating React Native project: ${name}`));
|
|
534
|
-
console.log(chalk.gray(` App display name: ${displayName}`));
|
|
535
|
-
const { projectPath, workspacePath, workspaceScope } = await resolveProjectPath(name, directory);
|
|
536
|
-
const templatePath = path.join(__dirname$4, '..', 'templates', 'native');
|
|
537
|
-
const templateData = getTemplateData(name, `React Native app built with Idealyst Framework`, displayName, workspaceScope || undefined);
|
|
538
|
-
try {
|
|
539
|
-
// Step 1: Update workspace configuration FIRST
|
|
540
|
-
await updateWorkspacePackageJson(workspacePath, directory);
|
|
541
|
-
// Step 2: Try React Native CLI initialization, with fallback to template-only
|
|
542
|
-
const useRnCli = process.env.IDEALYST_USE_RN_CLI !== 'false';
|
|
543
|
-
if (useRnCli) {
|
|
544
|
-
try {
|
|
545
|
-
console.log(chalk.blue('š Attempting React Native CLI initialization...'));
|
|
546
|
-
console.log(chalk.gray(' (This creates proper Android/iOS native directories)'));
|
|
547
|
-
// Initialize React Native project using CLI with --skip-install
|
|
548
|
-
const projectDir = path.dirname(projectPath);
|
|
549
|
-
const projectName = path.basename(projectPath);
|
|
550
|
-
await initializeReactNativeProject(projectName, projectDir, displayName, true);
|
|
551
|
-
// Step 3: Overlay Idealyst-specific files
|
|
552
|
-
await overlayIdealystFiles(templatePath, projectPath, templateData);
|
|
553
|
-
console.log(chalk.green('ā
React Native project created with native platform support'));
|
|
554
|
-
}
|
|
555
|
-
catch (rnError) {
|
|
556
|
-
console.log(chalk.yellow('ā ļø React Native CLI failed, falling back to template-only approach...'));
|
|
557
|
-
await createNativeProjectFromTemplate(templatePath, projectPath, templateData);
|
|
558
|
-
console.log(chalk.yellow('š Template-only project created. You may need to run "npx react-native init" later for native platforms.'));
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
else {
|
|
562
|
-
console.log(chalk.blue('ļæ½ļæ½ļø Creating project from template only (IDEALYST_USE_RN_CLI=false)'));
|
|
563
|
-
await createNativeProjectFromTemplate(templatePath, projectPath, templateData);
|
|
564
|
-
}
|
|
565
|
-
// Step 4: Handle tRPC setup
|
|
566
|
-
if (withTrpc) {
|
|
567
|
-
await copyTrpcFiles(templatePath, projectPath, templateData);
|
|
568
|
-
await copyTrpcAppComponent(templatePath, projectPath, templateData);
|
|
569
|
-
}
|
|
570
|
-
// Step 5: Configure Android vector icons (only if we have Android directory)
|
|
571
|
-
const hasAndroid = await fs.pathExists(path.join(projectPath, 'android'));
|
|
572
|
-
if (hasAndroid) {
|
|
573
|
-
await configureAndroidVectorIcons(projectPath);
|
|
574
|
-
}
|
|
575
|
-
// Step 6: Remove tRPC dependencies if not requested
|
|
576
|
-
if (!withTrpc) {
|
|
577
|
-
await removeTrpcDependencies(projectPath);
|
|
578
|
-
}
|
|
579
|
-
// Step 7: Install dependencies
|
|
580
|
-
await installDependencies(projectPath, skipInstall);
|
|
581
|
-
console.log(chalk.green('ā
React Native project created successfully!'));
|
|
582
|
-
console.log(chalk.blue('š Project includes:'));
|
|
583
|
-
console.log(chalk.white(' ⢠React Native with TypeScript'));
|
|
584
|
-
console.log(chalk.white(' ⢠Idealyst Components & Navigation'));
|
|
585
|
-
console.log(chalk.white(' ⢠Idealyst Theme & Styling'));
|
|
586
|
-
console.log(chalk.white(' ⢠Jest testing configuration'));
|
|
587
|
-
console.log(chalk.white(' ⢠Metro & Babel configuration'));
|
|
588
|
-
if (hasAndroid) {
|
|
589
|
-
console.log(chalk.white(' ⢠Android native platform setup'));
|
|
590
|
-
console.log(chalk.white(' ⢠React Native Vector Icons (configured)'));
|
|
591
|
-
}
|
|
592
|
-
const hasIos = await fs.pathExists(path.join(projectPath, 'ios'));
|
|
593
|
-
if (hasIos) {
|
|
594
|
-
console.log(chalk.white(' ⢠iOS native platform setup'));
|
|
595
|
-
}
|
|
596
|
-
if (!hasAndroid && !hasIos) {
|
|
597
|
-
console.log(chalk.yellow(' ā ļø No native platforms detected'));
|
|
598
|
-
console.log(chalk.yellow(' Run "npx react-native init" in project directory for native support'));
|
|
599
|
-
}
|
|
600
|
-
if (withTrpc) {
|
|
601
|
-
console.log(chalk.white(' ⢠tRPC client setup and utilities'));
|
|
602
|
-
console.log(chalk.white(' ⢠React Query integration'));
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
catch (error) {
|
|
606
|
-
console.error(chalk.red('ā Error creating React Native project:'));
|
|
607
|
-
console.error(error);
|
|
608
|
-
throw error;
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
// Helper function to create project from template only (fallback when RN CLI fails)
|
|
612
|
-
async function createNativeProjectFromTemplate(templatePath, projectPath, templateData) {
|
|
613
|
-
await copyTemplate(templatePath, projectPath, templateData);
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
const __filename$3 = fileURLToPath(import.meta.url);
|
|
617
|
-
const __dirname$3 = path.dirname(__filename$3);
|
|
618
|
-
async function generateWebProject(options) {
|
|
619
|
-
const { name, directory, skipInstall, withTrpc } = options;
|
|
620
|
-
if (!validateProjectName(name)) {
|
|
621
|
-
throw new Error(`Invalid project name: ${name}`);
|
|
622
|
-
}
|
|
623
|
-
console.log(chalk.blue(`š Creating React Web project: ${name}`));
|
|
624
|
-
const { projectPath, workspacePath, workspaceScope } = await resolveProjectPath(name, directory);
|
|
625
|
-
const templatePath = path.join(__dirname$3, '..', 'templates', 'web');
|
|
626
|
-
const templateData = getTemplateData(name, `React web app built with Idealyst Framework`, undefined, workspaceScope || undefined);
|
|
627
|
-
await copyTemplate(templatePath, projectPath, templateData);
|
|
628
|
-
// Handle tRPC setup
|
|
629
|
-
if (withTrpc) {
|
|
630
|
-
await copyTrpcFiles(templatePath, projectPath, templateData);
|
|
631
|
-
await copyTrpcAppComponent(templatePath, projectPath, templateData);
|
|
632
|
-
}
|
|
633
|
-
else {
|
|
634
|
-
// Remove tRPC dependencies if not requested
|
|
635
|
-
await removeTrpcDependencies(projectPath);
|
|
636
|
-
}
|
|
637
|
-
await installDependencies(projectPath, skipInstall);
|
|
638
|
-
await updateWorkspacePackageJson(workspacePath, directory);
|
|
639
|
-
console.log(chalk.green('ā
React Web project created successfully!'));
|
|
640
|
-
console.log(chalk.blue('š Project includes:'));
|
|
641
|
-
console.log(chalk.white(' ⢠React 19.1'));
|
|
642
|
-
console.log(chalk.white(' ⢠Vite build system'));
|
|
643
|
-
console.log(chalk.white(' ⢠Idealyst Components'));
|
|
644
|
-
console.log(chalk.white(' ⢠Idealyst Navigation'));
|
|
645
|
-
console.log(chalk.white(' ⢠Idealyst Theme'));
|
|
646
|
-
console.log(chalk.white(' ⢠TypeScript configuration'));
|
|
647
|
-
console.log(chalk.white(' ⢠React Router'));
|
|
648
|
-
if (withTrpc) {
|
|
649
|
-
console.log(chalk.white(' ⢠tRPC client setup and utilities'));
|
|
650
|
-
console.log(chalk.white(' ⢠React Query integration'));
|
|
651
|
-
console.log(chalk.white(' ⢠Pre-configured tRPC provider'));
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
const __filename$2 = fileURLToPath(import.meta.url);
|
|
656
|
-
const __dirname$2 = path.dirname(__filename$2);
|
|
657
|
-
async function generateSharedLibrary(options) {
|
|
658
|
-
const { name, directory, skipInstall } = options;
|
|
659
|
-
if (!validateProjectName(name)) {
|
|
660
|
-
throw new Error(`Invalid project name: ${name}`);
|
|
661
|
-
}
|
|
662
|
-
console.log(chalk.blue(`š¦ Creating shared library: ${name}`));
|
|
663
|
-
const { projectPath, workspacePath, workspaceScope } = await resolveProjectPath(name, directory);
|
|
664
|
-
const templatePath = path.join(__dirname$2, '..', 'templates', 'shared');
|
|
665
|
-
const templateData = getTemplateData(name, `Shared library built with Idealyst Framework`, undefined, workspaceScope || undefined);
|
|
666
|
-
await copyTemplate(templatePath, projectPath, templateData);
|
|
667
|
-
await installDependencies(projectPath, skipInstall);
|
|
668
|
-
await updateWorkspacePackageJson(workspacePath, directory);
|
|
669
|
-
console.log(chalk.green('ā
Shared library created successfully!'));
|
|
670
|
-
console.log(chalk.blue('š Project includes:'));
|
|
671
|
-
console.log(chalk.white(' ⢠Cross-platform components'));
|
|
672
|
-
console.log(chalk.white(' ⢠Idealyst Theme integration'));
|
|
673
|
-
console.log(chalk.white(' ⢠TypeScript configuration'));
|
|
674
|
-
console.log(chalk.white(' ⢠Rollup build system'));
|
|
675
|
-
console.log(chalk.white(' ⢠React & React Native support'));
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
const __filename$1 = fileURLToPath(import.meta.url);
|
|
679
|
-
const __dirname$1 = path.dirname(__filename$1);
|
|
680
|
-
async function generateWorkspace(options) {
|
|
681
|
-
const { name, directory, skipInstall } = options;
|
|
682
|
-
if (!validateProjectName(name)) {
|
|
683
|
-
throw new Error(`Invalid project name: ${name}`);
|
|
684
|
-
}
|
|
685
|
-
console.log(chalk.blue(`šļø Creating Idealyst workspace: ${name}`));
|
|
686
|
-
const projectPath = path.join(directory, name);
|
|
687
|
-
const templatePath = path.join(__dirname$1, '..', 'templates', 'workspace');
|
|
688
|
-
const templateData = getTemplateData(name, `Idealyst Framework monorepo workspace`);
|
|
689
|
-
await copyTemplate(templatePath, projectPath, templateData);
|
|
690
|
-
await installDependencies(projectPath, skipInstall);
|
|
691
|
-
console.log(chalk.green('ā
Workspace created successfully!'));
|
|
692
|
-
console.log(chalk.blue('š Workspace includes:'));
|
|
693
|
-
console.log(chalk.white(' ⢠Yarn workspace configuration'));
|
|
694
|
-
console.log(chalk.white(' ⢠Idealyst packages (theme, components, navigation)'));
|
|
695
|
-
console.log(chalk.white(' ⢠TypeScript configuration'));
|
|
696
|
-
console.log(chalk.white(' ⢠Build scripts'));
|
|
697
|
-
console.log(chalk.white(' ⢠Version management scripts'));
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
701
|
-
const __dirname = path.dirname(__filename);
|
|
702
|
-
async function generateApiProject(options) {
|
|
703
|
-
const { name, directory, skipInstall } = options;
|
|
704
|
-
if (!validateProjectName(name)) {
|
|
705
|
-
throw new Error(`Invalid project name: ${name}`);
|
|
706
|
-
}
|
|
707
|
-
console.log(chalk.blue(`š Creating API project: ${name}`));
|
|
708
|
-
const { projectPath, workspacePath, workspaceScope } = await resolveProjectPath(name, directory);
|
|
709
|
-
const templatePath = path.join(__dirname, '..', 'templates', 'api');
|
|
710
|
-
const templateData = getTemplateData(name, `Clean API server template with tRPC, Prisma, and Zod`, undefined, workspaceScope || undefined);
|
|
711
|
-
await copyTemplate(templatePath, projectPath, templateData);
|
|
712
|
-
await installDependencies(projectPath, skipInstall);
|
|
713
|
-
await updateWorkspacePackageJson(workspacePath, directory);
|
|
714
|
-
console.log(chalk.green('ā
API project created successfully!'));
|
|
715
|
-
console.log(chalk.blue('š Project includes:'));
|
|
716
|
-
console.log(chalk.white(' ⢠tRPC for type-safe APIs'));
|
|
717
|
-
console.log(chalk.white(' ⢠Prisma for database management'));
|
|
718
|
-
console.log(chalk.white(' ⢠Zod for schema validation'));
|
|
719
|
-
console.log(chalk.white(' ⢠Express.js server'));
|
|
720
|
-
console.log(chalk.white(' ⢠TypeScript configuration'));
|
|
721
|
-
console.log(chalk.white(' ⢠CORS and middleware setup'));
|
|
722
|
-
console.log(chalk.white(' ⢠Database migration scripts'));
|
|
723
|
-
console.log(chalk.white(' ⢠Clean template ready for your models'));
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
async function generateProject(options) {
|
|
727
|
-
const { type } = options;
|
|
728
|
-
switch (type) {
|
|
729
|
-
case 'native':
|
|
730
|
-
await generateNativeProject(options);
|
|
731
|
-
break;
|
|
732
|
-
case 'web':
|
|
733
|
-
await generateWebProject(options);
|
|
734
|
-
break;
|
|
735
|
-
case 'shared':
|
|
736
|
-
await generateSharedLibrary(options);
|
|
737
|
-
break;
|
|
738
|
-
case 'workspace':
|
|
739
|
-
await generateWorkspace(options);
|
|
740
|
-
break;
|
|
741
|
-
case 'api':
|
|
742
|
-
await generateApiProject(options);
|
|
743
|
-
break;
|
|
744
|
-
default:
|
|
745
|
-
throw new Error(`Unknown project type: ${type}`);
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
const program = new Command();
|
|
35
|
+
})();
|
|
36
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
const commander_1 = require("commander");
|
|
41
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
42
|
+
const index_1 = require("./generators/index");
|
|
43
|
+
const utils_1 = require("./generators/utils");
|
|
44
|
+
const program = new commander_1.Command();
|
|
750
45
|
program
|
|
751
46
|
.name('idealyst')
|
|
752
47
|
.description('CLI tool for generating Idealyst Framework projects')
|
|
@@ -763,14 +58,14 @@ program
|
|
|
763
58
|
try {
|
|
764
59
|
// Prompt for project name if not provided
|
|
765
60
|
if (!projectName) {
|
|
766
|
-
projectName = await promptForProjectName();
|
|
61
|
+
projectName = await (0, utils_1.promptForProjectName)();
|
|
767
62
|
}
|
|
768
63
|
else {
|
|
769
64
|
// Validate provided project name
|
|
770
|
-
const { validateProjectName } = await Promise.resolve().then(
|
|
65
|
+
const { validateProjectName } = await Promise.resolve().then(() => __importStar(require('./generators/utils')));
|
|
771
66
|
if (!validateProjectName(projectName.toLowerCase())) {
|
|
772
|
-
console.error(
|
|
773
|
-
console.error(
|
|
67
|
+
console.error(chalk_1.default.red(`Invalid project name: ${projectName}`));
|
|
68
|
+
console.error(chalk_1.default.yellow('Project name must be a valid npm package name (lowercase, no spaces)'));
|
|
774
69
|
process.exit(1);
|
|
775
70
|
}
|
|
776
71
|
projectName = projectName.toLowerCase();
|
|
@@ -778,25 +73,25 @@ program
|
|
|
778
73
|
// Prompt for project type if not provided
|
|
779
74
|
let projectType = options.type;
|
|
780
75
|
if (!projectType) {
|
|
781
|
-
projectType = await promptForProjectType();
|
|
76
|
+
projectType = await (0, utils_1.promptForProjectType)();
|
|
782
77
|
}
|
|
783
78
|
const validTypes = ['native', 'web', 'shared', 'api'];
|
|
784
79
|
if (!validTypes.includes(projectType)) {
|
|
785
|
-
console.error(
|
|
786
|
-
console.error(
|
|
80
|
+
console.error(chalk_1.default.red(`Invalid project type: ${projectType}`));
|
|
81
|
+
console.error(chalk_1.default.yellow(`Valid types are: ${validTypes.join(', ')}`));
|
|
787
82
|
process.exit(1);
|
|
788
83
|
}
|
|
789
84
|
// Prompt for app name if it's a native project and app name not provided
|
|
790
85
|
let appName = options.appName;
|
|
791
86
|
if (projectType === 'native' && !appName) {
|
|
792
|
-
appName = await promptForAppName(projectName);
|
|
87
|
+
appName = await (0, utils_1.promptForAppName)(projectName);
|
|
793
88
|
}
|
|
794
89
|
// Prompt for tRPC integration if it's a web/native project and flag not provided
|
|
795
90
|
let withTrpc = options.withTrpc;
|
|
796
91
|
if ((projectType === 'web' || projectType === 'native') && withTrpc === undefined) {
|
|
797
|
-
withTrpc = await promptForTrpcIntegration();
|
|
92
|
+
withTrpc = await (0, utils_1.promptForTrpcIntegration)();
|
|
798
93
|
}
|
|
799
|
-
await generateProject({
|
|
94
|
+
await (0, index_1.generateProject)({
|
|
800
95
|
name: projectName,
|
|
801
96
|
type: projectType,
|
|
802
97
|
directory: options.directory,
|
|
@@ -804,33 +99,33 @@ program
|
|
|
804
99
|
appName,
|
|
805
100
|
withTrpc: withTrpc || false
|
|
806
101
|
});
|
|
807
|
-
console.log(
|
|
808
|
-
console.log(
|
|
102
|
+
console.log(chalk_1.default.green(`⨠Successfully created ${projectName}!`));
|
|
103
|
+
console.log(chalk_1.default.blue(`š Project created in: ${options.directory}/packages/${projectName}`));
|
|
809
104
|
if (projectType === 'native') {
|
|
810
|
-
console.log(
|
|
811
|
-
console.log(
|
|
812
|
-
console.log(
|
|
105
|
+
console.log(chalk_1.default.yellow('\nš± Next steps for React Native:'));
|
|
106
|
+
console.log(chalk_1.default.white(' cd packages/' + projectName));
|
|
107
|
+
console.log(chalk_1.default.white(' yarn android # or yarn ios'));
|
|
813
108
|
}
|
|
814
109
|
else if (projectType === 'web') {
|
|
815
|
-
console.log(
|
|
816
|
-
console.log(
|
|
817
|
-
console.log(
|
|
110
|
+
console.log(chalk_1.default.yellow('\nš Next steps for React Web:'));
|
|
111
|
+
console.log(chalk_1.default.white(' cd packages/' + projectName));
|
|
112
|
+
console.log(chalk_1.default.white(' yarn dev'));
|
|
818
113
|
}
|
|
819
114
|
else if (projectType === 'api') {
|
|
820
|
-
console.log(
|
|
821
|
-
console.log(
|
|
822
|
-
console.log(
|
|
823
|
-
console.log(
|
|
824
|
-
console.log(
|
|
115
|
+
console.log(chalk_1.default.yellow('\nš Next steps for API Server:'));
|
|
116
|
+
console.log(chalk_1.default.white(' cd packages/' + projectName));
|
|
117
|
+
console.log(chalk_1.default.white(' yarn dev # Start development server'));
|
|
118
|
+
console.log(chalk_1.default.white(' yarn db:push # Push database schema'));
|
|
119
|
+
console.log(chalk_1.default.white(' yarn db:studio # Open Prisma Studio'));
|
|
825
120
|
}
|
|
826
121
|
else {
|
|
827
|
-
console.log(
|
|
828
|
-
console.log(
|
|
829
|
-
console.log(
|
|
122
|
+
console.log(chalk_1.default.yellow('\nš¦ Next steps for Shared Library:'));
|
|
123
|
+
console.log(chalk_1.default.white(' cd packages/' + projectName));
|
|
124
|
+
console.log(chalk_1.default.white(' yarn build'));
|
|
830
125
|
}
|
|
831
126
|
}
|
|
832
127
|
catch (error) {
|
|
833
|
-
console.error(
|
|
128
|
+
console.error(chalk_1.default.red('ā Error creating project:'), error);
|
|
834
129
|
process.exit(1);
|
|
835
130
|
}
|
|
836
131
|
});
|
|
@@ -843,34 +138,35 @@ program
|
|
|
843
138
|
try {
|
|
844
139
|
// Prompt for project name if not provided
|
|
845
140
|
if (!projectName) {
|
|
846
|
-
projectName = await promptForProjectName();
|
|
141
|
+
projectName = await (0, utils_1.promptForProjectName)();
|
|
847
142
|
}
|
|
848
143
|
else {
|
|
849
144
|
// Validate provided project name
|
|
850
|
-
const { validateProjectName } = await Promise.resolve().then(
|
|
145
|
+
const { validateProjectName } = await Promise.resolve().then(() => __importStar(require('./generators/utils')));
|
|
851
146
|
if (!validateProjectName(projectName.toLowerCase())) {
|
|
852
|
-
console.error(
|
|
853
|
-
console.error(
|
|
147
|
+
console.error(chalk_1.default.red(`Invalid project name: ${projectName}`));
|
|
148
|
+
console.error(chalk_1.default.yellow('Project name must be a valid npm package name (lowercase, no spaces)'));
|
|
854
149
|
process.exit(1);
|
|
855
150
|
}
|
|
856
151
|
projectName = projectName.toLowerCase();
|
|
857
152
|
}
|
|
858
|
-
await generateProject({
|
|
153
|
+
await (0, index_1.generateProject)({
|
|
859
154
|
name: projectName,
|
|
860
155
|
type: 'workspace',
|
|
861
156
|
directory: options.directory,
|
|
862
157
|
skipInstall: options.skipInstall || false
|
|
863
158
|
});
|
|
864
|
-
console.log(
|
|
865
|
-
console.log(
|
|
866
|
-
console.log(
|
|
867
|
-
console.log(
|
|
868
|
-
console.log(
|
|
869
|
-
console.log(
|
|
159
|
+
console.log(chalk_1.default.green('⨠Successfully initialized Idealyst workspace!'));
|
|
160
|
+
console.log(chalk_1.default.blue(`š Workspace created in: ${options.directory}/${projectName}`));
|
|
161
|
+
console.log(chalk_1.default.yellow('\nš Next steps:'));
|
|
162
|
+
console.log(chalk_1.default.white(` cd ${projectName}`));
|
|
163
|
+
console.log(chalk_1.default.white(' idealyst create my-app --type native'));
|
|
164
|
+
console.log(chalk_1.default.white(' idealyst create my-web-app --type web'));
|
|
870
165
|
}
|
|
871
166
|
catch (error) {
|
|
872
|
-
console.error(
|
|
167
|
+
console.error(chalk_1.default.red('ā Error initializing workspace:'), error);
|
|
873
168
|
process.exit(1);
|
|
874
169
|
}
|
|
875
170
|
});
|
|
876
171
|
program.parse();
|
|
172
|
+
//# sourceMappingURL=index.js.map
|