@avleon/cli 0.0.44 → 0.0.46

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/serve.js CHANGED
@@ -6,7 +6,11 @@ const fs = require("fs");
6
6
  const { transformFileSync } = require("@swc/core");
7
7
  const SRC_DIR = path.resolve(process.cwd(), "./src");
8
8
  const DIST_DIR = path.resolve(process.cwd(), "./dist");
9
- const ENTRY_FILE = path.join(DIST_DIR, "server.js");
9
+ const pkg = fs.existsSync(path.join(process.cwd(), "package.json"))
10
+ ? JSON.parse(fs.readFileSync(path.join(process.cwd(), "package.json"), "utf8"))
11
+ : {};
12
+ const ENTRY_RELATIVE = pkg?.avleon?.entry || pkg?.main?.replace("src/", "dist/").replace(".ts", ".js") || "dist/server.js";
13
+ const ENTRY_FILE = path.resolve(process.cwd(), ENTRY_RELATIVE);
10
14
  let nodeProcess = null;
11
15
  let isRestarting = false;
12
16
  // Color constants for better type safety
@@ -144,12 +148,6 @@ function startNode() {
144
148
  nodeProcess = null;
145
149
  isRestarting = false;
146
150
  });
147
- // Add a small delay to let the server start
148
- setTimeout(() => {
149
- if (nodeProcess) {
150
- logServer("✅ Server started successfully");
151
- }
152
- }, 500);
153
151
  }
154
152
  catch (error) {
155
153
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -229,6 +227,15 @@ async function restartNode() {
229
227
  isRestarting = false;
230
228
  }
231
229
  }
230
+ let restartTimer = null;
231
+ async function debouncedRestart() {
232
+ if (restartTimer)
233
+ clearTimeout(restartTimer);
234
+ restartTimer = setTimeout(async () => {
235
+ restartTimer = null;
236
+ await restartNode();
237
+ }, 300); // wait 300ms after last change
238
+ }
232
239
  // watch src
233
240
  function watch() {
234
241
  const watcher = chokidar.watch(SRC_DIR, {
@@ -244,10 +251,6 @@ function watch() {
244
251
  pollInterval: 50
245
252
  }
246
253
  });
247
- // Debug: log when watcher is ready
248
- // watcher.on('ready', () => {
249
- // logWatch('✅ Initial scan complete. Ready for changes');
250
- // });
251
254
  watcher.on("add", (file) => {
252
255
  if (file.endsWith('.ts') && !isTestFile(file)) {
253
256
  if (compileFile(file)) {
@@ -258,7 +261,7 @@ function watch() {
258
261
  watcher.on("change", async (file) => {
259
262
  if (file.endsWith('.ts') && !isTestFile(file)) {
260
263
  if (compileFile(file)) {
261
- await restartNode();
264
+ await debouncedRestart();
262
265
  }
263
266
  }
264
267
  });
@@ -283,15 +286,18 @@ function watch() {
283
286
  logError('WATCH', `Watcher error: ${error.message}`);
284
287
  });
285
288
  }
289
+ process.on("uncaughtException", (error) => {
290
+ logError('CLI', `Uncaught exception: ${error.message}`);
291
+ logError('CLI', error.stack ?? "");
292
+ });
293
+ process.on("unhandledRejection", (reason) => {
294
+ logError('CLI', `Unhandled rejection: ${reason}`);
295
+ });
286
296
  // Graceful shutdown
287
297
  process.on("SIGINT", async () => {
288
298
  await killNode();
289
299
  process.exit(0);
290
300
  });
291
- process.on("SIGTERM", async () => {
292
- await killNode();
293
- process.exit(0);
294
- });
295
301
  // Main execution
296
302
  (async () => {
297
303
  console.log(`${Colors.BOLD}${Colors.CYAN}🔧 Development Server${Colors.RESET}`);
package/package.json CHANGED
@@ -1,51 +1,62 @@
1
- {
2
- "name": "@avleon/cli",
3
- "version": "0.0.44",
4
- "bin": {
5
- "avleon": "./dist/cli.js"
6
- },
7
- "description": "",
8
- "main": "dist/index.js",
9
- "types": "dist/index.d.ts",
10
- "keywords": [
11
- "cli",
12
- "backend-api"
13
- ],
14
- "author": "Tareq Hossain",
15
- "license": "ISC",
16
- "devDependencies": {
17
- "@swc/cli": "^0.7.8",
18
- "@swc/core": "^1.13.5",
19
- "@types/fs-extra": "^11.0.4",
20
- "@types/lodash": "^4.17.16",
21
- "@types/node": "^22.9.3",
22
- "chokidar": "^4.0.3",
23
- "concurrently": "^9.2.1",
24
- "nodemon": "^3.1.7",
25
- "tsc-watch": "^6.2.1",
26
- "tsup": "^8.4.0",
27
- "typescript": "^5.7.2"
28
- },
29
- "dependencies": {
30
- "chalk": "^5.4.1",
31
- "cli-table3": "^0.6.5",
32
- "fs-extra": "^11.2.0",
33
- "inquirer": "^12.6.0",
34
- "lodash": "^4.17.21",
35
- "prettier": "^3.3.3",
36
- "rimraf": "^6.0.1"
37
- },
38
- "repository": {
39
- "type": "git",
40
- "url": "git+https://github.com/avleonjs/avleon-cli"
41
- },
42
- "publishConfig": {
43
- "access": "public"
44
- },
45
- "scripts": {
46
- "build": "rimraf dist & tsc",
47
- "clean": "rm -rf ./dist",
48
- "prepublish": "npm run build",
49
- "watch": "tsc-watch"
50
- }
51
- }
1
+ {
2
+ "name": "@avleon/cli",
3
+ "version": "0.0.46",
4
+ "description": "CLI for scaffolding and running Avleon applications",
5
+ "author": "Tareq Hossain",
6
+ "license": "ISC",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "bin": {
10
+ "avleon": "./dist/cli.js"
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "stubs",
15
+ "README.md"
16
+ ],
17
+ "scripts": {
18
+ "build": "rimraf dist && tsc",
19
+ "clean": "rimraf dist",
20
+ "prepublishOnly": "npm run build",
21
+ "watch": "tsc-watch --onSuccess \"echo Build complete\""
22
+ },
23
+ "keywords": [
24
+ "cli",
25
+ "avleon",
26
+ "backend",
27
+ "typescript"
28
+ ],
29
+ "dependencies": {
30
+ "@avleon/core": "*",
31
+ "@swc/core": "^1.13.5",
32
+ "chokidar": "^4.0.3",
33
+ "chalk": "^5.4.1",
34
+ "cli-table3": "^0.6.5",
35
+ "fs-extra": "^11.2.0",
36
+ "inquirer": "^12.6.0",
37
+ "lodash": "^4.17.21",
38
+ "prettier": "^3.3.3",
39
+ "rimraf": "^6.0.1"
40
+ },
41
+ "devDependencies": {
42
+ "@swc/cli": "^0.7.8",
43
+ "@types/fs-extra": "^11.0.4",
44
+ "@types/lodash": "^4.17.16",
45
+ "@types/node": "^22.9.3",
46
+ "concurrently": "^9.2.1",
47
+ "nodemon": "^3.1.7",
48
+ "tsc-watch": "^6.2.1",
49
+ "tsup": "^8.4.0",
50
+ "typescript": "^5.7.2"
51
+ },
52
+ "peerDependencies": {
53
+ "@avleon/core": ">=0.0.38"
54
+ },
55
+ "repository": {
56
+ "type": "git",
57
+ "url": "git+https://github.com/avleonjs/avleon-cli"
58
+ },
59
+ "publishConfig": {
60
+ "access": "public"
61
+ }
62
+ }
package/readme.md CHANGED
@@ -1,66 +1,66 @@
1
-
2
- ### ⚠️ WARNING: NOT FOR PRODUCTION USE
3
-
4
- > **🚧 This project is in active development.**
5
- >
6
- > It is **not stable** and **not ready** for live environments.
7
- > Use **only for testing, experimentation, or internal evaluation**.
8
- >
9
- > ####❗ Risks of using this in production:
10
- >
11
- > - 🔄 Breaking changes may be introduced at any time
12
- > - 🧪 Features are experimental and may be unstable
13
- > - 🔐 Security has not been audited
14
- > - 💥 Potential for data loss or critical errors
15
- >
16
- > **Please do not deploy this in production environments.**
17
-
18
- # Avleon CLI - v0.0.37
19
-
20
- ### Create Application
21
- ```sh
22
- npx @avleon/cli new my_api
23
- ```
24
- ### Create Controller
25
- ```sh
26
- npx avleon make:controller product
27
- # or shorthand
28
- npx avleon m:c product
29
- # for resource controller with -r flag
30
- npx avleon m:c product -m product -r
31
- ```
32
-
33
- ### Create Model/Entity
34
- ```sh
35
- # basic model
36
- npx avleon make:model product
37
- # typeorm model
38
- npx avleon m:m product --orm
39
- ```
40
-
41
- ### Create Service
42
- ```sh
43
- # basic service
44
- npx avleon make:service product
45
- # resource service with built-in collection
46
- npx avleon make:service product -m product -r
47
- # resource service with typeorm collection
48
- npx avleon make:service product -m product -r --orm
49
- ```
50
-
51
- ### Create Middleware
52
- ```sh
53
- npx avleon make:config product
54
- ```
55
-
56
- ### Create Config
57
- ```sh
58
- npx avleon make:config product
59
- ```
60
-
61
- ### Create authoriztion (Experimental)
62
- ```sh
63
- npx avleon make:auth jwt
64
- ```
65
-
66
-
1
+
2
+ ### ⚠️ WARNING: NOT FOR PRODUCTION USE
3
+
4
+ > **🚧 This project is in active development.**
5
+ >
6
+ > It is **not stable** and **not ready** for live environments.
7
+ > Use **only for testing, experimentation, or internal evaluation**.
8
+ >
9
+ > ####❗ Risks of using this in production:
10
+ >
11
+ > - 🔄 Breaking changes may be introduced at any time
12
+ > - 🧪 Features are experimental and may be unstable
13
+ > - 🔐 Security has not been audited
14
+ > - 💥 Potential for data loss or critical errors
15
+ >
16
+ > **Please do not deploy this in production environments.**
17
+
18
+ # Avleon CLI - v0.0.37
19
+
20
+ ### Create Application
21
+ ```sh
22
+ npx @avleon/cli new my_api
23
+ ```
24
+ ### Create Controller
25
+ ```sh
26
+ npx avleon make:controller product
27
+ # or shorthand
28
+ npx avleon m:c product
29
+ # for resource controller with -r flag
30
+ npx avleon m:c product -m product -r
31
+ ```
32
+
33
+ ### Create Model/Entity
34
+ ```sh
35
+ # basic model
36
+ npx avleon make:model product
37
+ # typeorm model
38
+ npx avleon m:m product --orm
39
+ ```
40
+
41
+ ### Create Service
42
+ ```sh
43
+ # basic service
44
+ npx avleon make:service product
45
+ # resource service with built-in collection
46
+ npx avleon make:service product -m product -r
47
+ # resource service with typeorm collection
48
+ npx avleon make:service product -m product -r --orm
49
+ ```
50
+
51
+ ### Create Middleware
52
+ ```sh
53
+ npx avleon make:config product
54
+ ```
55
+
56
+ ### Create Config
57
+ ```sh
58
+ npx avleon make:config product
59
+ ```
60
+
61
+ ### Create authoriztion (Experimental)
62
+ ```sh
63
+ npx avleon make:auth jwt
64
+ ```
65
+
66
+
@@ -1,11 +1,11 @@
1
- import { Builder, AppConfig } from '@avleon/core';
2
- import { HomeController } from './controllers/home.controller';
3
-
4
- const builder = Builder.createAppBuilder();
5
-
6
- const app = builder.build();
7
- app.useOpenApi((config:AppConfig)=> config.openApi);
8
- app.useControllers([HomeController]);
9
-
10
-
11
- app.run();
1
+ import { Builder, AppConfig } from '@avleon/core';
2
+ import { HomeController } from './controllers/home.controller';
3
+
4
+ const builder = Builder.createAppBuilder();
5
+
6
+ const app = builder.build();
7
+ app.useOpenApi((config:AppConfig)=> config.openApi);
8
+ app.useControllers([HomeController]);
9
+
10
+
11
+ app.run();
@@ -1,17 +1,17 @@
1
- import { Builder, AppConfig } from '@avleon/core';
2
- const builder = Builder.createAppBuilder();
3
-
4
- builder.services.addOpenApi();
5
- builder.services.addServices();
6
- builder.services.addAuthentication();
7
- builder.servicse.addControllers();
8
- const app = builder.build();
9
-
10
-
11
-
12
- if(app.isDevelopment()){
13
- app.useOpenApi((config:AppConfig)=> config.openApi);
14
- }
15
-
16
- app.mapGet('/', () => "Hello World!");
17
- export default app;
1
+ import { Builder, AppConfig } from '@avleon/core';
2
+ const builder = Builder.createAppBuilder();
3
+
4
+ builder.services.addOpenApi();
5
+ builder.services.addServices();
6
+ builder.services.addAuthentication();
7
+ builder.servicse.addControllers();
8
+ const app = builder.build();
9
+
10
+
11
+
12
+ if(app.isDevelopment()){
13
+ app.useOpenApi((config:AppConfig)=> config.openApi);
14
+ }
15
+
16
+ app.mapGet('/', () => "Hello World!");
17
+ export default app;
@@ -1,7 +1,7 @@
1
- import { Get, HttpResponse } from '@avleon/core';
2
- export class {{name}}{
3
- constructor(
4
- private readonly {}
5
- ){}
6
- }
7
-
1
+ import { Get, HttpResponse } from '@avleon/core';
2
+ export class {{name}}{
3
+ constructor(
4
+ private readonly {}
5
+ ){}
6
+ }
7
+
package/stubs/config.stub CHANGED
@@ -1,11 +1,11 @@
1
- @Config
2
- export class OpenApiConfig {
3
- config() {
4
- return {
5
- title: 'My API',
6
- version: '1.0.0',
7
- description: 'API documentation',
8
- path: '/api-docs',
9
- };
10
- }
11
- }
1
+ @Config
2
+ export class OpenApiConfig {
3
+ config() {
4
+ return {
5
+ title: 'My API',
6
+ version: '1.0.0',
7
+ description: 'API documentation',
8
+ path: '/api-docs',
9
+ };
10
+ }
11
+ }
@@ -1,12 +1,12 @@
1
- import { ApiController, Get, HttpResponse } from '@avleon/core';
2
-
3
-
4
- @ApiController('/{controller}s')
5
- export class {Controller}Controller{
6
-
7
- @Get()
8
- index(){
9
- return "{controller} ok";
10
- }
11
-
12
- }
1
+ import { ApiController, Get, HttpResponse } from '@avleon/core';
2
+
3
+
4
+ @ApiController('/{controller}s')
5
+ export class {Controller}Controller{
6
+
7
+ @Get()
8
+ index(){
9
+ return "{controller} ok";
10
+ }
11
+
12
+ }
@@ -1,52 +1,52 @@
1
- import { ApiController, Get, Post, Delete, Param, Query, Body, HttpExceptions } from '@avleon/core';
2
- import { {Model}Service } from '../services/{model}.service';
3
-
4
- @ApiController('/{controller}s')
5
- export class {Controller}Controller{
6
-
7
- constructor(
8
- private readonly {model}Service: {Model}Service
9
- ){}
10
-
11
- @Get()
12
- async index(@Query() query?:any){
13
- if(query && query.page){
14
- const result = await this.{model}Service.paginate(query.page);
15
- return result;
16
- }
17
- const result = await this.{model}Service.findAll();
18
- return result;
19
- }
20
-
21
- @Get('/:id')
22
- async findOne(@Param('id') id:number){
23
- const is{Model} = await this.{model}Service.findByPk(id);
24
- if(!is{Model}) throw HttpExceptions.notFound("{Model} not found.");
25
- return is{Model};
26
- }
27
-
28
- @Post()
29
- async create(@Body() body:any){
30
- const isSave = await this.{model}Service.create(body);
31
- return isSave;
32
- }
33
-
34
- @Post('/:id')
35
- async update(@Param('id') id:number, updateBody:any){
36
- const is{Model} = await this.{model}Service.findByPk(id);
37
- if(!is{Model}) throw HttpExceptions.notFound("{Model} not found.");
38
- const isUpdated = await this.{model}Service.update(id,updateBody);
39
- if(!isUpdated) throw HttpExceptions.internalError("Can't update {Model}");
40
- return "Updated Successfully";
41
- }
42
-
43
- @Delete('/:id')
44
- async delete(@Param('id') id:number){
45
- const is{Model} = await this.{model}Service.findByPk(id);
46
- if(!is{Model}) throw HttpExceptions.notFound("{Model} not found.");
47
- const isDeleted = await this.{model}Service.delete(id);
48
- if(!isDeleted) throw HttpExceptions.internalError("Can't delete");
49
- return "Deleted Successfully";
50
- }
51
-
52
- }
1
+ import { ApiController, Get, Post, Delete, Param, Query, Body, HttpExceptions } from '@avleon/core';
2
+ import { {Model}Service } from '../services/{model}.service';
3
+
4
+ @ApiController('/{controller}s')
5
+ export class {Controller}Controller{
6
+
7
+ constructor(
8
+ private readonly {model}Service: {Model}Service
9
+ ){}
10
+
11
+ @Get()
12
+ async index(@Query() query?:any){
13
+ if(query && query.page){
14
+ const result = await this.{model}Service.paginate(query.page);
15
+ return result;
16
+ }
17
+ const result = await this.{model}Service.findAll();
18
+ return result;
19
+ }
20
+
21
+ @Get('/:id')
22
+ async findOne(@Param('id') id:number){
23
+ const is{Model} = await this.{model}Service.findByPk(id);
24
+ if(!is{Model}) throw HttpExceptions.notFound("{Model} not found.");
25
+ return is{Model};
26
+ }
27
+
28
+ @Post()
29
+ async create(@Body() body:any){
30
+ const isSave = await this.{model}Service.create(body);
31
+ return isSave;
32
+ }
33
+
34
+ @Post('/:id')
35
+ async update(@Param('id') id:number, updateBody:any){
36
+ const is{Model} = await this.{model}Service.findByPk(id);
37
+ if(!is{Model}) throw HttpExceptions.notFound("{Model} not found.");
38
+ const isUpdated = await this.{model}Service.update(id,updateBody);
39
+ if(!isUpdated) throw HttpExceptions.internalError("Can't update {Model}");
40
+ return "Updated Successfully";
41
+ }
42
+
43
+ @Delete('/:id')
44
+ async delete(@Param('id') id:number){
45
+ const is{Model} = await this.{model}Service.findByPk(id);
46
+ if(!is{Model}) throw HttpExceptions.notFound("{Model} not found.");
47
+ const isDeleted = await this.{model}Service.delete(id);
48
+ if(!isDeleted) throw HttpExceptions.internalError("Can't delete");
49
+ return "Deleted Successfully";
50
+ }
51
+
52
+ }
@@ -1,34 +1,34 @@
1
- import { ApiController, Get, Post, Delete, Param, Query, Body, HttpExceptions } from '@avleon/core';
2
-
3
- @ApiController('/{controller}s')
4
- export class {Controller}Controller{
5
-
6
-
7
-
8
- @Get()
9
- async index(@Query() query?:any){
10
- throw new Error("Method not implemented.");
11
- }
12
-
13
- @Get('/:id')
14
- async findOne(@Param('id') id:number){
15
- throw new Error("Method not implemented.");
16
- }
17
-
18
- @Post()
19
- async create(@Body() body:any){
20
- throw new Error("Method not implemented.");
21
- }
22
-
23
- @Post('/:id')
24
- async update(@Param('id') id:number, updateBody:any){
25
-
26
- throw new Error("Method not implemented.");
27
- }
28
-
29
- @Delete('/:id')
30
- async delete(@Param('id') id:number){
31
- throw new Error("Method not implemented.");
32
- }
33
-
34
- }
1
+ import { ApiController, Get, Post, Delete, Param, Query, Body, HttpExceptions } from '@avleon/core';
2
+
3
+ @ApiController('/{controller}s')
4
+ export class {Controller}Controller{
5
+
6
+
7
+
8
+ @Get()
9
+ async index(@Query() query?:any){
10
+ throw new Error("Method not implemented.");
11
+ }
12
+
13
+ @Get('/:id')
14
+ async findOne(@Param('id') id:number){
15
+ throw new Error("Method not implemented.");
16
+ }
17
+
18
+ @Post()
19
+ async create(@Body() body:any){
20
+ throw new Error("Method not implemented.");
21
+ }
22
+
23
+ @Post('/:id')
24
+ async update(@Param('id') id:number, updateBody:any){
25
+
26
+ throw new Error("Method not implemented.");
27
+ }
28
+
29
+ @Delete('/:id')
30
+ async delete(@Param('id') id:number){
31
+ throw new Error("Method not implemented.");
32
+ }
33
+
34
+ }
@@ -1,6 +1,6 @@
1
-
2
-
3
- export class {Model}{
4
- id: number;
5
- name: string;
6
- }
1
+
2
+
3
+ export class {Model}{
4
+ id: number;
5
+ name: string;
6
+ }