@avleon/cli 0.0.42 → 0.0.44

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.
@@ -0,0 +1,69 @@
1
+ name: Publish to npm
2
+
3
+
4
+
5
+ on:
6
+
7
+ push:
8
+
9
+ tags:
10
+
11
+ - 'v*' # Trigger only when a tag like v1.0.0 is pushed
12
+
13
+
14
+
15
+ jobs:
16
+
17
+ publish:
18
+
19
+ runs-on: ubuntu-latest
20
+
21
+
22
+
23
+ steps:
24
+
25
+ - name: Checkout repository
26
+
27
+ uses: actions/checkout@v4
28
+
29
+ - name: Setup Node.js
30
+
31
+ uses: actions/setup-node@v4
32
+
33
+ with:
34
+
35
+ node-version: 20
36
+
37
+ registry-url: 'https://registry.npmjs.org'
38
+
39
+
40
+
41
+ - name: Install pnpm
42
+
43
+ uses: pnpm/action-setup@v4
44
+
45
+ with:
46
+
47
+ version: 9
48
+
49
+
50
+
51
+ - name: Install dependencies
52
+
53
+ run: pnpm install --frozen-lockfile
54
+
55
+
56
+ - name: Build package
57
+
58
+ run: pnpm run build
59
+
60
+
61
+
62
+ - name: Publish to npm
63
+
64
+ run: pnpm publish --access public --no-git-checks
65
+
66
+ env:
67
+
68
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
69
+
package/dist/cli.js CHANGED
@@ -117,28 +117,28 @@ async function createModel(name, options = { force: false, orm: false }) {
117
117
  console.log("Model already exists!", "Use -f or --force to overwrite.\r");
118
118
  return;
119
119
  }
120
- const basicModel = `
121
- \t
122
- export class ${modelName}{
123
- id:number;
124
- name: string;
125
- }
120
+ const basicModel = `
121
+ \t
122
+ export class ${modelName}{
123
+ id:number;
124
+ name: string;
125
+ }
126
126
  `;
127
- const ormModel = `
128
- import {Entity, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn } from 'typeorm';
129
- \t
130
- @Entity({name:'${modelName}'})
131
- export class ${modelName}{
132
-
133
- @PrimaryGeneratedColumn()
134
- id:number;
135
-
136
- @CreateDateColumn()
137
- createdAt: Date;
138
-
139
- @UpdateDateColumn()
140
- updatedAt: Date;
141
- }
127
+ const ormModel = `
128
+ import {Entity, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn } from 'typeorm';
129
+ \t
130
+ @Entity({name:'${modelName}'})
131
+ export class ${modelName}{
132
+
133
+ @PrimaryGeneratedColumn()
134
+ id:number;
135
+
136
+ @CreateDateColumn()
137
+ createdAt: Date;
138
+
139
+ @UpdateDateColumn()
140
+ updatedAt: Date;
141
+ }
142
142
  `;
143
143
  const formatModel = await prettier.format(options.orm ? ormModel : basicModel, {
144
144
  singleQuote: true,
@@ -164,19 +164,19 @@ async function createMiddleware(name, options = { force: false }) {
164
164
  recursive: true,
165
165
  });
166
166
  }
167
- const basicMiddleware = `
168
- \t
169
- import { Middleware, IMiddleware } from '@avleon/core';
170
-
171
- @Middleware
172
- export class ${modelName}Middleware implements IMiddleware{
173
-
174
- invoke(req:IRequest){
175
- // your logic goes here
176
- return req;
177
- }
178
-
179
- }
167
+ const basicMiddleware = `
168
+ \t
169
+ import { Middleware, IMiddleware } from '@avleon/core';
170
+
171
+ @Middleware
172
+ export class ${modelName}Middleware implements IMiddleware{
173
+
174
+ invoke(req:IRequest){
175
+ // your logic goes here
176
+ return req;
177
+ }
178
+
179
+ }
180
180
  `;
181
181
  const formatModel = await prettier.format(basicMiddleware, {
182
182
  singleQuote: true,
@@ -203,21 +203,21 @@ async function createConfig(name, options = { force: false }) {
203
203
  recursive: true,
204
204
  });
205
205
  }
206
- const basicMiddleware = `
207
- \t
208
- import { Config, IConfig } from '@avleon/core';
209
-
210
- @AppConfig
211
- export class ${modelClassName} implements IConfig<T>{
212
-
213
- config(env: Environment){
214
- // config must return config
215
- return {
216
-
217
- };
218
- }
219
-
220
- }
206
+ const basicMiddleware = `
207
+ \t
208
+ import { Config, IConfig } from '@avleon/core';
209
+
210
+ @AppConfig
211
+ export class ${modelClassName} implements IConfig<T>{
212
+
213
+ config(env: Environment){
214
+ // config must return config
215
+ return {
216
+
217
+ };
218
+ }
219
+
220
+ }
221
221
  `;
222
222
  const formatModel = await prettier.format(basicMiddleware, {
223
223
  singleQuote: true,
@@ -230,6 +230,10 @@ export class ${modelClassName} implements IConfig<T>{
230
230
  async function run() {
231
231
  try {
232
232
  const args = process.argv.slice(2);
233
+ if (args[0] == "serve") {
234
+ require('./serve');
235
+ return;
236
+ }
233
237
  if (args.length < 1) {
234
238
  await displayCommandList({ logo: true, all: false });
235
239
  }
package/dist/commands.js CHANGED
@@ -22,22 +22,22 @@ exports.commandList = [
22
22
  Command: "make:controller",
23
23
  Alias: "m:c",
24
24
  Options: `-f, --force for force create\n -r or --resource for resource controller`,
25
- 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.
26
- You may also pass model by -m or --model.\n
27
- ${chalk_1.default.blueBright("Note:")} when using a resource contorller iqra will automaticall check for dtos related to model name. If -m is user then
28
- it will check for dtos like UserCreateDto and UserUpdateDto. If dtos not found it will create automatically using
29
- model properties.
25
+ 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.
26
+ You may also pass model by -m or --model.\n
27
+ ${chalk_1.default.blueBright("Note:")} when using a resource contorller iqra will automaticall check for dtos related to model name. If -m is user then
28
+ it will check for dtos like UserCreateDto and UserUpdateDto. If dtos not found it will create automatically using
29
+ model properties.
30
30
  `,
31
31
  },
32
32
  {
33
33
  Command: "make:service",
34
34
  Alias: "m:s",
35
35
  Options: `-f, --force for force create\n -r or --resource for resource controller, --dtos`,
36
- 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.
37
- You may also pass model by -m or --model.\n
38
- ${chalk_1.default.blueBright("Note:")} when using a resource contorller iqra will automaticall check for dtos related to model name. If -m is user then
39
- it will check for dtos like UserCreateDto and UserUpdateDto. If dtos not found it will create automatically using
40
- model properties.
36
+ 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.
37
+ You may also pass model by -m or --model.\n
38
+ ${chalk_1.default.blueBright("Note:")} when using a resource contorller iqra will automaticall check for dtos related to model name. If -m is user then
39
+ it will check for dtos like UserCreateDto and UserUpdateDto. If dtos not found it will create automatically using
40
+ model properties.
41
41
  `,
42
42
  },
43
43
  {
package/dist/create.js CHANGED
@@ -101,22 +101,22 @@ async function createApplication(fname, flags = {}) {
101
101
  await fs_extra_1.default.ensureDir(appPaths.root + "/src/controllers");
102
102
  await fs_extra_1.default.ensureDir(appPaths.root + "/src/config");
103
103
  await fs_extra_1.default.ensureDir(appPaths.root + "/src/services");
104
- await fs_extra_1.default.ensureDir(appPaths.root + "/src/models");
104
+ // await fs.ensureDir(appPaths.root + "/src/models");
105
105
  await fs_extra_1.default.ensureDir(appPaths.root + "/test");
106
106
  await fs_extra_1.default.ensureDir(appPaths.root + "/public");
107
107
  // copy
108
108
  // home controller
109
- const homeService = `
110
- import { AppService } from '@avleon/core';
111
-
112
-
113
- @AppService
114
- export class HomeService{
115
-
116
- sayHello(){
117
- return "Hello World!";
118
- }
119
- }
109
+ const homeService = `
110
+ import { AppService } from '@avleon/core';
111
+
112
+
113
+ @AppService
114
+ export class HomeService{
115
+
116
+ sayHello(){
117
+ return "Hello World!";
118
+ }
119
+ }
120
120
  `;
121
121
  const formatHomeService = await prettier.format(homeService, {
122
122
  singleQuote: true,
@@ -125,23 +125,23 @@ export class HomeService{
125
125
  });
126
126
  await fs_extra_1.default.writeFile(path_1.default.join(appPaths.services, "home.service.ts"), formatHomeService);
127
127
  // home controller
128
- const homeContrlelr = `
129
- import { ApiController, Get } from '@avleon/core';
130
- import { HomeService } from '../services/home.service';
131
-
132
-
133
- @ApiController
134
- export class HomeController{
135
-
136
- constructor(
137
- private readonly homeService: HomeService
138
- ){}
139
-
140
- @Get()
141
- sayHello(){
142
- return this.homeService.sayHello();
143
- }
144
- }
128
+ const homeContrlelr = `
129
+ import { ApiController, Get } from '@avleon/core';
130
+ import { HomeService } from '../services/home.service';
131
+
132
+
133
+ @ApiController
134
+ export class HomeController{
135
+
136
+ constructor(
137
+ private readonly homeService: HomeService
138
+ ){}
139
+
140
+ @Get()
141
+ sayHello(){
142
+ return this.homeService.sayHello();
143
+ }
144
+ }
145
145
  `;
146
146
  const formatHomeController = await prettier.format(homeContrlelr, {
147
147
  singleQuote: true,
@@ -149,22 +149,52 @@ export class HomeController{
149
149
  parser: "typescript",
150
150
  });
151
151
  await fs_extra_1.default.writeFile(path_1.default.join(appPaths.controllers, "home.controller.ts"), formatHomeController);
152
+ const homeContrlelrTest = `
153
+ import { AvleonTest } from "@avleon/core";
154
+ import { HomeController } from "./home.controller"
155
+
156
+ describe('Home Controller', () => {
157
+ let controller!: HomeController;
158
+
159
+ beforeAll(()=>{
160
+ controller = AvleonTest.getController(HomeController);
161
+ })
162
+
163
+ it('should be defined', () => {
164
+ expect(controller).toBeDefined()
165
+ })
166
+
167
+ it('should have sayhello function', () => {
168
+ expect(controller.sayHello).toBeDefined
169
+ })
170
+
171
+ it('should return sayhello', () => {
172
+ expect(controller.sayHello()).toBe("Hello World!");
173
+ })
174
+ })
175
+ `;
176
+ const formatHomeControllerTest = await prettier.format(homeContrlelrTest, {
177
+ singleQuote: true,
178
+ singleAttributePerLine: true,
179
+ parser: "typescript",
180
+ });
181
+ await fs_extra_1.default.writeFile(path_1.default.join(appPaths.controllers, "home.controller.spec.ts"), formatHomeControllerTest);
152
182
  // openapi config file
153
- const openapiConfigFile = `
154
- import { AppConfig, Environment, IConfig } from "@avleon/core";
155
-
156
- @AppConfig
157
- export class OpenApiConfig implements IConfig {
158
-
159
- config(env: Environment) {
160
- return {
161
- info: {
162
- title: '${(0, lodash_1.capitalize)(fname)}',
163
- version: '0.0.1',
164
- },
165
- }
166
- }
167
- }
183
+ const openapiConfigFile = `
184
+ import { AppConfig, Environment, IConfig } from "@avleon/core";
185
+
186
+ @AppConfig
187
+ export class OpenApiConfig implements IConfig {
188
+
189
+ config(env: Environment) {
190
+ return {
191
+ info: {
192
+ title: '${(0, lodash_1.capitalize)(fname)}',
193
+ version: '0.0.1',
194
+ },
195
+ }
196
+ }
197
+ }
168
198
  `;
169
199
  const formatConfigFile = await prettier.format(openapiConfigFile, {
170
200
  singleQuote: true,
@@ -173,22 +203,22 @@ export class OpenApiConfig implements IConfig {
173
203
  });
174
204
  await fs_extra_1.default.writeFile(path_1.default.join(appPaths.configs, "openapi.config.ts"), formatConfigFile);
175
205
  // main file
176
- const mainFunc = `
177
- import { Avleon } from '@avleon/core';
178
- import { OpenApiConfig } from './config/openapi.config';
179
- import { HomeController } from './controllers/home.controller';
180
-
181
-
182
- const app = Avleon.createApplication();
183
-
184
- if(app.isDevelopemtn()){
185
- app.useOpenApi(OpenApiConfig);
186
- }
187
-
188
- app.useControllers([ HomeController ]);
189
- app.useStaticFiles();
190
-
191
- export default app;
206
+ const mainFunc = `
207
+ import { Avleon } from '@avleon/core';
208
+ import { OpenApiConfig } from './config/openapi.config';
209
+ import { HomeController } from './controllers/home.controller';
210
+
211
+
212
+ const app = Avleon.createApplication();
213
+
214
+ if(app.isDevelopment()){
215
+ app.useOpenApi(OpenApiConfig);
216
+ }
217
+
218
+ app.useControllers([ HomeController ]);
219
+ app.useStaticFiles();
220
+
221
+ export default app;
192
222
  `;
193
223
  const formatMainFunc = await prettier.format(mainFunc, {
194
224
  singleQuote: true,
@@ -197,14 +227,14 @@ export default app;
197
227
  });
198
228
  await fs_extra_1.default.writeFile(path_1.default.join(appPaths.src, "app.ts"), formatMainFunc);
199
229
  // create serve.ts
200
- const serveFunc = `
201
- import app from "./app";
202
-
203
- async function start(){
204
- app.run(); // default run on :4000
205
- }
206
-
207
- start();
230
+ const serveFunc = `
231
+ import app from "./app";
232
+
233
+ async function start(){
234
+ app.run(); // default run on :4000
235
+ }
236
+
237
+ start();
208
238
  `;
209
239
  const formatServeFunc = await prettier.format(serveFunc, {
210
240
  singleQuote: true,
@@ -213,96 +243,96 @@ start();
213
243
  });
214
244
  await fs_extra_1.default.writeFile(path_1.default.join(appPaths.src, "serve.ts"), formatServeFunc);
215
245
  // create package.json
216
- const packageJson = `
217
- {
218
- "name": "${(0, lodash_1.snakeCase)(fname)}",
219
- "version": "0.0.1",
220
- "description": "Basic avleon application",
221
- "main": "dist/serve.js",
222
- "scripts": {
223
- "start:dev": "nodemon ./src/serve.ts",
224
- "start:debug": "nodemon --watch ./src --ext ts --exec node --inspect=0.0.0.0:9229 -r ts-node/register ./src/serve.ts",
225
- "clean": "rimraf ./dist",
226
- "build": "npm run clean & tsc --project ./tsconfig.build.json",
227
- "start": "node ./dist/serve.js",
228
- "test": "jest",
229
- "test:watch": "jest --watch",
230
- "test:cov": "jest --coverage",
231
- "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
232
- "test:e2e": "jest --config ./test/e2e-spec.json"
233
- },
234
- "keywords": ["avleon","nodejs","typescript"],
235
- "license": "ISC",
236
- "dependencies": {
237
- "@avleon/core": "^0.0.36",
238
- "@avleon/cli": "^0.0.42",
239
- "class-transformer": "^0.5.1",
240
- "class-validator": "^0.14.1",
241
- "rimraf": "^6.0.1",
242
- "reflect-metadata": "^0.2.2"
243
- },
244
- "devDependencies": {
245
- "@types/jest": "^29.5.14",
246
- "@types/node": "^24.0.3",
247
- "jest": "^29.7.0",
248
- "ts-jest": "^29.2.6",
249
- "nodemon": "^3.1.7",
250
- "ts-node": "^10.9.2",
251
- "typescript": "^5.7.2"
252
- },
253
- "jest": {
254
- "preset": "ts-jest",
255
- "rootDir": "src",
256
- "testRegex": ".*/\/\.spec/\/\.ts$",
257
- "collectCoverageFrom": [
258
- "**/*.(t|j)s"
259
- ],
260
- "coverageDirectory": "../coverage",
261
- "testEnvironment": "node"
262
- }
263
-
264
- }
246
+ const packageJson = `
247
+ {
248
+ "name": "${(0, lodash_1.snakeCase)(fname)}",
249
+ "version": "0.0.1",
250
+ "description": "Basic avleon application",
251
+ "main": "dist/serve.js",
252
+ "scripts": {
253
+ "start:dev": "nodemon ./src/serve.ts",
254
+ "start:debug": "nodemon --watch ./src --ext ts --exec node --inspect=0.0.0.0:9229 -r ts-node/register ./src/serve.ts",
255
+ "clean": "rimraf ./dist",
256
+ "build": "npm run clean & tsc --project ./tsconfig.build.json",
257
+ "start": "node ./dist/serve.js",
258
+ "test": "jest",
259
+ "test:watch": "jest --watch",
260
+ "test:cov": "jest --coverage",
261
+ "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
262
+ "test:e2e": "jest --config ./test/e2e-spec.json"
263
+ },
264
+ "keywords": ["avleon","nodejs","typescript"],
265
+ "license": "ISC",
266
+ "dependencies": {
267
+ "@avleon/core": "^0.0.36",
268
+ "@avleon/cli": "^0.0.42",
269
+ "class-transformer": "^0.5.1",
270
+ "class-validator": "^0.14.1",
271
+ "rimraf": "^6.0.1",
272
+ "reflect-metadata": "^0.2.2"
273
+ },
274
+ "devDependencies": {
275
+ "@types/jest": "^29.5.14",
276
+ "@types/node": "^24.0.3",
277
+ "jest": "^29.7.0",
278
+ "ts-jest": "^29.2.6",
279
+ "nodemon": "^3.1.7",
280
+ "ts-node": "^10.9.2",
281
+ "typescript": "^5.7.2"
282
+ },
283
+ "jest": {
284
+ "preset": "ts-jest",
285
+ "rootDir": "src",
286
+ "testRegex": ".*.spec.ts$",
287
+ "collectCoverageFrom": [
288
+ "**/*.(t|j)s"
289
+ ],
290
+ "coverageDirectory": "../coverage",
291
+ "testEnvironment": "node"
292
+ }
293
+
294
+ }
265
295
  `;
266
296
  const formattedPackageJson = await prettier.format(packageJson, {
267
297
  parser: "json",
268
298
  });
269
299
  await fs_extra_1.default.writeFile(path_1.default.join(appPaths.root, "package.json"), formattedPackageJson);
270
- const tsconfigJson = await prettier.format(`{
271
- "compilerOptions": {
272
- "target": "ES2017",
273
- "module": "CommonJS",
274
- "moduleResolution": "node",
275
- "experimentalDecorators": true,
276
- "emitDecoratorMetadata": true,
277
- "outDir": "./dist",
278
- "esModuleInterop": true,
279
- "allowSyntheticDefaultImports": true,
280
- "forceConsistentCasingInFileNames": true,
281
- "skipLibCheck": true
282
- },
283
- "include": ["src/**/*"],
284
- "exclude": ["node_modules", "dist"]
300
+ const tsconfigJson = await prettier.format(`{
301
+ "compilerOptions": {
302
+ "target": "ES2017",
303
+ "module": "CommonJS",
304
+ "moduleResolution": "node",
305
+ "experimentalDecorators": true,
306
+ "emitDecoratorMetadata": true,
307
+ "outDir": "./dist",
308
+ "esModuleInterop": true,
309
+ "allowSyntheticDefaultImports": true,
310
+ "forceConsistentCasingInFileNames": true,
311
+ "skipLibCheck": true
312
+ },
313
+ "include": ["src/**/*"],
314
+ "exclude": ["node_modules", "dist"]
285
315
  }`, { parser: "json" });
286
316
  await fs_extra_1.default.writeFile(path_1.default.join(appPaths.root, "tsconfig.json"), tsconfigJson);
287
- const tsconfigBuildJson = await prettier.format(`{
288
- "extends": "./tsconfig.json",
289
- "exclude": ["node_modules","coverage", "test", "dist", "**/*spec.ts"]
290
- }
317
+ const tsconfigBuildJson = await prettier.format(`{
318
+ "extends": "./tsconfig.json",
319
+ "exclude": ["node_modules","coverage", "test", "dist", "**/*spec.ts"]
320
+ }
291
321
  `, { parser: "json" });
292
322
  await fs_extra_1.default.writeFile(path_1.default.join(appPaths.root, "tsconfig.build.json"), tsconfigBuildJson);
293
323
  // write e2e-test.json
294
- const e2eJson = await prettier.format(`{
295
- "moduleFileExtensions": [
296
- "js",
297
- "json",
298
- "ts"
299
- ],
300
- "rootDir": ".",
301
- "testEnvironment": "node",
302
- "testRegex": ".e2e-spec.ts$",
303
- "transform": {
304
- "^.+/\/\.(t|j)s$": "ts-jest"
305
- }
324
+ const e2eJson = await prettier.format(`{
325
+ "moduleFileExtensions": [
326
+ "js",
327
+ "json",
328
+ "ts"
329
+ ],
330
+ "rootDir": ".",
331
+ "testEnvironment": "node",
332
+ "testRegex": ".e2e-spec.ts$",
333
+ "transform": {
334
+ "^.+/\/\.(t|j)s$": "ts-jest"
335
+ }
306
336
  }`, { parser: "json" });
307
337
  await fs_extra_1.default.writeFile(path_1.default.join(appPaths.root, "test/e2e-spec.json"), e2eJson);
308
338
  await fs_extra_1.default.writeFile(path_1.default.join(appPaths.root, ".gitignore"), `node_modules/\ndist/\n.env`);