@triophore/falcon-cli 1.0.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.
Files changed (56) hide show
  1. package/README.md +62 -0
  2. package/auth/basic.js +8 -0
  3. package/auth/cookie.js +10 -0
  4. package/auth/jwks.js +6 -0
  5. package/auth/jwt.js +9 -0
  6. package/auth/openid.js +5 -0
  7. package/auth/webscoket.js +6 -0
  8. package/builder/EnvBuilder.js +0 -0
  9. package/builder/createCjsModule.js +95 -0
  10. package/builder/editModelInteractive.js +159 -0
  11. package/builder/interactiveModelBuilder.js +215 -0
  12. package/builder/interactiveMongobuilder.js +189 -0
  13. package/builder/interactiveUnifiedBuilder.js +277 -0
  14. package/builder/joiValidatorBuilder.js +218 -0
  15. package/builder/mongooseModelBuilder.js +290 -0
  16. package/builder/mongooseModelBuilder2.js +313 -0
  17. package/builder/runMigrations.js +106 -0
  18. package/builder/sequelizeModelBuilder.js +180 -0
  19. package/cli.js +60 -0
  20. package/commands/create.js +57 -0
  21. package/commands/generate.js +74 -0
  22. package/dev/Uset.schema.json +18 -0
  23. package/dev/buildSchemaInteractive.js +189 -0
  24. package/dev/buildSequelizeSchemaInteractive.js +128 -0
  25. package/dev/createJoiSchemaFromJson.js +137 -0
  26. package/dev/createModelFromJson.js +280 -0
  27. package/dev/generateAllFiles.js +45 -0
  28. package/dev/generateJoiFile.js +95 -0
  29. package/dev/generateSequelizeFiles.js +167 -0
  30. package/dev/interactiveJoiBuilder.js +177 -0
  31. package/dev/ra.js +22 -0
  32. package/dev/rj.js +18 -0
  33. package/dev/run.js +16 -0
  34. package/dev/run_seq.js +18 -0
  35. package/dev/tracker.js +23 -0
  36. package/editJsConfig.js +188 -0
  37. package/index.js +548 -0
  38. package/lib/ModelGenerator.js +203 -0
  39. package/lib/ProjectGenerator.js +246 -0
  40. package/lib/utils.js +100 -0
  41. package/logo.js +3 -0
  42. package/package.json +35 -0
  43. package/readme.md +2 -0
  44. package/schema.json +42 -0
  45. package/templates/auth_vals.json +3 -0
  46. package/templates/config.js +0 -0
  47. package/templates/example-route.js +94 -0
  48. package/templates/example-service.js +63 -0
  49. package/templates/example-validator.js +15 -0
  50. package/templates/example-worker.js +83 -0
  51. package/templates/index.txt +41 -0
  52. package/templates/post-init.js +78 -0
  53. package/templates/settings.js +192 -0
  54. package/templates/template1.settings.txt +15 -0
  55. package/templates/templatev1.json +38 -0
  56. package/validateJsConfig.js +125 -0
@@ -0,0 +1,203 @@
1
+ const { input, select, confirm, checkbox } = require("@inquirer/prompts");
2
+ const fs = require("fs").promises;
3
+ const path = require("path");
4
+
5
+ class ModelGenerator {
6
+ constructor(options = {}) {
7
+ this.verbose = options.verbose || false;
8
+ }
9
+
10
+ async generate(modelName, options = {}) {
11
+ const currentDir = process.cwd();
12
+ const modelsDir = path.join(currentDir, 'models', 'mongo');
13
+
14
+ // Check if we're in a Falcon project
15
+ try {
16
+ await fs.access(path.join(currentDir, 'settings.js'));
17
+ } catch (error) {
18
+ throw new Error('Not in a Falcon.js project directory. Run this command from your project root.');
19
+ }
20
+
21
+ // Get model name if not provided
22
+ if (!modelName) {
23
+ modelName = await input({
24
+ message: 'Model name (e.g., User):',
25
+ validate: v => v.trim() ? true : 'Model name is required',
26
+ });
27
+ }
28
+
29
+ console.log(`\nšŸ”§ Generating model: ${modelName}\n`);
30
+
31
+ // Create models directory if it doesn't exist
32
+ try {
33
+ await fs.mkdir(modelsDir, { recursive: true });
34
+ } catch (error) {
35
+ // Directory already exists
36
+ }
37
+
38
+ // Generate model interactively
39
+ const modelContent = await this.buildModelInteractively(modelName);
40
+
41
+ // Write model file
42
+ const modelPath = path.join(modelsDir, `${modelName.toLowerCase()}.js`);
43
+ await fs.writeFile(modelPath, modelContent);
44
+
45
+ console.log(`āœ… Model created: ${modelPath}`);
46
+
47
+ // Update settings.js to include the model
48
+ await this.updateSettings(currentDir, modelName.toLowerCase());
49
+
50
+ // Generate CRUD routes if requested
51
+ if (options.crud) {
52
+ await this.generateCrudRoutes(currentDir, modelName);
53
+ }
54
+ }
55
+
56
+ async buildModelInteractively(modelName) {
57
+ const fields = {};
58
+ const indexes = [];
59
+
60
+ // Add timestamps option
61
+ const useTimestamps = await confirm({
62
+ message: 'Enable timestamps (createdAt, updatedAt)?',
63
+ default: true
64
+ });
65
+
66
+ console.log('\nšŸ“ Add fields to your model:\n');
67
+
68
+ // Add fields interactively
69
+ while (true) {
70
+ const addField = await confirm({
71
+ message: 'Add a field?',
72
+ default: true
73
+ });
74
+
75
+ if (!addField) break;
76
+
77
+ const fieldName = await input({
78
+ message: 'Field name:',
79
+ validate: v => v && !fields[v] ? true : 'Invalid or duplicate field name',
80
+ });
81
+
82
+ const fieldType = await select({
83
+ message: 'Field type:',
84
+ choices: [
85
+ { name: 'String', value: 'String' },
86
+ { name: 'Number', value: 'Number' },
87
+ { name: 'Boolean', value: 'Boolean' },
88
+ { name: 'Date', value: 'Date' },
89
+ { name: 'ObjectId (Reference)', value: 'ObjectId' },
90
+ { name: 'Array', value: 'Array' },
91
+ { name: 'Mixed (Object)', value: 'Mixed' }
92
+ ]
93
+ });
94
+
95
+ const fieldOptions = {};
96
+
97
+ // Common options
98
+ const isRequired = await confirm({
99
+ message: 'Is this field required?',
100
+ default: false
101
+ });
102
+ if (isRequired) fieldOptions.required = true;
103
+
104
+ const hasIndex = await confirm({
105
+ message: 'Add index to this field?',
106
+ default: false
107
+ });
108
+ if (hasIndex) fieldOptions.index = true;
109
+
110
+ // Type-specific options
111
+ if (fieldType === 'String') {
112
+ const isUnique = await confirm({
113
+ message: 'Should this field be unique?',
114
+ default: false
115
+ });
116
+ if (isUnique) fieldOptions.unique = true;
117
+
118
+ const maxLength = await input({
119
+ message: 'Maximum length (optional):',
120
+ validate: v => !v || !isNaN(v) ? true : 'Must be a number'
121
+ });
122
+ if (maxLength) fieldOptions.maxlength = parseInt(maxLength);
123
+ }
124
+
125
+ if (fieldType === 'ObjectId') {
126
+ const refModel = await input({
127
+ message: 'Reference model name:',
128
+ validate: v => v.trim() ? true : 'Reference model is required'
129
+ });
130
+ fieldOptions.ref = refModel;
131
+ }
132
+
133
+ fields[fieldName] = {
134
+ type: fieldType,
135
+ ...fieldOptions
136
+ };
137
+ }
138
+
139
+ return this.generateModelCode(modelName, fields, { timestamps: useTimestamps });
140
+ }
141
+
142
+ generateModelCode(modelName, fields, options = {}) {
143
+ const fieldsCode = Object.entries(fields)
144
+ .map(([name, config]) => {
145
+ const configStr = JSON.stringify(config, null, 4)
146
+ .replace(/"([^"]+)":/g, '$1:')
147
+ .replace(/"/g, "'");
148
+ return ` ${name}: ${configStr}`;
149
+ })
150
+ .join(',\n');
151
+
152
+ const optionsCode = options.timestamps ? '{ timestamps: true }' : '{}';
153
+
154
+ return `module.exports = async function (mongoose) {
155
+ const ${modelName}Schema = new mongoose.Schema({
156
+ ${fieldsCode}
157
+ }, ${optionsCode});
158
+
159
+ // Add any custom methods here
160
+ // ${modelName}Schema.methods.customMethod = function() {
161
+ // // Custom instance method
162
+ // };
163
+
164
+ // ${modelName}Schema.statics.customStatic = function() {
165
+ // // Custom static method
166
+ // };
167
+
168
+ return mongoose.model('${modelName}', ${modelName}Schema);
169
+ };`;
170
+ }
171
+
172
+ async updateSettings(projectDir, modelName) {
173
+ const settingsPath = path.join(projectDir, 'settings.js');
174
+ let settingsContent = await fs.readFile(settingsPath, 'utf8');
175
+
176
+ // Add model to models array if not already present
177
+ const modelRegex = /models:\s*\[(.*?)\]/s;
178
+ const match = settingsContent.match(modelRegex);
179
+
180
+ if (match) {
181
+ const modelsArray = match[1];
182
+ if (!modelsArray.includes(`"${modelName}"`)) {
183
+ const newModelsArray = modelsArray.trim()
184
+ ? `${modelsArray.trim()}, "${modelName}"`
185
+ : `"${modelName}"`;
186
+ settingsContent = settingsContent.replace(
187
+ modelRegex,
188
+ `models: [${newModelsArray}]`
189
+ );
190
+ await fs.writeFile(settingsPath, settingsContent);
191
+ console.log(`āœ… Added "${modelName}" to settings.js models array`);
192
+ }
193
+ }
194
+ }
195
+
196
+ async generateCrudRoutes(projectDir, modelName) {
197
+ // This would generate basic CRUD routes
198
+ console.log(`šŸ”§ Generating CRUD routes for ${modelName}...`);
199
+ // Implementation would go here
200
+ }
201
+ }
202
+
203
+ module.exports = ModelGenerator;
@@ -0,0 +1,246 @@
1
+ const { input, select, confirm } = require("@inquirer/prompts");
2
+ const fs = require("fs").promises;
3
+ const path = require("path");
4
+ const { spawn } = require('child_process');
5
+
6
+ const { showSuccess, runNpmInstall, createDirectory } = require('./utils');
7
+
8
+ class ProjectGenerator {
9
+ constructor(options = {}) {
10
+ this.verbose = options.verbose || false;
11
+ this.skipInstall = options.skipInstall || false;
12
+ this.useDefaults = options.useDefaults || false;
13
+ }
14
+
15
+ async create(projectName, template = 'basic') {
16
+ const currentDir = process.cwd();
17
+
18
+ // Get project name if not provided
19
+ if (!projectName) {
20
+ projectName = await input({
21
+ message: 'Project name:',
22
+ validate: v => v.trim() ? true : 'Project name is required',
23
+ });
24
+ }
25
+
26
+ const projectPath = path.join(currentDir, projectName);
27
+
28
+ // Check if directory exists
29
+ try {
30
+ await fs.access(projectPath);
31
+ const overwrite = await confirm({
32
+ message: `Directory "${projectName}" already exists. Overwrite?`,
33
+ default: false
34
+ });
35
+ if (!overwrite) {
36
+ console.log('āŒ Project creation cancelled');
37
+ return;
38
+ }
39
+ } catch (error) {
40
+ // Directory doesn't exist, which is good
41
+ }
42
+
43
+ console.log(`\nšŸš€ Creating Falcon.js project: ${projectName}\n`);
44
+
45
+ // Create project structure
46
+ await this.createProjectStructure(projectPath, projectName, template);
47
+
48
+ // Install dependencies
49
+ if (!this.skipInstall) {
50
+ console.log('šŸ“¦ Installing dependencies...');
51
+ await runNpmInstall(projectPath);
52
+ }
53
+
54
+ showSuccess(projectName, this.skipInstall);
55
+ }
56
+
57
+ async createProjectStructure(projectPath, projectName, template) {
58
+ // Create directories
59
+ const directories = [
60
+ 'models/mongo',
61
+ 'routes',
62
+ 'services',
63
+ 'workers',
64
+ 'validators',
65
+ 'init',
66
+ 'logs',
67
+ 'public'
68
+ ];
69
+
70
+ for (const dir of directories) {
71
+ await createDirectory(path.join(projectPath, dir));
72
+ }
73
+
74
+ // Create files
75
+ await this.createPackageJson(projectPath, projectName);
76
+ await this.createSettings(projectPath, projectName);
77
+ await this.createIndexJs(projectPath);
78
+ await this.createEnvFile(projectPath, projectName);
79
+ await this.createExampleFiles(projectPath);
80
+ }
81
+
82
+ async createPackageJson(projectPath, projectName) {
83
+ const packageJson = {
84
+ name: projectName,
85
+ version: "1.0.0",
86
+ description: "Falcon.js application",
87
+ main: "index.js",
88
+ scripts: {
89
+ start: "node index.js",
90
+ dev: "nodemon index.js",
91
+ test: "echo \"Error: no test specified\" && exit 1"
92
+ },
93
+ keywords: ["falcon", "nodejs", "api"],
94
+ author: "",
95
+ license: "ISC",
96
+ type: "commonjs",
97
+ dependencies: {
98
+ "falconjs": "file:../falconjs",
99
+ "@hapi/boom": "^10.0.1",
100
+ "@hapi/inert": "^7.1.0",
101
+ "@hapi/vision": "^7.0.3",
102
+ "joi": "^17.13.3",
103
+ "mongoose": "^8.3.1",
104
+ "redis": "^4.7.0",
105
+ "mqtt": "^5.13.3",
106
+ "log4js": "^6.9.1",
107
+ "rate-limiter-flexible": "^2.4.2",
108
+ "hapi-alive": "^2.0.4",
109
+ "hapi-swagger": "^17.2.1",
110
+ "dotenv": "^16.0.0"
111
+ },
112
+ devDependencies: {
113
+ "nodemon": "^3.1.10"
114
+ }
115
+ };
116
+
117
+ await fs.writeFile(
118
+ path.join(projectPath, 'package.json'),
119
+ JSON.stringify(packageJson, null, 2)
120
+ );
121
+ }
122
+
123
+ async createSettings(projectPath, projectName) {
124
+ const settings = `module.exports.settings = {
125
+ name: "${projectName}",
126
+ http: {
127
+ host: process.env.HTTP_HOST || "localhost",
128
+ port: process.env.HTTP_PORT || 3000
129
+ },
130
+ database: {
131
+ mongodb: {
132
+ database: process.env.MONGODB_URL || "mongodb://localhost:27017/${projectName}_db"
133
+ }
134
+ },
135
+ mqtt: {
136
+ internal: true,
137
+ external: false
138
+ },
139
+ log: {
140
+ appenders: {
141
+ file: {
142
+ type: "file",
143
+ filename: process.env.LOG_FILE_NAME || "logs/app.log",
144
+ maxLogSize: process.env.LOG_MAX_SIZE || "10M",
145
+ backups: 3
146
+ },
147
+ console: {
148
+ type: "console"
149
+ }
150
+ },
151
+ categories: {
152
+ default: {
153
+ appenders: ["file", "console"],
154
+ level: process.env.LOG_LEVEL || "info"
155
+ }
156
+ }
157
+ },
158
+ swagger: {
159
+ enabled: true,
160
+ path: "/documentation"
161
+ },
162
+ auth: {
163
+ jwt: {
164
+ key: process.env.JWT_SECRET || "your-secret-key-here",
165
+ validate: async (decoded, request) => {
166
+ // Your JWT validation logic
167
+ return { id: decoded.id, roles: decoded.roles };
168
+ }
169
+ },
170
+ default: "jwt"
171
+ },
172
+ services: [],
173
+ workers: [],
174
+ models: [],
175
+ routes: [],
176
+ crud: {
177
+ exclude: []
178
+ },
179
+ postInit: "post"
180
+ };`;
181
+
182
+ await fs.writeFile(path.join(projectPath, 'settings.js'), settings);
183
+ }
184
+
185
+ async createIndexJs(projectPath) {
186
+ const indexContent = await fs.readFile(
187
+ path.join(__dirname, '../templates/index.txt'),
188
+ 'utf8'
189
+ );
190
+ await fs.writeFile(path.join(projectPath, 'index.js'), indexContent);
191
+ }
192
+
193
+ async createEnvFile(projectPath, projectName) {
194
+ const envContent = `# Falcon.js Environment Configuration
195
+ # Generated by falcon-cli
196
+
197
+ # Server Configuration
198
+ HTTP_HOST=localhost
199
+ HTTP_PORT=3000
200
+
201
+ # Database Configuration
202
+ MONGODB_URL=mongodb://localhost:27017/${projectName}_db
203
+
204
+ # MQTT Configuration
205
+ MQTT_PORT=1883
206
+ MQTT_URL=mqtt://localhost:1883
207
+
208
+ # Redis Configuration (optional)
209
+ REDIS_ENABLE=false
210
+ REDIS_URL=redis://localhost:6379
211
+
212
+ # Authentication
213
+ JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
214
+
215
+ # Logging
216
+ LOG_LEVEL=info
217
+ LOG_FILE_NAME=logs/app.log
218
+ LOG_MAX_SIZE=10M
219
+
220
+ # Development Mode
221
+ MODE=DEV
222
+ `;
223
+
224
+ await fs.writeFile(path.join(projectPath, '.env'), envContent);
225
+ }
226
+
227
+ async createExampleFiles(projectPath) {
228
+ const templates = [
229
+ { src: 'example-route.js', dest: 'routes/example.js' },
230
+ { src: 'example-validator.js', dest: 'validators/ExamplePayload.js' },
231
+ { src: 'example-service.js', dest: 'services/example.js' },
232
+ { src: 'example-worker.js', dest: 'workers/example.js' },
233
+ { src: 'post-init.js', dest: 'init/post.js' }
234
+ ];
235
+
236
+ for (const template of templates) {
237
+ const content = await fs.readFile(
238
+ path.join(__dirname, '../templates', template.src),
239
+ 'utf8'
240
+ );
241
+ await fs.writeFile(path.join(projectPath, template.dest), content);
242
+ }
243
+ }
244
+ }
245
+
246
+ module.exports = ProjectGenerator;
package/lib/utils.js ADDED
@@ -0,0 +1,100 @@
1
+ const fs = require("fs").promises;
2
+ const path = require("path");
3
+ const { spawn } = require('child_process');
4
+
5
+ const logo = `
6
+ ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā•— ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā•—
7
+ ā–ˆā–ˆā•”ā•ā•ā•ā•ā•ā–ˆā–ˆā•”ā•ā•ā–ˆā–ˆā•—ā–ˆā–ˆā•‘ ā–ˆā–ˆā•”ā•ā•ā•ā•ā•ā–ˆā–ˆā•”ā•ā•ā•ā–ˆā–ˆā•—ā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā•‘
8
+ ā–ˆā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•‘ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ā–ˆā–ˆā•”ā–ˆā–ˆā•— ā–ˆā–ˆā•‘
9
+ ā–ˆā–ˆā•”ā•ā•ā• ā–ˆā–ˆā•”ā•ā•ā–ˆā–ˆā•‘ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ā–ˆā–ˆā•‘ā•šā–ˆā–ˆā•—ā–ˆā–ˆā•‘
10
+ ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•—ā•šā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•—ā•šā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•”ā•ā–ˆā–ˆā•‘ ā•šā–ˆā–ˆā–ˆā–ˆā•‘
11
+ ā•šā•ā• ā•šā•ā• ā•šā•ā•ā•šā•ā•ā•ā•ā•ā•ā• ā•šā•ā•ā•ā•ā•ā• ā•šā•ā•ā•ā•ā•ā• ā•šā•ā• ā•šā•ā•ā•ā•
12
+
13
+ šŸš€ Falcon.js CLI - Build powerful Node.js APIs
14
+ `;
15
+
16
+ function showLogo() {
17
+ console.log(logo);
18
+ }
19
+
20
+ function showSuccess(projectName, skipInstall = false) {
21
+ console.log(`
22
+ āœ… Falcon.js project created successfully!
23
+
24
+ šŸ“ Project structure:
25
+ ā”œā”€ā”€ index.js # Main application entry point
26
+ ā”œā”€ā”€ settings.js # Falcon configuration
27
+ ā”œā”€ā”€ .env # Environment variables
28
+ ā”œā”€ā”€ package.json # Dependencies
29
+ ā”œā”€ā”€ routes/ # API route handlers
30
+ ā”œā”€ā”€ models/mongo/ # Database models
31
+ ā”œā”€ā”€ services/ # Background services
32
+ ā”œā”€ā”€ workers/ # Job processors
33
+ ā”œā”€ā”€ validators/ # Joi validation schemas
34
+ ā”œā”€ā”€ init/ # Initialization scripts
35
+ └── logs/ # Application logs
36
+
37
+ šŸš€ Next steps:
38
+ 1. cd ${projectName}${skipInstall ? '\n 2. npm install' : ''}
39
+ ${skipInstall ? '3' : '2'}. npm run dev
40
+
41
+ šŸ“š Documentation will be available at: http://localhost:3000/documentation
42
+ ā¤ļø Health check at: http://localhost:3000/health
43
+ `);
44
+ }
45
+
46
+ async function createDirectory(dirPath) {
47
+ try {
48
+ await fs.mkdir(dirPath, { recursive: true });
49
+ } catch (error) {
50
+ if (error.code !== 'EEXIST') {
51
+ throw error;
52
+ }
53
+ }
54
+ }
55
+
56
+ function runNpmInstall(projectPath, packageName = null) {
57
+ return new Promise((resolve, reject) => {
58
+ const args = packageName ? ['install', packageName] : ['install'];
59
+ const npm = spawn('npm', args, {
60
+ cwd: projectPath,
61
+ stdio: 'inherit'
62
+ });
63
+
64
+ npm.on('close', (code) => {
65
+ if (code === 0) {
66
+ resolve();
67
+ } else {
68
+ reject(new Error(`npm install failed with code ${code}`));
69
+ }
70
+ });
71
+
72
+ npm.on('error', (error) => {
73
+ reject(error);
74
+ });
75
+ });
76
+ }
77
+
78
+ function validateProjectName(name) {
79
+ if (!name || typeof name !== 'string') {
80
+ return 'Project name is required';
81
+ }
82
+
83
+ if (!/^[a-z0-9-_]+$/i.test(name)) {
84
+ return 'Project name can only contain letters, numbers, hyphens, and underscores';
85
+ }
86
+
87
+ if (name.length < 2) {
88
+ return 'Project name must be at least 2 characters long';
89
+ }
90
+
91
+ return true;
92
+ }
93
+
94
+ module.exports = {
95
+ showLogo,
96
+ showSuccess,
97
+ createDirectory,
98
+ runNpmInstall,
99
+ validateProjectName
100
+ };
package/logo.js ADDED
@@ -0,0 +1,3 @@
1
+ module.exports.logo =` ā–„ā––ā–„ā––ā–„ā––ā–„ā––ā–„ā––ā––ā––ā–„ā––ā–„ā––ā–„ā––
2
+ ▐ ā–™ā–˜ā– ā–Œā–Œā–™ā–Œā–™ā–Œā–Œā–Œā–™ā–˜ā–™ā––
3
+ ▐ ā–Œā–Œā–Ÿā––ā–™ā–Œā–Œ ā–Œā–Œā–™ā–Œā–Œā–Œā–™ā––`
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@triophore/falcon-cli",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "keywords": [],
10
+ "author": "",
11
+ "license": "ISC",
12
+ "type": "commonjs",
13
+ "bin": {
14
+ "falcon-cli": "./cli.js"
15
+ },
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "dependencies": {
20
+ "@inquirer/prompts": "^7.9.0",
21
+ "acorn": "^8.15.0",
22
+ "ajv": "^8.17.1",
23
+ "escodegen": "^2.1.0",
24
+ "estraverse": "^5.3.0",
25
+ "joi": "^18.0.1",
26
+ "mongoose": "^8.19.3",
27
+ "prompt-sync": "^4.2.0",
28
+ "reflect-metadata": "^0.2.2",
29
+ "sequelize": "^6.37.7",
30
+ "unzipper": "^0.12.3",
31
+ "yargs": "^18.0.0",
32
+ "@hapi/boom": "^10.0.1",
33
+ "rate-limiter-flexible": "^2.4.2"
34
+ }
35
+ }
package/readme.md ADDED
@@ -0,0 +1,2 @@
1
+ - create project
2
+ - create models for both mongo and sequalize
package/schema.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "$id": "configSchema",
3
+ "type": "object",
4
+ "required": ["crud", "routes", "models"],
5
+ "properties": {
6
+ "crud": {
7
+ "type": "object",
8
+ "required": ["exclude"],
9
+ "properties": {
10
+ "exclude": {
11
+ "type": "array",
12
+ "items": { "type": "string" },
13
+ "minItems": 1
14
+ }
15
+ },
16
+ "additionalProperties": false
17
+ },
18
+ "auth": { "type": "object" },
19
+ "services": {
20
+ "type": "array",
21
+ "items": { "type": "string" }
22
+ },
23
+ "workers": {
24
+ "type": "array",
25
+ "items": { "type": "string" }
26
+ },
27
+ "preInit": { "type": "string" },
28
+ "postInit": { "type": "string" },
29
+ "routes": {
30
+ "type": "array",
31
+ "items": { "type": "string" },
32
+ "minItems": 1,
33
+ "uniqueItems": true
34
+ },
35
+ "models": {
36
+ "type": "array",
37
+ "items": { "type": "string" },
38
+ "minItems": 1
39
+ }
40
+ },
41
+ "additionalProperties": false
42
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "basic":""
3
+ }
File without changes