@idealyst/cli 1.0.23 ā 1.0.25
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/README.md +109 -109
- package/dist/index.js +119 -30
- package/dist/types/generators/api.d.ts +2 -0
- package/dist/types/generators/index.d.ts +1 -0
- package/dist/types/generators/utils.d.ts +14 -1
- package/dist/types/types.d.ts +1 -1
- package/package.json +1 -1
- package/templates/api/README.md +207 -0
- package/templates/api/env.example +12 -0
- package/templates/api/package.json +49 -0
- package/templates/api/prisma/schema.prisma +21 -0
- package/templates/api/src/context.ts +23 -0
- package/templates/api/src/controllers/UserController.ts +102 -0
- package/templates/api/src/index.ts +50 -0
- package/templates/api/src/lib/controller.ts +90 -0
- package/templates/api/src/lib/middleware.ts +170 -0
- package/templates/api/src/middleware/auth.ts +75 -0
- package/templates/api/src/middleware/common.ts +103 -0
- package/templates/api/src/router/index.ts +130 -0
- package/templates/api/src/trpc.ts +28 -0
- package/templates/api/tsconfig.json +44 -0
- package/templates/native/.yarnrc.yml +18 -18
- package/templates/native/App.tsx +23 -23
- package/templates/native/README.md +85 -85
- package/templates/native/app.json +4 -4
- package/templates/native/babel.config.js +9 -9
- package/templates/native/index.js +5 -5
- package/templates/native/metro.config.js +27 -21
- package/templates/native/package.json +9 -9
- package/templates/native/tsconfig.json +29 -29
- package/templates/shared/README.md +108 -108
- package/templates/shared/package.json +39 -41
- package/templates/shared/src/index.ts +1 -11
- package/templates/shared/tsconfig.json +24 -24
- package/templates/web/README.md +89 -89
- package/templates/web/index.html +12 -12
- package/templates/web/package.json +51 -51
- package/templates/web/src/App.tsx +14 -14
- package/templates/web/src/main.tsx +24 -24
- package/templates/web/tsconfig.json +26 -26
- package/templates/web/vite.config.ts +68 -65
- package/templates/workspace/.yarnrc.yml +25 -25
- package/templates/workspace/README.md +79 -79
- package/templates/workspace/package.json +24 -24
- package/templates/shared/.yarnrc.yml +0 -19
- package/templates/shared/rollup.config.js +0 -27
- package/templates/shared/src/components/SharedComponent.tsx +0 -41
- package/templates/shared/src/components/index.ts +0 -3
- package/templates/shared/src/types/index.ts +0 -17
- package/templates/shared/src/utils/helpers.ts +0 -34
- package/templates/shared/src/utils/index.ts +0 -2
package/README.md
CHANGED
|
@@ -1,110 +1,110 @@
|
|
|
1
|
-
# @idealyst/cli
|
|
2
|
-
|
|
3
|
-
CLI tool for generating Idealyst Framework projects.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
Install globally:
|
|
8
|
-
```bash
|
|
9
|
-
npm install -g @idealyst/cli
|
|
10
|
-
# or
|
|
11
|
-
yarn global add @idealyst/cli
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
## Usage
|
|
15
|
-
|
|
16
|
-
### Create a new project
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
idealyst create <project-name> [options]
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
Options:
|
|
23
|
-
- `-t, --type <type>` - Project type: `native`, `web`, or `shared` (default: `native`)
|
|
24
|
-
- `-d, --directory <directory>` - Output directory (default: current directory)
|
|
25
|
-
- `--skip-install` - Skip installing dependencies
|
|
26
|
-
|
|
27
|
-
### Initialize a new workspace
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
idealyst init [options]
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
Options:
|
|
34
|
-
- `-d, --directory <directory>` - Output directory (default: current directory)
|
|
35
|
-
- `--skip-install` - Skip installing dependencies
|
|
36
|
-
|
|
37
|
-
## Examples
|
|
38
|
-
|
|
39
|
-
Create a React Native app:
|
|
40
|
-
```bash
|
|
41
|
-
idealyst create my-app --type native
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
Create a React web app:
|
|
45
|
-
```bash
|
|
46
|
-
idealyst create my-web-app --type web
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Create a shared library:
|
|
50
|
-
```bash
|
|
51
|
-
idealyst create my-lib --type shared
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
Initialize a new workspace:
|
|
55
|
-
```bash
|
|
56
|
-
idealyst init
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## Project Types
|
|
60
|
-
|
|
61
|
-
### Native (React Native)
|
|
62
|
-
- React Native 0.80.1
|
|
63
|
-
- Idealyst Components
|
|
64
|
-
- Idealyst Navigation
|
|
65
|
-
- Idealyst Theme
|
|
66
|
-
- TypeScript configuration
|
|
67
|
-
- Metro bundler configuration
|
|
68
|
-
- Babel configuration
|
|
69
|
-
|
|
70
|
-
### Web (React + Vite)
|
|
71
|
-
- React 19.1
|
|
72
|
-
- Vite build system
|
|
73
|
-
- Idealyst Components (web-compatible)
|
|
74
|
-
- Idealyst Navigation
|
|
75
|
-
- Idealyst Theme
|
|
76
|
-
- TypeScript configuration
|
|
77
|
-
- React Native Web support
|
|
78
|
-
|
|
79
|
-
### Shared Library
|
|
80
|
-
- Cross-platform components
|
|
81
|
-
- TypeScript definitions
|
|
82
|
-
- Rollup build system
|
|
83
|
-
- Peer dependencies for React/React Native
|
|
84
|
-
- Idealyst Theme integration
|
|
85
|
-
|
|
86
|
-
### Workspace
|
|
87
|
-
- Yarn workspace configuration
|
|
88
|
-
- Monorepo structure
|
|
89
|
-
- Version management scripts
|
|
90
|
-
- Build scripts for all packages
|
|
91
|
-
|
|
92
|
-
## Development
|
|
93
|
-
|
|
94
|
-
Build the CLI:
|
|
95
|
-
```bash
|
|
96
|
-
cd packages/cli
|
|
97
|
-
yarn build
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Link for local development:
|
|
101
|
-
```bash
|
|
102
|
-
yarn link
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
## Learn More
|
|
106
|
-
|
|
107
|
-
- [Idealyst Framework Documentation](https://github.com/your-username/idealyst-framework)
|
|
108
|
-
- [React Native Documentation](https://reactnative.dev/)
|
|
109
|
-
- [React Documentation](https://react.dev/)
|
|
1
|
+
# @idealyst/cli
|
|
2
|
+
|
|
3
|
+
CLI tool for generating Idealyst Framework projects.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Install globally:
|
|
8
|
+
```bash
|
|
9
|
+
npm install -g @idealyst/cli
|
|
10
|
+
# or
|
|
11
|
+
yarn global add @idealyst/cli
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
### Create a new project
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
idealyst create <project-name> [options]
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Options:
|
|
23
|
+
- `-t, --type <type>` - Project type: `native`, `web`, or `shared` (default: `native`)
|
|
24
|
+
- `-d, --directory <directory>` - Output directory (default: current directory)
|
|
25
|
+
- `--skip-install` - Skip installing dependencies
|
|
26
|
+
|
|
27
|
+
### Initialize a new workspace
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
idealyst init [options]
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Options:
|
|
34
|
+
- `-d, --directory <directory>` - Output directory (default: current directory)
|
|
35
|
+
- `--skip-install` - Skip installing dependencies
|
|
36
|
+
|
|
37
|
+
## Examples
|
|
38
|
+
|
|
39
|
+
Create a React Native app:
|
|
40
|
+
```bash
|
|
41
|
+
idealyst create my-app --type native
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Create a React web app:
|
|
45
|
+
```bash
|
|
46
|
+
idealyst create my-web-app --type web
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Create a shared library:
|
|
50
|
+
```bash
|
|
51
|
+
idealyst create my-lib --type shared
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Initialize a new workspace:
|
|
55
|
+
```bash
|
|
56
|
+
idealyst init
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Project Types
|
|
60
|
+
|
|
61
|
+
### Native (React Native)
|
|
62
|
+
- React Native 0.80.1
|
|
63
|
+
- Idealyst Components
|
|
64
|
+
- Idealyst Navigation
|
|
65
|
+
- Idealyst Theme
|
|
66
|
+
- TypeScript configuration
|
|
67
|
+
- Metro bundler configuration
|
|
68
|
+
- Babel configuration
|
|
69
|
+
|
|
70
|
+
### Web (React + Vite)
|
|
71
|
+
- React 19.1
|
|
72
|
+
- Vite build system
|
|
73
|
+
- Idealyst Components (web-compatible)
|
|
74
|
+
- Idealyst Navigation
|
|
75
|
+
- Idealyst Theme
|
|
76
|
+
- TypeScript configuration
|
|
77
|
+
- React Native Web support
|
|
78
|
+
|
|
79
|
+
### Shared Library
|
|
80
|
+
- Cross-platform components
|
|
81
|
+
- TypeScript definitions
|
|
82
|
+
- Rollup build system
|
|
83
|
+
- Peer dependencies for React/React Native
|
|
84
|
+
- Idealyst Theme integration
|
|
85
|
+
|
|
86
|
+
### Workspace
|
|
87
|
+
- Yarn workspace configuration
|
|
88
|
+
- Monorepo structure
|
|
89
|
+
- Version management scripts
|
|
90
|
+
- Build scripts for all packages
|
|
91
|
+
|
|
92
|
+
## Development
|
|
93
|
+
|
|
94
|
+
Build the CLI:
|
|
95
|
+
```bash
|
|
96
|
+
cd packages/cli
|
|
97
|
+
yarn build
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Link for local development:
|
|
101
|
+
```bash
|
|
102
|
+
yarn link
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Learn More
|
|
106
|
+
|
|
107
|
+
- [Idealyst Framework Documentation](https://github.com/your-username/idealyst-framework)
|
|
108
|
+
- [React Native Documentation](https://reactnative.dev/)
|
|
109
|
+
- [React Documentation](https://react.dev/)
|
|
110
110
|
- [Vite Documentation](https://vitejs.dev/)
|
package/dist/index.js
CHANGED
|
@@ -16,7 +16,7 @@ function validateProjectName(name) {
|
|
|
16
16
|
function createPackageName(name) {
|
|
17
17
|
return name.toLowerCase().replace(/[^a-z0-9-]/g, '-');
|
|
18
18
|
}
|
|
19
|
-
async function updateWorkspacePackageJson(
|
|
19
|
+
async function updateWorkspacePackageJson(workspacePath, directory) {
|
|
20
20
|
// Look for package.json in the directory to see if we're in a workspace
|
|
21
21
|
const packageJsonPath = path.join(directory, 'package.json');
|
|
22
22
|
if (await fs.pathExists(packageJsonPath)) {
|
|
@@ -24,11 +24,18 @@ async function updateWorkspacePackageJson(projectName, directory) {
|
|
|
24
24
|
const packageJson = await fs.readJSON(packageJsonPath);
|
|
25
25
|
// Check if this is a workspace (has workspaces property)
|
|
26
26
|
if (packageJson.workspaces && Array.isArray(packageJson.workspaces)) {
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
|
|
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);
|
|
30
34
|
await fs.writeJSON(packageJsonPath, packageJson, { spaces: 2 });
|
|
31
|
-
console.log(chalk.green(`ā
Added ${
|
|
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`));
|
|
32
39
|
}
|
|
33
40
|
}
|
|
34
41
|
}
|
|
@@ -78,6 +85,9 @@ async function processTemplateFile(filePath, data) {
|
|
|
78
85
|
content = content.replace(/\{\{packageName\}\}/g, data.packageName);
|
|
79
86
|
content = content.replace(/\{\{version\}\}/g, data.version);
|
|
80
87
|
content = content.replace(/\{\{description\}\}/g, data.description);
|
|
88
|
+
// Handle appName (with fallback to projectName if not provided)
|
|
89
|
+
const appName = data.appName || data.projectName;
|
|
90
|
+
content = content.replace(/\{\{appName\}\}/g, appName);
|
|
81
91
|
await fs.writeFile(filePath, content);
|
|
82
92
|
}
|
|
83
93
|
catch (error) {
|
|
@@ -133,6 +143,43 @@ function getTemplateData(projectName, description, appName) {
|
|
|
133
143
|
appName
|
|
134
144
|
};
|
|
135
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Detects if we're in a workspace root directory
|
|
148
|
+
*/
|
|
149
|
+
async function isWorkspaceRoot(directory) {
|
|
150
|
+
const packageJsonPath = path.join(directory, 'package.json');
|
|
151
|
+
if (await fs.pathExists(packageJsonPath)) {
|
|
152
|
+
try {
|
|
153
|
+
const packageJson = await fs.readJSON(packageJsonPath);
|
|
154
|
+
return !!(packageJson.workspaces && Array.isArray(packageJson.workspaces));
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Resolves the correct project path for individual projects (native, web, shared).
|
|
164
|
+
* Individual projects can ONLY be created within an existing workspace.
|
|
165
|
+
* This enforces proper monorepo structure and prevents scattered individual projects.
|
|
166
|
+
*/
|
|
167
|
+
async function resolveProjectPath(projectName, directory) {
|
|
168
|
+
// Check if we're in a workspace directory
|
|
169
|
+
const isWorkspace = await isWorkspaceRoot(directory);
|
|
170
|
+
if (!isWorkspace) {
|
|
171
|
+
throw new Error(`Individual projects can only be created within a workspace.\n` +
|
|
172
|
+
`Please first create a workspace with: idealyst init my-workspace\n` +
|
|
173
|
+
`Then navigate to the workspace directory and create your project.`);
|
|
174
|
+
}
|
|
175
|
+
// Create project in workspace's packages/ folder
|
|
176
|
+
const packagesDir = path.join(directory, 'packages');
|
|
177
|
+
await fs.ensureDir(packagesDir);
|
|
178
|
+
return {
|
|
179
|
+
projectPath: path.join(packagesDir, projectName),
|
|
180
|
+
workspacePath: `packages/${projectName}`
|
|
181
|
+
};
|
|
182
|
+
}
|
|
136
183
|
async function initializeReactNativeProject(projectName, directory, displayName, skipInstall) {
|
|
137
184
|
const spinner = ora('Initializing React Native project...').start();
|
|
138
185
|
try {
|
|
@@ -259,7 +306,8 @@ async function promptForProjectType() {
|
|
|
259
306
|
choices: [
|
|
260
307
|
{ name: 'React Native App', value: 'native' },
|
|
261
308
|
{ name: 'React Web App', value: 'web' },
|
|
262
|
-
{ name: 'Shared Library', value: 'shared' }
|
|
309
|
+
{ name: 'Shared Library', value: 'shared' },
|
|
310
|
+
{ name: 'API Server (tRPC + Prisma + Zod)', value: 'api' }
|
|
263
311
|
],
|
|
264
312
|
default: 'native'
|
|
265
313
|
}
|
|
@@ -327,6 +375,7 @@ var utils = /*#__PURE__*/Object.freeze({
|
|
|
327
375
|
getTemplateData: getTemplateData,
|
|
328
376
|
initializeReactNativeProject: initializeReactNativeProject,
|
|
329
377
|
installDependencies: installDependencies,
|
|
378
|
+
isWorkspaceRoot: isWorkspaceRoot,
|
|
330
379
|
mergePackageJsonDependencies: mergePackageJsonDependencies,
|
|
331
380
|
overlayIdealystFiles: overlayIdealystFiles,
|
|
332
381
|
processTemplateFile: processTemplateFile,
|
|
@@ -334,13 +383,14 @@ var utils = /*#__PURE__*/Object.freeze({
|
|
|
334
383
|
promptForAppName: promptForAppName,
|
|
335
384
|
promptForProjectName: promptForProjectName,
|
|
336
385
|
promptForProjectType: promptForProjectType,
|
|
386
|
+
resolveProjectPath: resolveProjectPath,
|
|
337
387
|
runCommand: runCommand,
|
|
338
388
|
updateWorkspacePackageJson: updateWorkspacePackageJson,
|
|
339
389
|
validateProjectName: validateProjectName
|
|
340
390
|
});
|
|
341
391
|
|
|
342
|
-
const __filename$
|
|
343
|
-
const __dirname$
|
|
392
|
+
const __filename$4 = fileURLToPath(import.meta.url);
|
|
393
|
+
const __dirname$4 = path.dirname(__filename$4);
|
|
344
394
|
async function generateNativeProject(options) {
|
|
345
395
|
const { name, directory, skipInstall, appName } = options;
|
|
346
396
|
if (!validateProjectName(name)) {
|
|
@@ -349,14 +399,17 @@ async function generateNativeProject(options) {
|
|
|
349
399
|
const displayName = appName || name.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(' ');
|
|
350
400
|
console.log(chalk.blue(`š± Creating React Native project: ${name}`));
|
|
351
401
|
console.log(chalk.gray(` App display name: ${displayName}`));
|
|
352
|
-
const projectPath =
|
|
353
|
-
const templatePath = path.join(__dirname$
|
|
402
|
+
const { projectPath, workspacePath } = await resolveProjectPath(name, directory);
|
|
403
|
+
const templatePath = path.join(__dirname$4, '..', 'templates', 'native');
|
|
354
404
|
const templateData = getTemplateData(name, `React Native app built with Idealyst Framework`, displayName);
|
|
355
405
|
try {
|
|
356
406
|
// Step 1: Update workspace configuration FIRST (before React Native CLI)
|
|
357
|
-
await updateWorkspacePackageJson(
|
|
407
|
+
await updateWorkspacePackageJson(workspacePath, directory);
|
|
358
408
|
// Step 2: Initialize React Native project using CLI with --skip-install
|
|
359
|
-
|
|
409
|
+
// Note: For React Native CLI, we need to run it in the parent directory and specify the project name
|
|
410
|
+
const projectDir = path.dirname(projectPath);
|
|
411
|
+
const projectName = path.basename(projectPath);
|
|
412
|
+
await initializeReactNativeProject(projectName, projectDir, displayName, true);
|
|
360
413
|
// Step 3: Overlay Idealyst-specific files
|
|
361
414
|
await overlayIdealystFiles(templatePath, projectPath, templateData);
|
|
362
415
|
// Step 4: Configure Android vector icons
|
|
@@ -382,20 +435,20 @@ async function generateNativeProject(options) {
|
|
|
382
435
|
}
|
|
383
436
|
}
|
|
384
437
|
|
|
385
|
-
const __filename$
|
|
386
|
-
const __dirname$
|
|
438
|
+
const __filename$3 = fileURLToPath(import.meta.url);
|
|
439
|
+
const __dirname$3 = path.dirname(__filename$3);
|
|
387
440
|
async function generateWebProject(options) {
|
|
388
441
|
const { name, directory, skipInstall } = options;
|
|
389
442
|
if (!validateProjectName(name)) {
|
|
390
443
|
throw new Error(`Invalid project name: ${name}`);
|
|
391
444
|
}
|
|
392
445
|
console.log(chalk.blue(`š Creating React Web project: ${name}`));
|
|
393
|
-
const projectPath =
|
|
394
|
-
const templatePath = path.join(__dirname$
|
|
446
|
+
const { projectPath, workspacePath } = await resolveProjectPath(name, directory);
|
|
447
|
+
const templatePath = path.join(__dirname$3, '..', 'templates', 'web');
|
|
395
448
|
const templateData = getTemplateData(name, `React web app built with Idealyst Framework`);
|
|
396
449
|
await copyTemplate(templatePath, projectPath, templateData);
|
|
397
450
|
await installDependencies(projectPath, skipInstall);
|
|
398
|
-
await updateWorkspacePackageJson(
|
|
451
|
+
await updateWorkspacePackageJson(workspacePath, directory);
|
|
399
452
|
console.log(chalk.green('ā
React Web project created successfully!'));
|
|
400
453
|
console.log(chalk.blue('š Project includes:'));
|
|
401
454
|
console.log(chalk.white(' ⢠React 19.1'));
|
|
@@ -407,20 +460,20 @@ async function generateWebProject(options) {
|
|
|
407
460
|
console.log(chalk.white(' ⢠React Router'));
|
|
408
461
|
}
|
|
409
462
|
|
|
410
|
-
const __filename$
|
|
411
|
-
const __dirname$
|
|
463
|
+
const __filename$2 = fileURLToPath(import.meta.url);
|
|
464
|
+
const __dirname$2 = path.dirname(__filename$2);
|
|
412
465
|
async function generateSharedLibrary(options) {
|
|
413
466
|
const { name, directory, skipInstall } = options;
|
|
414
467
|
if (!validateProjectName(name)) {
|
|
415
468
|
throw new Error(`Invalid project name: ${name}`);
|
|
416
469
|
}
|
|
417
470
|
console.log(chalk.blue(`š¦ Creating shared library: ${name}`));
|
|
418
|
-
const projectPath =
|
|
419
|
-
const templatePath = path.join(__dirname$
|
|
471
|
+
const { projectPath, workspacePath } = await resolveProjectPath(name, directory);
|
|
472
|
+
const templatePath = path.join(__dirname$2, '..', 'templates', 'shared');
|
|
420
473
|
const templateData = getTemplateData(name, `Shared library built with Idealyst Framework`);
|
|
421
474
|
await copyTemplate(templatePath, projectPath, templateData);
|
|
422
475
|
await installDependencies(projectPath, skipInstall);
|
|
423
|
-
await updateWorkspacePackageJson(
|
|
476
|
+
await updateWorkspacePackageJson(workspacePath, directory);
|
|
424
477
|
console.log(chalk.green('ā
Shared library created successfully!'));
|
|
425
478
|
console.log(chalk.blue('š Project includes:'));
|
|
426
479
|
console.log(chalk.white(' ⢠Cross-platform components'));
|
|
@@ -430,8 +483,8 @@ async function generateSharedLibrary(options) {
|
|
|
430
483
|
console.log(chalk.white(' ⢠React & React Native support'));
|
|
431
484
|
}
|
|
432
485
|
|
|
433
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
434
|
-
const __dirname = path.dirname(__filename);
|
|
486
|
+
const __filename$1 = fileURLToPath(import.meta.url);
|
|
487
|
+
const __dirname$1 = path.dirname(__filename$1);
|
|
435
488
|
async function generateWorkspace(options) {
|
|
436
489
|
const { name, directory, skipInstall } = options;
|
|
437
490
|
if (!validateProjectName(name)) {
|
|
@@ -439,7 +492,7 @@ async function generateWorkspace(options) {
|
|
|
439
492
|
}
|
|
440
493
|
console.log(chalk.blue(`šļø Creating Idealyst workspace: ${name}`));
|
|
441
494
|
const projectPath = path.join(directory, name);
|
|
442
|
-
const templatePath = path.join(__dirname, '..', 'templates', 'workspace');
|
|
495
|
+
const templatePath = path.join(__dirname$1, '..', 'templates', 'workspace');
|
|
443
496
|
const templateData = getTemplateData(name, `Idealyst Framework monorepo workspace`);
|
|
444
497
|
await copyTemplate(templatePath, projectPath, templateData);
|
|
445
498
|
await installDependencies(projectPath, skipInstall);
|
|
@@ -452,6 +505,32 @@ async function generateWorkspace(options) {
|
|
|
452
505
|
console.log(chalk.white(' ⢠Version management scripts'));
|
|
453
506
|
}
|
|
454
507
|
|
|
508
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
509
|
+
const __dirname = path.dirname(__filename);
|
|
510
|
+
async function generateApiProject(options) {
|
|
511
|
+
const { name, directory, skipInstall } = options;
|
|
512
|
+
if (!validateProjectName(name)) {
|
|
513
|
+
throw new Error(`Invalid project name: ${name}`);
|
|
514
|
+
}
|
|
515
|
+
console.log(chalk.blue(`š Creating API project: ${name}`));
|
|
516
|
+
const { projectPath, workspacePath } = await resolveProjectPath(name, directory);
|
|
517
|
+
const templatePath = path.join(__dirname, '..', 'templates', 'api');
|
|
518
|
+
const templateData = getTemplateData(name, `Clean API server template with tRPC, Prisma, and Zod`);
|
|
519
|
+
await copyTemplate(templatePath, projectPath, templateData);
|
|
520
|
+
await installDependencies(projectPath, skipInstall);
|
|
521
|
+
await updateWorkspacePackageJson(workspacePath, directory);
|
|
522
|
+
console.log(chalk.green('ā
API project created successfully!'));
|
|
523
|
+
console.log(chalk.blue('š Project includes:'));
|
|
524
|
+
console.log(chalk.white(' ⢠tRPC for type-safe APIs'));
|
|
525
|
+
console.log(chalk.white(' ⢠Prisma for database management'));
|
|
526
|
+
console.log(chalk.white(' ⢠Zod for schema validation'));
|
|
527
|
+
console.log(chalk.white(' ⢠Express.js server'));
|
|
528
|
+
console.log(chalk.white(' ⢠TypeScript configuration'));
|
|
529
|
+
console.log(chalk.white(' ⢠CORS and middleware setup'));
|
|
530
|
+
console.log(chalk.white(' ⢠Database migration scripts'));
|
|
531
|
+
console.log(chalk.white(' ⢠Clean template ready for your models'));
|
|
532
|
+
}
|
|
533
|
+
|
|
455
534
|
async function generateProject(options) {
|
|
456
535
|
const { type } = options;
|
|
457
536
|
switch (type) {
|
|
@@ -467,6 +546,9 @@ async function generateProject(options) {
|
|
|
467
546
|
case 'workspace':
|
|
468
547
|
await generateWorkspace(options);
|
|
469
548
|
break;
|
|
549
|
+
case 'api':
|
|
550
|
+
await generateApiProject(options);
|
|
551
|
+
break;
|
|
470
552
|
default:
|
|
471
553
|
throw new Error(`Unknown project type: ${type}`);
|
|
472
554
|
}
|
|
@@ -505,7 +587,7 @@ program
|
|
|
505
587
|
if (!projectType) {
|
|
506
588
|
projectType = await promptForProjectType();
|
|
507
589
|
}
|
|
508
|
-
const validTypes = ['native', 'web', 'shared'];
|
|
590
|
+
const validTypes = ['native', 'web', 'shared', 'api'];
|
|
509
591
|
if (!validTypes.includes(projectType)) {
|
|
510
592
|
console.error(chalk.red(`Invalid project type: ${projectType}`));
|
|
511
593
|
console.error(chalk.yellow(`Valid types are: ${validTypes.join(', ')}`));
|
|
@@ -524,20 +606,27 @@ program
|
|
|
524
606
|
appName
|
|
525
607
|
});
|
|
526
608
|
console.log(chalk.green(`⨠Successfully created ${projectName}!`));
|
|
527
|
-
console.log(chalk.blue(`š Project created in: ${options.directory}/${projectName}`));
|
|
609
|
+
console.log(chalk.blue(`š Project created in: ${options.directory}/packages/${projectName}`));
|
|
528
610
|
if (projectType === 'native') {
|
|
529
611
|
console.log(chalk.yellow('\nš± Next steps for React Native:'));
|
|
530
|
-
console.log(chalk.white(' cd ' + projectName));
|
|
612
|
+
console.log(chalk.white(' cd packages/' + projectName));
|
|
531
613
|
console.log(chalk.white(' yarn android # or yarn ios'));
|
|
532
614
|
}
|
|
533
615
|
else if (projectType === 'web') {
|
|
534
616
|
console.log(chalk.yellow('\nš Next steps for React Web:'));
|
|
535
|
-
console.log(chalk.white(' cd ' + projectName));
|
|
617
|
+
console.log(chalk.white(' cd packages/' + projectName));
|
|
536
618
|
console.log(chalk.white(' yarn dev'));
|
|
537
619
|
}
|
|
620
|
+
else if (projectType === 'api') {
|
|
621
|
+
console.log(chalk.yellow('\nš Next steps for API Server:'));
|
|
622
|
+
console.log(chalk.white(' cd packages/' + projectName));
|
|
623
|
+
console.log(chalk.white(' yarn dev # Start development server'));
|
|
624
|
+
console.log(chalk.white(' yarn db:push # Push database schema'));
|
|
625
|
+
console.log(chalk.white(' yarn db:studio # Open Prisma Studio'));
|
|
626
|
+
}
|
|
538
627
|
else {
|
|
539
628
|
console.log(chalk.yellow('\nš¦ Next steps for Shared Library:'));
|
|
540
|
-
console.log(chalk.white(' cd ' + projectName));
|
|
629
|
+
console.log(chalk.white(' cd packages/' + projectName));
|
|
541
630
|
console.log(chalk.white(' yarn build'));
|
|
542
631
|
}
|
|
543
632
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TemplateData } from '../types';
|
|
2
2
|
export declare function validateProjectName(name: string): boolean;
|
|
3
3
|
export declare function createPackageName(name: string): string;
|
|
4
|
-
export declare function updateWorkspacePackageJson(
|
|
4
|
+
export declare function updateWorkspacePackageJson(workspacePath: string, directory: string): Promise<void>;
|
|
5
5
|
export declare function copyTemplate(templatePath: string, destPath: string, data: TemplateData): Promise<void>;
|
|
6
6
|
export declare function processTemplateFiles(dir: string, data: TemplateData): Promise<void>;
|
|
7
7
|
export declare function processTemplateFile(filePath: string, data: TemplateData): Promise<void>;
|
|
@@ -10,6 +10,19 @@ export declare function runCommand(command: string, args: string[], options: {
|
|
|
10
10
|
cwd: string;
|
|
11
11
|
}): Promise<void>;
|
|
12
12
|
export declare function getTemplateData(projectName: string, description?: string, appName?: string): TemplateData;
|
|
13
|
+
/**
|
|
14
|
+
* Detects if we're in a workspace root directory
|
|
15
|
+
*/
|
|
16
|
+
export declare function isWorkspaceRoot(directory: string): Promise<boolean>;
|
|
17
|
+
/**
|
|
18
|
+
* Resolves the correct project path for individual projects (native, web, shared).
|
|
19
|
+
* Individual projects can ONLY be created within an existing workspace.
|
|
20
|
+
* This enforces proper monorepo structure and prevents scattered individual projects.
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveProjectPath(projectName: string, directory: string): Promise<{
|
|
23
|
+
projectPath: string;
|
|
24
|
+
workspacePath: string;
|
|
25
|
+
}>;
|
|
13
26
|
export declare function initializeReactNativeProject(projectName: string, directory: string, displayName?: string, skipInstall?: boolean): Promise<void>;
|
|
14
27
|
export declare function overlayIdealystFiles(templatePath: string, projectPath: string, data: TemplateData): Promise<void>;
|
|
15
28
|
export declare function mergePackageJsonDependencies(templatePath: string, projectPath: string): Promise<void>;
|
package/dist/types/types.d.ts
CHANGED