@avleon/cli 0.0.5 → 0.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/dist/avcli.js +26 -0
- package/dist/cli.js +26 -14
- package/dist/controller.js +31 -43
- package/dist/create.js +31 -36
- package/package.json +12 -6
- package/pnpm-workspace.yaml +2 -0
- package/src/av-cli.ts +0 -95
- package/src/cli.interface.ts +0 -55
- package/src/cli.ts +0 -241
- package/src/commands.ts +0 -56
- package/src/controller.ts +0 -106
- package/src/create.ts +0 -126
- package/src/index.ts +0 -1
- package/src/paths.ts +0 -29
- package/src/stubs/basic-controller.stub +0 -7
- package/src/stubs/model.stub +0 -0
package/dist/avcli.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AvCli = void 0;
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
5
|
+
class AvCli {
|
|
6
|
+
constructor() { }
|
|
7
|
+
formatFileName() { }
|
|
8
|
+
async executeCommand(cmd) {
|
|
9
|
+
const { stdout, stderr } = (0, node_child_process_1.exec)(cmd, { encoding: "utf8" });
|
|
10
|
+
if (stderr) {
|
|
11
|
+
throw new Error("Can't execute command");
|
|
12
|
+
}
|
|
13
|
+
console.log(stdout);
|
|
14
|
+
}
|
|
15
|
+
displayHelp() { }
|
|
16
|
+
newProject() { }
|
|
17
|
+
makeModel() { }
|
|
18
|
+
makeController() { }
|
|
19
|
+
makeService() { }
|
|
20
|
+
makeConfig() { }
|
|
21
|
+
makeHelper() { }
|
|
22
|
+
makeRestController() { }
|
|
23
|
+
makeRestService() { }
|
|
24
|
+
run() { }
|
|
25
|
+
}
|
|
26
|
+
exports.AvCli = AvCli;
|
package/dist/cli.js
CHANGED
|
@@ -45,13 +45,16 @@ const promises_1 = __importDefault(require("fs/promises"));
|
|
|
45
45
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
46
46
|
const fs_1 = require("fs");
|
|
47
47
|
const prettier = __importStar(require("prettier"));
|
|
48
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
49
48
|
const controller_1 = require("./controller");
|
|
50
49
|
const commands_1 = require("./commands");
|
|
51
50
|
const child_process_1 = require("child_process");
|
|
52
51
|
const create_1 = require("./create");
|
|
53
52
|
function iqraCli() { }
|
|
54
|
-
const listedCommands = commands_1.commandList
|
|
53
|
+
const listedCommands = commands_1.commandList
|
|
54
|
+
.flatMap((x) => x.Command)
|
|
55
|
+
.concat(commands_1.commandList.flatMap((x) => x.Alias.split(",")))
|
|
56
|
+
.flatMap((a) => a.trim())
|
|
57
|
+
.concat("build");
|
|
55
58
|
/**
|
|
56
59
|
* @description Displaying basic info
|
|
57
60
|
* @since v0.0.2
|
|
@@ -110,7 +113,7 @@ async function createModel(name, options = { force: false }) {
|
|
|
110
113
|
const modelName = name.at(0).toUpperCase() + name.slice(1);
|
|
111
114
|
const modelExists = (0, fs_1.existsSync)(path_1.default.join(process.cwd(), `./src/models/${modelName.toLowerCase()}.ts`));
|
|
112
115
|
if (modelExists && !options.force) {
|
|
113
|
-
console.log(
|
|
116
|
+
console.log("Model already exists!", "Use -f or --force to overwrite.\r");
|
|
114
117
|
return;
|
|
115
118
|
}
|
|
116
119
|
const model = `
|
|
@@ -144,7 +147,7 @@ async function createXApplication(fname) {
|
|
|
144
147
|
const projectPath = path_1.default.join(process.cwd(), fname);
|
|
145
148
|
const templateDir = path_1.default.resolve("D:\\projects\\node\\iqra\\packages\\cli\\src\\stubs");
|
|
146
149
|
//await fs.mkdir(projectPath);
|
|
147
|
-
//await fsExtra.copy(templateDir, projectPath + '/');
|
|
150
|
+
//await fsExtra.copy(templateDir, projectPath + '/');
|
|
148
151
|
// Define project path
|
|
149
152
|
// const projectPath = path.resolve('new_test');
|
|
150
153
|
// Clone the repository and move the required folder
|
|
@@ -159,29 +162,31 @@ cd ..
|
|
|
159
162
|
`;
|
|
160
163
|
try {
|
|
161
164
|
// Execute the cloning and moving process
|
|
162
|
-
console.log(
|
|
165
|
+
console.log("Cloning and setting up the repository...");
|
|
163
166
|
(0, child_process_1.exec)(cloneCommand, {});
|
|
164
167
|
// Check if the projectPath exists before proceeding
|
|
165
168
|
if (!fs_extra_1.default.existsSync(projectPath)) {
|
|
166
169
|
throw new Error(`Project path "${projectPath}" was not created.`);
|
|
167
170
|
}
|
|
168
171
|
// Remove the Git origin from the new project
|
|
169
|
-
console.log(
|
|
170
|
-
(0, child_process_1.execSync)(`cd ${projectPath} && git remote remove origin`, {
|
|
172
|
+
console.log("Removing Git origin...");
|
|
173
|
+
(0, child_process_1.execSync)(`cd ${projectPath} && git remote remove origin`, {
|
|
174
|
+
stdio: "inherit",
|
|
175
|
+
});
|
|
171
176
|
// Clean up the temporary repository
|
|
172
|
-
console.log(
|
|
173
|
-
fs_extra_1.default.removeSync(
|
|
177
|
+
console.log("Cleaning up temporary files...");
|
|
178
|
+
fs_extra_1.default.removeSync("./temp_repo");
|
|
174
179
|
console.log(`Project created successfully in ${projectPath}`);
|
|
175
180
|
}
|
|
176
181
|
catch (error) {
|
|
177
|
-
console.error(
|
|
182
|
+
console.error("An error occurred:", error);
|
|
178
183
|
// Cleanup in case of failure
|
|
179
|
-
if (fs_extra_1.default.existsSync(
|
|
180
|
-
console.log(
|
|
181
|
-
fs_extra_1.default.removeSync(
|
|
184
|
+
if (fs_extra_1.default.existsSync("./temp_repo")) {
|
|
185
|
+
console.log("Cleaning up temporary repository...");
|
|
186
|
+
fs_extra_1.default.removeSync("./temp_repo");
|
|
182
187
|
}
|
|
183
188
|
if (fs_extra_1.default.existsSync(projectPath)) {
|
|
184
|
-
console.log(
|
|
189
|
+
console.log("Cleaning up project path...");
|
|
185
190
|
fs_extra_1.default.removeSync(projectPath);
|
|
186
191
|
}
|
|
187
192
|
}
|
|
@@ -209,6 +214,13 @@ async function run() {
|
|
|
209
214
|
const fname = args[1];
|
|
210
215
|
await (0, create_1.createApplication)(fname);
|
|
211
216
|
}
|
|
217
|
+
if (args[0] == "build") {
|
|
218
|
+
process.env.NODE_ENV = "production";
|
|
219
|
+
//const appPath =
|
|
220
|
+
(0, child_process_1.execSync)("rm -r ./dist");
|
|
221
|
+
(0, child_process_1.execSync)("npx tsc --project tsconfig.build.json");
|
|
222
|
+
console.log("Build successfully");
|
|
223
|
+
}
|
|
212
224
|
if (args[0] == "make:model") {
|
|
213
225
|
await createModel(args[1], { force });
|
|
214
226
|
}
|
package/dist/controller.js
CHANGED
|
@@ -1,37 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
4
|
};
|
|
@@ -42,7 +9,13 @@ const fs_1 = require("fs");
|
|
|
42
9
|
const promises_1 = require("fs/promises");
|
|
43
10
|
const path_1 = __importDefault(require("path"));
|
|
44
11
|
const prettier_1 = __importDefault(require("prettier"));
|
|
12
|
+
function capitalize(str) {
|
|
13
|
+
if (!str)
|
|
14
|
+
return '';
|
|
15
|
+
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
|
|
16
|
+
}
|
|
45
17
|
async function createController(name, options = { force: false, resource: false, model: null }, p) {
|
|
18
|
+
var _a;
|
|
46
19
|
if (!name) {
|
|
47
20
|
throw new Error("Controller name not found. use --name or node artisan make:controller HomeController");
|
|
48
21
|
}
|
|
@@ -54,24 +27,39 @@ async function createController(name, options = { force: false, resource: false,
|
|
|
54
27
|
});
|
|
55
28
|
}
|
|
56
29
|
const controllerName = name.at(0).toUpperCase() + name.slice(1);
|
|
57
|
-
const controllerNameLowerCase =
|
|
30
|
+
const controllerNameLowerCase = ((_a = name
|
|
31
|
+
.replace(/Controller/ig, '')
|
|
32
|
+
.match(/[A-Z]?[a-z]+|[0-9]+/g) // added ? to also capture single lowercase words
|
|
33
|
+
) === null || _a === void 0 ? void 0 : _a.join('-').toLowerCase()) || name.toLowerCase();
|
|
58
34
|
const controllerNameCap = controllerName.replace(/Controller/ig, '');
|
|
59
35
|
const controllerExists = (0, fs_1.existsSync)(`${controllerPath}/${name.toLowerCase()}.controller.ts`);
|
|
60
36
|
if (controllerExists && !options.force) {
|
|
61
37
|
console.log(chalk_1.default.bold(chalk_1.default.red("controller already exists!")), chalk_1.default.greenBright("Use -f or --force to overwrite.\r"));
|
|
62
38
|
return;
|
|
63
39
|
}
|
|
64
|
-
if (options.model) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
Object.getOwnPropertyNames(file);
|
|
68
|
-
}
|
|
40
|
+
if (options.resource && !options.model) {
|
|
41
|
+
console.log(chalk_1.default.bold(chalk_1.default.red("Model must be provide to generate rest controller!")), chalk_1.default.greenBright("Use -m Model or --model Model to .\r"));
|
|
42
|
+
return;
|
|
69
43
|
}
|
|
44
|
+
// if (options.model) {
|
|
45
|
+
// const file = require(
|
|
46
|
+
// path.join(process.cwd(), "./src/models/" + options.model.toUpperCase() + ".ts")
|
|
47
|
+
// ).default;
|
|
48
|
+
// if (file) {
|
|
49
|
+
// Object.getOwnPropertyNames(file);
|
|
50
|
+
// }
|
|
51
|
+
// }
|
|
70
52
|
const restController = `
|
|
71
|
-
import { ApiController, Get, Post, Put, Delete, Param, Body } from '@avleon/core';
|
|
53
|
+
import { ApiController, Collection, Get, Post, Put, Delete, Param, Body } from '@avleon/core';
|
|
54
|
+
import { ${capitalize(options.model)} } from '../models/${capitalize(options.model)}'
|
|
72
55
|
\t
|
|
73
|
-
@ApiController("/${controllerNameLowerCase}")
|
|
74
|
-
export class ${controllerName}{\n
|
|
56
|
+
@ApiController("/${controllerNameLowerCase}s")
|
|
57
|
+
export class ${controllerName}Controller {\n
|
|
58
|
+
|
|
59
|
+
constructor(
|
|
60
|
+
private readonly ${options.model.toLowerCase()}Repository = Collection.fromRepository(${capitalize(options.model)})
|
|
61
|
+
){}
|
|
62
|
+
|
|
75
63
|
@Get()
|
|
76
64
|
async findAll(){
|
|
77
65
|
return "okay";
|
|
@@ -111,6 +99,6 @@ async function createController(name, options = { force: false, resource: false,
|
|
|
111
99
|
singleAttributePerLine: true,
|
|
112
100
|
parser: "typescript",
|
|
113
101
|
});
|
|
114
|
-
await (0, promises_1.writeFile)(path_1.default.join(process.cwd(), "./src/controllers/" + controllerName.toLowerCase().replace("controller", "") + ".controller
|
|
102
|
+
await (0, promises_1.writeFile)(path_1.default.join(process.cwd(), "./src/controllers/" + controllerName.toLowerCase().replace("controller", "") + ".controller" + ".ts"), formatcontroller);
|
|
115
103
|
console.log("Controller created succssessfully!");
|
|
116
104
|
}
|
package/dist/create.js
CHANGED
|
@@ -41,7 +41,6 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
41
41
|
const paths_1 = require("./paths");
|
|
42
42
|
const prettier = __importStar(require("prettier"));
|
|
43
43
|
const win32_1 = __importDefault(require("path/win32"));
|
|
44
|
-
const child_process_1 = require("child_process");
|
|
45
44
|
async function createApplication(fname) {
|
|
46
45
|
const appPaths = (0, paths_1.appPaths)(fname);
|
|
47
46
|
const dirs = Object.values(appPaths);
|
|
@@ -49,31 +48,17 @@ async function createApplication(fname) {
|
|
|
49
48
|
await fs_extra_1.default.ensureDir(dirs[i]);
|
|
50
49
|
}
|
|
51
50
|
await fs_extra_1.default.ensureDir(appPaths.root + "/public");
|
|
52
|
-
// copy
|
|
51
|
+
// copy
|
|
53
52
|
//
|
|
54
53
|
const mainFunc = `
|
|
55
54
|
import {
|
|
56
|
-
|
|
57
|
-
env
|
|
55
|
+
Avleon
|
|
58
56
|
} from "@avleon/core";
|
|
59
57
|
|
|
60
58
|
|
|
61
|
-
|
|
62
|
-
const builder = Builder.createAppBuilder();
|
|
63
|
-
|
|
64
|
-
// registering all services and dependencies here
|
|
65
|
-
// builder.addDataSource({
|
|
66
|
-
// type: "better-sqlite3",
|
|
67
|
-
// database: path.join(process.cwd(), "mydb.db"),
|
|
68
|
-
// entities: [Category, Product],
|
|
69
|
-
// synchronize: true,
|
|
70
|
-
// });
|
|
71
|
-
|
|
72
|
-
// build app
|
|
73
|
-
const app = builder.build();
|
|
59
|
+
const app = Avleon.createApplication();
|
|
74
60
|
app.mapGet('/', ()=> "Welcome");
|
|
75
|
-
|
|
76
|
-
app.listen(env.PORT);
|
|
61
|
+
app.run();
|
|
77
62
|
|
|
78
63
|
`;
|
|
79
64
|
const formatMainFunc = await prettier.format(mainFunc, {
|
|
@@ -81,24 +66,31 @@ app.listen(env.PORT);
|
|
|
81
66
|
singleAttributePerLine: true,
|
|
82
67
|
parser: "typescript",
|
|
83
68
|
});
|
|
84
|
-
await fs_extra_1.default.writeFile(win32_1.default.join(appPaths.src,
|
|
69
|
+
await fs_extra_1.default.writeFile(win32_1.default.join(appPaths.src, "app.ts"), formatMainFunc);
|
|
85
70
|
// create package.json
|
|
86
71
|
const packageJson = `
|
|
87
72
|
{
|
|
88
73
|
"name": "${fname}",
|
|
89
|
-
"version": "
|
|
90
|
-
"description": "",
|
|
74
|
+
"version": "0.0.0",
|
|
75
|
+
"description": "Basic avleon application",
|
|
91
76
|
"main": "index.js",
|
|
92
77
|
"scripts": {
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"build": "
|
|
78
|
+
"start:dev": "nodemon src/serve.ts",
|
|
79
|
+
"start:debug": "nodemon --watch src --ext ts --exec node --inspect=0.0.0.0:9229 -r ts-node/register src/serve.ts",
|
|
80
|
+
"clean": "rimraf ./dist",
|
|
81
|
+
"build": "npm run clean & tsc --project ./tsconfig.build.json",
|
|
82
|
+
"start": "node dist/serve.js",
|
|
83
|
+
"test": "jest",
|
|
84
|
+
"test:watch": "jest --watch",
|
|
85
|
+
"test:cov": "jest --coverage",
|
|
86
|
+
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
|
87
|
+
"test:e2e": "jest --config ./test/e2e-spec.json"
|
|
97
88
|
},
|
|
98
|
-
"keywords": [],
|
|
99
|
-
"author": "",
|
|
89
|
+
"keywords": ["avleon","nodejs","typescript"],
|
|
100
90
|
"license": "ISC",
|
|
101
91
|
"dependencies": {
|
|
92
|
+
"@avleon/core": "^0.0.25",
|
|
93
|
+
"@avleon/cli": "^0.0.25",
|
|
102
94
|
"class-transformer": "^0.5.1",
|
|
103
95
|
"class-validator": "^0.14.1",
|
|
104
96
|
"reflect-metadata": "^0.2.2"
|
|
@@ -114,14 +106,15 @@ app.listen(env.PORT);
|
|
|
114
106
|
const formattedPackageJson = await prettier.format(packageJson, {
|
|
115
107
|
parser: "json",
|
|
116
108
|
});
|
|
117
|
-
await fs_extra_1.default.writeFile(win32_1.default.join(appPaths.root,
|
|
109
|
+
await fs_extra_1.default.writeFile(win32_1.default.join(appPaths.root, "package.json"), formattedPackageJson);
|
|
118
110
|
const tsconfigJson = await prettier.format(`{
|
|
119
111
|
"compilerOptions": {
|
|
120
112
|
"target": "ES2017",
|
|
121
113
|
"module": "CommonJS",
|
|
122
114
|
"moduleResolution": "node",
|
|
115
|
+
"experimentalDecorators": true,
|
|
116
|
+
"emitDecoratorMetadata": true,
|
|
123
117
|
"outDir": "./dist",
|
|
124
|
-
"rootDir": "./src",
|
|
125
118
|
"esModuleInterop": true,
|
|
126
119
|
"allowSyntheticDefaultImports": true,
|
|
127
120
|
"forceConsistentCasingInFileNames": true,
|
|
@@ -129,12 +122,14 @@ app.listen(env.PORT);
|
|
|
129
122
|
},
|
|
130
123
|
"include": ["src/**/*"],
|
|
131
124
|
"exclude": ["node_modules", "dist"]
|
|
132
|
-
}`, { parser:
|
|
133
|
-
await fs_extra_1.default.writeFile(win32_1.default.join(appPaths.root,
|
|
134
|
-
await fs_extra_1.default.writeFile(win32_1.default.join(appPaths.root,
|
|
125
|
+
}`, { parser: "json" });
|
|
126
|
+
await fs_extra_1.default.writeFile(win32_1.default.join(appPaths.root, "tsconfig.json"), tsconfigJson);
|
|
127
|
+
await fs_extra_1.default.writeFile(win32_1.default.join(appPaths.root, ".gitignore"), `node_modules/\ndist/\n.env`);
|
|
135
128
|
// create basic service
|
|
136
129
|
// create basic controller
|
|
137
|
-
console.info("
|
|
138
|
-
|
|
139
|
-
console.
|
|
130
|
+
console.info("App created successfully. Run the following command to get start.");
|
|
131
|
+
console.log(`cd ${fname} && pnpm install`);
|
|
132
|
+
console.log(`npm run start:dev`);
|
|
133
|
+
//execSync(`cd ${fname} && pnpm install && pnpm add @avleon/core`, { stdio: 'inherit' })
|
|
134
|
+
console.info("Enjoy :D");
|
|
140
135
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@avleon/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.25",
|
|
4
4
|
"bin": {
|
|
5
5
|
"avleon": "./dist/cli.js"
|
|
6
6
|
},
|
|
@@ -12,24 +12,30 @@
|
|
|
12
12
|
"clean": "rm -rf ./dist",
|
|
13
13
|
"watch": "tsc-watch"
|
|
14
14
|
},
|
|
15
|
-
"keywords": [
|
|
15
|
+
"keywords": [
|
|
16
|
+
"cli",
|
|
17
|
+
"backend-api"
|
|
18
|
+
],
|
|
16
19
|
"author": "Tareq Hossain",
|
|
17
20
|
"license": "ISC",
|
|
18
21
|
"devDependencies": {
|
|
19
22
|
"@types/fs-extra": "^11.0.4",
|
|
23
|
+
"@types/lodash": "^4.17.16",
|
|
20
24
|
"@types/node": "^22.9.3",
|
|
21
25
|
"nodemon": "^3.1.7",
|
|
22
26
|
"tsc-watch": "^6.2.1",
|
|
27
|
+
"tsup": "^8.4.0",
|
|
23
28
|
"typescript": "^5.7.2"
|
|
24
29
|
},
|
|
25
30
|
"dependencies": {
|
|
26
|
-
"chalk": "^4",
|
|
27
|
-
"prettier": "^3.3.3",
|
|
31
|
+
"chalk": "^5.4.1",
|
|
28
32
|
"cli-table3": "^0.6.5",
|
|
29
|
-
"fs-extra": "^11.2.0"
|
|
33
|
+
"fs-extra": "^11.2.0",
|
|
34
|
+
"lodash": "^4.17.21",
|
|
35
|
+
"prettier": "^3.3.3"
|
|
30
36
|
},
|
|
31
37
|
"repository": {
|
|
32
38
|
"type": "git",
|
|
33
39
|
"url": "git+https://github.com/avleonjs/avleon-cli"
|
|
34
40
|
}
|
|
35
|
-
}
|
|
41
|
+
}
|
package/src/av-cli.ts
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { AvCli, CreateModelOptions } from "./cli.interface";
|
|
3
|
-
import { commandList, CommandType } from "./commands";
|
|
4
|
-
|
|
5
|
-
type ProjectFileType =
|
|
6
|
-
| "controller"
|
|
7
|
-
| "service"
|
|
8
|
-
| "model"
|
|
9
|
-
| "util"
|
|
10
|
-
| "helper"
|
|
11
|
-
| "config";
|
|
12
|
-
|
|
13
|
-
interface FilePathExtractor {
|
|
14
|
-
name: string;
|
|
15
|
-
ext?: string;
|
|
16
|
-
parent: string;
|
|
17
|
-
givenPath: string;
|
|
18
|
-
outputPath?: string;
|
|
19
|
-
newFileName: string;
|
|
20
|
-
className: string;
|
|
21
|
-
exsits: boolean;
|
|
22
|
-
force: boolean;
|
|
23
|
-
fileType?: ProjectFileType;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function formatFileName(name: string) {
|
|
27
|
-
return name
|
|
28
|
-
.replace(/[_\s]+/g, "-")
|
|
29
|
-
.replace(/([a-z])([A-Z])/g, "$1-$2")
|
|
30
|
-
.replace(
|
|
31
|
-
/((-|_|\.)+(Controller|Service|Model))|(Controller|Service|Model)/gi,
|
|
32
|
-
"",
|
|
33
|
-
)
|
|
34
|
-
.toLowerCase();
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function formatClassName(name: string) {
|
|
38
|
-
return name
|
|
39
|
-
.replace(/[_\s-]+/g, " ")
|
|
40
|
-
.replace(/([a-z])([A-Z])/g, "$1 $2")
|
|
41
|
-
.toLowerCase()
|
|
42
|
-
.replace(/\b\w/g, (char) => char.toUpperCase())
|
|
43
|
-
.replace(/\s+/g, "");
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function PathExtractor(givenPath: string, options: string[]) {
|
|
47
|
-
let pathSplits = givenPath.split("/");
|
|
48
|
-
let splitSize = pathSplits.length;
|
|
49
|
-
let hasSubDirectory = splitSize > 0;
|
|
50
|
-
let name = hasSubDirectory ? pathSplits[splitSize - 1] : pathSplits[0];
|
|
51
|
-
let className = formatClassName(name);
|
|
52
|
-
let fileType = "any";
|
|
53
|
-
let isRest = false;
|
|
54
|
-
let isForced = false;
|
|
55
|
-
if (options.includes("make:controller") || options.includes("m:c")) {
|
|
56
|
-
fileType = "controller";
|
|
57
|
-
className = name.toLowerCase().replace(/controller|Controller/g, "");
|
|
58
|
-
}
|
|
59
|
-
if (options.includes("make:model") || options.includes("m:m")) {
|
|
60
|
-
fileType = "model";
|
|
61
|
-
className = name.toLowerCase().replace(/controller|Controller/g, "");
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (options.includes("make:service") || options.includes("m:s")) {
|
|
65
|
-
fileType = "service";
|
|
66
|
-
className = name.toLowerCase().replace(/controller|Controller/g, "");
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (options.includes("make:util") || options.includes("m:u")) {
|
|
70
|
-
fileType = "util";
|
|
71
|
-
className = name.toLowerCase().replace(/controller|Controller/g, "");
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (options.includes("make:config")) {
|
|
75
|
-
fileType = "config";
|
|
76
|
-
className = name.toLowerCase().replace(/controller|Controller/g, "");
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (options.includes("--rest") || options.includes("-r")) {
|
|
80
|
-
isRest = true;
|
|
81
|
-
className = name.toLowerCase().replace(/controller|Controller/g, "");
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (options.includes("--force") || options.includes("-f")) {
|
|
85
|
-
isForced = true;
|
|
86
|
-
className = name.toLowerCase().replace(/controller|Controller/g, "");
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
let outputFileName = formatFileName(name);
|
|
90
|
-
|
|
91
|
-
let outputPath = givenPath + "." + fileType + ".ts";
|
|
92
|
-
|
|
93
|
-
return {};
|
|
94
|
-
}
|
|
95
|
-
|
package/src/cli.interface.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { CommandType } from "./commands";
|
|
2
|
-
|
|
3
|
-
export interface AvCli {
|
|
4
|
-
commands: CommandType[];
|
|
5
|
-
|
|
6
|
-
createModel(): void;
|
|
7
|
-
createService(): void;
|
|
8
|
-
createController(): void;
|
|
9
|
-
createProject(): void;
|
|
10
|
-
createResource(): void;
|
|
11
|
-
createRestService(): void;
|
|
12
|
-
createRestController(): void;
|
|
13
|
-
displayHelp(): void;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
type BaseBuildOptions = {
|
|
17
|
-
force: boolean;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export type CreateModelOptions = {
|
|
21
|
-
orm: boolean; //default false
|
|
22
|
-
timestamps: boolean; // timestamp true
|
|
23
|
-
fields: any;
|
|
24
|
-
} & BaseBuildOptions;
|
|
25
|
-
|
|
26
|
-
export type CreateControllerOptions = {
|
|
27
|
-
service: Function;
|
|
28
|
-
model: Function;
|
|
29
|
-
rest: boolean;
|
|
30
|
-
} & BaseBuildOptions;
|
|
31
|
-
|
|
32
|
-
export type CreateServiceOptions = {
|
|
33
|
-
model: Function;
|
|
34
|
-
rest: boolean;
|
|
35
|
-
orm: boolean;
|
|
36
|
-
} & BaseBuildOptions;
|
|
37
|
-
|
|
38
|
-
export type CreateApplicationOptions = {
|
|
39
|
-
orm: boolean;
|
|
40
|
-
minimal: boolean;
|
|
41
|
-
} & BaseBuildOptions;
|
|
42
|
-
|
|
43
|
-
export interface IBuilder {
|
|
44
|
-
content: string;
|
|
45
|
-
parse(content: string): IBuilder;
|
|
46
|
-
process(content: string): IBuilder;
|
|
47
|
-
format(content: string, parseOptions: any): IBuilder;
|
|
48
|
-
build(): string;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export interface ModelBuilder extends IBuilder {}
|
|
52
|
-
export interface ProjectBuilder extends IBuilder {}
|
|
53
|
-
export interface ControllerBuilder extends IBuilder {}
|
|
54
|
-
export interface ServiceBuilder extends IBuilder {}
|
|
55
|
-
export interface ResourceBuilder extends IBuilder {}
|
package/src/cli.ts
DELETED
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import Table, { HorizontalTableRow } from "cli-table3";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import fs from "fs/promises";
|
|
5
|
-
import fsExtra from 'fs-extra';
|
|
6
|
-
import { existsSync } from "fs";
|
|
7
|
-
import * as prettier from "prettier";
|
|
8
|
-
import chalk from "chalk";
|
|
9
|
-
import { createController } from "./controller";
|
|
10
|
-
import { commandList } from "./commands";
|
|
11
|
-
import { exec, execSync } from "child_process";
|
|
12
|
-
import { createApplication } from "./create";
|
|
13
|
-
|
|
14
|
-
export function iqraCli() { }
|
|
15
|
-
|
|
16
|
-
const listedCommands = commandList.flatMap(x => x.Command).concat(commandList.flatMap(x => x.Alias.split(","))).flatMap(a => a.trim());
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @description Displaying basic info
|
|
20
|
-
* @since v0.0.2
|
|
21
|
-
* */
|
|
22
|
-
async function printLogo() {
|
|
23
|
-
try {
|
|
24
|
-
const packageInfo = await fs.readFile(
|
|
25
|
-
path.join(__dirname, "../package.json"),
|
|
26
|
-
"utf8",
|
|
27
|
-
);
|
|
28
|
-
const parsedPackInfo = JSON.parse(packageInfo);
|
|
29
|
-
console.log(`Name: Avleon CLI`, "\r");
|
|
30
|
-
console.log(`Version: ${parsedPackInfo.version}`, "\r");
|
|
31
|
-
} catch (error) {
|
|
32
|
-
throw new Error("Can't read packag info");
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async function displayCommandList(info = { logo: true, all: false }) {
|
|
37
|
-
if (info.logo) {
|
|
38
|
-
await printLogo();
|
|
39
|
-
}
|
|
40
|
-
console.log("Available commandList:");
|
|
41
|
-
|
|
42
|
-
if (info.all) {
|
|
43
|
-
const table = new Table({
|
|
44
|
-
head: ["Command", "Alias", "Available Options", "Description"],
|
|
45
|
-
colWidths: [20, 10, 30, 50],
|
|
46
|
-
wrapOnWordBoundary: true,
|
|
47
|
-
wordWrap: true,
|
|
48
|
-
});
|
|
49
|
-
commandList.forEach((c) => {
|
|
50
|
-
table.push([c.Command, c.Alias, c.Options, c.Description]);
|
|
51
|
-
});
|
|
52
|
-
console.log(table.toString());
|
|
53
|
-
} else {
|
|
54
|
-
const table = new Table({
|
|
55
|
-
head: ["Command", "Alias", "Available Options"],
|
|
56
|
-
colWidths: [20, 10, 50],
|
|
57
|
-
wrapOnWordBoundary: true,
|
|
58
|
-
wordWrap: true,
|
|
59
|
-
});
|
|
60
|
-
commandList.forEach((c) => {
|
|
61
|
-
table.push([c.Command, c.Alias, c.Options]);
|
|
62
|
-
});
|
|
63
|
-
console.log(table.toString());
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
async function createModel(name: string, options = { force: false }) {
|
|
69
|
-
if (!name) {
|
|
70
|
-
throw new Error(
|
|
71
|
-
"Model name not found . use --name or node artisan make:model ModelName",
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const modelFolderExists = existsSync(
|
|
76
|
-
path.join(process.cwd(), "./src/models"),
|
|
77
|
-
);
|
|
78
|
-
if (!modelFolderExists) {
|
|
79
|
-
await fs.mkdir(path.join(process.cwd(), "./src/models"), {
|
|
80
|
-
recursive: true,
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const modelName = name.at(0).toUpperCase() + name.slice(1);
|
|
85
|
-
const modelExists = existsSync(
|
|
86
|
-
path.join(process.cwd(), `./src/models/${modelName.toLowerCase()}.ts`),
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
if (modelExists && !options.force) {
|
|
90
|
-
console.log(
|
|
91
|
-
chalk.bold(chalk.red("Model already exists!")),
|
|
92
|
-
chalk.greenBright("Use -f or --force to overwrite.\r"),
|
|
93
|
-
);
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const model = `
|
|
98
|
-
import {Entity, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn } from 'typeorm';
|
|
99
|
-
\t
|
|
100
|
-
@Entity({name:'${modelName}'})
|
|
101
|
-
export class ${modelName}{
|
|
102
|
-
|
|
103
|
-
@PrimaryGeneratedColumn()
|
|
104
|
-
id:number;
|
|
105
|
-
|
|
106
|
-
@CreateDateColumn()
|
|
107
|
-
createdAt: Date;
|
|
108
|
-
|
|
109
|
-
@UpdateDateColumn()
|
|
110
|
-
updatedAt: Date;
|
|
111
|
-
}
|
|
112
|
-
`;
|
|
113
|
-
|
|
114
|
-
const formatModel = await prettier.format(model, {
|
|
115
|
-
singleQuote: true,
|
|
116
|
-
singleAttributePerLine: true,
|
|
117
|
-
parser: "typescript",
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
await fs.writeFile(
|
|
121
|
-
path.join(process.cwd(), "./src/models/" + modelName.toLowerCase() + ".ts"),
|
|
122
|
-
formatModel,
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
console.log("Model created succssessfully!");
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
async function createXApplication(fname: string) {
|
|
129
|
-
if (existsSync(process.cwd() + fname)) {
|
|
130
|
-
throw new Error("Application already exists");
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
const projectPath = path.join(process.cwd(), fname);
|
|
135
|
-
const templateDir = path.resolve("D:\\projects\\node\\iqra\\packages\\cli\\src\\stubs");
|
|
136
|
-
|
|
137
|
-
//await fs.mkdir(projectPath);
|
|
138
|
-
|
|
139
|
-
//await fsExtra.copy(templateDir, projectPath + '/');
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
// Define project path
|
|
143
|
-
// const projectPath = path.resolve('new_test');
|
|
144
|
-
|
|
145
|
-
// Clone the repository and move the required folder
|
|
146
|
-
const cloneCommand = `
|
|
147
|
-
git clone -n --depth=1 --filter=tree:0 https://github.com/xtareq/iqra temp_repo &&
|
|
148
|
-
cd temp_repo &&
|
|
149
|
-
git sparse-checkout init --no-cone &&
|
|
150
|
-
git sparse-checkout set examples/iqra_test &&
|
|
151
|
-
git checkout &&
|
|
152
|
-
mv examples/iqra_test ${projectPath} &&
|
|
153
|
-
cd ..
|
|
154
|
-
`;
|
|
155
|
-
|
|
156
|
-
try {
|
|
157
|
-
// Execute the cloning and moving process
|
|
158
|
-
console.log('Cloning and setting up the repository...');
|
|
159
|
-
exec(cloneCommand, {});
|
|
160
|
-
|
|
161
|
-
// Check if the projectPath exists before proceeding
|
|
162
|
-
if (!fsExtra.existsSync(projectPath)) {
|
|
163
|
-
throw new Error(`Project path "${projectPath}" was not created.`);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Remove the Git origin from the new project
|
|
167
|
-
console.log('Removing Git origin...');
|
|
168
|
-
execSync(`cd ${projectPath} && git remote remove origin`, { stdio: 'inherit' });
|
|
169
|
-
|
|
170
|
-
// Clean up the temporary repository
|
|
171
|
-
console.log('Cleaning up temporary files...');
|
|
172
|
-
fsExtra.removeSync('./temp_repo');
|
|
173
|
-
|
|
174
|
-
console.log(`Project created successfully in ${projectPath}`);
|
|
175
|
-
} catch (error) {
|
|
176
|
-
console.error('An error occurred:', error);
|
|
177
|
-
|
|
178
|
-
// Cleanup in case of failure
|
|
179
|
-
if (fsExtra.existsSync('./temp_repo')) {
|
|
180
|
-
console.log('Cleaning up temporary repository...');
|
|
181
|
-
fsExtra.removeSync('./temp_repo');
|
|
182
|
-
}
|
|
183
|
-
if (fsExtra.existsSync(projectPath)) {
|
|
184
|
-
console.log('Cleaning up project path...');
|
|
185
|
-
fsExtra.removeSync(projectPath);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
export async function run() {
|
|
192
|
-
try {
|
|
193
|
-
const args = process.argv.slice(2);
|
|
194
|
-
if (args.length < 1) {
|
|
195
|
-
await displayCommandList({ logo: true, all: false });
|
|
196
|
-
} else {
|
|
197
|
-
const cmdList = commandList
|
|
198
|
-
.flatMap((x) => x.Command)
|
|
199
|
-
.concat(
|
|
200
|
-
...commandList.flatMap((f) => f.Alias.split(",").map((s) => s.trim())),
|
|
201
|
-
);
|
|
202
|
-
if (!listedCommands.includes(args[0].trim())) {
|
|
203
|
-
console.error("Invalid command");
|
|
204
|
-
await displayCommandList({ logo: false, all: false });
|
|
205
|
-
} else {
|
|
206
|
-
let force = false;
|
|
207
|
-
if (args.some((x) => x == "-f" || x == "--force")) {
|
|
208
|
-
force = true;
|
|
209
|
-
}
|
|
210
|
-
if (args[0] == "new") {
|
|
211
|
-
const fname = args[1];
|
|
212
|
-
await createApplication(fname);
|
|
213
|
-
}
|
|
214
|
-
if (args[0] == "make:model") {
|
|
215
|
-
await createModel(args[1], { force });
|
|
216
|
-
}
|
|
217
|
-
if (args[0] == "make:controller" || args[0] == "m:c") {
|
|
218
|
-
let resource = false;
|
|
219
|
-
if (args.some((x) => x == "-r" || x == "--resource")) {
|
|
220
|
-
resource = true;
|
|
221
|
-
}
|
|
222
|
-
let model = null;
|
|
223
|
-
if (args.some((x) => x == "-m" || x == "--model")) {
|
|
224
|
-
const index = args.includes("-m")
|
|
225
|
-
? args.indexOf("-m")
|
|
226
|
-
: args.indexOf("--model");
|
|
227
|
-
if (args[index + 1] == undefined) {
|
|
228
|
-
throw new Error("Model not defined");
|
|
229
|
-
}
|
|
230
|
-
const modelName = args[index + 1];
|
|
231
|
-
model = modelName;
|
|
232
|
-
}
|
|
233
|
-
await createController(args[1], { force, resource, model });
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
} catch (error) {
|
|
238
|
-
console.log("CLI ERROR:", error);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
run()
|
package/src/commands.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
|
-
export type CommandType = {
|
|
3
|
-
Command: string;
|
|
4
|
-
Alias: string;
|
|
5
|
-
Options: string;
|
|
6
|
-
Description: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const commandList: CommandType[] = [
|
|
10
|
-
{
|
|
11
|
-
Command: "new",
|
|
12
|
-
Alias: "",
|
|
13
|
-
Options: "--minimal -m, -d --database",
|
|
14
|
-
Description: "Create a new application"
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
Command: "make:model",
|
|
18
|
-
Alias: "m:m, mm",
|
|
19
|
-
Options: "-f --force",
|
|
20
|
-
Description:
|
|
21
|
-
"Create a new model. Use -f or --froce to overwrite if any model exists with name",
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
Command: "make:controller",
|
|
25
|
-
Alias: "m:c",
|
|
26
|
-
Options: `-f, --force for force create\n -r or --resource for resource controller`,
|
|
27
|
-
Description: `Create a new controller. Use -f or --force to overwrite existing controller. If you want to create a resource controller pass options -r or --resource.
|
|
28
|
-
You may also pass model by -m or --model.\n
|
|
29
|
-
${chalk.blueBright("Note:")} when using a resource contorller iqra will automaticall check for dtos related to model name. If -m is user then
|
|
30
|
-
it will check for dtos like UserCreateDto and UserUpdateDto. If dtos not found it will create automatically using
|
|
31
|
-
model properties.
|
|
32
|
-
`,
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
Command: "make:service",
|
|
36
|
-
Alias: "m:s",
|
|
37
|
-
Options: `-f, --force for force create\n -r or --resource for resource controller`,
|
|
38
|
-
Description: `Create a new controller. Use -f or --force to overwrite existing controller. If you want to create a resource controller pass options -r or --resource.
|
|
39
|
-
You may also pass model by -m or --model.\n
|
|
40
|
-
${chalk.blueBright("Note:")} when using a resource contorller iqra will automaticall check for dtos related to model name. If -m is user then
|
|
41
|
-
it will check for dtos like UserCreateDto and UserUpdateDto. If dtos not found it will create automatically using
|
|
42
|
-
model properties.
|
|
43
|
-
`,
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
Command: "make:resource",
|
|
47
|
-
Alias: "m:r",
|
|
48
|
-
Options: `-f, --force for force create\n -r or --resource for resource`,
|
|
49
|
-
Description: `Create a new resource. Use -f or --force to overwrite existing controller. If you want to create a resource controller pass options -r or --resource.
|
|
50
|
-
You may also pass model by -m or --model.\n
|
|
51
|
-
${chalk.blueBright("Note:")} when using a resource contorller iqra will automaticall check for dtos related to model name. If -m is user then
|
|
52
|
-
it will check for dtos like UserCreateDto and UserUpdateDto. If dtos not found it will create automatically using
|
|
53
|
-
model properties.
|
|
54
|
-
`,
|
|
55
|
-
},
|
|
56
|
-
];
|
package/src/controller.ts
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
|
-
import { existsSync } from "fs";
|
|
3
|
-
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
4
|
-
import path from "path";
|
|
5
|
-
import prettier from "prettier";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
async function createController(
|
|
9
|
-
name: string,
|
|
10
|
-
options = { force: false, resource: false, model: null },
|
|
11
|
-
p?: string
|
|
12
|
-
) {
|
|
13
|
-
if (!name) {
|
|
14
|
-
throw new Error(
|
|
15
|
-
"Controller name not found. use --name or node artisan make:controller HomeController",
|
|
16
|
-
);
|
|
17
|
-
}
|
|
18
|
-
const controllerPath = path.join(process.cwd(), "./src/controllers");
|
|
19
|
-
const controllerFolderExists = existsSync(controllerPath);
|
|
20
|
-
if (!controllerFolderExists) {
|
|
21
|
-
await mkdir(controllerPath, {
|
|
22
|
-
recursive: true,
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const controllerName = name.at(0).toUpperCase() + name.slice(1);
|
|
27
|
-
const controllerNameLowerCase = name.replace(/Controller/ig, '').match(/[A-Z][a-z]+|[0-9]+/g).join("-").toLowerCase();
|
|
28
|
-
const controllerNameCap = controllerName.replace(/Controller/ig, '')
|
|
29
|
-
const controllerExists = existsSync(`${controllerPath}/${name.toLowerCase()}.controller.ts`);
|
|
30
|
-
|
|
31
|
-
if (controllerExists && !options.force) {
|
|
32
|
-
console.log(
|
|
33
|
-
chalk.bold(chalk.red("controller already exists!")),
|
|
34
|
-
chalk.greenBright("Use -f or --force to overwrite.\r"),
|
|
35
|
-
);
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (options.model) {
|
|
40
|
-
const file = await import(
|
|
41
|
-
path.join(process.cwd(), "./src/models/" + options.model.toUpperCase() + ".ts")
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
if (file) {
|
|
45
|
-
Object.getOwnPropertyNames(file);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const restController = `
|
|
50
|
-
import { ApiController, Get, Post, Put, Delete, Param, Body } from '@avleon/core';
|
|
51
|
-
\t
|
|
52
|
-
@ApiController("/${controllerNameLowerCase}")
|
|
53
|
-
export class ${controllerName}{\n
|
|
54
|
-
@Get()
|
|
55
|
-
async findAll(){
|
|
56
|
-
return "okay";
|
|
57
|
-
}\n
|
|
58
|
-
@Get('/:id')
|
|
59
|
-
async findOne(@Param('id') id:number){
|
|
60
|
-
return "okay";
|
|
61
|
-
}\n
|
|
62
|
-
@Post()
|
|
63
|
-
async create(@Body() body:any){
|
|
64
|
-
return true;
|
|
65
|
-
}\n
|
|
66
|
-
@Put('/:id')
|
|
67
|
-
async update(@Param('id') id:number, @Body() body:any){
|
|
68
|
-
return true;
|
|
69
|
-
}\n
|
|
70
|
-
@Delete('/:id')
|
|
71
|
-
async delete(@Param('id') id:number){
|
|
72
|
-
return true;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
`;
|
|
77
|
-
|
|
78
|
-
const basicContorller = `import {ApiController, Get} from '@avleon/core'
|
|
79
|
-
\n
|
|
80
|
-
@ApiController("/${controllerNameLowerCase}")
|
|
81
|
-
export class ${controllerName}{
|
|
82
|
-
\n
|
|
83
|
-
@Get()
|
|
84
|
-
index(){
|
|
85
|
-
return []
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
`;
|
|
89
|
-
|
|
90
|
-
const formatcontroller = await prettier.format(
|
|
91
|
-
options.resource ? restController : basicContorller,
|
|
92
|
-
{
|
|
93
|
-
singleQuote: true,
|
|
94
|
-
singleAttributePerLine: true,
|
|
95
|
-
parser: "typescript",
|
|
96
|
-
},
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
await writeFile(
|
|
100
|
-
path.join(process.cwd(), "./src/controllers/" + controllerName.toLowerCase().replace("controller", "") + ".controller." + ".ts"),
|
|
101
|
-
formatcontroller,
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
console.log("Controller created succssessfully!");
|
|
105
|
-
}
|
|
106
|
-
export { createController };
|
package/src/create.ts
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import fs from 'fs-extra';
|
|
3
|
-
import { appPaths as getAppPaths } from './paths';
|
|
4
|
-
import * as prettier from 'prettier';
|
|
5
|
-
import path from 'path/win32';
|
|
6
|
-
import { execSync } from 'child_process';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
async function createApplication(fname: any) {
|
|
11
|
-
|
|
12
|
-
const appPaths = getAppPaths(fname);
|
|
13
|
-
const dirs = Object.values(appPaths);
|
|
14
|
-
for (let i = 0; i < dirs.length; i++) {
|
|
15
|
-
await fs.ensureDir(dirs[i]);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
await fs.ensureDir(appPaths.root + "/public");
|
|
19
|
-
// copy
|
|
20
|
-
//
|
|
21
|
-
const mainFunc = `
|
|
22
|
-
import {
|
|
23
|
-
Builder,
|
|
24
|
-
env
|
|
25
|
-
} from "@avleon/core";
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
// create builder
|
|
29
|
-
const builder = Builder.createAppBuilder();
|
|
30
|
-
|
|
31
|
-
// registering all services and dependencies here
|
|
32
|
-
// builder.addDataSource({
|
|
33
|
-
// type: "better-sqlite3",
|
|
34
|
-
// database: path.join(process.cwd(), "mydb.db"),
|
|
35
|
-
// entities: [Category, Product],
|
|
36
|
-
// synchronize: true,
|
|
37
|
-
// });
|
|
38
|
-
|
|
39
|
-
// build app
|
|
40
|
-
const app = builder.build();
|
|
41
|
-
app.mapGet('/', ()=> "Welcome");
|
|
42
|
-
|
|
43
|
-
app.listen(env.PORT);
|
|
44
|
-
|
|
45
|
-
`
|
|
46
|
-
|
|
47
|
-
const formatMainFunc = await prettier.format(
|
|
48
|
-
mainFunc,
|
|
49
|
-
{
|
|
50
|
-
singleQuote: true,
|
|
51
|
-
singleAttributePerLine: true,
|
|
52
|
-
parser: "typescript",
|
|
53
|
-
},
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
await fs.writeFile(path.join(appPaths.src, 'app.ts'), formatMainFunc);
|
|
57
|
-
|
|
58
|
-
// create package.json
|
|
59
|
-
const packageJson = `
|
|
60
|
-
{
|
|
61
|
-
"name": "${fname}",
|
|
62
|
-
"version": "1.0.0",
|
|
63
|
-
"description": "",
|
|
64
|
-
"main": "index.js",
|
|
65
|
-
"scripts": {
|
|
66
|
-
"test": "echo \\"Error: no test specified\\" && exit 1",
|
|
67
|
-
"dev": "nodemon src/app.ts",
|
|
68
|
-
"start": "node dist/app.js",
|
|
69
|
-
"build": "rimraf dist && tsc"
|
|
70
|
-
},
|
|
71
|
-
"keywords": [],
|
|
72
|
-
"author": "",
|
|
73
|
-
"license": "ISC",
|
|
74
|
-
"dependencies": {
|
|
75
|
-
"class-transformer": "^0.5.1",
|
|
76
|
-
"class-validator": "^0.14.1",
|
|
77
|
-
"reflect-metadata": "^0.2.2"
|
|
78
|
-
},
|
|
79
|
-
"devDependencies": {
|
|
80
|
-
"nodemon": "^3.1.7",
|
|
81
|
-
"ts-node": "^10.9.2",
|
|
82
|
-
"typescript": "^5.7.2"
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
`
|
|
87
|
-
|
|
88
|
-
const formattedPackageJson = await prettier.format(
|
|
89
|
-
packageJson,
|
|
90
|
-
{
|
|
91
|
-
parser: "json",
|
|
92
|
-
},
|
|
93
|
-
);
|
|
94
|
-
await fs.writeFile(path.join(appPaths.root, 'package.json'), formattedPackageJson);
|
|
95
|
-
const tsconfigJson = await prettier.format(`{
|
|
96
|
-
"compilerOptions": {
|
|
97
|
-
"target": "ES2017",
|
|
98
|
-
"module": "CommonJS",
|
|
99
|
-
"moduleResolution": "node",
|
|
100
|
-
"outDir": "./dist",
|
|
101
|
-
"rootDir": "./src",
|
|
102
|
-
"esModuleInterop": true,
|
|
103
|
-
"allowSyntheticDefaultImports": true,
|
|
104
|
-
"forceConsistentCasingInFileNames": true,
|
|
105
|
-
"skipLibCheck": true
|
|
106
|
-
},
|
|
107
|
-
"include": ["src/**/*"],
|
|
108
|
-
"exclude": ["node_modules", "dist"]
|
|
109
|
-
}`, { parser: 'json' })
|
|
110
|
-
await fs.writeFile(path.join(appPaths.root, 'tsconfig.json'), tsconfigJson);
|
|
111
|
-
await fs.writeFile(path.join(appPaths.root, '.gitignore'), `node_modules/\ndist/\n.env`);
|
|
112
|
-
// create basic service
|
|
113
|
-
// create basic controller
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
console.info("Running pnpm install");
|
|
117
|
-
execSync(`cd ${fname}&& pnpm install && pnpm link @avleon/core`, { stdio: 'inherit' })
|
|
118
|
-
|
|
119
|
-
console.info("App create successfully.");
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
export { createApplication }
|
package/src/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./cli";
|
package/src/paths.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
|
|
3
|
-
export type AppPaths = {
|
|
4
|
-
root: string,
|
|
5
|
-
src: string,
|
|
6
|
-
test: string,
|
|
7
|
-
controllers: string,
|
|
8
|
-
models: string,
|
|
9
|
-
services: string,
|
|
10
|
-
requests: string,
|
|
11
|
-
responses: string,
|
|
12
|
-
configs: string
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
export const appPaths = (rootPath?: string): AppPaths => {
|
|
17
|
-
const root = rootPath ? rootPath : path.join(process.cwd(), "./");
|
|
18
|
-
return {
|
|
19
|
-
root: root,
|
|
20
|
-
src: path.join(root, "src"),
|
|
21
|
-
test: path.join(root, "test"),
|
|
22
|
-
controllers: path.join(root, "src/controllers"),
|
|
23
|
-
models: path.join(root, "src/models"),
|
|
24
|
-
services: path.join(root, "src/services"),
|
|
25
|
-
requests: path.join(root, "src/requests"),
|
|
26
|
-
responses: path.join(root, "src/responses"),
|
|
27
|
-
configs: path.join(root, "src/configs")
|
|
28
|
-
}
|
|
29
|
-
}
|
package/src/stubs/model.stub
DELETED
|
File without changes
|