fragment-ts 1.0.33 → 1.0.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/API.md +248 -38
  2. package/DOCS.md +327 -63
  3. package/NewCLIGENERATECOMMANDS.txt +5 -0
  4. package/README.md +168 -3
  5. package/USAGE.md +395 -2
  6. package/dist/cli/commands/build.command.d.ts.map +1 -1
  7. package/dist/cli/commands/build.command.js +20 -8
  8. package/dist/cli/commands/build.command.js.map +1 -1
  9. package/dist/cli/commands/diagnostics.command.d.ts +1 -2
  10. package/dist/cli/commands/diagnostics.command.d.ts.map +1 -1
  11. package/dist/cli/commands/diagnostics.command.js +37 -23
  12. package/dist/cli/commands/diagnostics.command.js.map +1 -1
  13. package/dist/cli/commands/generate.command.d.ts +5 -1
  14. package/dist/cli/commands/generate.command.d.ts.map +1 -1
  15. package/dist/cli/commands/generate.command.js +171 -39
  16. package/dist/cli/commands/generate.command.js.map +1 -1
  17. package/dist/cli/commands/init.command.d.ts.map +1 -1
  18. package/dist/cli/commands/init.command.js +98 -28
  19. package/dist/cli/commands/init.command.js.map +1 -1
  20. package/dist/cli/commands/migrate.command.d.ts +10 -17
  21. package/dist/cli/commands/migrate.command.d.ts.map +1 -1
  22. package/dist/cli/commands/migrate.command.js +133 -170
  23. package/dist/cli/commands/migrate.command.js.map +1 -1
  24. package/dist/cli/commands/serve.command.d.ts.map +1 -1
  25. package/dist/cli/commands/serve.command.js +9 -4
  26. package/dist/cli/commands/serve.command.js.map +1 -1
  27. package/dist/cli/commands/test.command.d.ts.map +1 -1
  28. package/dist/cli/commands/test.command.js +24 -6
  29. package/dist/cli/commands/test.command.js.map +1 -1
  30. package/dist/core/decorators/exception-filter.decorator.d.ts.map +1 -1
  31. package/dist/core/decorators/exception-filter.decorator.js +11 -4
  32. package/dist/core/decorators/exception-filter.decorator.js.map +1 -1
  33. package/dist/core/decorators/guard.decorator.d.ts.map +1 -1
  34. package/dist/core/decorators/guard.decorator.js +11 -4
  35. package/dist/core/decorators/guard.decorator.js.map +1 -1
  36. package/dist/core/decorators/interceptor.decorator.d.ts.map +1 -1
  37. package/dist/core/decorators/interceptor.decorator.js +10 -4
  38. package/dist/core/decorators/interceptor.decorator.js.map +1 -1
  39. package/dist/core/decorators/middleware.decorator.d.ts.map +1 -1
  40. package/dist/core/decorators/middleware.decorator.js +8 -4
  41. package/dist/core/decorators/middleware.decorator.js.map +1 -1
  42. package/dist/core/scanner/component-scanner.d.ts +12 -0
  43. package/dist/core/scanner/component-scanner.d.ts.map +1 -1
  44. package/dist/core/scanner/component-scanner.js +72 -14
  45. package/dist/core/scanner/component-scanner.js.map +1 -1
  46. package/dist/shared/config.utils.d.ts +58 -0
  47. package/dist/shared/config.utils.d.ts.map +1 -0
  48. package/dist/shared/config.utils.js +137 -0
  49. package/dist/shared/config.utils.js.map +1 -0
  50. package/dist/shared/env.utils.d.ts +27 -0
  51. package/dist/shared/env.utils.d.ts.map +1 -0
  52. package/dist/shared/env.utils.js +68 -0
  53. package/dist/shared/env.utils.js.map +1 -0
  54. package/dist/shared/tsconfig.utils.d.ts +122 -0
  55. package/dist/shared/tsconfig.utils.d.ts.map +1 -0
  56. package/dist/shared/tsconfig.utils.js +305 -0
  57. package/dist/shared/tsconfig.utils.js.map +1 -0
  58. package/dist/testing/runner.d.ts +9 -1
  59. package/dist/testing/runner.d.ts.map +1 -1
  60. package/dist/testing/runner.js +50 -10
  61. package/dist/testing/runner.js.map +1 -1
  62. package/dist/typeorm/typeorm-module.d.ts +1 -0
  63. package/dist/typeorm/typeorm-module.d.ts.map +1 -1
  64. package/dist/typeorm/typeorm-module.js +193 -85
  65. package/dist/typeorm/typeorm-module.js.map +1 -1
  66. package/dist/web/application.d.ts +0 -1
  67. package/dist/web/application.d.ts.map +1 -1
  68. package/dist/web/application.js +4 -26
  69. package/dist/web/application.js.map +1 -1
  70. package/package.json +1 -1
  71. package/src/cli/commands/build.command.ts +24 -9
  72. package/src/cli/commands/diagnostics.command.ts +42 -30
  73. package/src/cli/commands/generate.command.ts +212 -52
  74. package/src/cli/commands/init.command.ts +100 -29
  75. package/src/cli/commands/migrate.command.ts +145 -198
  76. package/src/cli/commands/serve.command.ts +181 -170
  77. package/src/cli/commands/test.command.ts +25 -11
  78. package/src/core/decorators/exception-filter.decorator.ts +29 -6
  79. package/src/core/decorators/guard.decorator.ts +28 -5
  80. package/src/core/decorators/interceptor.decorator.ts +32 -6
  81. package/src/core/decorators/middleware.decorator.ts +30 -6
  82. package/src/core/scanner/component-scanner.ts +100 -18
  83. package/src/shared/config.utils.ts +148 -0
  84. package/src/shared/env.utils.ts +72 -0
  85. package/src/shared/tsconfig.utils.ts +360 -0
  86. package/src/testing/runner.ts +62 -14
  87. package/src/typeorm/typeorm-module.ts +209 -86
  88. package/src/web/application.ts +4 -33
@@ -120,6 +120,9 @@ export class InitCommand {
120
120
  "src/dto",
121
121
  "src/repositories",
122
122
  "src/middlewares",
123
+ "src/guards",
124
+ "src/interceptors",
125
+ "src/filters",
123
126
  "src/config",
124
127
  ];
125
128
 
@@ -173,14 +176,19 @@ export class InitCommand {
173
176
  "migrate:revert": "fragment migrate:revert",
174
177
  },
175
178
  dependencies: {
176
- "fragment-ts": "^1.0.33",
179
+ "fragment-ts": "^1.0.35",
177
180
  "reflect-metadata": "^0.1.13",
181
+ express: "^4.18.2",
178
182
  },
179
183
  devDependencies: {
180
184
  typescript: "^5.3.3",
181
185
  "@types/node": "^20.10.5",
186
+ "@types/express": "^4.17.21",
182
187
  "ts-node": "^10.9.2",
183
188
  "tsconfig-paths": "^4.2.0",
189
+ jest: "^29.7.0",
190
+ "@types/jest": "^29.5.12",
191
+ "ts-jest": "^29.1.2",
184
192
  },
185
193
  };
186
194
 
@@ -200,6 +208,7 @@ export class InitCommand {
200
208
  experimentalDecorators: true,
201
209
  emitDecoratorMetadata: true,
202
210
  skipLibCheck: true,
211
+ sourceMap: true,
203
212
  },
204
213
  include: ["src/**/*"],
205
214
  exclude: ["node_modules", "dist"],
@@ -209,21 +218,32 @@ export class InitCommand {
209
218
  spaces: 2,
210
219
  });
211
220
 
221
+ // Create fragment.json with proper environment structure
212
222
  const fragmentConfig: any = {};
213
223
 
214
224
  if (features.includes("database")) {
215
- const isProd = process.env.NODE_ENV === "production";
216
-
217
- fragmentConfig.database = {
218
- type: "sqlite",
219
- database: process.env.DATABASE_FILE || "database.sqlite",
220
- synchronize: true,
221
- logging: false,
222
- entities: isProd ? ["dist/**/*.entity.js"] : ["src/**/*.entity.ts"],
223
- migrations: isProd
224
- ? ["dist/migrations/**/*.js"]
225
- : ["src/migrations/**/*.ts"],
226
- subscribers: [],
225
+ fragmentConfig.development = {
226
+ database: {
227
+ type: "sqlite",
228
+ database: process.env.DATABASE_FILE || "database.sqlite",
229
+ synchronize: true, // Enable sync in development for easy setup
230
+ logging: false,
231
+ entities: ["src/**/*.entity.ts"],
232
+ migrations: ["src/migrations/**/*.ts"],
233
+ subscribers: [],
234
+ },
235
+ };
236
+
237
+ fragmentConfig.production = {
238
+ database: {
239
+ type: "sqlite",
240
+ database: process.env.DATABASE_FILE || "database.sqlite",
241
+ synchronize: false, // Disable sync in production
242
+ logging: true,
243
+ entities: ["dist/**/*.entity.js"],
244
+ migrations: ["dist/migrations/**/*.js"],
245
+ subscribers: [],
246
+ },
227
247
  };
228
248
  }
229
249
 
@@ -243,7 +263,12 @@ ${features.includes("database") ? "DATABASE_FILE=database.sqlite" : ""}
243
263
 
244
264
  await fs.writeFile(
245
265
  path.join(projectPath, ".gitignore"),
246
- "node_modules/\ndist/\n.env\n*.sqlite\n",
266
+ `node_modules/
267
+ dist/
268
+ .env
269
+ *.sqlite
270
+ coverage/
271
+ `,
247
272
  );
248
273
  }
249
274
 
@@ -257,7 +282,7 @@ import { FragmentWebApplication } from 'fragment-ts';
257
282
  import { AppController } from './controllers/app.controller';
258
283
 
259
284
  @FragmentApplication({
260
- port: 3000,
285
+ port: parseInt(process.env.PORT || '3000', 10),
261
286
  autoScan: true
262
287
  })
263
288
  class Application {
@@ -282,12 +307,21 @@ bootstrap().catch(console.error);
282
307
  projectPath: string,
283
308
  ): Promise<void> {
284
309
  const content = `import { Controller, Get } from 'fragment-ts';
310
+ import { AppService } from '../services/app.service';
311
+ import { Autowired } from 'fragment-ts';
285
312
 
286
313
  @Controller('/api')
287
314
  export class AppController {
315
+ @Autowired()
316
+ private appService!: AppService;
317
+
288
318
  @Get('/health')
289
319
  health() {
290
- return { status: 'ok', timestamp: new Date().toISOString() };
320
+ return {
321
+ status: 'ok',
322
+ timestamp: new Date().toISOString(),
323
+ message: this.appService.getMessage()
324
+ };
291
325
  }
292
326
  }
293
327
  `;
@@ -320,20 +354,20 @@ export class AppService {
320
354
  private static async generateExampleEntity(
321
355
  projectPath: string,
322
356
  ): Promise<void> {
323
- const content = `import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
357
+ const content = `import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn } from 'typeorm';
324
358
 
325
359
  @Entity()
326
360
  export class User {
327
361
  @PrimaryGeneratedColumn()
328
362
  id: number;
329
363
 
330
- @Column()
364
+ @Column({ unique: true })
331
365
  email: string;
332
366
 
333
367
  @Column()
334
368
  name: string;
335
369
 
336
- @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
370
+ @CreateDateColumn()
337
371
  createdAt: Date;
338
372
  }
339
373
  `;
@@ -345,12 +379,13 @@ export class User {
345
379
  }
346
380
 
347
381
  private static async generateAuthFiles(projectPath: string): Promise<void> {
348
- const controllerContent = `import { Controller, Post, Body } from 'fragment-ts';
382
+ const controllerContent = `import { Controller, Post, Body, Autowired } from 'fragment-ts';
349
383
  import { AuthService } from '../services/auth.service';
350
384
 
351
385
  @Controller('/auth')
352
386
  export class AuthController {
353
- constructor(private authService: AuthService) {}
387
+ @Autowired()
388
+ private authService!: AuthService;
354
389
 
355
390
  @Post('/login')
356
391
  async login(@Body() body: any) {
@@ -365,18 +400,38 @@ export class AuthController {
365
400
  `;
366
401
 
367
402
  const serviceContent = `import { Service } from 'fragment-ts';
368
- import { AuthModule } from 'fragment-ts';
403
+ import * as bcrypt from 'bcrypt';
404
+ import * as jwt from 'jsonwebtoken';
369
405
 
370
406
  @Service()
371
407
  export class AuthService {
408
+ private readonly jwtSecret = process.env.JWT_SECRET || 'default-secret-key';
409
+
372
410
  async login(email: string, password: string) {
373
- const token = AuthModule.generateToken({ userId: '1', email });
374
- return { token };
411
+ // TODO: Implement actual user lookup and password verification
412
+ const isValid = await this.validatePassword(password, 'hashed-password-placeholder');
413
+
414
+ if (isValid) {
415
+ const token = jwt.sign({ userId: '1', email }, this.jwtSecret, { expiresIn: '1h' });
416
+ return { token };
417
+ }
418
+
419
+ throw new Error('Invalid credentials');
375
420
  }
376
421
 
377
422
  async register(userData: any) {
378
- const hashedPassword = await AuthModule.hashPassword(userData.password);
379
- return { message: 'User registered successfully' };
423
+ // TODO: Implement actual user creation
424
+ const hashedPassword = await this.hashPassword(userData.password);
425
+ return { message: 'User registered successfully', email: userData.email };
426
+ }
427
+
428
+ private async hashPassword(password: string): Promise<string> {
429
+ const saltRounds = 10;
430
+ return bcrypt.hash(password, saltRounds);
431
+ }
432
+
433
+ private async validatePassword(password: string, hashedPassword: string): Promise<boolean> {
434
+ return bcrypt.compare(password, hashedPassword);
380
435
  }
381
436
  }
382
437
  `;
@@ -397,10 +452,9 @@ import { DIContainer } from 'fragment-ts';
397
452
 
398
453
  describe('AppService', () => {
399
454
  let service: AppService;
400
- let container: DIContainer;
401
455
 
402
456
  beforeEach(() => {
403
- container = DIContainer.getInstance();
457
+ const container = DIContainer.getInstance();
404
458
  container.reset();
405
459
  service = container.resolve(AppService);
406
460
  });
@@ -411,14 +465,31 @@ describe('AppService', () => {
411
465
  expect(message).toBe('Welcome to Fragment Framework!');
412
466
  expect(message).toBeTruthy();
413
467
  expect(message).toContain('Fragment');
414
- // expect(message).toHaveLength(28);
415
468
  });
416
469
  });
470
+ `;
471
+
472
+ const jestConfig = `module.exports = {
473
+ preset: 'ts-jest',
474
+ testEnvironment: 'node',
475
+ roots: ['<rootDir>/src'],
476
+ transform: {
477
+ '^.+\\\\.tsx?$': 'ts-jest',
478
+ },
479
+ testRegex: '(/__tests__/.*|(\\\\.|/)(test|spec))\\\\.tsx?$',
480
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
481
+ collectCoverageFrom: [
482
+ 'src/**/*.{ts,tsx}',
483
+ '!src/main.ts',
484
+ '!src/**/*.controller.ts',
485
+ ],
486
+ };
417
487
  `;
418
488
 
419
489
  const testDir = path.join(projectPath, "src", "test");
420
490
  await fs.ensureDir(testDir);
421
491
 
422
492
  await fs.writeFile(path.join(testDir, "app.spec.ts"), testContent);
493
+ await fs.writeFile(path.join(projectPath, "jest.config.js"), jestConfig);
423
494
  }
424
495
  }