@gyxer-studio/cli 0.1.0
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 +61 -0
- package/dist/commands/generate.d.ts +6 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +157 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/new.d.ts +2 -0
- package/dist/commands/new.d.ts.map +1 -0
- package/dist/commands/new.js +147 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/package.json +59 -0
package/README.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# @gyxer-studio/cli
|
|
2
|
+
|
|
3
|
+
CLI tool for generating production-ready NestJS projects from Gyxer schema configs.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
### Generate from config
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx @gyxer-studio/cli generate my-app.json -o ./my-app
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or if installed globally:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
gyxer generate my-app.json -o ./my-app
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Interactive wizard
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx @gyxer-studio/cli new my-app
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The wizard walks you through choosing:
|
|
26
|
+
- Database (PostgreSQL, MySQL, SQLite)
|
|
27
|
+
- Port
|
|
28
|
+
- Swagger
|
|
29
|
+
- JWT Authentication
|
|
30
|
+
- Docker
|
|
31
|
+
- Helmet & Rate Limiting
|
|
32
|
+
|
|
33
|
+
### Auto-discovery
|
|
34
|
+
|
|
35
|
+
The `generate` command automatically searches for config files in:
|
|
36
|
+
- `./configs/`
|
|
37
|
+
- `./examples/`
|
|
38
|
+
- Current directory
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# If my-app.json exists in ./configs/
|
|
42
|
+
gyxer generate my-app
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Global Installation
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm install -g @gyxer-studio/cli
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Example Configs
|
|
52
|
+
|
|
53
|
+
See [examples/](https://github.com/Gyxer513/gyxer-studio/tree/master/examples) for ready-to-use configs:
|
|
54
|
+
|
|
55
|
+
- `blog.json` — Blog with users, posts, comments
|
|
56
|
+
- `blog-with-auth.json` — Same blog + JWT authentication
|
|
57
|
+
- `shop.json` — E-commerce with 6 entities and enums
|
|
58
|
+
|
|
59
|
+
## Part of [Gyxer Studio](https://github.com/Gyxer513/gyxer-studio)
|
|
60
|
+
|
|
61
|
+
MIT License
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAQA,UAAU,eAAe;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA4FD,wBAAsB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,eAAe,iBAsF7F"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import ora from 'ora';
|
|
5
|
+
import inquirer from 'inquirer';
|
|
6
|
+
import { parseProjectJson } from '@gyxer-studio/schema';
|
|
7
|
+
import { generateProject } from '@gyxer-studio/generator';
|
|
8
|
+
/**
|
|
9
|
+
* Search for config files in known locations:
|
|
10
|
+
* - ./configs/
|
|
11
|
+
* - Current directory (.json files, excluding package.json / tsconfig)
|
|
12
|
+
*/
|
|
13
|
+
function findConfigFiles() {
|
|
14
|
+
const configs = [];
|
|
15
|
+
// 1. Look in configs/ directory (relative to cwd)
|
|
16
|
+
const configsDir = path.resolve('configs');
|
|
17
|
+
if (fs.existsSync(configsDir)) {
|
|
18
|
+
const files = fs.readdirSync(configsDir).filter((f) => f.endsWith('.json'));
|
|
19
|
+
for (const file of files) {
|
|
20
|
+
const filePath = path.join(configsDir, file);
|
|
21
|
+
const stat = fs.statSync(filePath);
|
|
22
|
+
configs.push({ name: file, path: filePath, modified: stat.mtime });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// 2. Look in current directory for .json files (root level only)
|
|
26
|
+
const cwdFiles = fs.readdirSync(process.cwd()).filter((f) => f.endsWith('.json') &&
|
|
27
|
+
!f.startsWith('package') &&
|
|
28
|
+
!f.startsWith('tsconfig') &&
|
|
29
|
+
f !== '.gitkeep');
|
|
30
|
+
for (const file of cwdFiles) {
|
|
31
|
+
const filePath = path.resolve(file);
|
|
32
|
+
// Avoid duplicates if configs/ is in cwd
|
|
33
|
+
if (!configs.some((c) => c.path === filePath)) {
|
|
34
|
+
const stat = fs.statSync(filePath);
|
|
35
|
+
configs.push({ name: file, path: filePath, modified: stat.mtime });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Sort by modification date (newest first)
|
|
39
|
+
configs.sort((a, b) => b.modified.getTime() - a.modified.getTime());
|
|
40
|
+
return configs;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Interactive config selection — called when no schema path is provided.
|
|
44
|
+
*/
|
|
45
|
+
async function selectConfigInteractive() {
|
|
46
|
+
console.log('');
|
|
47
|
+
console.log(chalk.bold(' \u26A1 Gyxer Generator'));
|
|
48
|
+
console.log(chalk.dim(' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550'));
|
|
49
|
+
console.log('');
|
|
50
|
+
const configs = findConfigFiles();
|
|
51
|
+
if (configs.length === 0) {
|
|
52
|
+
console.log(chalk.yellow(' \u26A0 No config files found.'));
|
|
53
|
+
console.log('');
|
|
54
|
+
console.log(chalk.dim(' Place .json configs in one of these locations:'));
|
|
55
|
+
console.log(chalk.cyan(' ./configs/*.json'));
|
|
56
|
+
console.log(chalk.cyan(' ./*.json'));
|
|
57
|
+
console.log('');
|
|
58
|
+
console.log(chalk.dim(' Or specify a path directly:'));
|
|
59
|
+
console.log(chalk.cyan(' gyxer generate <path-to-schema.json>'));
|
|
60
|
+
console.log('');
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
console.log(chalk.dim(` Found ${configs.length} config(s):`));
|
|
64
|
+
console.log('');
|
|
65
|
+
const choices = configs.map((c) => {
|
|
66
|
+
const relPath = path.relative(process.cwd(), c.path);
|
|
67
|
+
const date = c.modified.toLocaleString();
|
|
68
|
+
return {
|
|
69
|
+
name: `${c.name} ${chalk.dim(`\u2014 ${relPath} (${date})`)}`,
|
|
70
|
+
value: c.path,
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
const { selectedConfig } = await inquirer.prompt([
|
|
74
|
+
{
|
|
75
|
+
type: 'list',
|
|
76
|
+
name: 'selectedConfig',
|
|
77
|
+
message: 'Select a config to generate:',
|
|
78
|
+
choices,
|
|
79
|
+
},
|
|
80
|
+
]);
|
|
81
|
+
return selectedConfig;
|
|
82
|
+
}
|
|
83
|
+
export async function generateCommand(schemaPath, options) {
|
|
84
|
+
// If no schema path provided — interactive selection
|
|
85
|
+
const resolvedPath = schemaPath
|
|
86
|
+
? path.resolve(schemaPath)
|
|
87
|
+
: await selectConfigInteractive();
|
|
88
|
+
if (schemaPath) {
|
|
89
|
+
console.log('');
|
|
90
|
+
console.log(chalk.bold(' \u26A1 Gyxer Generator'));
|
|
91
|
+
console.log(chalk.dim(' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550'));
|
|
92
|
+
console.log('');
|
|
93
|
+
}
|
|
94
|
+
// Read schema file
|
|
95
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
96
|
+
console.error(chalk.red(` \u2716 Schema file not found: ${resolvedPath}`));
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
const json = fs.readFileSync(resolvedPath, 'utf-8');
|
|
100
|
+
// Validate
|
|
101
|
+
console.log(` ${chalk.dim('Schema:')} ${resolvedPath}`);
|
|
102
|
+
const result = parseProjectJson(json);
|
|
103
|
+
if (!result.success || !result.data) {
|
|
104
|
+
console.error(chalk.red(' \u2716 Validation failed:'));
|
|
105
|
+
for (const err of result.errors || []) {
|
|
106
|
+
console.error(chalk.red(` \u2022 ${err.path}: ${err.message}`));
|
|
107
|
+
}
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
const projectName = result.data.name;
|
|
111
|
+
console.log(` ${chalk.dim('Project:')} ${projectName}`);
|
|
112
|
+
console.log(` ${chalk.dim('Entities:')} ${result.data.entities.length}`);
|
|
113
|
+
console.log('');
|
|
114
|
+
// Determine output directory
|
|
115
|
+
const outputDir = path.resolve(options.output || `./${projectName}`);
|
|
116
|
+
// If output dir exists, ask for confirmation
|
|
117
|
+
if (fs.existsSync(outputDir)) {
|
|
118
|
+
const { overwrite } = await inquirer.prompt([
|
|
119
|
+
{
|
|
120
|
+
type: 'confirm',
|
|
121
|
+
name: 'overwrite',
|
|
122
|
+
message: chalk.yellow(`Directory "${path.relative(process.cwd(), outputDir)}" already exists. Overwrite?`),
|
|
123
|
+
default: false,
|
|
124
|
+
},
|
|
125
|
+
]);
|
|
126
|
+
if (!overwrite) {
|
|
127
|
+
console.log(chalk.dim(' Cancelled.'));
|
|
128
|
+
process.exit(0);
|
|
129
|
+
}
|
|
130
|
+
console.log('');
|
|
131
|
+
}
|
|
132
|
+
// Generate with spinner
|
|
133
|
+
const spinner = ora('Generating project...').start();
|
|
134
|
+
try {
|
|
135
|
+
const genResult = await generateProject(result.data, { outputDir, silent: true });
|
|
136
|
+
spinner.succeed(chalk.green('Project generated!'));
|
|
137
|
+
console.log('');
|
|
138
|
+
console.log(` ${chalk.green('\u2705')} ${chalk.bold(String(genResult.filesCreated.length))} files created in ${chalk.cyan(outputDir)}`);
|
|
139
|
+
// Security score
|
|
140
|
+
const score = genResult.securityReport.score;
|
|
141
|
+
const scoreColor = score >= 80 ? chalk.green : score >= 50 ? chalk.yellow : chalk.red;
|
|
142
|
+
console.log(` ${chalk.yellow('\uD83D\uDEE1\uFE0F')} Security: ${scoreColor(`${score}%`)}`);
|
|
143
|
+
console.log('');
|
|
144
|
+
console.log(chalk.dim(' Next steps:'));
|
|
145
|
+
console.log(chalk.cyan(` cd ${path.relative(process.cwd(), outputDir)}`));
|
|
146
|
+
console.log(chalk.cyan(' npm install'));
|
|
147
|
+
console.log(chalk.cyan(' npx prisma migrate dev --name init'));
|
|
148
|
+
console.log(chalk.cyan(' npm run start:dev'));
|
|
149
|
+
console.log('');
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
spinner.fail(chalk.red('Generation failed'));
|
|
153
|
+
console.error(chalk.red(` ${error instanceof Error ? error.message : String(error)}`));
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"AAiCA,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,iBAuI5C"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import inquirer from 'inquirer';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
import { generateProject } from '@gyxer-studio/generator';
|
|
7
|
+
/** Build a database URL based on database type and project name. */
|
|
8
|
+
function buildDatabaseUrl(db, projectName) {
|
|
9
|
+
const dbName = projectName.replace(/-/g, '_');
|
|
10
|
+
switch (db) {
|
|
11
|
+
case 'postgresql':
|
|
12
|
+
return `postgresql://postgres:postgres@localhost:5432/${dbName}`;
|
|
13
|
+
case 'mysql':
|
|
14
|
+
return `mysql://root:root@localhost:3306/${dbName}`;
|
|
15
|
+
case 'sqlite':
|
|
16
|
+
return `file:./${dbName}.db`;
|
|
17
|
+
default:
|
|
18
|
+
return `postgresql://postgres:postgres@localhost:5432/${dbName}`;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export async function newCommand(name) {
|
|
22
|
+
console.log('');
|
|
23
|
+
console.log(chalk.bold(' \u{1F680} Gyxer \u2014 New Project'));
|
|
24
|
+
console.log(chalk.dim(' \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550'));
|
|
25
|
+
console.log('');
|
|
26
|
+
// Validate project name
|
|
27
|
+
if (!/^[a-z][a-z0-9-]*$/.test(name)) {
|
|
28
|
+
console.error(chalk.red(' \u2716 Project name must be kebab-case (e.g., "my-app")'));
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
const outputDir = path.resolve(name);
|
|
32
|
+
if (fs.existsSync(outputDir)) {
|
|
33
|
+
console.error(chalk.red(` \u2716 Directory "${name}" already exists`));
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
// ── Interactive wizard ──────────────────────────────────
|
|
37
|
+
const answers = await inquirer.prompt([
|
|
38
|
+
{
|
|
39
|
+
type: 'list',
|
|
40
|
+
name: 'database',
|
|
41
|
+
message: 'Database:',
|
|
42
|
+
choices: [
|
|
43
|
+
{ name: 'PostgreSQL', value: 'postgresql' },
|
|
44
|
+
{ name: 'MySQL', value: 'mysql' },
|
|
45
|
+
{ name: 'SQLite', value: 'sqlite' },
|
|
46
|
+
],
|
|
47
|
+
default: 'postgresql',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
type: 'number',
|
|
51
|
+
name: 'port',
|
|
52
|
+
message: 'Port:',
|
|
53
|
+
default: 3000,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
type: 'confirm',
|
|
57
|
+
name: 'swagger',
|
|
58
|
+
message: 'Enable Swagger?',
|
|
59
|
+
default: true,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
type: 'confirm',
|
|
63
|
+
name: 'authJwt',
|
|
64
|
+
message: 'Enable JWT Auth?',
|
|
65
|
+
default: false,
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
type: 'confirm',
|
|
69
|
+
name: 'docker',
|
|
70
|
+
message: 'Enable Docker?',
|
|
71
|
+
default: true,
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
type: 'confirm',
|
|
75
|
+
name: 'helmet',
|
|
76
|
+
message: 'Enable Helmet?',
|
|
77
|
+
default: true,
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
type: 'confirm',
|
|
81
|
+
name: 'rateLimit',
|
|
82
|
+
message: 'Enable Rate Limit?',
|
|
83
|
+
default: true,
|
|
84
|
+
},
|
|
85
|
+
]);
|
|
86
|
+
console.log('');
|
|
87
|
+
// ── Build project schema ────────────────────────────────
|
|
88
|
+
const modules = [];
|
|
89
|
+
if (answers.authJwt) {
|
|
90
|
+
modules.push({ name: 'auth-jwt', enabled: true, options: {} });
|
|
91
|
+
}
|
|
92
|
+
const project = {
|
|
93
|
+
name,
|
|
94
|
+
version: '0.1.0',
|
|
95
|
+
description: `${name} API`,
|
|
96
|
+
entities: [
|
|
97
|
+
{
|
|
98
|
+
name: 'User',
|
|
99
|
+
fields: [
|
|
100
|
+
{ name: 'email', type: 'string', required: true, unique: true, index: true },
|
|
101
|
+
{ name: 'name', type: 'string', required: true, unique: false, index: false },
|
|
102
|
+
{ name: 'isActive', type: 'boolean', required: true, unique: false, index: false, default: true },
|
|
103
|
+
],
|
|
104
|
+
relations: [],
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
modules,
|
|
108
|
+
settings: {
|
|
109
|
+
port: answers.port || 3000,
|
|
110
|
+
database: answers.database,
|
|
111
|
+
databaseUrl: buildDatabaseUrl(answers.database, name),
|
|
112
|
+
enableSwagger: answers.swagger,
|
|
113
|
+
enableCors: true,
|
|
114
|
+
enableHelmet: answers.helmet,
|
|
115
|
+
enableRateLimit: answers.rateLimit,
|
|
116
|
+
rateLimitTtl: 60,
|
|
117
|
+
rateLimitMax: 100,
|
|
118
|
+
docker: answers.docker,
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
// ── Generate with spinner ───────────────────────────────
|
|
122
|
+
const spinner = ora('Generating project...').start();
|
|
123
|
+
try {
|
|
124
|
+
const result = await generateProject(project, { outputDir, silent: true });
|
|
125
|
+
spinner.succeed(chalk.green('Project generated!'));
|
|
126
|
+
console.log('');
|
|
127
|
+
console.log(` ${chalk.green('\u2705')} Project ${chalk.bold(`"${name}"`)} created!`);
|
|
128
|
+
console.log(` ${chalk.blue('\u{1F4C1}')} ${outputDir} \u2014 ${chalk.bold(String(result.filesCreated.length))} files`);
|
|
129
|
+
// Security score
|
|
130
|
+
const score = result.securityReport.score;
|
|
131
|
+
const scoreColor = score >= 80 ? chalk.green : score >= 50 ? chalk.yellow : chalk.red;
|
|
132
|
+
console.log(` ${chalk.yellow('\u{1F6E1}\uFE0F')} Security: ${scoreColor(`${score}%`)}`);
|
|
133
|
+
console.log('');
|
|
134
|
+
console.log(chalk.dim(' Next steps:'));
|
|
135
|
+
console.log(chalk.cyan(` cd ${name}`));
|
|
136
|
+
console.log(chalk.cyan(' npm install'));
|
|
137
|
+
console.log(chalk.cyan(' npx prisma migrate dev --name init'));
|
|
138
|
+
console.log(chalk.cyan(' npm run start:dev'));
|
|
139
|
+
console.log('');
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
spinner.fail(chalk.red('Generation failed'));
|
|
143
|
+
console.error(chalk.red(` ${error instanceof Error ? error.message : String(error)}`));
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=new.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"new.js","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { generateCommand } from './commands/generate.js';
|
|
4
|
+
import { newCommand } from './commands/new.js';
|
|
5
|
+
const program = new Command();
|
|
6
|
+
program
|
|
7
|
+
.name('gyxer')
|
|
8
|
+
.description('Gyxer CLI — generate production-ready NestJS backends')
|
|
9
|
+
.version('0.1.0');
|
|
10
|
+
// gyxer generate [schema.json] — with or without a config path
|
|
11
|
+
program
|
|
12
|
+
.command('generate [schema]')
|
|
13
|
+
.description('Generate a NestJS project from a JSON schema (interactive if omitted)')
|
|
14
|
+
.option('-o, --output <dir>', 'Output directory (defaults to ./<project-name>)')
|
|
15
|
+
.action(generateCommand);
|
|
16
|
+
// gyxer new <name>
|
|
17
|
+
program
|
|
18
|
+
.command('new <name>')
|
|
19
|
+
.description('Create a new project with interactive wizard')
|
|
20
|
+
.action(newCommand);
|
|
21
|
+
// gyxer studio (placeholder)
|
|
22
|
+
program
|
|
23
|
+
.command('studio')
|
|
24
|
+
.description('Open the visual editor (coming soon)')
|
|
25
|
+
.action(() => {
|
|
26
|
+
console.log('Gyxer Studio visual editor is coming soon!');
|
|
27
|
+
console.log('For now, use the editor package: npm run dev -w packages/editor');
|
|
28
|
+
});
|
|
29
|
+
program.parse();
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,uDAAuD,CAAC;KACpE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,+DAA+D;AAC/D,OAAO;KACJ,OAAO,CAAC,mBAAmB,CAAC;KAC5B,WAAW,CAAC,uEAAuE,CAAC;KACpF,MAAM,CAAC,oBAAoB,EAAE,iDAAiD,CAAC;KAC/E,MAAM,CAAC,eAAe,CAAC,CAAC;AAE3B,mBAAmB;AACnB,OAAO;KACJ,OAAO,CAAC,YAAY,CAAC;KACrB,WAAW,CAAC,8CAA8C,CAAC;KAC3D,MAAM,CAAC,UAAU,CAAC,CAAC;AAEtB,6BAA6B;AAC7B,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,sCAAsC,CAAC;KACnD,MAAM,CAAC,GAAG,EAAE;IACX,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAC;AACjF,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gyxer-studio/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Gyxer CLI — generate production-ready NestJS projects from the command line",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"gyxer": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"dev": "tsc --watch",
|
|
23
|
+
"prepublishOnly": "npm run build"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"gyxer",
|
|
27
|
+
"cli",
|
|
28
|
+
"nestjs",
|
|
29
|
+
"codegen",
|
|
30
|
+
"backend",
|
|
31
|
+
"generator",
|
|
32
|
+
"scaffold",
|
|
33
|
+
"api"
|
|
34
|
+
],
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/Gyxer513/gyxer-studio.git",
|
|
38
|
+
"directory": "packages/cli"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/Gyxer513/gyxer-studio#readme",
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/Gyxer513/gyxer-studio/issues"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=20.0.0"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@gyxer-studio/schema": "0.1.0",
|
|
49
|
+
"@gyxer-studio/generator": "0.1.0",
|
|
50
|
+
"commander": "^13.0.0",
|
|
51
|
+
"chalk": "^5.4.0",
|
|
52
|
+
"ora": "^8.1.0",
|
|
53
|
+
"inquirer": "^12.0.0"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"typescript": "^5.7.0"
|
|
57
|
+
},
|
|
58
|
+
"license": "MIT"
|
|
59
|
+
}
|