fragment-ts 1.0.0
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/.env.example +0 -0
- package/base.ts +1810 -0
- package/base2.ts +968 -0
- package/bin/frg.ts +5 -0
- package/config/fragment.lock.yaml +0 -0
- package/config/fragment.yaml +0 -0
- package/dist/app.d.ts +15 -0
- package/dist/app.js +90 -0
- package/dist/auth/auth.controller.d.ts +10 -0
- package/dist/auth/auth.controller.js +87 -0
- package/dist/auth/auth.middleware.d.ts +2 -0
- package/dist/auth/auth.middleware.js +24 -0
- package/dist/auth/auth.service.d.ts +20 -0
- package/dist/auth/auth.service.js +143 -0
- package/dist/auth/dto/login.dto.d.ts +9 -0
- package/dist/auth/dto/login.dto.js +2 -0
- package/dist/cli/cli.d.ts +12 -0
- package/dist/cli/cli.js +186 -0
- package/dist/cli/commands/build.command.d.ts +3 -0
- package/dist/cli/commands/build.command.js +23 -0
- package/dist/cli/commands/config.command.d.ts +6 -0
- package/dist/cli/commands/config.command.js +284 -0
- package/dist/cli/commands/generate.command.d.ts +8 -0
- package/dist/cli/commands/generate.command.js +180 -0
- package/dist/cli/commands/init.command.d.ts +7 -0
- package/dist/cli/commands/init.command.js +380 -0
- package/dist/cli/commands/migrate.command.d.ts +7 -0
- package/dist/cli/commands/migrate.command.js +116 -0
- package/dist/cli/commands/serve.command.d.ts +6 -0
- package/dist/cli/commands/serve.command.js +31 -0
- package/dist/cli/templates/controller.template.d.ts +1 -0
- package/dist/cli/templates/controller.template.js +52 -0
- package/dist/cli/templates/entity.template.d.ts +1 -0
- package/dist/cli/templates/entity.template.js +23 -0
- package/dist/cli/templates/repository.template.d.ts +1 -0
- package/dist/cli/templates/repository.template.js +43 -0
- package/dist/cli/templates/service.template.d.ts +1 -0
- package/dist/cli/templates/service.template.js +43 -0
- package/dist/cli/utils/file-generator.d.ts +9 -0
- package/dist/cli/utils/file-generator.js +67 -0
- package/dist/cli/utils/logger.d.ts +14 -0
- package/dist/cli/utils/logger.js +49 -0
- package/dist/controllers/health.controller.d.ts +13 -0
- package/dist/controllers/health.controller.js +50 -0
- package/dist/core/config/config-loader.d.ts +31 -0
- package/dist/core/config/config-loader.js +98 -0
- package/dist/core/container/di-container.d.ts +9 -0
- package/dist/core/container/di-container.js +37 -0
- package/dist/core/decorators/auth-guard.decorator.d.ts +3 -0
- package/dist/core/decorators/auth-guard.decorator.js +18 -0
- package/dist/core/decorators/autowire.decorator.d.ts +3 -0
- package/dist/core/decorators/autowire.decorator.js +17 -0
- package/dist/core/decorators/controller.decorator.d.ts +4 -0
- package/dist/core/decorators/controller.decorator.js +16 -0
- package/dist/core/decorators/injectable.decorator.d.ts +3 -0
- package/dist/core/decorators/injectable.decorator.js +14 -0
- package/dist/core/decorators/middleware.decorator.d.ts +3 -0
- package/dist/core/decorators/middleware.decorator.js +20 -0
- package/dist/core/decorators/repository.decorator.d.ts +1 -0
- package/dist/core/decorators/repository.decorator.js +7 -0
- package/dist/core/decorators/route.decorator.d.ts +14 -0
- package/dist/core/decorators/route.decorator.js +32 -0
- package/dist/core/decorators/service.decorator.d.ts +1 -0
- package/dist/core/decorators/service.decorator.js +7 -0
- package/dist/core/openai/openai-client.d.ts +12 -0
- package/dist/core/openai/openai-client.js +93 -0
- package/dist/database/data-source.d.ts +4 -0
- package/dist/database/data-source.js +26 -0
- package/dist/entities/session.entity.d.ts +9 -0
- package/dist/entities/session.entity.js +45 -0
- package/dist/entities/user.entity.d.ts +10 -0
- package/dist/entities/user.entity.js +48 -0
- package/dist/middlewares/logging.middleware.d.ts +2 -0
- package/dist/middlewares/logging.middleware.js +28 -0
- package/dist/repositories/session.repository.d.ts +9 -0
- package/dist/repositories/session.repository.js +50 -0
- package/dist/repositories/user.repository.d.ts +10 -0
- package/dist/repositories/user.repository.js +43 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +30 -0
- package/dist/services/health.service.d.ts +13 -0
- package/dist/services/health.service.js +44 -0
- package/package.json +46 -0
- package/readme.md +120 -0
- package/src/app.ts +121 -0
- package/src/auth/auth.controller.ts +52 -0
- package/src/auth/auth.middleware.ts +27 -0
- package/src/auth/auth.service.ts +110 -0
- package/src/auth/dto/login.dto.ts +11 -0
- package/src/cli/cli.ts +212 -0
- package/src/cli/commands/build.command.ts +24 -0
- package/src/cli/commands/config.command.ts +280 -0
- package/src/cli/commands/generate.command.ts +170 -0
- package/src/cli/commands/init.command.ts +395 -0
- package/src/cli/commands/migrate.command.ts +118 -0
- package/src/cli/commands/serve.command.ts +37 -0
- package/src/cli/templates/controller.template.ts +51 -0
- package/src/cli/templates/entity.template.ts +22 -0
- package/src/cli/templates/repository.template.ts +42 -0
- package/src/cli/templates/service.template.ts +42 -0
- package/src/cli/utils/file-generator.ts +37 -0
- package/src/cli/utils/logger.ts +52 -0
- package/src/controllers/health.controller.ts +24 -0
- package/src/core/config/config-loader.ts +98 -0
- package/src/core/container/di-container.ts +43 -0
- package/src/core/decorators/auth-guard.decorator.ts +15 -0
- package/src/core/decorators/autowire.decorator.ts +18 -0
- package/src/core/decorators/controller.decorator.ts +15 -0
- package/src/core/decorators/injectable.decorator.ts +13 -0
- package/src/core/decorators/middleware.decorator.ts +18 -0
- package/src/core/decorators/repository.decorator.ts +6 -0
- package/src/core/decorators/route.decorator.ts +33 -0
- package/src/core/decorators/service.decorator.ts +6 -0
- package/src/core/openai/openai-client.ts +99 -0
- package/src/database/data-source.ts +29 -0
- package/src/entities/session.entity.ts +25 -0
- package/src/entities/user.entity.ts +27 -0
- package/src/middlewares/logging.middleware.ts +28 -0
- package/src/repositories/session.repository.ts +42 -0
- package/src/repositories/user.repository.ts +37 -0
- package/src/server.ts +32 -0
- package/src/services/health.service.ts +29 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.OpenAIClient = void 0;
|
|
13
|
+
const injectable_decorator_1 = require("../decorators/injectable.decorator");
|
|
14
|
+
const config_loader_1 = require("../config/config-loader");
|
|
15
|
+
let OpenAIClient = class OpenAIClient {
|
|
16
|
+
constructor() {
|
|
17
|
+
this.baseURL = "https://api.openai.com/v1";
|
|
18
|
+
const config = config_loader_1.ConfigLoader.get();
|
|
19
|
+
this.apiKey = config.openai.apiKey;
|
|
20
|
+
this.model = config.openai.model;
|
|
21
|
+
}
|
|
22
|
+
async complete(prompt, options) {
|
|
23
|
+
const response = await fetch(`${this.baseURL}/chat/completions`, {
|
|
24
|
+
method: "POST",
|
|
25
|
+
headers: {
|
|
26
|
+
"Content-Type": "application/json",
|
|
27
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
28
|
+
},
|
|
29
|
+
body: JSON.stringify({
|
|
30
|
+
model: options?.model || this.model,
|
|
31
|
+
messages: [{ role: "user", content: prompt }],
|
|
32
|
+
max_tokens: options?.maxTokens || 1000,
|
|
33
|
+
temperature: options?.temperature || 0.7,
|
|
34
|
+
}),
|
|
35
|
+
});
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
throw new Error(`OpenAI API error: ${response.statusText}`);
|
|
38
|
+
}
|
|
39
|
+
const data = (await response.json());
|
|
40
|
+
return data.choices[0].message.content;
|
|
41
|
+
}
|
|
42
|
+
async streamComplete(prompt, onChunk) {
|
|
43
|
+
const response = await fetch(`${this.baseURL}/chat/completions`, {
|
|
44
|
+
method: "POST",
|
|
45
|
+
headers: {
|
|
46
|
+
"Content-Type": "application/json",
|
|
47
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
48
|
+
},
|
|
49
|
+
body: JSON.stringify({
|
|
50
|
+
model: this.model,
|
|
51
|
+
messages: [{ role: "user", content: prompt }],
|
|
52
|
+
stream: true,
|
|
53
|
+
}),
|
|
54
|
+
});
|
|
55
|
+
if (!response.ok) {
|
|
56
|
+
throw new Error(`OpenAI API error: ${response.statusText}`);
|
|
57
|
+
}
|
|
58
|
+
const reader = response.body?.getReader();
|
|
59
|
+
const decoder = new TextDecoder();
|
|
60
|
+
if (!reader) {
|
|
61
|
+
throw new Error("No response body");
|
|
62
|
+
}
|
|
63
|
+
while (true) {
|
|
64
|
+
const { done, value } = await reader.read();
|
|
65
|
+
if (done)
|
|
66
|
+
break;
|
|
67
|
+
const chunk = decoder.decode(value);
|
|
68
|
+
const lines = chunk.split("\n").filter((line) => line.trim() !== "");
|
|
69
|
+
for (const line of lines) {
|
|
70
|
+
if (line.startsWith("data: ")) {
|
|
71
|
+
const data = line.slice(6);
|
|
72
|
+
if (data === "[DONE]")
|
|
73
|
+
continue;
|
|
74
|
+
try {
|
|
75
|
+
const parsed = JSON.parse(data);
|
|
76
|
+
const content = parsed.choices[0]?.delta?.content;
|
|
77
|
+
if (content) {
|
|
78
|
+
onChunk(content);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
// Skip invalid JSON
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
exports.OpenAIClient = OpenAIClient;
|
|
90
|
+
exports.OpenAIClient = OpenAIClient = __decorate([
|
|
91
|
+
(0, injectable_decorator_1.Injectable)(),
|
|
92
|
+
__metadata("design:paramtypes", [])
|
|
93
|
+
], OpenAIClient);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AppDataSource = void 0;
|
|
4
|
+
exports.initializeDataSource = initializeDataSource;
|
|
5
|
+
const typeorm_1 = require("typeorm");
|
|
6
|
+
const config_loader_1 = require("../core/config/config-loader");
|
|
7
|
+
const user_entity_1 = require("../entities/user.entity");
|
|
8
|
+
const session_entity_1 = require("../entities/session.entity");
|
|
9
|
+
let AppDataSource;
|
|
10
|
+
function initializeDataSource() {
|
|
11
|
+
const config = config_loader_1.ConfigLoader.get();
|
|
12
|
+
exports.AppDataSource = AppDataSource = new typeorm_1.DataSource({
|
|
13
|
+
type: config.database.type,
|
|
14
|
+
host: config.database.host,
|
|
15
|
+
port: config.database.port,
|
|
16
|
+
username: config.database.username,
|
|
17
|
+
password: config.database.password,
|
|
18
|
+
database: config.database.database,
|
|
19
|
+
synchronize: config.database.synchronize,
|
|
20
|
+
logging: config.database.logging,
|
|
21
|
+
entities: [user_entity_1.User, session_entity_1.Session],
|
|
22
|
+
migrations: [],
|
|
23
|
+
subscribers: []
|
|
24
|
+
});
|
|
25
|
+
return AppDataSource;
|
|
26
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.Session = void 0;
|
|
13
|
+
const typeorm_1 = require("typeorm");
|
|
14
|
+
const user_entity_1 = require("./user.entity");
|
|
15
|
+
let Session = class Session {
|
|
16
|
+
};
|
|
17
|
+
exports.Session = Session;
|
|
18
|
+
__decorate([
|
|
19
|
+
(0, typeorm_1.PrimaryGeneratedColumn)(),
|
|
20
|
+
__metadata("design:type", Number)
|
|
21
|
+
], Session.prototype, "id", void 0);
|
|
22
|
+
__decorate([
|
|
23
|
+
(0, typeorm_1.Column)({ unique: true, length: 255 }),
|
|
24
|
+
__metadata("design:type", String)
|
|
25
|
+
], Session.prototype, "token", void 0);
|
|
26
|
+
__decorate([
|
|
27
|
+
(0, typeorm_1.Column)(),
|
|
28
|
+
__metadata("design:type", Number)
|
|
29
|
+
], Session.prototype, "userId", void 0);
|
|
30
|
+
__decorate([
|
|
31
|
+
(0, typeorm_1.ManyToOne)(() => user_entity_1.User, (user) => user.sessions, { onDelete: 'CASCADE' }),
|
|
32
|
+
(0, typeorm_1.JoinColumn)({ name: 'userId' }),
|
|
33
|
+
__metadata("design:type", user_entity_1.User)
|
|
34
|
+
], Session.prototype, "user", void 0);
|
|
35
|
+
__decorate([
|
|
36
|
+
(0, typeorm_1.Column)(),
|
|
37
|
+
__metadata("design:type", Date)
|
|
38
|
+
], Session.prototype, "expiresAt", void 0);
|
|
39
|
+
__decorate([
|
|
40
|
+
(0, typeorm_1.CreateDateColumn)(),
|
|
41
|
+
__metadata("design:type", Date)
|
|
42
|
+
], Session.prototype, "createdAt", void 0);
|
|
43
|
+
exports.Session = Session = __decorate([
|
|
44
|
+
(0, typeorm_1.Entity)('sessions')
|
|
45
|
+
], Session);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.User = void 0;
|
|
13
|
+
const typeorm_1 = require("typeorm");
|
|
14
|
+
const session_entity_1 = require("./session.entity");
|
|
15
|
+
let User = class User {
|
|
16
|
+
};
|
|
17
|
+
exports.User = User;
|
|
18
|
+
__decorate([
|
|
19
|
+
(0, typeorm_1.PrimaryGeneratedColumn)(),
|
|
20
|
+
__metadata("design:type", Number)
|
|
21
|
+
], User.prototype, "id", void 0);
|
|
22
|
+
__decorate([
|
|
23
|
+
(0, typeorm_1.Column)({ length: 100 }),
|
|
24
|
+
__metadata("design:type", String)
|
|
25
|
+
], User.prototype, "name", void 0);
|
|
26
|
+
__decorate([
|
|
27
|
+
(0, typeorm_1.Column)({ unique: true, length: 255 }),
|
|
28
|
+
__metadata("design:type", String)
|
|
29
|
+
], User.prototype, "email", void 0);
|
|
30
|
+
__decorate([
|
|
31
|
+
(0, typeorm_1.Column)({ length: 255 }),
|
|
32
|
+
__metadata("design:type", String)
|
|
33
|
+
], User.prototype, "passwordHash", void 0);
|
|
34
|
+
__decorate([
|
|
35
|
+
(0, typeorm_1.OneToMany)(() => session_entity_1.Session, (session) => session.user),
|
|
36
|
+
__metadata("design:type", Array)
|
|
37
|
+
], User.prototype, "sessions", void 0);
|
|
38
|
+
__decorate([
|
|
39
|
+
(0, typeorm_1.CreateDateColumn)(),
|
|
40
|
+
__metadata("design:type", Date)
|
|
41
|
+
], User.prototype, "createdAt", void 0);
|
|
42
|
+
__decorate([
|
|
43
|
+
(0, typeorm_1.UpdateDateColumn)(),
|
|
44
|
+
__metadata("design:type", Date)
|
|
45
|
+
], User.prototype, "updatedAt", void 0);
|
|
46
|
+
exports.User = User = __decorate([
|
|
47
|
+
(0, typeorm_1.Entity)('users')
|
|
48
|
+
], User);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loggingMiddleware = loggingMiddleware;
|
|
7
|
+
const pino_1 = __importDefault(require("pino"));
|
|
8
|
+
const logger = (0, pino_1.default)({
|
|
9
|
+
transport: {
|
|
10
|
+
target: 'pino-pretty',
|
|
11
|
+
options: {
|
|
12
|
+
colorize: true
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
function loggingMiddleware(req, res, next) {
|
|
17
|
+
const start = Date.now();
|
|
18
|
+
res.on('finish', () => {
|
|
19
|
+
const duration = Date.now() - start;
|
|
20
|
+
logger.info({
|
|
21
|
+
method: req.method,
|
|
22
|
+
url: req.url,
|
|
23
|
+
status: res.statusCode,
|
|
24
|
+
duration: `${duration}ms`
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
next();
|
|
28
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Session } from '../entities/session.entity';
|
|
2
|
+
export declare class SessionRepository {
|
|
3
|
+
private repository;
|
|
4
|
+
constructor();
|
|
5
|
+
findByToken(token: string): Promise<Session | null>;
|
|
6
|
+
create(sessionData: Partial<Session>): Promise<Session>;
|
|
7
|
+
deleteByToken(token: string): Promise<boolean>;
|
|
8
|
+
deleteExpired(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.SessionRepository = void 0;
|
|
13
|
+
const typeorm_1 = require("typeorm");
|
|
14
|
+
const repository_decorator_1 = require("../core/decorators/repository.decorator");
|
|
15
|
+
const session_entity_1 = require("../entities/session.entity");
|
|
16
|
+
const data_source_1 = require("../database/data-source");
|
|
17
|
+
let SessionRepository = class SessionRepository {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.repository = data_source_1.AppDataSource.getRepository(session_entity_1.Session);
|
|
20
|
+
}
|
|
21
|
+
async findByToken(token) {
|
|
22
|
+
return await this.repository.findOne({
|
|
23
|
+
where: {
|
|
24
|
+
token,
|
|
25
|
+
expiresAt: (0, typeorm_1.MoreThan)(new Date())
|
|
26
|
+
},
|
|
27
|
+
relations: ['user']
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
async create(sessionData) {
|
|
31
|
+
const session = this.repository.create(sessionData);
|
|
32
|
+
return await this.repository.save(session);
|
|
33
|
+
}
|
|
34
|
+
async deleteByToken(token) {
|
|
35
|
+
const result = await this.repository.delete({ token });
|
|
36
|
+
return result.affected ? result.affected > 0 : false;
|
|
37
|
+
}
|
|
38
|
+
async deleteExpired() {
|
|
39
|
+
await this.repository
|
|
40
|
+
.createQueryBuilder()
|
|
41
|
+
.delete()
|
|
42
|
+
.where('expiresAt < :now', { now: new Date() })
|
|
43
|
+
.execute();
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
exports.SessionRepository = SessionRepository;
|
|
47
|
+
exports.SessionRepository = SessionRepository = __decorate([
|
|
48
|
+
(0, repository_decorator_1.Repository)(),
|
|
49
|
+
__metadata("design:paramtypes", [])
|
|
50
|
+
], SessionRepository);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { User } from '../entities/user.entity';
|
|
2
|
+
export declare class UserRepository {
|
|
3
|
+
private repository;
|
|
4
|
+
constructor();
|
|
5
|
+
findById(id: number): Promise<User | null>;
|
|
6
|
+
findByEmail(email: string): Promise<User | null>;
|
|
7
|
+
create(userData: Partial<User>): Promise<User>;
|
|
8
|
+
update(id: number, userData: Partial<User>): Promise<User | null>;
|
|
9
|
+
delete(id: number): Promise<boolean>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.UserRepository = void 0;
|
|
13
|
+
const repository_decorator_1 = require("../core/decorators/repository.decorator");
|
|
14
|
+
const user_entity_1 = require("../entities/user.entity");
|
|
15
|
+
const data_source_1 = require("../database/data-source");
|
|
16
|
+
let UserRepository = class UserRepository {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.repository = data_source_1.AppDataSource.getRepository(user_entity_1.User);
|
|
19
|
+
}
|
|
20
|
+
async findById(id) {
|
|
21
|
+
return await this.repository.findOne({ where: { id } });
|
|
22
|
+
}
|
|
23
|
+
async findByEmail(email) {
|
|
24
|
+
return await this.repository.findOne({ where: { email } });
|
|
25
|
+
}
|
|
26
|
+
async create(userData) {
|
|
27
|
+
const user = this.repository.create(userData);
|
|
28
|
+
return await this.repository.save(user);
|
|
29
|
+
}
|
|
30
|
+
async update(id, userData) {
|
|
31
|
+
await this.repository.update(id, userData);
|
|
32
|
+
return await this.findById(id);
|
|
33
|
+
}
|
|
34
|
+
async delete(id) {
|
|
35
|
+
const result = await this.repository.delete(id);
|
|
36
|
+
return result.affected ? result.affected > 0 : false;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
exports.UserRepository = UserRepository;
|
|
40
|
+
exports.UserRepository = UserRepository = __decorate([
|
|
41
|
+
(0, repository_decorator_1.Repository)(),
|
|
42
|
+
__metadata("design:paramtypes", [])
|
|
43
|
+
], UserRepository);
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const app_1 = require("./app");
|
|
4
|
+
const config_loader_1 = require("./core/config/config-loader");
|
|
5
|
+
async function bootstrap() {
|
|
6
|
+
try {
|
|
7
|
+
const app = new app_1.FragmentApplication();
|
|
8
|
+
await app.initialize();
|
|
9
|
+
const config = config_loader_1.ConfigLoader.get();
|
|
10
|
+
const port = config.app.port;
|
|
11
|
+
app.getExpressApp().listen(port, () => {
|
|
12
|
+
console.log(`
|
|
13
|
+
╔═══════════════════════════════════════════════════╗
|
|
14
|
+
║ ║
|
|
15
|
+
║ 🔷 FRAGMENT Framework Started ║
|
|
16
|
+
║ ║
|
|
17
|
+
║ Port: ${port} ║
|
|
18
|
+
║ Environment: ${config.app.env} ║
|
|
19
|
+
║ Database: Connected ║
|
|
20
|
+
║ ║
|
|
21
|
+
╚═══════════════════════════════════════════════════╝
|
|
22
|
+
`);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
console.error('❌ Failed to start application:', error);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
bootstrap();
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { OpenAIClient } from '../core/openai/openai-client';
|
|
2
|
+
export declare class HealthService {
|
|
3
|
+
private openAIClient;
|
|
4
|
+
constructor(openAIClient: OpenAIClient);
|
|
5
|
+
getStatus(): Promise<{
|
|
6
|
+
status: string;
|
|
7
|
+
timestamp: string;
|
|
8
|
+
database: string;
|
|
9
|
+
}>;
|
|
10
|
+
generateHealthTip(): Promise<{
|
|
11
|
+
tip: string;
|
|
12
|
+
}>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.HealthService = void 0;
|
|
16
|
+
const service_decorator_1 = require("../core/decorators/service.decorator");
|
|
17
|
+
const autowire_decorator_1 = require("../core/decorators/autowire.decorator");
|
|
18
|
+
const openai_client_1 = require("../core/openai/openai-client");
|
|
19
|
+
let HealthService = class HealthService {
|
|
20
|
+
constructor(openAIClient) {
|
|
21
|
+
this.openAIClient = openAIClient;
|
|
22
|
+
}
|
|
23
|
+
async getStatus() {
|
|
24
|
+
return {
|
|
25
|
+
status: 'ok',
|
|
26
|
+
timestamp: new Date().toISOString(),
|
|
27
|
+
database: 'connected'
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
async generateHealthTip() {
|
|
31
|
+
const prompt = 'Give me a short health tip in one sentence.';
|
|
32
|
+
const tip = await this.openAIClient.complete(prompt, {
|
|
33
|
+
maxTokens: 50,
|
|
34
|
+
temperature: 0.9
|
|
35
|
+
});
|
|
36
|
+
return { tip };
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
exports.HealthService = HealthService;
|
|
40
|
+
exports.HealthService = HealthService = __decorate([
|
|
41
|
+
(0, service_decorator_1.Service)(),
|
|
42
|
+
__param(0, (0, autowire_decorator_1.Autowire)()),
|
|
43
|
+
__metadata("design:paramtypes", [openai_client_1.OpenAIClient])
|
|
44
|
+
], HealthService);
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fragment-ts",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "TypeScript Backend Framework (v1.0.0)",
|
|
5
|
+
"main": "dist/server.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"fragment": "./dist/cli/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "ts-node-dev --respawn --transpile-only src/server.ts",
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"start": "node dist/server.js",
|
|
13
|
+
"cli": "ts-node src/cli/index.ts"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"express": "^4.18.2",
|
|
17
|
+
"typeorm": "^0.3.17",
|
|
18
|
+
"pg": "^8.11.3",
|
|
19
|
+
"mysql2": "^3.6.0",
|
|
20
|
+
"sqlite3": "^5.1.6",
|
|
21
|
+
"dotenv": "^16.3.1",
|
|
22
|
+
"pino": "^8.15.0",
|
|
23
|
+
"pino-pretty": "^10.2.0",
|
|
24
|
+
"reflect-metadata": "^0.1.13",
|
|
25
|
+
"commander": "^11.0.0",
|
|
26
|
+
"inquirer": "^9.2.11",
|
|
27
|
+
"chalk": "^4.1.2",
|
|
28
|
+
"ora": "^5.4.1",
|
|
29
|
+
"js-yaml": "^4.1.0",
|
|
30
|
+
"@anthropic-ai/sdk": "^0.9.0",
|
|
31
|
+
"openai": "^4.20.0",
|
|
32
|
+
"axios": "^1.6.0",
|
|
33
|
+
"bcrypt": "^5.1.1"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/express": "^4.17.17",
|
|
37
|
+
"@types/node": "^20.5.0",
|
|
38
|
+
"@types/inquirer": "^9.0.3",
|
|
39
|
+
"@types/js-yaml": "^4.0.5",
|
|
40
|
+
"@types/bcrypt": "^5.0.0",
|
|
41
|
+
"@types/jsonwebtoken": "^9.0.3",
|
|
42
|
+
"ts-node-dev": "^2.0.0",
|
|
43
|
+
"ts-node": "^10.9.1",
|
|
44
|
+
"typescript": "^5.1.6"
|
|
45
|
+
}
|
|
46
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#### **Project Initialization**
|
|
2
|
+
```bash
|
|
3
|
+
frg init my-app # Create new project with wizard
|
|
4
|
+
frg init # Interactive mode
|
|
5
|
+
```
|
|
6
|
+
Features:
|
|
7
|
+
- Database selection (PostgreSQL/MySQL/SQLite/MongoDB)
|
|
8
|
+
- Optional OpenAI integration
|
|
9
|
+
- Optional authentication system
|
|
10
|
+
- Package manager choice (npm/yarn/pnpm)
|
|
11
|
+
- Automatic dependency installation
|
|
12
|
+
|
|
13
|
+
#### **Code Generation**
|
|
14
|
+
```bash
|
|
15
|
+
frg generate controller User # Generate controller
|
|
16
|
+
frg g c User # Short alias
|
|
17
|
+
|
|
18
|
+
frg generate service User # Generate service
|
|
19
|
+
frg g s User # Short alias
|
|
20
|
+
|
|
21
|
+
frg generate repository User # Generate repository
|
|
22
|
+
frg g r User # Short alias
|
|
23
|
+
|
|
24
|
+
frg generate entity User # Generate entity
|
|
25
|
+
frg g e User # Short alias
|
|
26
|
+
|
|
27
|
+
frg generate resource Product # Generate everything at once!
|
|
28
|
+
frg g res Product # Controller + Service + Repository + Entity
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
#### **Configuration Management**
|
|
32
|
+
```bash
|
|
33
|
+
frg config ai # Configure OpenAI (interactive)
|
|
34
|
+
frg config db # Configure database (interactive)
|
|
35
|
+
frg config show # Display current configuration
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
#### **Development**
|
|
39
|
+
```bash
|
|
40
|
+
frg serve # Start dev server with hot-reload
|
|
41
|
+
frg dev # Alias
|
|
42
|
+
frg serve --port 8080 # Custom port
|
|
43
|
+
frg serve --no-watch # Disable auto-restart
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
#### **Production**
|
|
47
|
+
```bash
|
|
48
|
+
frg build # Build for production
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
#### **Database Migrations**
|
|
52
|
+
```bash
|
|
53
|
+
frg migrate run # Run pending migrations
|
|
54
|
+
frg migrate generate # Create new migration
|
|
55
|
+
frg migrate revert # Revert last migration
|
|
56
|
+
frg migrate show # Migration status
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### **🎨 CLI Features:**
|
|
60
|
+
|
|
61
|
+
1. **Beautiful ASCII Art** - Fragment logo on startup
|
|
62
|
+
2. **Color-Coded Output** - Success (green), errors (red), info (blue)
|
|
63
|
+
3. **Progress Spinners** - Visual feedback for long operations
|
|
64
|
+
4. **Interactive Prompts** - inquirer.js powered wizards
|
|
65
|
+
5. **Validation** - Input validation with helpful messages
|
|
66
|
+
6. **Smart Templates** - Auto-generates boilerplate code
|
|
67
|
+
7. **Configuration Boxes** - Formatted output tables
|
|
68
|
+
8. **Error Handling** - Graceful failures with helpful messages
|
|
69
|
+
|
|
70
|
+
### **📦 Template System:**
|
|
71
|
+
|
|
72
|
+
All generators use smart templates that:
|
|
73
|
+
- Auto-inject dependencies via `@Autowire()`
|
|
74
|
+
- Follow naming conventions
|
|
75
|
+
- Include CRUD operations
|
|
76
|
+
- Are fully typed with TypeScript
|
|
77
|
+
- Follow Fragment patterns
|
|
78
|
+
|
|
79
|
+
### **🚀 Example Workflow:**
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Initialize new project
|
|
83
|
+
frg init my-blog-api
|
|
84
|
+
✓ Select PostgreSQL
|
|
85
|
+
✓ Enable OpenAI
|
|
86
|
+
✓ Include auth system
|
|
87
|
+
|
|
88
|
+
# Configure OpenAI
|
|
89
|
+
frg config ai
|
|
90
|
+
✓ Enter API key
|
|
91
|
+
✓ Select model
|
|
92
|
+
|
|
93
|
+
# Generate complete resource
|
|
94
|
+
frg generate resource Post
|
|
95
|
+
✓ Creates controller, service, repository, entity
|
|
96
|
+
✓ Sets up routes at /api/posts
|
|
97
|
+
|
|
98
|
+
# Start server
|
|
99
|
+
frg serve
|
|
100
|
+
🔷 Fragment Framework Started
|
|
101
|
+
📍 Routes registered
|
|
102
|
+
✓ Ready on port 3000
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### **Project Structure:**
|
|
106
|
+
```
|
|
107
|
+
my-fragment-app/
|
|
108
|
+
├── bin/frg.ts # CLI entry point
|
|
109
|
+
├── src/
|
|
110
|
+
│ ├── cli/ # CLI commands & utils
|
|
111
|
+
│ ├── core/ # Framework core
|
|
112
|
+
│ ├── controllers/ # HTTP controllers
|
|
113
|
+
│ ├── services/ # Business logic
|
|
114
|
+
│ ├── repositories/ # Data access
|
|
115
|
+
│ ├── entities/ # TypeORM entities
|
|
116
|
+
│ └── app.ts # FragmentApplication
|
|
117
|
+
├── config/
|
|
118
|
+
│ └── fragment.yaml # Configuration
|
|
119
|
+
└── package.json
|
|
120
|
+
```
|