@husky-di/decorator 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/README.md +238 -0
- package/dist/constants/metadata-key.const.d.ts +8 -0
- package/dist/decorators/inject.decorator.d.ts +9 -0
- package/dist/decorators/injectable.decorator.d.ts +10 -0
- package/dist/decorators/tagged.decorator.d.ts +7 -0
- package/dist/index.cjs +99 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +56 -0
- package/dist/middlewares/decorator.middleware.d.ts +8 -0
- package/dist/shared/instances.d.ts +12 -0
- package/dist/types/injection-metadata.type.d.ts +9 -0
- package/package.json +41 -0
package/README.md
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# @husky-di/decorator
|
|
2
|
+
|
|
3
|
+
`@husky-di/decorator` 是 husky-di 的装饰器支持包,提供了基于 TypeScript 装饰器的依赖注入功能。
|
|
4
|
+
|
|
5
|
+
## 概述
|
|
6
|
+
|
|
7
|
+
该包专门为偏好使用装饰器语法的开发者设计,提供了简洁直观的依赖注入方式。**仅支持 TypeScript 装饰器**,不支持 ES 装饰器。
|
|
8
|
+
|
|
9
|
+
### 为什么仅支持 TypeScript 装饰器?
|
|
10
|
+
|
|
11
|
+
husky-di 的设计理念是**仅支持构造函数注入**,而 ES 装饰器的规范中**没有设计参数注入器**。
|
|
12
|
+
|
|
13
|
+
## 安装
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm add @husky-di/decorator
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 核心装饰器
|
|
20
|
+
|
|
21
|
+
### @injectable()
|
|
22
|
+
|
|
23
|
+
标记一个类为可注入,使其能够被依赖注入容器管理。
|
|
24
|
+
|
|
25
|
+
> 背后的原因是因为只有应用了装饰器,typescript 编译器才会触发元数据的标记。
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { injectable } from "@husky-di/decorator";
|
|
29
|
+
|
|
30
|
+
@injectable()
|
|
31
|
+
class UserService {
|
|
32
|
+
constructor() {}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### @inject()
|
|
37
|
+
|
|
38
|
+
用于构造函数参数注入,支持多种注入选项。
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { inject, injectable } from "@husky-di/decorator";
|
|
42
|
+
|
|
43
|
+
@injectable()
|
|
44
|
+
class LoggerService {
|
|
45
|
+
log(message: string) {
|
|
46
|
+
console.log(message);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@injectable()
|
|
51
|
+
class UserService {
|
|
52
|
+
constructor(@inject(LoggerService) private logger: LoggerService) {}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 注入选项
|
|
57
|
+
|
|
58
|
+
`@inject()` 装饰器支持多种注入选项:
|
|
59
|
+
|
|
60
|
+
### 动态注入 (dynamic)
|
|
61
|
+
|
|
62
|
+
获取服务的动态引用,支持延迟解析:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
@injectable()
|
|
66
|
+
class ConfigService {
|
|
67
|
+
getValue(key: string) {
|
|
68
|
+
return `config-${key}`;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@injectable()
|
|
73
|
+
class CacheService {
|
|
74
|
+
constructor(
|
|
75
|
+
@inject(ConfigService, { dynamic: true })
|
|
76
|
+
private configRef: Ref<ConfigService>
|
|
77
|
+
) {}
|
|
78
|
+
|
|
79
|
+
get(key: string) {
|
|
80
|
+
const config = this.configRef.current;
|
|
81
|
+
return `cached-${config.getValue(key)}`;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 引用注入 (ref)
|
|
87
|
+
|
|
88
|
+
获取服务的引用对象:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
@injectable()
|
|
92
|
+
class ApiService {
|
|
93
|
+
constructor(
|
|
94
|
+
@inject(CacheService, { ref: true })
|
|
95
|
+
public cacheRef: Ref<CacheService>
|
|
96
|
+
) {}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 可选注入 (optional)
|
|
101
|
+
|
|
102
|
+
支持可选依赖,当依赖不存在时不会抛出错误:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
@injectable()
|
|
106
|
+
class TestService {
|
|
107
|
+
constructor(
|
|
108
|
+
@inject(ExistingService, { optional: true })
|
|
109
|
+
public service: ExistingService
|
|
110
|
+
) {}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## 中间件集成
|
|
115
|
+
|
|
116
|
+
装饰器包提供了 `decoratorMiddleware` 中间件,需要注册到全局中间件中:
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
import { globalMiddleware } from "@husky-di/core";
|
|
120
|
+
import { decoratorMiddleware } from "@husky-di/decorator";
|
|
121
|
+
|
|
122
|
+
// 注册装饰器中间件
|
|
123
|
+
globalMiddleware.use(decoratorMiddleware);
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## 完整示例
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import "reflect-metadata";
|
|
130
|
+
import { createContainer, globalMiddleware } from "@husky-di/core";
|
|
131
|
+
import { decoratorMiddleware, inject, injectable } from "@husky-di/decorator";
|
|
132
|
+
|
|
133
|
+
// 注册装饰器中间件
|
|
134
|
+
globalMiddleware.use(decoratorMiddleware);
|
|
135
|
+
|
|
136
|
+
// 创建容器
|
|
137
|
+
const container = createContainer();
|
|
138
|
+
|
|
139
|
+
// 定义服务
|
|
140
|
+
@injectable()
|
|
141
|
+
class LoggerService {
|
|
142
|
+
log(message: string) {
|
|
143
|
+
return `Logged: ${message}`;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
@injectable()
|
|
148
|
+
class DatabaseService {
|
|
149
|
+
constructor(@inject(LoggerService) private logger: LoggerService) {}
|
|
150
|
+
|
|
151
|
+
query(sql: string) {
|
|
152
|
+
return this.logger.log(`Executing: ${sql}`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
@injectable()
|
|
157
|
+
class UserService {
|
|
158
|
+
constructor(
|
|
159
|
+
@inject(DatabaseService) private db: DatabaseService,
|
|
160
|
+
@inject(LoggerService) private logger: LoggerService
|
|
161
|
+
) {}
|
|
162
|
+
|
|
163
|
+
getUser(id: string) {
|
|
164
|
+
return this.db.query(`SELECT * FROM users WHERE id = ${id}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// 使用服务
|
|
169
|
+
const userService = container.resolve(UserService);
|
|
170
|
+
const result = userService.getUser("123");
|
|
171
|
+
console.log(result); // "Logged: Executing: SELECT * FROM users WHERE id = 123"
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## 错误处理
|
|
175
|
+
|
|
176
|
+
### 常见错误
|
|
177
|
+
|
|
178
|
+
1. **重复使用 @injectable()**
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
// ❌ 错误:不能对同一个类使用两次 @injectable()
|
|
182
|
+
@injectable()
|
|
183
|
+
@injectable()
|
|
184
|
+
class TestService {}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
2. **注入非可注入类**
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
// ❌ 错误:依赖的类没有使用 @injectable()
|
|
191
|
+
class NonInjectableService {}
|
|
192
|
+
|
|
193
|
+
@injectable()
|
|
194
|
+
class TestService {
|
|
195
|
+
constructor(@inject(NonInjectableService) dep: NonInjectableService) {}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
3. **循环依赖**
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
// ❌ 错误:检测到循环依赖
|
|
203
|
+
@injectable()
|
|
204
|
+
class ServiceA {
|
|
205
|
+
constructor(@inject(ServiceB) public serviceB: ServiceB) {}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
@injectable()
|
|
209
|
+
class ServiceB {
|
|
210
|
+
constructor(@inject(ServiceA) public serviceA: ServiceA) {}
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## 设计原理
|
|
215
|
+
|
|
216
|
+
装饰器包使用 TypeScript 的 `reflect-metadata`或其他提供 Reflect API 的库来存储和管理注入元数据:
|
|
217
|
+
|
|
218
|
+
- `@injectable()` 收集构造函数参数的注入信息
|
|
219
|
+
- `@inject()` 为特定参数位置设置注入配置
|
|
220
|
+
- `decoratorMiddleware` 在实例化时读取元数据并执行注入
|
|
221
|
+
|
|
222
|
+
## 最佳实践
|
|
223
|
+
|
|
224
|
+
1. **始终使用 @injectable() 标记可注入类**
|
|
225
|
+
2. **为所有依赖参数使用 @inject() 装饰器**
|
|
226
|
+
3. **合理使用注入选项(dynamic、ref、optional)**
|
|
227
|
+
4. **避免循环依赖,必要时使用 ref 选项**
|
|
228
|
+
5. **在应用启动时注册 decoratorMiddleware**
|
|
229
|
+
|
|
230
|
+
## 注意事项
|
|
231
|
+
|
|
232
|
+
- 需要启用 TypeScript 的装饰器支持
|
|
233
|
+
|
|
234
|
+
> 建议在 tsconfig.json 中启用 `experimentalDecorators` 和 `emitDecoratorMetadata` 选项
|
|
235
|
+
|
|
236
|
+
- 需要引入 `reflect-metadata` 包或其他提供 Reflect API 的库
|
|
237
|
+
- `@inject()` 仅支持构造函数注入,不支持属性注入 (可以 `@husky-di/core` 中的 `resolve` 方法来实现属性注入)
|
|
238
|
+
- 装饰器中间件需要全局注册,这样才会在每个容器中都生效
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @overview
|
|
3
|
+
* @author AEPKILL
|
|
4
|
+
* @created 2021-10-03 20:55:17
|
|
5
|
+
*/
|
|
6
|
+
export declare const ParamsMetadataKeyConst = "design:paramtypes";
|
|
7
|
+
export declare const InjectionMetadataKeyConst = "husky-di.injection-metadata";
|
|
8
|
+
export declare const InjectionParamsMetadataKeyConst = "husky-di.injection-params-metadata";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @overview
|
|
3
|
+
* @author AEPKILL
|
|
4
|
+
* @created 2021-10-03 21:08:27
|
|
5
|
+
*/
|
|
6
|
+
import type { ServiceIdentifier } from "@husky-di/core";
|
|
7
|
+
import type { InjectionMetadata } from "../types/injection-metadata.type";
|
|
8
|
+
export type InjectOptions<T> = Omit<InjectionMetadata<T>, "serviceIdentifier">;
|
|
9
|
+
export declare const inject: <T>(serviceIdentifier: ServiceIdentifier<T>, options?: InjectOptions<T>) => ParameterDecorator;
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
inject: ()=>inject,
|
|
28
|
+
tagged: ()=>tagged,
|
|
29
|
+
decoratorMiddleware: ()=>decoratorMiddleware,
|
|
30
|
+
injectable: ()=>injectable
|
|
31
|
+
});
|
|
32
|
+
const ParamsMetadataKeyConst = "design:paramtypes";
|
|
33
|
+
const InjectionMetadataKeyConst = "husky-di.injection-metadata";
|
|
34
|
+
const tagged = (metadata)=>(target, _propertyKey, parameterIndex)=>{
|
|
35
|
+
const parametersMetadata = Reflect.getMetadata(InjectionMetadataKeyConst, target) || [];
|
|
36
|
+
parametersMetadata[parameterIndex] = metadata;
|
|
37
|
+
Reflect.defineMetadata(InjectionMetadataKeyConst, parametersMetadata, target);
|
|
38
|
+
};
|
|
39
|
+
const inject = (serviceIdentifier, options)=>tagged({
|
|
40
|
+
...options,
|
|
41
|
+
serviceIdentifier
|
|
42
|
+
});
|
|
43
|
+
const InjectionMetadataMap = "undefined" == typeof WeakMap ? Map : WeakMap;
|
|
44
|
+
const injectionMetadataMap = new InjectionMetadataMap();
|
|
45
|
+
const injectable = ()=>(target)=>{
|
|
46
|
+
if (injectionMetadataMap.has(target)) throw new Error(`can't use "@injectable()" decorate class "${target.name}" twice`);
|
|
47
|
+
const parametersServiceIdentifiers = Reflect.getMetadata(ParamsMetadataKeyConst, target) || [];
|
|
48
|
+
const parametersMetadata = Reflect.getMetadata(InjectionMetadataKeyConst, target) || [];
|
|
49
|
+
const metadata = [];
|
|
50
|
+
const parametersMetadataLength = Math.max(parametersServiceIdentifiers.length, parametersMetadata.length);
|
|
51
|
+
for(let index = 0; index < parametersMetadataLength; index++){
|
|
52
|
+
if (void 0 !== parametersMetadata[index]) {
|
|
53
|
+
metadata.push(parametersMetadata[index]);
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const serviceIdentifier = parametersServiceIdentifiers[index];
|
|
57
|
+
if ("function" != typeof serviceIdentifier) throw new Error(`only can inject class type in constructor "${target.name}" parameter #${index}`);
|
|
58
|
+
metadata.push({
|
|
59
|
+
serviceIdentifier
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
injectionMetadataMap.set(target, metadata);
|
|
63
|
+
};
|
|
64
|
+
const core_namespaceObject = require("@husky-di/core");
|
|
65
|
+
const decoratorMiddleware = {
|
|
66
|
+
name: Symbol("DecoratorMiddleware"),
|
|
67
|
+
executor: (params, next)=>{
|
|
68
|
+
const { registration, resolveRecord } = params;
|
|
69
|
+
if (registration.type !== core_namespaceObject.RegistrationTypeEnum["class"]) return next(params);
|
|
70
|
+
const provider = registration.provider;
|
|
71
|
+
const parametersMetadata = injectionMetadataMap.get(provider);
|
|
72
|
+
if (!parametersMetadata) throw new core_namespaceObject.ResolveException(`The class ${provider.name} has no injection metadata, please make sure the class is decorated with @Injectable().`, resolveRecord);
|
|
73
|
+
const parameters = parametersMetadata.map((metadata, index)=>{
|
|
74
|
+
const { serviceIdentifier, ...options } = metadata;
|
|
75
|
+
resolveRecord._internalStashCurrent();
|
|
76
|
+
resolveRecord.addRecordNode({
|
|
77
|
+
type: core_namespaceObject.ResolveRecordTypeEnum.message,
|
|
78
|
+
message: `Resolve parameter #${index} of constructor "${provider.name}"`
|
|
79
|
+
});
|
|
80
|
+
const instance = (0, core_namespaceObject.resolve)(serviceIdentifier, options);
|
|
81
|
+
resolveRecord._internalRestoreCurrent();
|
|
82
|
+
return instance;
|
|
83
|
+
});
|
|
84
|
+
return new provider(...parameters);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
exports.decoratorMiddleware = __webpack_exports__.decoratorMiddleware;
|
|
88
|
+
exports.inject = __webpack_exports__.inject;
|
|
89
|
+
exports.injectable = __webpack_exports__.injectable;
|
|
90
|
+
exports.tagged = __webpack_exports__.tagged;
|
|
91
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
92
|
+
"decoratorMiddleware",
|
|
93
|
+
"inject",
|
|
94
|
+
"injectable",
|
|
95
|
+
"tagged"
|
|
96
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
97
|
+
Object.defineProperty(exports, '__esModule', {
|
|
98
|
+
value: true
|
|
99
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @overview
|
|
3
|
+
* @author AEPKILL
|
|
4
|
+
* @created 2025-08-08 21:00:35
|
|
5
|
+
*/
|
|
6
|
+
export * from "./decorators/inject.decorator";
|
|
7
|
+
export * from "./decorators/injectable.decorator";
|
|
8
|
+
export * from "./decorators/tagged.decorator";
|
|
9
|
+
export { decoratorMiddleware } from "./middlewares/decorator.middleware";
|
|
10
|
+
export * from "./types/injection-metadata.type";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { RegistrationTypeEnum, ResolveException, ResolveRecordTypeEnum, resolve } from "@husky-di/core";
|
|
2
|
+
const ParamsMetadataKeyConst = "design:paramtypes";
|
|
3
|
+
const InjectionMetadataKeyConst = "husky-di.injection-metadata";
|
|
4
|
+
const tagged = (metadata)=>(target, _propertyKey, parameterIndex)=>{
|
|
5
|
+
const parametersMetadata = Reflect.getMetadata(InjectionMetadataKeyConst, target) || [];
|
|
6
|
+
parametersMetadata[parameterIndex] = metadata;
|
|
7
|
+
Reflect.defineMetadata(InjectionMetadataKeyConst, parametersMetadata, target);
|
|
8
|
+
};
|
|
9
|
+
const inject = (serviceIdentifier, options)=>tagged({
|
|
10
|
+
...options,
|
|
11
|
+
serviceIdentifier
|
|
12
|
+
});
|
|
13
|
+
const InjectionMetadataMap = "undefined" == typeof WeakMap ? Map : WeakMap;
|
|
14
|
+
const injectionMetadataMap = new InjectionMetadataMap();
|
|
15
|
+
const injectable = ()=>(target)=>{
|
|
16
|
+
if (injectionMetadataMap.has(target)) throw new Error(`can't use "@injectable()" decorate class "${target.name}" twice`);
|
|
17
|
+
const parametersServiceIdentifiers = Reflect.getMetadata(ParamsMetadataKeyConst, target) || [];
|
|
18
|
+
const parametersMetadata = Reflect.getMetadata(InjectionMetadataKeyConst, target) || [];
|
|
19
|
+
const metadata = [];
|
|
20
|
+
const parametersMetadataLength = Math.max(parametersServiceIdentifiers.length, parametersMetadata.length);
|
|
21
|
+
for(let index = 0; index < parametersMetadataLength; index++){
|
|
22
|
+
if (void 0 !== parametersMetadata[index]) {
|
|
23
|
+
metadata.push(parametersMetadata[index]);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const serviceIdentifier = parametersServiceIdentifiers[index];
|
|
27
|
+
if ("function" != typeof serviceIdentifier) throw new Error(`only can inject class type in constructor "${target.name}" parameter #${index}`);
|
|
28
|
+
metadata.push({
|
|
29
|
+
serviceIdentifier
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
injectionMetadataMap.set(target, metadata);
|
|
33
|
+
};
|
|
34
|
+
const decoratorMiddleware = {
|
|
35
|
+
name: Symbol("DecoratorMiddleware"),
|
|
36
|
+
executor: (params, next)=>{
|
|
37
|
+
const { registration, resolveRecord } = params;
|
|
38
|
+
if (registration.type !== RegistrationTypeEnum["class"]) return next(params);
|
|
39
|
+
const provider = registration.provider;
|
|
40
|
+
const parametersMetadata = injectionMetadataMap.get(provider);
|
|
41
|
+
if (!parametersMetadata) throw new ResolveException(`The class ${provider.name} has no injection metadata, please make sure the class is decorated with @Injectable().`, resolveRecord);
|
|
42
|
+
const parameters = parametersMetadata.map((metadata, index)=>{
|
|
43
|
+
const { serviceIdentifier, ...options } = metadata;
|
|
44
|
+
resolveRecord._internalStashCurrent();
|
|
45
|
+
resolveRecord.addRecordNode({
|
|
46
|
+
type: ResolveRecordTypeEnum.message,
|
|
47
|
+
message: `Resolve parameter #${index} of constructor "${provider.name}"`
|
|
48
|
+
});
|
|
49
|
+
const instance = resolve(serviceIdentifier, options);
|
|
50
|
+
resolveRecord._internalRestoreCurrent();
|
|
51
|
+
return instance;
|
|
52
|
+
});
|
|
53
|
+
return new provider(...parameters);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
export { decoratorMiddleware, inject, injectable, tagged };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @overview
|
|
3
|
+
* @author AEPKILL
|
|
4
|
+
* @created 2025-08-06 22:51:38
|
|
5
|
+
*/
|
|
6
|
+
/** biome-ignore-all lint/suspicious/noExplicitAny: need to use any to avoid type errors */
|
|
7
|
+
import { type ResolveMiddleware } from "@husky-di/core";
|
|
8
|
+
export declare const decoratorMiddleware: ResolveMiddleware<any, any>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @overview
|
|
3
|
+
* @author AEPKILL
|
|
4
|
+
* @created 2025-08-06 21:47:22
|
|
5
|
+
*/
|
|
6
|
+
import type { Constructor } from "@husky-di/core";
|
|
7
|
+
import type { InjectionMetadata } from "../types/injection-metadata.type";
|
|
8
|
+
export declare const injectionMetadataMap: {
|
|
9
|
+
get<T>(target: Constructor<T>): InjectionMetadata<T>[];
|
|
10
|
+
has<T>(target: Constructor<T>): boolean;
|
|
11
|
+
set<T>(target: Constructor<T>, metadata: InjectionMetadata<T>[]): void;
|
|
12
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@husky-di/decorator",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"import": "./dist/index.js",
|
|
9
|
+
"require": "./dist/index.cjs"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"main": "./dist/index.cjs",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@husky-di/core": "1.0.0"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@biomejs/biome": "2.1.3",
|
|
22
|
+
"@rslib/core": "^0.11.2",
|
|
23
|
+
"@types/node": "^22.17.0",
|
|
24
|
+
"reflect-metadata": "^0.2.2",
|
|
25
|
+
"typescript": "^5.9.2",
|
|
26
|
+
"vitest": "^3.2.4"
|
|
27
|
+
},
|
|
28
|
+
"peerDependencies": {
|
|
29
|
+
"reflect-metadata": "^0.2.2"
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "rslib build",
|
|
36
|
+
"check": "biome check --write",
|
|
37
|
+
"dev": "rslib build --watch",
|
|
38
|
+
"format": "biome format --write",
|
|
39
|
+
"test": "vitest run"
|
|
40
|
+
}
|
|
41
|
+
}
|