@avleon/cli 0.0.1 → 0.0.2

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/av-cli.js CHANGED
@@ -1,8 +1,7 @@
1
+ #!/usr/bin/env node
1
2
  "use strict";
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Cli = void 0;
4
4
  exports.PathExtractor = PathExtractor;
5
- const commands_1 = require("./commands");
6
5
  function formatFileName(name) {
7
6
  return name
8
7
  .replace(/[_\s]+/g, "-")
@@ -59,35 +58,3 @@ function PathExtractor(givenPath, options) {
59
58
  let outputPath = givenPath + "." + fileType + ".ts";
60
59
  return {};
61
60
  }
62
- class Cli {
63
- constructor() {
64
- this.commands = commands_1.commandList;
65
- this.isBusy = false;
66
- }
67
- createApplication() { }
68
- createModel(options) {
69
- throw new Error("Method not implemented.");
70
- }
71
- createService() {
72
- throw new Error("Method not implemented.");
73
- }
74
- createController() {
75
- throw new Error("Method not implemented.");
76
- }
77
- createProject() {
78
- throw new Error("Method not implemented.");
79
- }
80
- createResource() {
81
- throw new Error("Method not implemented.");
82
- }
83
- createRestService() {
84
- throw new Error("Method not implemented.");
85
- }
86
- createRestController() {
87
- throw new Error("Method not implemented.");
88
- }
89
- displayHelp() {
90
- throw new Error("Method not implemented.");
91
- }
92
- }
93
- exports.Cli = Cli;
package/dist/cli.js CHANGED
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env node
1
2
  "use strict";
2
3
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
4
  if (k2 === undefined) k2 = k;
@@ -70,9 +70,7 @@ async function createController(name, options = { force: false, resource: false,
70
70
  const restController = `
71
71
  import { ApiController, Get, Post, Put, Delete, Param, Body } from '@avleon/core';
72
72
  \t
73
- @ApiController("/${controllerNameLowerCase}", {
74
- name: "${controllerNameCap}"
75
- })
73
+ @ApiController("/${controllerNameLowerCase}")
76
74
  export class ${controllerName}{\n
77
75
  @Get()
78
76
  async findAll(){
@@ -103,7 +101,7 @@ async function createController(name, options = { force: false, resource: false,
103
101
  export class ${controllerName}{
104
102
  \n
105
103
  @Get()
106
- async index(){
104
+ index(){
107
105
  return []
108
106
  }
109
107
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@avleon/cli",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "bin": {
5
5
  "av": "./dist/cli.js"
6
6
  },
package/src/av-cli.ts ADDED
@@ -0,0 +1,95 @@
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
+
@@ -0,0 +1,55 @@
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 ADDED
@@ -0,0 +1,241 @@
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()
@@ -0,0 +1,56 @@
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
+ ];
@@ -0,0 +1,106 @@
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 ADDED
@@ -0,0 +1,117 @@
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 'reflect-metadata';
23
+ import { AppBuilder } from '@avleon/core';
24
+
25
+ async function main() {
26
+ const builder = AppBuilder.createBuilder();
27
+ // builder.useLogger();
28
+ builder.useDatabase();
29
+
30
+ const app = await builder.build();
31
+ await app.mapControllers();
32
+ await app.run();
33
+
34
+ }
35
+ main().catch(err=> console.log(err));
36
+ `
37
+
38
+ const formatMainFunc = await prettier.format(
39
+ mainFunc,
40
+ {
41
+ singleQuote: true,
42
+ singleAttributePerLine: true,
43
+ parser: "typescript",
44
+ },
45
+ );
46
+
47
+ await fs.writeFile(path.join(appPaths.src, 'app.ts'), formatMainFunc);
48
+
49
+ // create package.json
50
+ const packageJson = `
51
+ {
52
+ "name": "${fname}",
53
+ "version": "1.0.0",
54
+ "description": "",
55
+ "main": "index.js",
56
+ "scripts": {
57
+ "test": "echo \\"Error: no test specified\\" && exit 1",
58
+ "dev": "nodemon src/app.ts",
59
+ "start": "node dist/app.js",
60
+ "build": "rimraf dist && tsc"
61
+ },
62
+ "keywords": [],
63
+ "author": "",
64
+ "license": "ISC",
65
+ "dependencies": {
66
+ "class-transformer": "^0.5.1",
67
+ "class-validator": "^0.14.1",
68
+ "reflect-metadata": "^0.2.2"
69
+ },
70
+ "devDependencies": {
71
+ "nodemon": "^3.1.7",
72
+ "ts-node": "^10.9.2",
73
+ "typescript": "^5.7.2"
74
+ }
75
+
76
+ }
77
+ `
78
+
79
+ const formattedPackageJson = await prettier.format(
80
+ packageJson,
81
+ {
82
+ parser: "json",
83
+ },
84
+ );
85
+ await fs.writeFile(path.join(appPaths.root, 'package.json'), formattedPackageJson);
86
+ const tsconfigJson = await prettier.format(`{
87
+ "compilerOptions": {
88
+ "target": "ES2017",
89
+ "module": "CommonJS",
90
+ "moduleResolution": "node",
91
+ "outDir": "./dist",
92
+ "rootDir": "./src",
93
+ "esModuleInterop": true,
94
+ "allowSyntheticDefaultImports": true,
95
+ "forceConsistentCasingInFileNames": true,
96
+ "skipLibCheck": true
97
+ },
98
+ "include": ["src/**/*"],
99
+ "exclude": ["node_modules", "dist"]
100
+ }`, { parser: 'json' })
101
+ await fs.writeFile(path.join(appPaths.root, 'tsconfig.json'), tsconfigJson);
102
+ await fs.writeFile(path.join(appPaths.root, '.gitignore'), `node_modules/\ndist/\n.env`);
103
+ // create basic service
104
+ // create basic controller
105
+
106
+
107
+ console.info("Running pnpm install");
108
+ execSync(`cd ${fname}&& pnpm install && pnpm link @avleon/core && pnpm link @avleon/data`, { stdio: 'inherit' })
109
+
110
+ console.info("App create successfully.");
111
+
112
+
113
+ }
114
+
115
+
116
+
117
+ export { createApplication }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./cli";
package/src/paths.ts ADDED
@@ -0,0 +1,29 @@
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
+ }
@@ -0,0 +1,7 @@
1
+ import { Get, HttpResponse } from '@avleon/core';
2
+ export class {{name}}{
3
+ constructor(
4
+ private readonly {}
5
+ ){}
6
+ }
7
+
File without changes