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.
- package/API.md +248 -38
- package/DOCS.md +327 -63
- package/NewCLIGENERATECOMMANDS.txt +5 -0
- package/README.md +168 -3
- package/USAGE.md +395 -2
- package/dist/cli/commands/build.command.d.ts.map +1 -1
- package/dist/cli/commands/build.command.js +20 -8
- package/dist/cli/commands/build.command.js.map +1 -1
- package/dist/cli/commands/diagnostics.command.d.ts +1 -2
- package/dist/cli/commands/diagnostics.command.d.ts.map +1 -1
- package/dist/cli/commands/diagnostics.command.js +37 -23
- package/dist/cli/commands/diagnostics.command.js.map +1 -1
- package/dist/cli/commands/generate.command.d.ts +5 -1
- package/dist/cli/commands/generate.command.d.ts.map +1 -1
- package/dist/cli/commands/generate.command.js +171 -39
- package/dist/cli/commands/generate.command.js.map +1 -1
- package/dist/cli/commands/init.command.d.ts.map +1 -1
- package/dist/cli/commands/init.command.js +98 -28
- package/dist/cli/commands/init.command.js.map +1 -1
- package/dist/cli/commands/migrate.command.d.ts +10 -17
- package/dist/cli/commands/migrate.command.d.ts.map +1 -1
- package/dist/cli/commands/migrate.command.js +133 -170
- package/dist/cli/commands/migrate.command.js.map +1 -1
- package/dist/cli/commands/serve.command.d.ts.map +1 -1
- package/dist/cli/commands/serve.command.js +9 -4
- package/dist/cli/commands/serve.command.js.map +1 -1
- package/dist/cli/commands/test.command.d.ts.map +1 -1
- package/dist/cli/commands/test.command.js +24 -6
- package/dist/cli/commands/test.command.js.map +1 -1
- package/dist/core/decorators/exception-filter.decorator.d.ts.map +1 -1
- package/dist/core/decorators/exception-filter.decorator.js +11 -4
- package/dist/core/decorators/exception-filter.decorator.js.map +1 -1
- package/dist/core/decorators/guard.decorator.d.ts.map +1 -1
- package/dist/core/decorators/guard.decorator.js +11 -4
- package/dist/core/decorators/guard.decorator.js.map +1 -1
- package/dist/core/decorators/interceptor.decorator.d.ts.map +1 -1
- package/dist/core/decorators/interceptor.decorator.js +10 -4
- package/dist/core/decorators/interceptor.decorator.js.map +1 -1
- package/dist/core/decorators/middleware.decorator.d.ts.map +1 -1
- package/dist/core/decorators/middleware.decorator.js +8 -4
- package/dist/core/decorators/middleware.decorator.js.map +1 -1
- package/dist/core/scanner/component-scanner.d.ts +12 -0
- package/dist/core/scanner/component-scanner.d.ts.map +1 -1
- package/dist/core/scanner/component-scanner.js +72 -14
- package/dist/core/scanner/component-scanner.js.map +1 -1
- package/dist/shared/config.utils.d.ts +58 -0
- package/dist/shared/config.utils.d.ts.map +1 -0
- package/dist/shared/config.utils.js +137 -0
- package/dist/shared/config.utils.js.map +1 -0
- package/dist/shared/env.utils.d.ts +27 -0
- package/dist/shared/env.utils.d.ts.map +1 -0
- package/dist/shared/env.utils.js +68 -0
- package/dist/shared/env.utils.js.map +1 -0
- package/dist/shared/tsconfig.utils.d.ts +122 -0
- package/dist/shared/tsconfig.utils.d.ts.map +1 -0
- package/dist/shared/tsconfig.utils.js +305 -0
- package/dist/shared/tsconfig.utils.js.map +1 -0
- package/dist/testing/runner.d.ts +9 -1
- package/dist/testing/runner.d.ts.map +1 -1
- package/dist/testing/runner.js +50 -10
- package/dist/testing/runner.js.map +1 -1
- package/dist/typeorm/typeorm-module.d.ts +1 -0
- package/dist/typeorm/typeorm-module.d.ts.map +1 -1
- package/dist/typeorm/typeorm-module.js +193 -85
- package/dist/typeorm/typeorm-module.js.map +1 -1
- package/dist/web/application.d.ts +0 -1
- package/dist/web/application.d.ts.map +1 -1
- package/dist/web/application.js +4 -26
- package/dist/web/application.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/commands/build.command.ts +24 -9
- package/src/cli/commands/diagnostics.command.ts +42 -30
- package/src/cli/commands/generate.command.ts +212 -52
- package/src/cli/commands/init.command.ts +100 -29
- package/src/cli/commands/migrate.command.ts +145 -198
- package/src/cli/commands/serve.command.ts +181 -170
- package/src/cli/commands/test.command.ts +25 -11
- package/src/core/decorators/exception-filter.decorator.ts +29 -6
- package/src/core/decorators/guard.decorator.ts +28 -5
- package/src/core/decorators/interceptor.decorator.ts +32 -6
- package/src/core/decorators/middleware.decorator.ts +30 -6
- package/src/core/scanner/component-scanner.ts +100 -18
- package/src/shared/config.utils.ts +148 -0
- package/src/shared/env.utils.ts +72 -0
- package/src/shared/tsconfig.utils.ts +360 -0
- package/src/testing/runner.ts +62 -14
- package/src/typeorm/typeorm-module.ts +209 -86
- 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.
|
|
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
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
-
@
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
374
|
-
|
|
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
|
-
|
|
379
|
-
|
|
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
|
}
|