Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@hestjs/core

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@hestjs/core - npm Package Compare versions

Comparing version
0.1.8
to
0.1.9
+29
dist/application/application-hooks.d.ts
/**
* 应用启动钩子系统
*
* 这是一个通用的钩子系统,允许外部包注册自己的初始化逻辑
* 而不会让 core 包与特定的外部包产生耦合
*/
export type ApplicationHook = (container: any) => Promise<void> | void;
/**
* 应用钩子管理器
*/
export declare class ApplicationHooks {
private static instance;
private hooks;
private constructor();
static getInstance(): ApplicationHooks;
/**
* 注册应用启动钩子
*/
registerHook(hook: ApplicationHook): void;
/**
* 执行所有注册的钩子
*/
executeHooks(container: any): Promise<void>;
/**
* 清空所有钩子
*/
clearHooks(): void;
}
//# sourceMappingURL=application-hooks.d.ts.map
{"version":3,"file":"application-hooks.d.ts","sourceRoot":"","sources":["../../src/application/application-hooks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,SAAS,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEvE;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAmB;IAC1C,OAAO,CAAC,KAAK,CAAyB;IAEtC,OAAO;IAEP,MAAM,CAAC,WAAW,IAAI,gBAAgB;IAOtC;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI;IAIzC;;OAEG;IACG,YAAY,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAUjD;;OAEG;IACH,UAAU,IAAI,IAAI;CAGnB"}
"use strict";
/**
* 应用启动钩子系统
*
* 这是一个通用的钩子系统,允许外部包注册自己的初始化逻辑
* 而不会让 core 包与特定的外部包产生耦合
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ApplicationHooks = void 0;
/**
* 应用钩子管理器
*/
class ApplicationHooks {
static instance;
hooks = [];
constructor() { }
static getInstance() {
if (!ApplicationHooks.instance) {
ApplicationHooks.instance = new ApplicationHooks();
}
return ApplicationHooks.instance;
}
/**
* 注册应用启动钩子
*/
registerHook(hook) {
this.hooks.push(hook);
}
/**
* 执行所有注册的钩子
*/
async executeHooks(container) {
for (const hook of this.hooks) {
try {
await hook(container);
}
catch (error) {
console.warn('Failed to execute application hook:', error);
}
}
}
/**
* 清空所有钩子
*/
clearHooks() {
this.hooks = [];
}
}
exports.ApplicationHooks = ApplicationHooks;
//# sourceMappingURL=application-hooks.js.map
{"version":3,"file":"application-hooks.js","sourceRoot":"","sources":["../../src/application/application-hooks.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAIH;;GAEG;AACH,MAAa,gBAAgB;IACnB,MAAM,CAAC,QAAQ,CAAmB;IAClC,KAAK,GAAsB,EAAE,CAAC;IAEtC,gBAAuB,CAAC;IAExB,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC;YAC/B,gBAAgB,CAAC,QAAQ,GAAG,IAAI,gBAAgB,EAAE,CAAC;QACrD,CAAC;QACD,OAAO,gBAAgB,CAAC,QAAQ,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,IAAqB;QAChC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,SAAc;QAC/B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC;YACxB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAClB,CAAC;CACF;AAvCD,4CAuCC"}
+1
-1

@@ -1,1 +0,1 @@

{"version":3,"file":"application-factory.d.ts","sourceRoot":"","sources":["../../src/application/application-factory.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAG7D;;GAEG;AACH,qBAAa,WAAW;IACtB;;OAEG;WACU,MAAM,CAAC,WAAW,EAAE,GAAG,GAAG,OAAO,CAAC,uBAAuB,CAAC;IA0BvE;;OAEG;mBACkB,gBAAgB;CAgDtC"}
{"version":3,"file":"application-factory.d.ts","sourceRoot":"","sources":["../../src/application/application-factory.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAI7D;;GAEG;AACH,qBAAa,WAAW;IACtB;;OAEG;WACU,MAAM,CAAC,WAAW,EAAE,GAAG,GAAG,OAAO,CAAC,uBAAuB,CAAC;IA6BvE;;OAEG;mBACkB,gBAAgB;CAgDtC"}

@@ -9,2 +9,3 @@ "use strict";

const hest_application_1 = require("./hest-application");
const application_hooks_1 = require("./application-hooks");
const logger_1 = require("@hestjs/logger");

@@ -35,2 +36,4 @@ /**

}
// 执行所有注册的应用启动钩子
await application_hooks_1.ApplicationHooks.getInstance().executeHooks(container);
return appInstance;

@@ -47,3 +50,3 @@ }

// 注册模块自身
container.register(moduleClass, moduleClass);
container.register(moduleClass, moduleClass, 'module');
// 注册提供者

@@ -54,5 +57,5 @@ if (moduleMetadata.providers) {

// 注册类本身作为令牌
container.register(provider, provider);
container.register(provider, provider, 'provider');
// 同时注册类名字符串作为令牌,以支持 @Inject('ClassName') 语法
container.register(provider.name, provider);
container.register(provider.name, provider, 'provider');
}

@@ -68,3 +71,3 @@ else {

if (metadata_scanner_1.MetadataScanner.isController(controller)) {
container.register(controller, controller);
container.register(controller, controller, 'controller');
}

@@ -71,0 +74,0 @@ else {

@@ -1,1 +0,1 @@

{"version":3,"file":"application-factory.js","sourceRoot":"","sources":["../../src/application/application-factory.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"application-factory.js","sourceRoot":"","sources":["../../src/application/application-factory.ts"],"names":[],"mappings":"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"}

@@ -0,3 +1,4 @@

export * from './application-factory';
export * from './hest-application';
export * from './application-factory';
export * from './application-hooks';
//# sourceMappingURL=index.d.ts.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/application/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC"}
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/application/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC"}

@@ -17,4 +17,5 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./application-factory"), exports);
__exportStar(require("./hest-application"), exports);
__exportStar(require("./application-factory"), exports);
__exportStar(require("./application-hooks"), exports);
//# sourceMappingURL=index.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/application/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAmC;AACnC,wDAAsC"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/application/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,wDAAsC;AACtC,qDAAmC;AACnC,sDAAoC"}
import "reflect-metadata";
import { DependencyContainer, InjectionToken } from "tsyringe";
import type { InjectableMetadata, ControllerMetadata, ModuleMetadata } from "../interfaces/metadata";
import type { ControllerConstructor } from "../interfaces/router";
import { Scope } from "../utils/constants";
declare global {

@@ -9,2 +12,19 @@ namespace Reflect {

/**
* 逻辑容器项类型
*/
export interface LogicalContainerItem<T = any> {
token: InjectionToken<T>;
provider: T;
type: 'controller' | 'provider' | 'module';
metadata?: ControllerMetadata | InjectableMetadata | ModuleMetadata;
scope?: Scope;
}
/**
* 控制器容器项特化类型
*/
export interface ControllerContainerItem extends LogicalContainerItem<ControllerConstructor> {
type: 'controller';
metadata?: ControllerMetadata;
}
/**
* HestJS DI 容器封装

@@ -15,2 +35,3 @@ */

private container;
private logicalContainer;
constructor();

@@ -24,3 +45,3 @@ /**

*/
register<T>(token: InjectionToken<T>, provider: any): void;
register<T>(token: InjectionToken<T>, provider: any, type?: 'controller' | 'provider' | 'module'): void;
/**

@@ -50,3 +71,19 @@ * 注册实例

getContainer(): DependencyContainer;
/**
* 获取逻辑容器中的所有项
*/
getLogicalContainer(): Map<InjectionToken<any>, LogicalContainerItem>;
/**
* 获取指定类型的所有项
*/
getItemsByType(type: 'controller' | 'provider' | 'module'): LogicalContainerItem[];
/**
* 获取所有控制器
*/
getAllControllers(): ControllerContainerItem[];
/**
* 提取元数据信息
*/
private extractMetadata;
}
//# sourceMappingURL=container.d.ts.map

@@ -1,1 +0,1 @@

{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../src/container/container.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EACL,mBAAmB,EACnB,cAAc,EAEf,MAAM,UAAU,CAAC;AAKlB,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,SAAS,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC;KACjF;CACF;AAED;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAY;IACnC,OAAO,CAAC,SAAS,CAAsB;;IAMvC;;OAEG;IACH,MAAM,CAAC,WAAW,IAAI,SAAS;IAO/B;;OAEG;IACH,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,GAAG,IAAI;IAgB1D;;OAEG;IACH,gBAAgB,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI;IAIhE;;OAEG;IACH,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC;IAIvC;;OAEG;IACH,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,OAAO;IAIlD;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,WAAW,IAAI,SAAS;IAMxB;;OAEG;IACH,YAAY,IAAI,mBAAmB;CAGpC"}
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../src/container/container.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EACL,mBAAmB,EACnB,cAAc,EAEf,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACrG,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAiB,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAG1D,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,SAAS,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC;KACjF;CACF;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB,CAAC,CAAC,GAAG,GAAG;IAC3C,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IACzB,QAAQ,EAAE,CAAC,CAAC;IACZ,IAAI,EAAE,YAAY,GAAG,UAAU,GAAG,QAAQ,CAAC;IAC3C,QAAQ,CAAC,EAAE,kBAAkB,GAAG,kBAAkB,GAAG,cAAc,CAAC;IACpE,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,uBAAwB,SAAQ,oBAAoB,CAAC,qBAAqB,CAAC;IAC1F,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC/B;AAED;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAY;IACnC,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,gBAAgB,CAA6D;;IAMrF;;OAEG;IACH,MAAM,CAAC,WAAW,IAAI,SAAS;IAO/B;;OAEG;IACH,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,GAAE,YAAY,GAAG,UAAU,GAAG,QAAqB,GAAG,IAAI;IA0BnH;;OAEG;IACH,gBAAgB,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI;IAIhE;;OAEG;IACH,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC;IAIvC;;OAEG;IACH,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,OAAO;IAIlD;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,WAAW,IAAI,SAAS;IAMxB;;OAEG;IACH,YAAY,IAAI,mBAAmB;IAInC;;OAEG;IACH,mBAAmB,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,oBAAoB,CAAC;IAIrE;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,UAAU,GAAG,QAAQ,GAAG,oBAAoB,EAAE;IAIlF;;OAEG;IACH,iBAAiB,IAAI,uBAAuB,EAAE;IAI9C;;OAEG;IACH,OAAO,CAAC,eAAe;CAYxB"}

@@ -13,2 +13,3 @@ "use strict";

container;
logicalContainer = new Map();
constructor() {

@@ -29,4 +30,13 @@ this.container = tsyringe_1.container.createChildContainer();

*/
register(token, provider) {
register(token, provider, type = 'provider') {
const metadata = Reflect.getMetadata(constants_1.METADATA_KEYS.INJECTABLE, provider) || {};
// 保存到逻辑容器
const logicalItem = {
token,
provider,
type,
metadata: this.extractMetadata(provider, type),
scope: metadata.scope
};
this.logicalContainer.set(token, logicalItem);
switch (metadata.scope) {

@@ -81,4 +91,37 @@ case constants_1.Scope.SINGLETON:

}
/**
* 获取逻辑容器中的所有项
*/
getLogicalContainer() {
return this.logicalContainer;
}
/**
* 获取指定类型的所有项
*/
getItemsByType(type) {
return Array.from(this.logicalContainer.values()).filter(item => item.type === type);
}
/**
* 获取所有控制器
*/
getAllControllers() {
return this.getItemsByType('controller');
}
/**
* 提取元数据信息
*/
extractMetadata(provider, type) {
switch (type) {
case 'controller':
return Reflect.getMetadata(constants_1.METADATA_KEYS.CONTROLLER, provider);
case 'module':
return Reflect.getMetadata(constants_1.METADATA_KEYS.MODULE, provider);
case 'provider':
return Reflect.getMetadata(constants_1.METADATA_KEYS.INJECTABLE, provider);
default:
return null;
}
}
}
exports.Container = Container;
//# sourceMappingURL=container.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container/container.ts"],"names":[],"mappings":";;;AAAA,4BAA0B;AAC1B,uCAIkB;AAElB,kDAA0D;AAS1D;;GAEG;AACH,MAAa,SAAS;IACZ,MAAM,CAAC,QAAQ,CAAY;IAC3B,SAAS,CAAsB;IAEvC;QACE,IAAI,CAAC,SAAS,GAAG,oBAAiB,CAAC,oBAAoB,EAAE,CAAC;IAC5D,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;YACxB,SAAS,CAAC,QAAQ,GAAG,IAAI,SAAS,EAAE,CAAC;QACvC,CAAC;QACD,OAAO,SAAS,CAAC,QAAQ,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,QAAQ,CAAI,KAAwB,EAAE,QAAa;QACjD,MAAM,QAAQ,GACZ,OAAO,CAAC,WAAW,CAAC,yBAAa,CAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEhE,QAAQ,QAAQ,CAAC,KAAK,EAAE,CAAC;YACvB,KAAK,iBAAK,CAAC,SAAS;gBAClB,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAClD,MAAM;YACR,KAAK,iBAAK,CAAC,SAAS;gBAClB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;gBACvD,MAAM;YACR;gBACE,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAI,KAAwB,EAAE,QAAW;QACvD,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,OAAO,CAAI,KAAwB;QACjC,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,YAAY,CAAI,KAAwB;QACtC,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,WAAW;QACT,MAAM,KAAK,GAAG,IAAI,SAAS,EAAE,CAAC;QAC9B,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,oBAAoB,EAAE,CAAC;QACxD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF;AAhFD,8BAgFC"}
{"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container/container.ts"],"names":[],"mappings":";;;AAAA,4BAA0B;AAC1B,uCAIkB;AAGlB,kDAA0D;AA4B1D;;GAEG;AACH,MAAa,SAAS;IACZ,MAAM,CAAC,QAAQ,CAAY;IAC3B,SAAS,CAAsB;IAC/B,gBAAgB,GAAmD,IAAI,GAAG,EAAE,CAAC;IAErF;QACE,IAAI,CAAC,SAAS,GAAG,oBAAiB,CAAC,oBAAoB,EAAE,CAAC;IAC5D,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;YACxB,SAAS,CAAC,QAAQ,GAAG,IAAI,SAAS,EAAE,CAAC;QACvC,CAAC;QACD,OAAO,SAAS,CAAC,QAAQ,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,QAAQ,CAAI,KAAwB,EAAE,QAAa,EAAE,OAA6C,UAAU;QAC1G,MAAM,QAAQ,GACZ,OAAO,CAAC,WAAW,CAAC,yBAAa,CAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEhE,UAAU;QACV,MAAM,WAAW,GAAyB;YACxC,KAAK;YACL,QAAQ;YACR,IAAI;YACJ,QAAQ,EAAE,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC;YAC9C,KAAK,EAAE,QAAQ,CAAC,KAAc;SAC/B,CAAC;QACF,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAE9C,QAAQ,QAAQ,CAAC,KAAK,EAAE,CAAC;YACvB,KAAK,iBAAK,CAAC,SAAS;gBAClB,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAClD,MAAM;YACR,KAAK,iBAAK,CAAC,SAAS;gBAClB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;gBACvD,MAAM;YACR;gBACE,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAI,KAAwB,EAAE,QAAW;QACvD,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,OAAO,CAAI,KAAwB;QACjC,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,YAAY,CAAI,KAAwB;QACtC,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,WAAW;QACT,MAAM,KAAK,GAAG,IAAI,SAAS,EAAE,CAAC;QAC9B,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,oBAAoB,EAAE,CAAC;QACxD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,mBAAmB;QACjB,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,IAA0C;QACvD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IACvF,CAAC;IAED;;OAEG;IACH,iBAAiB;QACf,OAAO,IAAI,CAAC,cAAc,CAAC,YAAY,CAA8B,CAAC;IACxE,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,QAAa,EAAE,IAA0C;QAC/E,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,YAAY;gBACf,OAAO,OAAO,CAAC,WAAW,CAAC,yBAAa,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YACjE,KAAK,QAAQ;gBACX,OAAO,OAAO,CAAC,WAAW,CAAC,yBAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAC7D,KAAK,UAAU;gBACb,OAAO,OAAO,CAAC,WAAW,CAAC,yBAAa,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YACjE;gBACE,OAAO,IAAI,CAAC;QAChB,CAAC;IACH,CAAC;CACF;AAhID,8BAgIC"}

@@ -1,3 +0,4 @@

export * from './container';
export * from './injection-token';
export * from "./container";
export * from "./injection-token";
export type { LogicalContainerItem, ControllerContainerItem } from "./container";
//# sourceMappingURL=index.d.ts.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/container/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC"}
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/container/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,YAAY,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC"}
{
"name": "@hestjs/core",
"version": "0.1.8",
"version": "0.1.9",
"description": "HestJS Core Framework - A TypeScript framework built on Hono with dependency injection and decorators",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

+326
-262

@@ -1,373 +0,440 @@

# HestJS 🚀
# @hestjs/core
一个基于 **Hono + Bun + TSyringe** 的现代化 TypeScript 后端框架,提供类似 NestJS 的开发体验,但具有更轻量和更高性能的特点。
<div align="center">
[![npm version](https://img.shields.io/npm/v/@hestjs/core.svg)](https://www.npmjs.com/package/@hestjs/core)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue.svg)](https://www.typescriptlang.org/)
[![Bun](https://img.shields.io/badge/Bun-latest-orange.svg)](https://bun.sh/)
[![Hono](https://img.shields.io/badge/Hono-4.x-green.svg)](https://hono.dev/)
[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
## ✨ 特性
</div>
- 🎯 **装饰器驱动** - 使用装饰器定义控制器、服务、中间件
- 💉 **依赖注入** - 基于 TSyringe 的完整 DI 容器,用户透明
- 🏗️ **模块化架构** - 采用模块系统组织代码
- ⚡ **高性能** - 基于 Hono 和 Bun 获得最佳性能
- 🔒 **类型安全** - 完全的 TypeScript 支持
- 🛡️ **验证系统** - 基于 TypeBox 的强大验证功能
- 🔄 **拦截器** - 灵活的请求/响应拦截机制
- 🚨 **异常处理** - 完善的异常过滤和处理系统
HestJS 核心包 - 基于 Hono 构建的现代化 TypeScript 后端库,提供装饰器驱动的开发体验和依赖注入系统。
## 🚀 快速开始
## 🎯 核心理念
### 安装
- **🔓 拒绝过度封装**:直接暴露原生 Hono 实例,保留所有底层功能
- **✈️ 零配置**:你看不到类似 `hestjs.config.ts`这样的配置文件,无需任何配置
- **🎯 装饰器驱动**:提供熟悉的 NestJS 风格开发体验
- **💉 轻量依赖注入**:基于 TSyringe 的简洁 DI 容器
- **⚡ 极致性能**:基于 Hono 和 Bun 的高性能运行时
## 📦 安装
```bash
# 克隆项目
git clone https://github.com/aqz236/hest.git
cd HestJS
npm install @hestjs/core
# 或
yarn add @hestjs/core
# 或
bun add @hestjs/core
```
# 安装依赖
bun install
## 🚀 快速开始
# 构建包
bun run build
### 1. 创建基础应用
# 运行示例应用
cd apps/hest-demo
bun run dev
在此之前你应该在tsconfig中添加以下内容:
```json
{
"compilerOptions": {
...
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"esModuleInterop": true
}
}
```
### 创建你的第一个应用
```typescript
// app.controller.ts
import { Controller, Get, Post, Body } from "@hestjs/core";
import { IsString, IsEmail, IsNumber } from "@hestjs/validation";
import { Controller, Get, HestFactory, Module } from "@hestjs/core";
export class CreateUserDto {
@IsString({ minLength: 2, maxLength: 50 })
name!: string;
@Controller("/")
export class WelcomeController {
@Get("/welcome")
async welcome() {
return "Welcome to HestJS!";
}
}
@IsEmail()
email!: string;
@Module({
controllers: [WelcomeController],
providers: [],
imports: [],
exports: [],
})
export class AppModule {}
@IsNumber({ minimum: 0, maximum: 120 })
age!: number;
async function bootstrap() {
const app = await HestFactory.create(AppModule);
const hono = app.hono();
Bun.serve({
port: 3000,
fetch: hono.fetch,
});
}
@Controller("/api")
export class AppController {
@Get("/users")
getUsers() {
return { users: [] };
bootstrap();
```
### 2. 定义控制器
```typescript
import { Controller, Get, Post, Context, Body, Param } from "@hestjs/core";
import type { HestContext } from "@hestjs/core";
@Controller("/users")
export class UsersController {
@Get("/")
async getAllUsers() {
return { message: "Get all users" };
}
@Post("/users")
createUser(@Body(CreateUserDto) createUserDto: CreateUserDto) {
// createUserDto 已经过验证和类型转换
return { success: true, data: createUserDto };
@Get("/:id")
async getUser(@Param("id") id: string, @Context() c: HestContext) {
return { id, message: `Get user ${id}` };
}
@Post("/")
async createUser(@Body() body: any, @Context() c: HestContext) {
return { message: "User created", data: body };
}
}
```
### 3. 创建模块
```typescript
// app.module.ts
import { Module } from "@hestjs/core";
import { AppController } from "./app.controller";
import { UsersController } from "./users.controller";
import { UsersService } from "./users.service";
@Module({
controllers: [AppController],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService],
})
export class AppModule {}
export class UsersModule {}
```
### 4. 创建服务
```typescript
// main.ts
import { HestFactory } from "@hestjs/core";
import { ValidationInterceptor } from "@hestjs/validation";
import { AppModule } from "./app.module";
import { injectable } from "@hestjs/core";
async function bootstrap() {
const app = await HestFactory.create(AppModule);
@injectable()
export class UsersService {
findAll() {
return [
{ id: 1, name: "John" },
{ id: 2, name: "Jane" },
];
}
// 启用全局验证
app.useGlobalInterceptors(new ValidationInterceptor());
await app.listen(3000);
console.log("🚀 Application is running on: http://localhost:3000");
findOne(id: number) {
return { id, name: `User ${id}` };
}
}
bootstrap();
```
## 📁 项目结构
## 🏗️ 架构概览
### 核心模块
HestJS Core 包含以下主要模块:
```
packages/
├── core/ # 核心框架包
│ ├── decorators/ # 装饰器定义
│ ├── interfaces/ # 核心接口
│ ├── application/ # 应用核心
│ └── exceptions/ # 异常处理
├── validation/ # 验证模块
│ ├── decorators/ # 验证装饰器
│ ├── pipes/ # 验证管道
│ └── interceptors/ # 验证拦截器
└── ...
@hestjs/core/
├── application/ # 应用工厂和实例
│ ├── HestFactory # 应用工厂
│ └── HestApplicationInstance # 应用实例
├── decorators/ # 装饰器系统
│ ├── @Controller # 控制器装饰器
│ ├── @Module # 模块装饰器
│ ├── @injectable # 可注入装饰器
│ └── 路由装饰器 # @Get, @Post, @Put, @Delete, @Patch
├── container/ # 依赖注入容器
├── router/ # 路由系统
├── exceptions/ # 异常处理
├── interceptors/ # 拦截器
├── interfaces/ # 类型定义
└── utils/ # 工具函数
```
## 🎯 核心概念
## 📚 API 参考
### 控制器 (Controllers)
### 🏭 应用工厂
#### `HestFactory.create(moduleClass)`
创建应用实例的静态方法。
```typescript
@Controller("/users")
export class UserController {
@Get("/")
findAll() {
return { users: [] };
}
import { HestFactory } from "@hestjs/core";
import { AppModule } from "./app.module";
@Get("/:id")
findOne(@Param("id") id: string) {
return { user: { id } };
}
const app = await HestFactory.create(AppModule);
```
@Post("/")
create(@Body(CreateUserDto) createUserDto: CreateUserDto) {
return { success: true };
}
### 🎮 控制器装饰器
#### `@Controller(path?: string)`
定义控制器类和基础路径。
```typescript
@Controller("/api/users")
export class UsersController {
// 控制器方法
}
```
### 服务和依赖注入 (Services & DI)
### 🛣️ 路由装饰器
#### HTTP 方法装饰器
- `@Get(path?: string)` - GET 请求
- `@Post(path?: string)` - POST 请求
- `@Put(path?: string)` - PUT 请求
- `@Delete(path?: string)` - DELETE 请求
- `@Patch(path?: string)` - PATCH 请求
```typescript
@Injectable()
export class UserService {
async findAll() {
return [];
}
@Controller('/users')
export class UsersController {
@Get('/') // GET /users/
@Get('/:id') // GET /users/:id
@Post('/') // POST /users/
@Put('/:id') // PUT /users/:id
@Delete('/:id') // DELETE /users/:id
@Patch('/:id') // PATCH /users/:id
}
```
async create(userData: any) {
// 创建用户逻辑
return userData;
}
### 📥 参数装饰器
#### `@Context()`
获取完整的 Hono Context 对象。
```typescript
@Get('/')
async getUsers(@Context() c: HestContext) {
// 访问所有 Hono Context 功能
const userAgent = c.req.header('User-Agent');
return c.json({ message: 'Hello' });
}
```
@Controller("/users")
export class UserController {
constructor(private readonly userService: UserService) {}
#### `@Body()`
@Get("/")
async findAll() {
return await this.userService.findAll();
}
获取请求体数据。
```typescript
@Post('/')
async createUser(@Body() userData: CreateUserDto) {
return userData;
}
```
### 验证系统 (Validation)
#### `@Param(key?: string)`
#### 基础验证装饰器
获取路径参数。
```typescript
export class CreateUserDto {
@IsString({ minLength: 2, maxLength: 50 })
name!: string;
@Get('/:id')
async getUser(@Param('id') id: string) {
return { id };
}
```
@IsEmail()
email!: string;
#### `@Query(key?: string)`
@IsNumber({ minimum: 18, maximum: 100 })
age!: number;
获取查询参数。
@IsOptional()
@IsString()
bio?: string;
```typescript
@Get('/')
async getUsers(@Query('page') page: string) {
return { page };
}
```
#### 自定义验证 (TypeBox API)
#### `@Header(key?: string)`
获取请求头。
```typescript
import { Type } from "@sinclair/typebox";
import { Custom, CommonValidators, SchemaFactory } from "@hestjs/validation";
@Get('/')
async getUsers(@Header('authorization') auth: string) {
return { auth };
}
```
export class AdvancedDto {
// 使用 TypeBox API 自定义验证
@Custom(
Type.String({
minLength: 3,
maxLength: 20,
pattern: "^[a-zA-Z0-9_]+$",
})
)
username!: string;
### 🏗️ 模块系统
// 使用联合类型
@Custom(
Type.Union([
Type.Literal("admin"),
Type.Literal("user"),
Type.Literal("guest"),
])
)
role!: "admin" | "user" | "guest";
#### `@Module(options)`
// 使用常用验证器
@CommonValidators.UUID()
userId!: string;
定义模块和依赖关系。
// 使用便捷构建器
@Custom(SchemaFactory.chinesePhoneNumber())
phoneNumber!: string;
```typescript
interface ModuleOptions {
imports?: any[]; // 导入的模块
controllers?: any[]; // 控制器
providers?: any[]; // 提供者(服务)
exports?: any[]; // 导出的提供者
}
// 复杂对象验证
@Custom(
Type.Object({
lat: Type.Number({ minimum: -90, maximum: 90 }),
lng: Type.Number({ minimum: -180, maximum: 180 }),
})
)
location!: { lat: number; lng: number };
@Module({
imports: [DatabaseModule],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService],
})
export class UsersModule {}
```
### 💉 依赖注入
#### `@injectable()`
标记类为可注入的服务。
```typescript
@injectable()
export class UsersService {
constructor(private readonly databaseService: DatabaseService) {}
}
```
### 拦截器 (Interceptors)
### 🔄 拦截器和过滤器
#### 全局拦截器
```typescript
import { Interceptor, ExecutionContext, CallHandler } from "@hestjs/core";
const app = await HestFactory.create(AppModule);
export class LoggingInterceptor implements Interceptor {
intercept(context: ExecutionContext, next: CallHandler) {
console.log("Before...");
// 添加全局拦截器
app.useGlobalInterceptors(new ValidationInterceptor());
app.useGlobalInterceptors(new ResponseInterceptor());
```
const now = Date.now();
return next.handle().then(() => {
console.log(`After... ${Date.now() - now}ms`);
});
}
}
#### 全局异常过滤器
// 使用拦截器
app.useGlobalInterceptors(new LoggingInterceptor());
```typescript
const app = await HestFactory.create(AppModule);
// 添加全局异常过滤器
app.useGlobalFilters(new HttpExceptionFilter());
```
### 异常处理 (Exception Handling)
### 🌐 直接访问 Hono
HestJS 不会封装 Hono,你可以直接使用所有 Hono 功能:
```typescript
import {
HttpException,
NotFoundException,
BadRequestException,
} from "@hestjs/core";
const app = await HestFactory.create(AppModule);
const honoApp = app.hono();
@Controller("/users")
export class UserController {
@Get("/:id")
findOne(@Param("id") id: string) {
const user = this.findUserById(id);
if (!user) {
throw new NotFoundException(`User with id ${id} not found`);
}
return user;
}
// 使用 Hono 原生中间件
honoApp.use(cors());
honoApp.use("/api/*", async (c, next) => {
console.log(`${c.req.method} ${c.req.url}`);
await next();
});
@Post("/")
create(@Body() userData: any) {
if (!userData.email) {
throw new BadRequestException("Email is required");
}
return this.createUser(userData);
}
}
// 添加自定义路由
honoApp.get("/health", (c) => c.text("OK"));
```
## 🔧 开发状态
## 🧪 类型系统
### ✅ 已完成功能
### HestContext
- **Phase 1: 核心基础设施** ✅
- 装饰器系统 (`@Controller`, `@Injectable`, `@Module`, 路由装饰器)
- 依赖注入容器 (基于 TSyringe)
- 应用工厂 (`HestFactory.create()`)
- 路由系统和参数注入
提供完整的 Hono Context 类型安全:
- **Phase 2: 中间件和异常处理** ✅
- 异常处理系统 (HttpException, 异常过滤器)
- 拦截器系统 (Interceptor, ExecutionContext)
- 全局拦截器和异常过滤器支持
```typescript
import type { HestContext } from '@hestjs/core';
- **Phase 3: 验证系统** ✅
- 基于 TypeBox 的验证装饰器
- @Custom() 装饰器支持完整 TypeBox API
- ValidationInterceptor 自动验证
- SchemaFactory 和 CommonValidators
- 详细验证错误处理
@Get('/')
async handler(@Context() c: HestContext) {
// 完整的 Hono Context API
const method = c.req.method;
const url = c.req.url;
const headers = c.req.header();
### 🚧 开发中
return c.json({ method, url });
}
```
- **Phase 4: 配置和日志系统**
- **Phase 5: 高级拦截器和管道**
- **Phase 6: CLI 工具**
## 🔮 未来路线图
## 📊 性能
### v0.2.x - 增强功能
基于 Bun 运行时和 Hono 框架,HestJS 提供了卓越的性能:
- [ ] **中间件系统** - 完善的中间件装饰器支持
- [ ] **管道系统** - 数据转换和验证管道
- [ ] **守卫系统** - 路由级别的访问控制
- [ ] **元数据增强** - 更丰富的反射元数据支持
- 🚀 **快速启动** - 得益于 Bun 的快速启动时间
- ⚡ **高吞吐量** - Hono 的高效路由和中间件系统
- 💾 **低内存占用** - 轻量级架构设计
- 🔧 **编译时优化** - TypeScript 装饰器元数据预处理
### v0.3.x - 性能优化
## 🛠️ 开发
- [ ] **路由缓存** - 路由匹配性能优化
- [ ] **依赖注入优化** - 容器解析性能提升
- [ ] **热重载支持** - 开发环境下的热重载
- [ ] **构建优化** - 更小的打包体积
### 构建项目
### v0.4.x - 生态系统
```bash
# 安装依赖
bun install
- [ ] **WebSocket 支持** - 实时通信功能
- [ ] **文件上传** - 内置文件处理能力
- [ ] **缓存系统** - 多级缓存支持
- [ ] **任务调度** - 定时任务和队列系统
# 构建所有包
bun run build
### v0.5.x - 企业级功能
# 运行测试
bun run test
- [ ] **微服务支持** - 服务发现和通信
- [ ] **配置管理** - 环境配置和动态配置
- [ ] **健康检查** - 应用监控和诊断
- [ ] **链路追踪** - 分布式追踪支持
# 运行示例应用
cd apps/hest-demo
bun run dev
```
### v1.0.x - 稳定版本
### 测试验证功能
- [ ] **API 稳定** - 向后兼容的 API
- [ ] **完整文档** - 全面的使用指南
- [ ] **性能基准** - 与其他框架的对比
- [ ] **生产就绪** - 企业级部署支持
```bash
# 运行 Phase 3 验证测试
bun test-phase3.ts
```
## 📋 当前功能状态
## 📖 API 参考
### ✅ 已实现功能
### 装饰器
- [x] **应用工厂** - `HestFactory.create()`
- [x] **控制器系统** - `@Controller()` 装饰器
- [x] **路由装饰器** - `@Get()`, `@Post()`, `@Put()`, `@Delete()`, `@Patch()`
- [x] **参数装饰器** - `@Context()`, `@Body()`, `@Param()`, `@Query()`, `@Header()`
- [x] **模块系统** - `@Module()` 装饰器
- [x] **依赖注入** - 基于 TSyringe 的 DI 容器
- [x] **异常处理** - 基础异常过滤器
- [x] **拦截器** - 全局拦截器支持
- [x] **类型安全** - 完整的 TypeScript 支持
- [x] **Hono 集成** - 直接访问 Hono 实例
- `@Controller(path?)` - 定义控制器
- `@Injectable()` - 标记可注入服务
- `@Module(options)` - 定义模块
- `@Get(path?)`, `@Post(path?)`, `@Put(path?)`, `@Delete(path?)` - HTTP 路由
- `@Body(dtoClass?)`, `@Param(key?)`, `@Query(key?)` - 参数注入
- `@IsString()`, `@IsEmail()`, `@IsNumber()` - 基础验证
- `@Custom(schema, options?)` - 自定义 TypeBox 验证
### 🚧 开发中功能
### 核心类
- [ ] **装饰器中间件** - `@UseMiddleware()` 装饰器
- [ ] **路由守卫** - `@UseGuards()` 装饰器
- [ ] **数据管道** - `@UsePipes()` 装饰器
- [ ] **OpenAPI 集成** - 自动 API 文档生成
- `HestFactory` - 应用工厂
- `HttpException` - HTTP 异常基类
- `ValidationInterceptor` - 验证拦截器
- `Interceptor` - 拦截器接口
- `ExecutionContext` - 执行上下文
## 💡 设计原则
1. **最小封装** - 不隐藏底层框架的功能
2. **类型安全** - 完整的 TypeScript 支持
3. **性能优先** - 基于高性能的 Hono 和 Bun
4. **开发体验** - 熟悉的装饰器语法
5. **渐进式** - 可以逐步采用各种功能
## 🤝 贡献
欢迎贡献代码!请查看 [贡献指南](CONTRIBUTING.md) 了解详情。
欢迎提交 Issue 和 Pull Request!

@@ -378,11 +445,8 @@ ## 📄 许可证

## 🔗 相关链接
---
- [Hono](https://hono.dev/) - 快速、轻量级的 Web 框架
- [Bun](https://bun.sh/) - 快速的 JavaScript 运行时
- [TSyringe](https://github.com/microsoft/tsyringe) - 依赖注入容器
- [TypeBox](https://github.com/sinclairzx81/typebox) - JSON Schema 类型构建器
**更多信息**:
---
⭐ 如果这个项目对你有帮助,请给个 Star!
- 📚 [完整文档](https://aqz236.github.io/hestjs-demo)
- 🎮 [示例项目](https://github.com/aqz236/hestjs-demo)
- 🐛 [问题反馈](https://github.com/aqz236/hest/issues)