@fluojs/mongoose 1.0.0-beta.1
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/LICENSE +21 -0
- package/README.ko.md +123 -0
- package/README.md +113 -0
- package/dist/connection.d.ts +77 -0
- package/dist/connection.d.ts.map +1 -0
- package/dist/connection.js +189 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/module.d.ts +21 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +97 -0
- package/dist/status.d.ts +18 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +70 -0
- package/dist/tokens.d.ts +7 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +6 -0
- package/dist/transaction.d.ts +25 -0
- package/dist/transaction.d.ts.map +1 -0
- package/dist/transaction.js +39 -0
- package/dist/types.d.ts +64 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +62 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 fluo contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.ko.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# @fluojs/mongoose
|
|
2
|
+
|
|
3
|
+
<p><a href="./README.md"><kbd>English</kbd></a> <strong><kbd>한국어</kbd></strong></p>
|
|
4
|
+
|
|
5
|
+
fluo 애플리케이션을 위한 Mongoose 라이프사이클 및 세션 기반 트랜잭션 컨텍스트 모듈입니다. Mongoose 연결을 모듈 시스템에 연결하여 자동 연결 관리 및 선택적 요청 범위 트랜잭션을 제공합니다.
|
|
6
|
+
|
|
7
|
+
## 목차
|
|
8
|
+
|
|
9
|
+
- [설치](#설치)
|
|
10
|
+
- [사용 시점](#사용-시점)
|
|
11
|
+
- [빠른 시작](#빠른-시작)
|
|
12
|
+
- [공통 패턴](#공통-패턴)
|
|
13
|
+
- [공개 API](#공개-api)
|
|
14
|
+
- [관련 패키지](#관련-패키지)
|
|
15
|
+
- [예제 소스](#예제-소스)
|
|
16
|
+
|
|
17
|
+
## 설치
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pnpm add @fluojs/mongoose
|
|
21
|
+
# mongoose도 함께 설치되어 있어야 합니다.
|
|
22
|
+
pnpm add mongoose
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 사용 시점
|
|
26
|
+
|
|
27
|
+
- Mongoose를 MongoDB ODM으로 사용하면서 fluo의 의존성 주입 및 라이프사이클 훅과 통합하고 싶을 때.
|
|
28
|
+
- 서비스 전반에서 MongoDB 세션과 트랜잭션을 중앙에서 관리하고 싶을 때.
|
|
29
|
+
- 애플리케이션 종료 시 자동 연결 정리(dispose)가 필요할 때.
|
|
30
|
+
|
|
31
|
+
## 빠른 시작
|
|
32
|
+
|
|
33
|
+
루트 모듈에 Mongoose 연결 인스턴스를 전달하여 `MongooseModule`을 등록합니다.
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { Module } from '@fluojs/core';
|
|
37
|
+
import { MongooseModule } from '@fluojs/mongoose';
|
|
38
|
+
import mongoose from 'mongoose';
|
|
39
|
+
|
|
40
|
+
const connection = mongoose.createConnection('mongodb://localhost:27017/test');
|
|
41
|
+
|
|
42
|
+
@Module({
|
|
43
|
+
imports: [
|
|
44
|
+
MongooseModule.forRoot({
|
|
45
|
+
connection,
|
|
46
|
+
dispose: async (conn) => await conn.close(),
|
|
47
|
+
}),
|
|
48
|
+
],
|
|
49
|
+
})
|
|
50
|
+
class AppModule {}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 공통 패턴
|
|
54
|
+
|
|
55
|
+
### `MongooseConnection`을 통한 연결 접근
|
|
56
|
+
|
|
57
|
+
`MongooseConnection` 래퍼는 기본 Mongoose 연결에 대한 접근을 제공합니다.
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { MongooseConnection } from '@fluojs/mongoose';
|
|
61
|
+
|
|
62
|
+
export class UserRepository {
|
|
63
|
+
constructor(private readonly conn: MongooseConnection) {}
|
|
64
|
+
|
|
65
|
+
async findById(id: string) {
|
|
66
|
+
const User = this.conn.current().model('User');
|
|
67
|
+
return User.findById(id);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 수동 트랜잭션과 세션
|
|
73
|
+
|
|
74
|
+
`conn.transaction()`을 사용하여 세션을 관리합니다. Prisma와 달리 Mongoose는 각 작업에 세션을 명시적으로 전달해야 합니다.
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
await this.conn.transaction(async () => {
|
|
78
|
+
const session = this.conn.currentSession();
|
|
79
|
+
const User = this.conn.current().model('User');
|
|
80
|
+
|
|
81
|
+
// 작업에 세션을 명시적으로 전달
|
|
82
|
+
await User.create([{ name: 'Ada' }], { session });
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 자동 요청 트랜잭션
|
|
87
|
+
|
|
88
|
+
컨트롤러나 메서드에 `MongooseTransactionInterceptor`를 적용하면 전체 요청을 자동으로 MongoDB 세션으로 감쌉니다.
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { UseInterceptors } from '@fluojs/http';
|
|
92
|
+
import { MongooseTransactionInterceptor } from '@fluojs/mongoose';
|
|
93
|
+
|
|
94
|
+
@UseInterceptors(MongooseTransactionInterceptor)
|
|
95
|
+
class UserController {}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 공개 API
|
|
99
|
+
|
|
100
|
+
- `MongooseModule.forRoot(options)` / `MongooseModule.forRootAsync(options)`
|
|
101
|
+
- `MongooseConnection`
|
|
102
|
+
- `MongooseTransactionInterceptor`
|
|
103
|
+
- `MONGOOSE_CONNECTION`, `MONGOOSE_DISPOSE`, `MONGOOSE_OPTIONS`
|
|
104
|
+
- `createMongooseProviders(options)`
|
|
105
|
+
- `createMongoosePlatformStatusSnapshot(...)`
|
|
106
|
+
|
|
107
|
+
### 관련 export 타입
|
|
108
|
+
|
|
109
|
+
- `MongooseModuleOptions<TConnection>`
|
|
110
|
+
- `MongooseConnectionLike`
|
|
111
|
+
- `MongooseSessionLike`
|
|
112
|
+
|
|
113
|
+
## 관련 패키지
|
|
114
|
+
|
|
115
|
+
- `@fluojs/runtime`: 애플리케이션 라이프사이클 및 종료 훅을 관리합니다.
|
|
116
|
+
- `@fluojs/http`: 인터셉터 시스템을 제공합니다.
|
|
117
|
+
- `@fluojs/prisma` / `@fluojs/drizzle`: 대안 데이터베이스 통합 모듈입니다.
|
|
118
|
+
|
|
119
|
+
## 예제 소스
|
|
120
|
+
|
|
121
|
+
- `packages/mongoose/src/vertical-slice.test.ts`: 표준 DTO → 서비스 → 리포지토리 → Mongoose 흐름 예제.
|
|
122
|
+
- `packages/mongoose/src/module.test.ts`: 모듈 등록과 수명 주기 계약 예제.
|
|
123
|
+
- `packages/mongoose/src/public-api.test.ts`: 공개 export 검증 예제.
|
package/README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# @fluojs/mongoose
|
|
2
|
+
|
|
3
|
+
<p><strong><kbd>English</kbd></strong> <a href="./README.ko.md"><kbd>한국어</kbd></a></p>
|
|
4
|
+
|
|
5
|
+
Mongoose integration for fluo with session-aware transaction handling and lifecycle-friendly connection management.
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Installation](#installation)
|
|
10
|
+
- [When to Use](#when-to-use)
|
|
11
|
+
- [Quick Start](#quick-start)
|
|
12
|
+
- [Common Patterns](#common-patterns)
|
|
13
|
+
- [Public API](#public-api)
|
|
14
|
+
- [Related Packages](#related-packages)
|
|
15
|
+
- [Example Sources](#example-sources)
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pnpm add @fluojs/mongoose
|
|
21
|
+
pnpm add mongoose
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## When to Use
|
|
25
|
+
|
|
26
|
+
- when Mongoose should plug into the same DI and application lifecycle as the rest of the app
|
|
27
|
+
- when MongoDB sessions and transactions need one shared wrapper instead of ad hoc session plumbing in every service
|
|
28
|
+
- when request-scoped transactions should be opt-in through an interceptor
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { Module } from '@fluojs/core';
|
|
34
|
+
import { MongooseModule } from '@fluojs/mongoose';
|
|
35
|
+
import mongoose from 'mongoose';
|
|
36
|
+
|
|
37
|
+
const connection = mongoose.createConnection('mongodb://localhost:27017/test');
|
|
38
|
+
|
|
39
|
+
@Module({
|
|
40
|
+
imports: [
|
|
41
|
+
MongooseModule.forRoot({
|
|
42
|
+
connection,
|
|
43
|
+
dispose: async (conn) => conn.close(),
|
|
44
|
+
}),
|
|
45
|
+
],
|
|
46
|
+
})
|
|
47
|
+
class AppModule {}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Common Patterns
|
|
51
|
+
|
|
52
|
+
### Access the connection through `MongooseConnection`
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { MongooseConnection } from '@fluojs/mongoose';
|
|
56
|
+
|
|
57
|
+
export class UserRepository {
|
|
58
|
+
constructor(private readonly conn: MongooseConnection) {}
|
|
59
|
+
|
|
60
|
+
async findById(id: string) {
|
|
61
|
+
const User = this.conn.current().model('User');
|
|
62
|
+
return User.findById(id);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Manual transactions still need explicit sessions
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
await this.conn.transaction(async () => {
|
|
71
|
+
const session = this.conn.currentSession();
|
|
72
|
+
const User = this.conn.current().model('User');
|
|
73
|
+
|
|
74
|
+
await User.create([{ name: 'Ada' }], { session });
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Request-scoped transactions
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { UseInterceptors } from '@fluojs/http';
|
|
82
|
+
import { MongooseTransactionInterceptor } from '@fluojs/mongoose';
|
|
83
|
+
|
|
84
|
+
@UseInterceptors(MongooseTransactionInterceptor)
|
|
85
|
+
class UserController {}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Public API
|
|
89
|
+
|
|
90
|
+
- `MongooseModule.forRoot(options)` / `MongooseModule.forRootAsync(options)`
|
|
91
|
+
- `MongooseConnection`
|
|
92
|
+
- `MongooseTransactionInterceptor`
|
|
93
|
+
- `MONGOOSE_CONNECTION`, `MONGOOSE_DISPOSE`, `MONGOOSE_OPTIONS`
|
|
94
|
+
- `createMongooseProviders(options)`
|
|
95
|
+
- `createMongoosePlatformStatusSnapshot(...)`
|
|
96
|
+
|
|
97
|
+
### Related exported types
|
|
98
|
+
|
|
99
|
+
- `MongooseModuleOptions<TConnection>`
|
|
100
|
+
- `MongooseConnectionLike`
|
|
101
|
+
- `MongooseSessionLike`
|
|
102
|
+
|
|
103
|
+
## Related Packages
|
|
104
|
+
|
|
105
|
+
- `@fluojs/runtime`: manages startup and shutdown hooks
|
|
106
|
+
- `@fluojs/http`: provides the interceptor chain for request transactions
|
|
107
|
+
- `@fluojs/prisma` and `@fluojs/drizzle`: alternate database integrations with different transaction models
|
|
108
|
+
|
|
109
|
+
## Example Sources
|
|
110
|
+
|
|
111
|
+
- `packages/mongoose/src/vertical-slice.test.ts`
|
|
112
|
+
- `packages/mongoose/src/module.test.ts`
|
|
113
|
+
- `packages/mongoose/src/public-api.test.ts`
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { OnApplicationShutdown } from '@fluojs/runtime';
|
|
2
|
+
import type { MongooseConnectionLike, MongooseHandleProvider, MongooseSessionLike } from './types.js';
|
|
3
|
+
type MongooseRuntimeOptions = {
|
|
4
|
+
strictTransactions: boolean;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Session-aware Mongoose wrapper that integrates request scoping and shutdown handling with the Fluo runtime.
|
|
8
|
+
*
|
|
9
|
+
* @typeParam TConnection Root Mongoose connection shape registered in the module.
|
|
10
|
+
*/
|
|
11
|
+
export declare class MongooseConnection<TConnection extends MongooseConnectionLike = MongooseConnectionLike> implements MongooseHandleProvider<TConnection>, OnApplicationShutdown {
|
|
12
|
+
private readonly connection;
|
|
13
|
+
private readonly dispose?;
|
|
14
|
+
private readonly connectionOptions;
|
|
15
|
+
private readonly sessions;
|
|
16
|
+
private readonly activeRequestTransactions;
|
|
17
|
+
private lifecycleState;
|
|
18
|
+
constructor(connection: TConnection, dispose?: ((connection: TConnection) => Promise<void> | void) | undefined, connectionOptions?: MongooseRuntimeOptions);
|
|
19
|
+
/**
|
|
20
|
+
* Returns the root Mongoose connection handle.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const User = conn.current().model('User');
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @returns The registered Mongoose connection.
|
|
28
|
+
*/
|
|
29
|
+
current(): TConnection;
|
|
30
|
+
/**
|
|
31
|
+
* Returns the active Mongoose session for the current async context, if one exists.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* const session = conn.currentSession();
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @returns The ambient session inside a transaction boundary, or `undefined` outside one.
|
|
39
|
+
*/
|
|
40
|
+
currentSession(): MongooseSessionLike | undefined;
|
|
41
|
+
/** Aborts active request transactions, waits for settlement, then runs the optional dispose hook. */
|
|
42
|
+
onApplicationShutdown(): Promise<void>;
|
|
43
|
+
/** Produces the shared persistence status snapshot for platform diagnostics surfaces. */
|
|
44
|
+
createPlatformStatusSnapshot(): import("@fluojs/runtime").PersistencePlatformStatusSnapshot;
|
|
45
|
+
/**
|
|
46
|
+
* Opens a Mongoose session transaction boundary or reuses the current one when already active.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* await conn.transaction(async () => {
|
|
51
|
+
* await User.create([{ name: 'Ada' }], { session: conn.currentSession() });
|
|
52
|
+
* });
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @param fn Callback executed within the transaction scope.
|
|
56
|
+
* @returns The callback result after the session transaction finishes or the direct-execution fallback completes.
|
|
57
|
+
*/
|
|
58
|
+
transaction<T>(fn: () => Promise<T>): Promise<T>;
|
|
59
|
+
/**
|
|
60
|
+
* Opens an abort-aware request transaction boundary for the current HTTP request.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```ts
|
|
64
|
+
* await conn.requestTransaction(async () => next.handle(), request.signal);
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* @param fn Callback executed within the request transaction scope.
|
|
68
|
+
* @param signal Optional abort signal linked to the request lifecycle.
|
|
69
|
+
* @returns The callback result after the request transaction finishes or the direct-execution fallback completes.
|
|
70
|
+
*/
|
|
71
|
+
requestTransaction<T>(fn: () => Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
72
|
+
private trackActiveRequestTransaction;
|
|
73
|
+
private untrackActiveRequestTransaction;
|
|
74
|
+
private resolveSession;
|
|
75
|
+
}
|
|
76
|
+
export {};
|
|
77
|
+
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAK7D,OAAO,KAAK,EACV,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAcpB,KAAK,sBAAsB,GAAG;IAC5B,kBAAkB,EAAE,OAAO,CAAC;CAC7B,CAAC;AAmBF;;;;GAIG;AACH,qBACa,kBAAkB,CAAC,WAAW,SAAS,sBAAsB,GAAG,sBAAsB,CACjG,YAAW,sBAAsB,CAAC,WAAW,CAAC,EAAE,qBAAqB;IAOnE,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAPpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgD;IACzE,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAuC;IACjF,OAAO,CAAC,cAAc,CAAkD;gBAGrD,UAAU,EAAE,WAAW,EACvB,OAAO,CAAC,GAAE,CAAC,UAAU,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,aAAA,EAC3D,iBAAiB,GAAE,sBAAsD;IAG5F;;;;;;;;;OASG;IACH,OAAO,IAAI,WAAW;IAItB;;;;;;;;;OASG;IACH,cAAc,IAAI,mBAAmB,GAAG,SAAS;IAIjD,qGAAqG;IAC/F,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB5C,yFAAyF;IACzF,4BAA4B;IAU5B;;;;;;;;;;;;OAYG;IACG,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAoBtD;;;;;;;;;;;OAWG;IACG,kBAAkB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAoCnF,OAAO,CAAC,6BAA6B;IAIrC,OAAO,CAAC,+BAA+B;YAIzB,cAAc;CAW7B"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
let _initClass;
|
|
2
|
+
function _applyDecs(e, t, n, r, o, i) { var a, c, u, s, f, l, p, d = Symbol.metadata || Symbol.for("Symbol.metadata"), m = Object.defineProperty, h = Object.create, y = [h(null), h(null)], v = t.length; function g(t, n, r) { return function (o, i) { n && (i = o, o = e); for (var a = 0; a < t.length; a++) i = t[a].apply(o, r ? [i] : []); return r ? i : o; }; } function b(e, t, n, r) { if ("function" != typeof e && (r || void 0 !== e)) throw new TypeError(t + " must " + (n || "be") + " a function" + (r ? "" : " or undefined")); return e; } function applyDec(e, t, n, r, o, i, u, s, f, l, p) { function d(e) { if (!p(e)) throw new TypeError("Attempted to access private element on non-instance"); } var h = [].concat(t[0]), v = t[3], w = !u, D = 1 === o, S = 3 === o, j = 4 === o, E = 2 === o; function I(t, n, r) { return function (o, i) { return n && (i = o, o = e), r && r(o), P[t].call(o, i); }; } if (!w) { var P = {}, k = [], F = S ? "get" : j || D ? "set" : "value"; if (f ? (l || D ? P = { get: _setFunctionName(function () { return v(this); }, r, "get"), set: function (e) { t[4](this, e); } } : P[F] = v, l || _setFunctionName(P[F], r, E ? "" : F)) : l || (P = Object.getOwnPropertyDescriptor(e, r)), !l && !f) { if ((c = y[+s][r]) && 7 !== (c ^ o)) throw Error("Decorating two elements with the same name (" + P[F].name + ") is not supported yet"); y[+s][r] = o < 3 ? 1 : o; } } for (var N = e, O = h.length - 1; O >= 0; O -= n ? 2 : 1) { var T = b(h[O], "A decorator", "be", !0), z = n ? h[O - 1] : void 0, A = {}, H = { kind: ["field", "accessor", "method", "getter", "setter", "class"][o], name: r, metadata: a, addInitializer: function (e, t) { if (e.v) throw new TypeError("attempted to call addInitializer after decoration was finished"); b(t, "An initializer", "be", !0), i.push(t); }.bind(null, A) }; if (w) c = T.call(z, N, H), A.v = 1, b(c, "class decorators", "return") && (N = c);else if (H.static = s, H.private = f, c = H.access = { has: f ? p.bind() : function (e) { return r in e; } }, j || (c.get = f ? E ? function (e) { return d(e), P.value; } : I("get", 0, d) : function (e) { return e[r]; }), E || S || (c.set = f ? I("set", 0, d) : function (e, t) { e[r] = t; }), N = T.call(z, D ? { get: P.get, set: P.set } : P[F], H), A.v = 1, D) { if ("object" == typeof N && N) (c = b(N.get, "accessor.get")) && (P.get = c), (c = b(N.set, "accessor.set")) && (P.set = c), (c = b(N.init, "accessor.init")) && k.unshift(c);else if (void 0 !== N) throw new TypeError("accessor decorators must return an object with get, set, or init properties or undefined"); } else b(N, (l ? "field" : "method") + " decorators", "return") && (l ? k.unshift(N) : P[F] = N); } return o < 2 && u.push(g(k, s, 1), g(i, s, 0)), l || w || (f ? D ? u.splice(-1, 0, I("get", s), I("set", s)) : u.push(E ? P[F] : b.call.bind(P[F])) : m(e, r, P)), N; } function w(e) { return m(e, d, { configurable: !0, enumerable: !0, value: a }); } return void 0 !== i && (a = i[d]), a = h(null == a ? null : a), f = [], l = function (e) { e && f.push(g(e)); }, p = function (t, r) { for (var i = 0; i < n.length; i++) { var a = n[i], c = a[1], l = 7 & c; if ((8 & c) == t && !l == r) { var p = a[2], d = !!a[3], m = 16 & c; applyDec(t ? e : e.prototype, a, m, d ? "#" + p : _toPropertyKey(p), l, l < 2 ? [] : t ? s = s || [] : u = u || [], f, !!t, d, r, t && d ? function (t) { return _checkInRHS(t) === e; } : o); } } }, p(8, 0), p(0, 0), p(8, 1), p(0, 1), l(u), l(s), c = f, v || w(e), { e: c, get c() { var n = []; return v && [w(e = applyDec(e, [t], r, e.name, 5, n)), g(n, 1)]; } }; }
|
|
3
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
4
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
5
|
+
function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); try { Object.defineProperty(e, "name", { configurable: !0, value: n ? n + " " + t : t }); } catch (e) {} return e; }
|
|
6
|
+
function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
|
|
7
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
8
|
+
import { createRequestAbortContext, raceWithAbort, trackActiveRequestTransaction, untrackActiveRequestTransaction } from '@fluojs/runtime';
|
|
9
|
+
import { Inject } from '@fluojs/core';
|
|
10
|
+
import { MONGOOSE_CONNECTION, MONGOOSE_DISPOSE, MONGOOSE_OPTIONS } from './tokens.js';
|
|
11
|
+
import { createMongoosePlatformStatusSnapshot } from './status.js';
|
|
12
|
+
const TRANSACTIONS_NOT_SUPPORTED_ERROR = 'Transaction not supported: Mongoose connection does not implement startSession.';
|
|
13
|
+
async function executeSessionTransaction(session, fn) {
|
|
14
|
+
try {
|
|
15
|
+
await session.startTransaction();
|
|
16
|
+
const result = await fn();
|
|
17
|
+
await session.commitTransaction();
|
|
18
|
+
return result;
|
|
19
|
+
} catch (error) {
|
|
20
|
+
try {
|
|
21
|
+
await session.abortTransaction();
|
|
22
|
+
} catch (abortError) {
|
|
23
|
+
void abortError;
|
|
24
|
+
}
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Session-aware Mongoose wrapper that integrates request scoping and shutdown handling with the Fluo runtime.
|
|
31
|
+
*
|
|
32
|
+
* @typeParam TConnection Root Mongoose connection shape registered in the module.
|
|
33
|
+
*/
|
|
34
|
+
let _MongooseConnection;
|
|
35
|
+
class MongooseConnection {
|
|
36
|
+
static {
|
|
37
|
+
[_MongooseConnection, _initClass] = _applyDecs(this, [Inject(MONGOOSE_CONNECTION, MONGOOSE_DISPOSE, MONGOOSE_OPTIONS)], []).c;
|
|
38
|
+
}
|
|
39
|
+
sessions = new AsyncLocalStorage();
|
|
40
|
+
activeRequestTransactions = new Set();
|
|
41
|
+
lifecycleState = 'ready';
|
|
42
|
+
constructor(connection, dispose, connectionOptions = {
|
|
43
|
+
strictTransactions: false
|
|
44
|
+
}) {
|
|
45
|
+
this.connection = connection;
|
|
46
|
+
this.dispose = dispose;
|
|
47
|
+
this.connectionOptions = connectionOptions;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Returns the root Mongoose connection handle.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* const User = conn.current().model('User');
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @returns The registered Mongoose connection.
|
|
59
|
+
*/
|
|
60
|
+
current() {
|
|
61
|
+
return this.connection;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Returns the active Mongoose session for the current async context, if one exists.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* const session = conn.currentSession();
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* @returns The ambient session inside a transaction boundary, or `undefined` outside one.
|
|
73
|
+
*/
|
|
74
|
+
currentSession() {
|
|
75
|
+
return this.sessions.getStore();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Aborts active request transactions, waits for settlement, then runs the optional dispose hook. */
|
|
79
|
+
async onApplicationShutdown() {
|
|
80
|
+
this.lifecycleState = 'shutting-down';
|
|
81
|
+
for (const transaction of this.activeRequestTransactions) {
|
|
82
|
+
transaction.abort(new Error('Application shutdown interrupted an open request transaction.'));
|
|
83
|
+
}
|
|
84
|
+
await Promise.allSettled(Array.from(this.activeRequestTransactions, transaction => transaction.settled));
|
|
85
|
+
if (this.dispose) {
|
|
86
|
+
await this.dispose(this.connection);
|
|
87
|
+
}
|
|
88
|
+
this.lifecycleState = 'stopped';
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Produces the shared persistence status snapshot for platform diagnostics surfaces. */
|
|
92
|
+
createPlatformStatusSnapshot() {
|
|
93
|
+
return createMongoosePlatformStatusSnapshot({
|
|
94
|
+
activeRequestTransactions: this.activeRequestTransactions.size,
|
|
95
|
+
hasActiveSession: this.sessions.getStore() !== undefined,
|
|
96
|
+
lifecycleState: this.lifecycleState,
|
|
97
|
+
strictTransactions: this.connectionOptions.strictTransactions,
|
|
98
|
+
supportsStartSession: typeof this.connection.startSession === 'function'
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Opens a Mongoose session transaction boundary or reuses the current one when already active.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```ts
|
|
107
|
+
* await conn.transaction(async () => {
|
|
108
|
+
* await User.create([{ name: 'Ada' }], { session: conn.currentSession() });
|
|
109
|
+
* });
|
|
110
|
+
* ```
|
|
111
|
+
*
|
|
112
|
+
* @param fn Callback executed within the transaction scope.
|
|
113
|
+
* @returns The callback result after the session transaction finishes or the direct-execution fallback completes.
|
|
114
|
+
*/
|
|
115
|
+
async transaction(fn) {
|
|
116
|
+
const currentSession = this.sessions.getStore();
|
|
117
|
+
if (currentSession) {
|
|
118
|
+
return fn();
|
|
119
|
+
}
|
|
120
|
+
const session = await this.resolveSession();
|
|
121
|
+
if (!session) {
|
|
122
|
+
return fn();
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
return await this.sessions.run(session, () => executeSessionTransaction(session, () => this.sessions.run(session, fn)));
|
|
126
|
+
} finally {
|
|
127
|
+
await session.endSession();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Opens an abort-aware request transaction boundary for the current HTTP request.
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```ts
|
|
136
|
+
* await conn.requestTransaction(async () => next.handle(), request.signal);
|
|
137
|
+
* ```
|
|
138
|
+
*
|
|
139
|
+
* @param fn Callback executed within the request transaction scope.
|
|
140
|
+
* @param signal Optional abort signal linked to the request lifecycle.
|
|
141
|
+
* @returns The callback result after the request transaction finishes or the direct-execution fallback completes.
|
|
142
|
+
*/
|
|
143
|
+
async requestTransaction(fn, signal) {
|
|
144
|
+
const currentSession = this.sessions.getStore();
|
|
145
|
+
if (currentSession) {
|
|
146
|
+
if (signal) {
|
|
147
|
+
return raceWithAbort(fn, signal);
|
|
148
|
+
}
|
|
149
|
+
return fn();
|
|
150
|
+
}
|
|
151
|
+
const abortContext = createRequestAbortContext(signal);
|
|
152
|
+
const active = this.trackActiveRequestTransaction(abortContext.controller);
|
|
153
|
+
let acquiredSession;
|
|
154
|
+
try {
|
|
155
|
+
const resolvedSession = await this.resolveSession();
|
|
156
|
+
if (!resolvedSession) {
|
|
157
|
+
return await raceWithAbort(fn, abortContext.signal);
|
|
158
|
+
}
|
|
159
|
+
acquiredSession = resolvedSession;
|
|
160
|
+
return await this.sessions.run(resolvedSession, () => executeSessionTransaction(resolvedSession, () => this.sessions.run(resolvedSession, () => raceWithAbort(fn, abortContext.signal))));
|
|
161
|
+
} finally {
|
|
162
|
+
abortContext.cleanup();
|
|
163
|
+
try {
|
|
164
|
+
await acquiredSession?.endSession();
|
|
165
|
+
} finally {
|
|
166
|
+
this.untrackActiveRequestTransaction(active);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
trackActiveRequestTransaction(controller) {
|
|
171
|
+
return trackActiveRequestTransaction(this.activeRequestTransactions, controller);
|
|
172
|
+
}
|
|
173
|
+
untrackActiveRequestTransaction(handle) {
|
|
174
|
+
untrackActiveRequestTransaction(this.activeRequestTransactions, handle);
|
|
175
|
+
}
|
|
176
|
+
async resolveSession() {
|
|
177
|
+
if (typeof this.connection.startSession !== 'function') {
|
|
178
|
+
if (this.connectionOptions.strictTransactions) {
|
|
179
|
+
throw new Error(TRANSACTIONS_NOT_SUPPORTED_ERROR);
|
|
180
|
+
}
|
|
181
|
+
return undefined;
|
|
182
|
+
}
|
|
183
|
+
return this.connection.startSession();
|
|
184
|
+
}
|
|
185
|
+
static {
|
|
186
|
+
_initClass();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
export { _MongooseConnection as MongooseConnection };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC"}
|
package/dist/index.js
ADDED
package/dist/module.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AsyncModuleOptions } from '@fluojs/core';
|
|
2
|
+
import type { Provider } from '@fluojs/di';
|
|
3
|
+
import { type ModuleType } from '@fluojs/runtime';
|
|
4
|
+
import type { MongooseConnectionLike, MongooseModuleOptions } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Creates Mongoose providers for manual module composition.
|
|
7
|
+
*
|
|
8
|
+
* @param options Mongoose module options with a connection handle, optional dispose hook, and strict transaction policy.
|
|
9
|
+
* @returns Provider definitions equivalent to `MongooseModule.forRoot(...)`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createMongooseProviders<TConnection extends MongooseConnectionLike>(options: MongooseModuleOptions<TConnection>): Provider[];
|
|
12
|
+
/**
|
|
13
|
+
* Module entrypoint for wiring a Mongoose connection into the Fluo runtime lifecycle.
|
|
14
|
+
*/
|
|
15
|
+
export declare class MongooseModule {
|
|
16
|
+
/** Creates a module definition from static Mongoose options. */
|
|
17
|
+
static forRoot<TConnection extends MongooseConnectionLike>(options: MongooseModuleOptions<TConnection>): ModuleType;
|
|
18
|
+
/** Creates a module definition from DI-aware async Mongoose options. */
|
|
19
|
+
static forRootAsync<TConnection extends MongooseConnectionLike>(options: AsyncModuleOptions<MongooseModuleOptions<TConnection>>): ModuleType;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAKhE,OAAO,KAAK,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AA4FhF;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,SAAS,sBAAsB,EAChF,OAAO,EAAE,qBAAqB,CAAC,WAAW,CAAC,GAC1C,QAAQ,EAAE,CAOZ;AAwBD;;GAEG;AACH,qBAAa,cAAc;IACzB,gEAAgE;IAChE,MAAM,CAAC,OAAO,CAAC,WAAW,SAAS,sBAAsB,EAAE,OAAO,EAAE,qBAAqB,CAAC,WAAW,CAAC,GAAG,UAAU;IAInH,wEAAwE;IACxE,MAAM,CAAC,YAAY,CAAC,WAAW,SAAS,sBAAsB,EAC5D,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC,GAC9D,UAAU;CAGd"}
|
package/dist/module.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { defineModule } from '@fluojs/runtime';
|
|
2
|
+
import { MongooseConnection } from './connection.js';
|
|
3
|
+
import { MONGOOSE_CONNECTION, MONGOOSE_DISPOSE, MONGOOSE_OPTIONS } from './tokens.js';
|
|
4
|
+
import { MongooseTransactionInterceptor } from './transaction.js';
|
|
5
|
+
const MONGOOSE_NORMALIZED_OPTIONS = Symbol('fluo.mongoose.normalized-options');
|
|
6
|
+
const MONGOOSE_MODULE_EXPORTS = [MongooseConnection, MongooseTransactionInterceptor];
|
|
7
|
+
function normalizeMongooseModuleOptions(options) {
|
|
8
|
+
return {
|
|
9
|
+
...options,
|
|
10
|
+
strictTransactions: options.strictTransactions ?? false
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function createRuntimeOptionsProviderValue(strictTransactions) {
|
|
14
|
+
return {
|
|
15
|
+
strictTransactions
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function createMongooseRuntimeProviders(normalizedOptionsProvider) {
|
|
19
|
+
return [normalizedOptionsProvider, {
|
|
20
|
+
inject: [MONGOOSE_NORMALIZED_OPTIONS],
|
|
21
|
+
provide: MONGOOSE_CONNECTION,
|
|
22
|
+
useFactory: options => options.connection
|
|
23
|
+
}, {
|
|
24
|
+
inject: [MONGOOSE_NORMALIZED_OPTIONS],
|
|
25
|
+
provide: MONGOOSE_DISPOSE,
|
|
26
|
+
useFactory: options => options.dispose
|
|
27
|
+
}, {
|
|
28
|
+
inject: [MONGOOSE_NORMALIZED_OPTIONS],
|
|
29
|
+
provide: MONGOOSE_OPTIONS,
|
|
30
|
+
useFactory: options => createRuntimeOptionsProviderValue(options.strictTransactions)
|
|
31
|
+
}, MongooseConnection, MongooseTransactionInterceptor];
|
|
32
|
+
}
|
|
33
|
+
function createMemoizedMongooseOptionsResolver(options) {
|
|
34
|
+
let cachedResult;
|
|
35
|
+
return (...deps) => {
|
|
36
|
+
if (!cachedResult) {
|
|
37
|
+
cachedResult = Promise.resolve(options.useFactory(...deps)).then(resolved => normalizeMongooseModuleOptions(resolved));
|
|
38
|
+
}
|
|
39
|
+
if (!cachedResult) {
|
|
40
|
+
throw new Error('Mongoose module options resolver initialization failed.');
|
|
41
|
+
}
|
|
42
|
+
return cachedResult;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function createMongooseProvidersAsync(options) {
|
|
46
|
+
const resolveOptions = createMemoizedMongooseOptionsResolver(options);
|
|
47
|
+
const normalizedOptionsProvider = {
|
|
48
|
+
inject: options.inject,
|
|
49
|
+
provide: MONGOOSE_NORMALIZED_OPTIONS,
|
|
50
|
+
scope: 'singleton',
|
|
51
|
+
useFactory: async (...deps) => resolveOptions(...deps)
|
|
52
|
+
};
|
|
53
|
+
return createMongooseRuntimeProviders(normalizedOptionsProvider);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Creates Mongoose providers for manual module composition.
|
|
58
|
+
*
|
|
59
|
+
* @param options Mongoose module options with a connection handle, optional dispose hook, and strict transaction policy.
|
|
60
|
+
* @returns Provider definitions equivalent to `MongooseModule.forRoot(...)`.
|
|
61
|
+
*/
|
|
62
|
+
export function createMongooseProviders(options) {
|
|
63
|
+
const resolved = normalizeMongooseModuleOptions(options);
|
|
64
|
+
return createMongooseRuntimeProviders({
|
|
65
|
+
provide: MONGOOSE_NORMALIZED_OPTIONS,
|
|
66
|
+
useValue: resolved
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function buildMongooseModule(options) {
|
|
70
|
+
class MongooseRootModuleDefinition {}
|
|
71
|
+
return defineModule(MongooseRootModuleDefinition, {
|
|
72
|
+
exports: MONGOOSE_MODULE_EXPORTS,
|
|
73
|
+
providers: createMongooseProviders(options)
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function buildMongooseModuleAsync(options) {
|
|
77
|
+
class MongooseAsyncModuleDefinition {}
|
|
78
|
+
return defineModule(MongooseAsyncModuleDefinition, {
|
|
79
|
+
exports: MONGOOSE_MODULE_EXPORTS,
|
|
80
|
+
providers: createMongooseProvidersAsync(options)
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Module entrypoint for wiring a Mongoose connection into the Fluo runtime lifecycle.
|
|
86
|
+
*/
|
|
87
|
+
export class MongooseModule {
|
|
88
|
+
/** Creates a module definition from static Mongoose options. */
|
|
89
|
+
static forRoot(options) {
|
|
90
|
+
return buildMongooseModule(options);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Creates a module definition from DI-aware async Mongoose options. */
|
|
94
|
+
static forRootAsync(options) {
|
|
95
|
+
return buildMongooseModuleAsync(options);
|
|
96
|
+
}
|
|
97
|
+
}
|
package/dist/status.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { PersistencePlatformStatusSnapshot } from '@fluojs/runtime';
|
|
2
|
+
type MongoosePlatformLifecycleState = 'ready' | 'shutting-down' | 'stopped';
|
|
3
|
+
type MongoosePlatformStatusSnapshotInput = {
|
|
4
|
+
activeRequestTransactions: number;
|
|
5
|
+
hasActiveSession: boolean;
|
|
6
|
+
lifecycleState: MongoosePlatformLifecycleState;
|
|
7
|
+
strictTransactions: boolean;
|
|
8
|
+
supportsStartSession: boolean;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Maps Mongoose lifecycle and session capability diagnostics into the shared persistence snapshot shape.
|
|
12
|
+
*
|
|
13
|
+
* @param input Current Mongoose ownership, readiness, and health inputs.
|
|
14
|
+
* @returns Platform-facing persistence status data for diagnostics surfaces.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createMongoosePlatformStatusSnapshot(input: MongoosePlatformStatusSnapshotInput): PersistencePlatformStatusSnapshot;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iCAAiC,EAGlC,MAAM,iBAAiB,CAAC;AAEzB,KAAK,8BAA8B,GAAG,OAAO,GAAG,eAAe,GAAG,SAAS,CAAC;AAE5E,KAAK,mCAAmC,GAAG;IACzC,yBAAyB,EAAE,MAAM,CAAC;IAClC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,8BAA8B,CAAC;IAC/C,kBAAkB,EAAE,OAAO,CAAC;IAC5B,oBAAoB,EAAE,OAAO,CAAC;CAC/B,CAAC;AAqDF;;;;;GAKG;AACH,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,mCAAmC,GACzC,iCAAiC,CAkBnC"}
|
package/dist/status.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
function createReadiness(input) {
|
|
2
|
+
if (input.lifecycleState === 'shutting-down') {
|
|
3
|
+
return {
|
|
4
|
+
critical: true,
|
|
5
|
+
reason: 'Mongoose integration is shutting down.',
|
|
6
|
+
status: 'not-ready'
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
if (input.lifecycleState === 'stopped') {
|
|
10
|
+
return {
|
|
11
|
+
critical: true,
|
|
12
|
+
reason: 'Mongoose integration is stopped.',
|
|
13
|
+
status: 'not-ready'
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
if (input.strictTransactions && !input.supportsStartSession) {
|
|
17
|
+
return {
|
|
18
|
+
critical: true,
|
|
19
|
+
reason: 'Mongoose strictTransactions is enabled but connection.startSession is unavailable.',
|
|
20
|
+
status: 'not-ready'
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
critical: true,
|
|
25
|
+
status: 'ready'
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function createHealth(input) {
|
|
29
|
+
if (input.lifecycleState === 'stopped') {
|
|
30
|
+
return {
|
|
31
|
+
reason: 'Mongoose integration has been disposed.',
|
|
32
|
+
status: 'unhealthy'
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (input.lifecycleState === 'shutting-down') {
|
|
36
|
+
return {
|
|
37
|
+
reason: 'Mongoose integration is draining request transactions during shutdown.',
|
|
38
|
+
status: 'degraded'
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
status: 'healthy'
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Maps Mongoose lifecycle and session capability diagnostics into the shared persistence snapshot shape.
|
|
48
|
+
*
|
|
49
|
+
* @param input Current Mongoose ownership, readiness, and health inputs.
|
|
50
|
+
* @returns Platform-facing persistence status data for diagnostics surfaces.
|
|
51
|
+
*/
|
|
52
|
+
export function createMongoosePlatformStatusSnapshot(input) {
|
|
53
|
+
return {
|
|
54
|
+
details: {
|
|
55
|
+
activeRequestTransactions: input.activeRequestTransactions,
|
|
56
|
+
hasActiveSession: input.hasActiveSession,
|
|
57
|
+
lifecycleState: input.lifecycleState,
|
|
58
|
+
sessionStrategy: input.supportsStartSession ? 'explicit-session' : 'none',
|
|
59
|
+
strictTransactions: input.strictTransactions,
|
|
60
|
+
supportsStartSession: input.supportsStartSession,
|
|
61
|
+
transactionContext: 'als'
|
|
62
|
+
},
|
|
63
|
+
health: createHealth(input),
|
|
64
|
+
ownership: {
|
|
65
|
+
externallyManaged: true,
|
|
66
|
+
ownsResources: false
|
|
67
|
+
},
|
|
68
|
+
readiness: createReadiness(input)
|
|
69
|
+
};
|
|
70
|
+
}
|
package/dist/tokens.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Dependency-injection token for the raw Mongoose connection handle. */
|
|
2
|
+
export declare const MONGOOSE_CONNECTION: unique symbol;
|
|
3
|
+
/** Dependency-injection token for the optional Mongoose shutdown dispose hook. */
|
|
4
|
+
export declare const MONGOOSE_DISPOSE: unique symbol;
|
|
5
|
+
/** Dependency-injection token for normalized Mongoose runtime options. */
|
|
6
|
+
export declare const MONGOOSE_OPTIONS: unique symbol;
|
|
7
|
+
//# sourceMappingURL=tokens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,eAAyC,CAAC;AAC1E,kFAAkF;AAClF,eAAO,MAAM,gBAAgB,eAAsC,CAAC;AACpE,0EAA0E;AAC1E,eAAO,MAAM,gBAAgB,eAAsC,CAAC"}
|
package/dist/tokens.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Dependency-injection token for the raw Mongoose connection handle. */
|
|
2
|
+
export const MONGOOSE_CONNECTION = Symbol.for('fluo.mongoose.connection');
|
|
3
|
+
/** Dependency-injection token for the optional Mongoose shutdown dispose hook. */
|
|
4
|
+
export const MONGOOSE_DISPOSE = Symbol.for('fluo.mongoose.dispose');
|
|
5
|
+
/** Dependency-injection token for normalized Mongoose runtime options. */
|
|
6
|
+
export const MONGOOSE_OPTIONS = Symbol.for('fluo.mongoose.options');
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Interceptor, InterceptorContext } from '@fluojs/http';
|
|
2
|
+
import { MongooseConnection } from './connection.js';
|
|
3
|
+
import type { MongooseConnectionLike } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* HTTP interceptor that wraps each request in a Mongoose request transaction boundary.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* Pair this with repository/service code that reads `MongooseConnection.current()` and `currentSession()` so downstream
|
|
9
|
+
* calls share the same request-scoped session.
|
|
10
|
+
*/
|
|
11
|
+
export declare class MongooseTransactionInterceptor implements Interceptor {
|
|
12
|
+
private readonly connection;
|
|
13
|
+
constructor(connection: MongooseConnection<MongooseConnectionLike>);
|
|
14
|
+
/**
|
|
15
|
+
* Runs the downstream handler inside a Mongoose request transaction boundary.
|
|
16
|
+
*
|
|
17
|
+
* @param context Interceptor context that supplies the request abort signal.
|
|
18
|
+
* @param next Downstream handler chain.
|
|
19
|
+
* @returns The downstream handler result after the request transaction settles.
|
|
20
|
+
*/
|
|
21
|
+
intercept(context: InterceptorContext, next: {
|
|
22
|
+
handle(): Promise<unknown>;
|
|
23
|
+
}): Promise<unknown>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=transaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../src/transaction.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEzD;;;;;;GAMG;AACH,qBACa,8BAA+B,YAAW,WAAW;IACpD,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,kBAAkB,CAAC,sBAAsB,CAAC;IAEnF;;;;;;OAMG;IACG,SAAS,CAAC,OAAO,EAAE,kBAAkB,EAAE,IAAI,EAAE;QAAE,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC;CAGrG"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
let _initClass;
|
|
2
|
+
function _applyDecs(e, t, n, r, o, i) { var a, c, u, s, f, l, p, d = Symbol.metadata || Symbol.for("Symbol.metadata"), m = Object.defineProperty, h = Object.create, y = [h(null), h(null)], v = t.length; function g(t, n, r) { return function (o, i) { n && (i = o, o = e); for (var a = 0; a < t.length; a++) i = t[a].apply(o, r ? [i] : []); return r ? i : o; }; } function b(e, t, n, r) { if ("function" != typeof e && (r || void 0 !== e)) throw new TypeError(t + " must " + (n || "be") + " a function" + (r ? "" : " or undefined")); return e; } function applyDec(e, t, n, r, o, i, u, s, f, l, p) { function d(e) { if (!p(e)) throw new TypeError("Attempted to access private element on non-instance"); } var h = [].concat(t[0]), v = t[3], w = !u, D = 1 === o, S = 3 === o, j = 4 === o, E = 2 === o; function I(t, n, r) { return function (o, i) { return n && (i = o, o = e), r && r(o), P[t].call(o, i); }; } if (!w) { var P = {}, k = [], F = S ? "get" : j || D ? "set" : "value"; if (f ? (l || D ? P = { get: _setFunctionName(function () { return v(this); }, r, "get"), set: function (e) { t[4](this, e); } } : P[F] = v, l || _setFunctionName(P[F], r, E ? "" : F)) : l || (P = Object.getOwnPropertyDescriptor(e, r)), !l && !f) { if ((c = y[+s][r]) && 7 !== (c ^ o)) throw Error("Decorating two elements with the same name (" + P[F].name + ") is not supported yet"); y[+s][r] = o < 3 ? 1 : o; } } for (var N = e, O = h.length - 1; O >= 0; O -= n ? 2 : 1) { var T = b(h[O], "A decorator", "be", !0), z = n ? h[O - 1] : void 0, A = {}, H = { kind: ["field", "accessor", "method", "getter", "setter", "class"][o], name: r, metadata: a, addInitializer: function (e, t) { if (e.v) throw new TypeError("attempted to call addInitializer after decoration was finished"); b(t, "An initializer", "be", !0), i.push(t); }.bind(null, A) }; if (w) c = T.call(z, N, H), A.v = 1, b(c, "class decorators", "return") && (N = c);else if (H.static = s, H.private = f, c = H.access = { has: f ? p.bind() : function (e) { return r in e; } }, j || (c.get = f ? E ? function (e) { return d(e), P.value; } : I("get", 0, d) : function (e) { return e[r]; }), E || S || (c.set = f ? I("set", 0, d) : function (e, t) { e[r] = t; }), N = T.call(z, D ? { get: P.get, set: P.set } : P[F], H), A.v = 1, D) { if ("object" == typeof N && N) (c = b(N.get, "accessor.get")) && (P.get = c), (c = b(N.set, "accessor.set")) && (P.set = c), (c = b(N.init, "accessor.init")) && k.unshift(c);else if (void 0 !== N) throw new TypeError("accessor decorators must return an object with get, set, or init properties or undefined"); } else b(N, (l ? "field" : "method") + " decorators", "return") && (l ? k.unshift(N) : P[F] = N); } return o < 2 && u.push(g(k, s, 1), g(i, s, 0)), l || w || (f ? D ? u.splice(-1, 0, I("get", s), I("set", s)) : u.push(E ? P[F] : b.call.bind(P[F])) : m(e, r, P)), N; } function w(e) { return m(e, d, { configurable: !0, enumerable: !0, value: a }); } return void 0 !== i && (a = i[d]), a = h(null == a ? null : a), f = [], l = function (e) { e && f.push(g(e)); }, p = function (t, r) { for (var i = 0; i < n.length; i++) { var a = n[i], c = a[1], l = 7 & c; if ((8 & c) == t && !l == r) { var p = a[2], d = !!a[3], m = 16 & c; applyDec(t ? e : e.prototype, a, m, d ? "#" + p : _toPropertyKey(p), l, l < 2 ? [] : t ? s = s || [] : u = u || [], f, !!t, d, r, t && d ? function (t) { return _checkInRHS(t) === e; } : o); } } }, p(8, 0), p(0, 0), p(8, 1), p(0, 1), l(u), l(s), c = f, v || w(e), { e: c, get c() { var n = []; return v && [w(e = applyDec(e, [t], r, e.name, 5, n)), g(n, 1)]; } }; }
|
|
3
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
4
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
5
|
+
function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); try { Object.defineProperty(e, "name", { configurable: !0, value: n ? n + " " + t : t }); } catch (e) {} return e; }
|
|
6
|
+
function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
|
|
7
|
+
import { Inject } from '@fluojs/core';
|
|
8
|
+
import { MongooseConnection } from './connection.js';
|
|
9
|
+
let _MongooseTransactionI;
|
|
10
|
+
/**
|
|
11
|
+
* HTTP interceptor that wraps each request in a Mongoose request transaction boundary.
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* Pair this with repository/service code that reads `MongooseConnection.current()` and `currentSession()` so downstream
|
|
15
|
+
* calls share the same request-scoped session.
|
|
16
|
+
*/
|
|
17
|
+
class MongooseTransactionInterceptor {
|
|
18
|
+
static {
|
|
19
|
+
[_MongooseTransactionI, _initClass] = _applyDecs(this, [Inject(MongooseConnection)], []).c;
|
|
20
|
+
}
|
|
21
|
+
constructor(connection) {
|
|
22
|
+
this.connection = connection;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Runs the downstream handler inside a Mongoose request transaction boundary.
|
|
27
|
+
*
|
|
28
|
+
* @param context Interceptor context that supplies the request abort signal.
|
|
29
|
+
* @param next Downstream handler chain.
|
|
30
|
+
* @returns The downstream handler result after the request transaction settles.
|
|
31
|
+
*/
|
|
32
|
+
async intercept(context, next) {
|
|
33
|
+
return this.connection.requestTransaction(async () => next.handle(), context.requestContext.request.signal);
|
|
34
|
+
}
|
|
35
|
+
static {
|
|
36
|
+
_initClass();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export { _MongooseTransactionI as MongooseTransactionInterceptor };
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { MaybePromise } from '@fluojs/core';
|
|
2
|
+
/**
|
|
3
|
+
* Minimal Mongoose connection seam that optionally supports session creation.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Fluo only requires `startSession()` to expose transaction helpers; plain connection usage still works without it.
|
|
7
|
+
*/
|
|
8
|
+
export interface MongooseConnectionLike {
|
|
9
|
+
startSession?(): Promise<MongooseSessionLike>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Session contract used by the Mongoose transaction wrapper.
|
|
13
|
+
*/
|
|
14
|
+
export interface MongooseSessionLike {
|
|
15
|
+
startTransaction(): MaybePromise<void>;
|
|
16
|
+
commitTransaction(): MaybePromise<void>;
|
|
17
|
+
abortTransaction(): MaybePromise<void>;
|
|
18
|
+
endSession(): MaybePromise<void>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Module options for registering a Mongoose connection and optional shutdown disposal hook.
|
|
22
|
+
*
|
|
23
|
+
* @typeParam TConnection Root Mongoose connection shape registered in the module.
|
|
24
|
+
*/
|
|
25
|
+
export interface MongooseModuleOptions<TConnection extends MongooseConnectionLike = MongooseConnectionLike> {
|
|
26
|
+
/** Root Mongoose connection shared outside request/session transaction scopes. */
|
|
27
|
+
connection: TConnection;
|
|
28
|
+
/** Optional shutdown hook used to close the connection or surrounding driver resources. */
|
|
29
|
+
dispose?: (connection: TConnection) => MaybePromise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Throws when transaction helpers are used against a connection that does not implement `startSession()`.
|
|
32
|
+
*
|
|
33
|
+
* @remarks
|
|
34
|
+
* Leave this disabled when `transaction()` / `requestTransaction()` should fall back to direct execution.
|
|
35
|
+
*/
|
|
36
|
+
strictTransactions?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Public Mongoose wrapper contract exposed through dependency injection.
|
|
40
|
+
*
|
|
41
|
+
* @typeParam TConnection Root Mongoose connection shape registered in the module.
|
|
42
|
+
*/
|
|
43
|
+
export interface MongooseHandleProvider<TConnection extends MongooseConnectionLike = MongooseConnectionLike> {
|
|
44
|
+
/** Returns the root Mongoose connection used for model access and session creation. */
|
|
45
|
+
current(): TConnection;
|
|
46
|
+
/** Returns the ambient Mongoose session for the current async context, when one exists. */
|
|
47
|
+
currentSession(): MongooseSessionLike | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Opens a Mongoose session transaction boundary around `fn`.
|
|
50
|
+
*
|
|
51
|
+
* @param fn Callback executed within the transaction scope.
|
|
52
|
+
* @returns The callback result after the session transaction finishes or the direct-execution fallback completes.
|
|
53
|
+
*/
|
|
54
|
+
transaction<T>(fn: () => Promise<T>): Promise<T>;
|
|
55
|
+
/**
|
|
56
|
+
* Opens an abort-aware request transaction boundary around `fn`.
|
|
57
|
+
*
|
|
58
|
+
* @param fn Callback executed within the request transaction scope.
|
|
59
|
+
* @param signal Optional abort signal linked to the request lifecycle.
|
|
60
|
+
* @returns The callback result after the request transaction finishes or the direct-execution fallback completes.
|
|
61
|
+
*/
|
|
62
|
+
requestTransaction<T>(fn: () => Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,YAAY,CAAC,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;CAC/C;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,gBAAgB,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;IACvC,iBAAiB,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;IACxC,gBAAgB,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;IACvC,UAAU,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;CAClC;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB,CAAC,WAAW,SAAS,sBAAsB,GAAG,sBAAsB;IACxG,kFAAkF;IAClF,UAAU,EAAE,WAAW,CAAC;IACxB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,WAAW,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;IAC1D;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB,CAAC,WAAW,SAAS,sBAAsB,GAAG,sBAAsB;IACzG,uFAAuF;IACvF,OAAO,IAAI,WAAW,CAAC;IACvB,2FAA2F;IAC3F,cAAc,IAAI,mBAAmB,GAAG,SAAS,CAAC;IAClD;;;;;OAKG;IACH,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACjD;;;;;;OAMG;IACH,kBAAkB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC/E"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fluojs/mongoose",
|
|
3
|
+
"description": "Mongoose integration for Fluo with session-aware transaction context and lifecycle management.",
|
|
4
|
+
"keywords": [
|
|
5
|
+
"fluo",
|
|
6
|
+
"mongoose",
|
|
7
|
+
"mongodb",
|
|
8
|
+
"database",
|
|
9
|
+
"transaction",
|
|
10
|
+
"odm"
|
|
11
|
+
],
|
|
12
|
+
"version": "1.0.0-beta.1",
|
|
13
|
+
"private": false,
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/fluojs/fluo.git",
|
|
18
|
+
"directory": "packages/mongoose"
|
|
19
|
+
},
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=20.0.0"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"type": "module",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"main": "./dist/index.js",
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"files": [
|
|
36
|
+
"dist"
|
|
37
|
+
],
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@fluojs/core": "^1.0.0-beta.1",
|
|
40
|
+
"@fluojs/di": "^1.0.0-beta.1",
|
|
41
|
+
"@fluojs/runtime": "^1.0.0-beta.1",
|
|
42
|
+
"@fluojs/http": "^1.0.0-beta.1"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"mongoose": ">=7.0.0"
|
|
46
|
+
},
|
|
47
|
+
"peerDependenciesMeta": {
|
|
48
|
+
"mongoose": {
|
|
49
|
+
"optional": true
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"vitest": "^3.2.4"
|
|
54
|
+
},
|
|
55
|
+
"scripts": {
|
|
56
|
+
"prebuild": "node ../../tooling/scripts/clean-dist.mjs",
|
|
57
|
+
"build": "pnpm exec babel src --extensions .ts --ignore 'src/**/*.test.ts' --out-dir dist --config-file ../../tooling/babel/babel.config.cjs && pnpm exec tsc -p tsconfig.build.json",
|
|
58
|
+
"typecheck": "pnpm exec tsc -p tsconfig.json --noEmit",
|
|
59
|
+
"test": "pnpm exec vitest run -c vitest.config.ts",
|
|
60
|
+
"test:watch": "pnpm exec vitest -c vitest.config.ts"
|
|
61
|
+
}
|
|
62
|
+
}
|