monsqlize 1.2.3 → 1.3.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/CHANGELOG.md +2 -1
- package/lib/index.js +134 -0
- package/package.json +1 -1
- package/types/base.ts +4 -0
- package/types/monsqlize.ts +63 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# 变更日志 (CHANGELOG)
|
|
2
2
|
|
|
3
3
|
> **说明**: 版本概览摘要,详细变更见 [changelogs/](./changelogs/) 目录
|
|
4
|
-
> **最后更新**: 2026-04-
|
|
4
|
+
> **最后更新**: 2026-04-27
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
| 版本 | 日期 | 变更摘要 | 详细 |
|
|
11
11
|
|------|------|---------|------|
|
|
12
|
+
| [v1.3.0](./changelogs/v1.3.0.md) | 2026-04-27 | 🆕 **新功能**:链式池访问 API — `pool(name)` / `use(dbName)` / `scopedCollection()` / `scopedModel()` 四个公开方法,支持多连接池多数据库路由,connection 合并语义,TypeScript 类型签名完整覆盖 | [查看](./changelogs/v1.3.0.md) |
|
|
12
13
|
| [v1.2.3](./changelogs/v1.2.3.md) | 2026-04-26 | 🐛 **Bug Fix**:`model()` 方法修复注册 key 直接作为 MongoDB 集合名的问题,优先读 `definition.collection > definition.name`,注册 key 仅作 fallback,向后兼容 | [查看](./changelogs/v1.2.3.md) |
|
|
13
14
|
| [v1.2.2](./changelogs/v1.2.2.md) | 2026-04-24 | 🆕 **新功能**:Model 数据源绑定 — `connection: { pool?, database? }` 支持 Model 绑定指定连接池和/或数据库,四种组合路由,向后兼容;🐛 **Bug Fix**:修复 `Model._clear()` 导致 `msq.model()` 实例缓存失效失效,populate 关系丢失问题 | [查看](./changelogs/v1.2.2.md) |
|
|
14
15
|
| [v1.2.1](./changelogs/v1.2.1.md) | 2026-04-13 | 🐛 **Bug 修复**:`msq.model()` 实例缓存 + 索引去重 + 死代码清理 + `types/monsqlize.ts` 补全 `model()` / `collection()` 类型 | [查看](./changelogs/v1.2.1.md) |
|
package/lib/index.js
CHANGED
|
@@ -830,6 +830,140 @@ module.exports = class {
|
|
|
830
830
|
return this.dbInstance.collection(collectionName);
|
|
831
831
|
}
|
|
832
832
|
|
|
833
|
+
// ============================================================
|
|
834
|
+
// v1.3.0 — scoped access APIs
|
|
835
|
+
// ============================================================
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* 获取限定池/库的 collection(公开底层方法)
|
|
839
|
+
*
|
|
840
|
+
* opts.pool / opts.database 均为可选;均不填时退化为默认路由。
|
|
841
|
+
*
|
|
842
|
+
* @param {string} collectionName
|
|
843
|
+
* @param {{ pool?: string, database?: string }} [opts={}]
|
|
844
|
+
* @returns {Object} Collection 实例
|
|
845
|
+
* @throws {Error} NOT_CONNECTED / NO_POOL_MANAGER / POOL_NOT_FOUND
|
|
846
|
+
* @since v1.3.0
|
|
847
|
+
*/
|
|
848
|
+
scopedCollection(collectionName, opts = {}) {
|
|
849
|
+
if (!this.dbInstance) {
|
|
850
|
+
const err = new Error('Database is not connected. Call connect() first.');
|
|
851
|
+
err.code = 'NOT_CONNECTED';
|
|
852
|
+
throw err;
|
|
853
|
+
}
|
|
854
|
+
const { pool, database } = opts;
|
|
855
|
+
if (!pool && !database) {
|
|
856
|
+
return this.collection(collectionName);
|
|
857
|
+
}
|
|
858
|
+
return this._resolveModelCollection(collectionName, { pool, database });
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
/**
|
|
862
|
+
* 获取限定池/库的 Model 实例(公开底层方法,不走 _modelInstances 缓存)
|
|
863
|
+
*
|
|
864
|
+
* connection 合并语义:opts 字段优先,definition.connection 作 fallback。
|
|
865
|
+
* 例:billing/invoice.ts 有 connection:{database:'billing'},
|
|
866
|
+
* 调用 scopedModel('BillingInvoice', { pool:'cn' }) →
|
|
867
|
+
* merged = { database:'billing', pool:'cn' },路由到 cn 池 billing 库。
|
|
868
|
+
*
|
|
869
|
+
* @param {string} key - 已注册的 Model key(或 alias)
|
|
870
|
+
* @param {{ pool?: string, database?: string }} [opts={}]
|
|
871
|
+
* @returns {ModelInstance}
|
|
872
|
+
* @throws {Error} NOT_CONNECTED / MODEL_NOT_DEFINED / NO_POOL_MANAGER / POOL_NOT_FOUND
|
|
873
|
+
* @since v1.3.0
|
|
874
|
+
*/
|
|
875
|
+
scopedModel(key, opts = {}) {
|
|
876
|
+
if (!this.dbInstance) {
|
|
877
|
+
const err = new Error('Database is not connected. Call connect() first.');
|
|
878
|
+
err.code = 'NOT_CONNECTED';
|
|
879
|
+
throw err;
|
|
880
|
+
}
|
|
881
|
+
const Model = require('./model');
|
|
882
|
+
if (!Model.has(key)) {
|
|
883
|
+
const err = new Error(`Model '${key}' is not defined. Call Model.define() first.`);
|
|
884
|
+
err.code = 'MODEL_NOT_DEFINED';
|
|
885
|
+
throw err;
|
|
886
|
+
}
|
|
887
|
+
const modelDef = Model.get(key);
|
|
888
|
+
const actualCollectionName =
|
|
889
|
+
modelDef.definition.collection ||
|
|
890
|
+
modelDef.definition.name ||
|
|
891
|
+
key;
|
|
892
|
+
const merged = { ...(modelDef.definition.connection || {}), ...opts };
|
|
893
|
+
const { pool, database } = merged;
|
|
894
|
+
const collection = (pool || database)
|
|
895
|
+
? this._resolveModelCollection(actualCollectionName, { pool, database })
|
|
896
|
+
: this.dbInstance.collection(actualCollectionName);
|
|
897
|
+
return new Model.ModelInstance(collection, modelDef.definition, this);
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
/**
|
|
901
|
+
* 获取指定连接池的链式访问器
|
|
902
|
+
*
|
|
903
|
+
* 前置校验(立即执行):NOT_CONNECTED / NO_POOL_MANAGER / POOL_NOT_FOUND。
|
|
904
|
+
*
|
|
905
|
+
* @param {string} poolName - 连接池名称
|
|
906
|
+
* @returns {{ collection, model, use }} PoolAccessor 纯对象
|
|
907
|
+
* @throws {Error} NOT_CONNECTED / NO_POOL_MANAGER / POOL_NOT_FOUND
|
|
908
|
+
* @since v1.3.0
|
|
909
|
+
*/
|
|
910
|
+
pool(poolName) {
|
|
911
|
+
if (!this.dbInstance) {
|
|
912
|
+
const err = new Error('Database is not connected. Call connect() first.');
|
|
913
|
+
err.code = 'NOT_CONNECTED';
|
|
914
|
+
throw err;
|
|
915
|
+
}
|
|
916
|
+
if (!this._poolManager) {
|
|
917
|
+
const err = new Error('No pool manager configured. Add pools to MonSQLize constructor options.');
|
|
918
|
+
err.code = 'NO_POOL_MANAGER';
|
|
919
|
+
throw err;
|
|
920
|
+
}
|
|
921
|
+
if (!this._poolManager._getPool(poolName)) {
|
|
922
|
+
const available = this._poolManager.getPoolNames?.() ?? [];
|
|
923
|
+
const err = new Error(`Pool '${poolName}' not found. Available pools: [${available.join(', ')}]`);
|
|
924
|
+
err.code = 'POOL_NOT_FOUND';
|
|
925
|
+
err.available = available;
|
|
926
|
+
throw err;
|
|
927
|
+
}
|
|
928
|
+
return {
|
|
929
|
+
collection: (name) =>
|
|
930
|
+
this.scopedCollection(name, { pool: poolName }),
|
|
931
|
+
model: (key) =>
|
|
932
|
+
this.scopedModel(key, { pool: poolName }),
|
|
933
|
+
use: (dbName) => ({
|
|
934
|
+
collection: (name) =>
|
|
935
|
+
this.scopedCollection(name, { pool: poolName, database: dbName }),
|
|
936
|
+
model: (key) =>
|
|
937
|
+
this.scopedModel(key, { pool: poolName, database: dbName }),
|
|
938
|
+
}),
|
|
939
|
+
};
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
/**
|
|
943
|
+
* 获取「默认池 + 指定库」访问器
|
|
944
|
+
*
|
|
945
|
+
* 适用于单连接多库场景(无需配置多连接池)。
|
|
946
|
+
* 只校验 NOT_CONNECTED,不涉及 poolManager。
|
|
947
|
+
*
|
|
948
|
+
* @param {string} dbName - 数据库名称
|
|
949
|
+
* @returns {{ collection, model }} ScopedAccessor 纯对象
|
|
950
|
+
* @throws {Error} NOT_CONNECTED
|
|
951
|
+
* @since v1.3.0
|
|
952
|
+
*/
|
|
953
|
+
use(dbName) {
|
|
954
|
+
if (!this.dbInstance) {
|
|
955
|
+
const err = new Error('Database is not connected. Call connect() first.');
|
|
956
|
+
err.code = 'NOT_CONNECTED';
|
|
957
|
+
throw err;
|
|
958
|
+
}
|
|
959
|
+
return {
|
|
960
|
+
collection: (name) =>
|
|
961
|
+
this.scopedCollection(name, { database: dbName }),
|
|
962
|
+
model: (key) =>
|
|
963
|
+
this.scopedModel(key, { database: dbName }),
|
|
964
|
+
};
|
|
965
|
+
}
|
|
966
|
+
|
|
833
967
|
/**
|
|
834
968
|
* 自动加载 Model 文件
|
|
835
969
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monsqlize",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "A lightweight MongoDB ORM with multi-level caching, transaction support, distributed features, Saga distributed transactions, unified expression system with 122 operators, and universal function caching (100% MongoDB support)",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "index.mjs",
|
package/types/base.ts
CHANGED
|
@@ -68,6 +68,10 @@ export const enum ErrorCodes {
|
|
|
68
68
|
JUMP_TOO_FAR = 'JUMP_TOO_FAR',
|
|
69
69
|
STREAM_NO_JUMP = 'STREAM_NO_JUMP',
|
|
70
70
|
STREAM_NO_TOTALS = 'STREAM_NO_TOTALS',
|
|
71
|
+
NOT_CONNECTED = 'NOT_CONNECTED',
|
|
72
|
+
NO_POOL_MANAGER = 'NO_POOL_MANAGER',
|
|
73
|
+
POOL_NOT_FOUND = 'POOL_NOT_FOUND',
|
|
74
|
+
MODEL_NOT_DEFINED = 'MODEL_NOT_DEFINED',
|
|
71
75
|
CONNECTION_TIMEOUT = 'CONNECTION_TIMEOUT',
|
|
72
76
|
CONNECTION_FAILED = 'CONNECTION_FAILED',
|
|
73
77
|
CONNECTION_CLOSED = 'CONNECTION_CLOSED',
|
package/types/monsqlize.ts
CHANGED
|
@@ -70,6 +70,69 @@ export interface MonSQLize {
|
|
|
70
70
|
*/
|
|
71
71
|
collection(collectionName: string): Collection;
|
|
72
72
|
|
|
73
|
+
/**
|
|
74
|
+
* 获取限定池/库的 collection(公开底层方法)
|
|
75
|
+
*
|
|
76
|
+
* opts.pool / opts.database 均为可选;均不填时退化为默认路由。
|
|
77
|
+
*
|
|
78
|
+
* @param collectionName - MongoDB 集合名
|
|
79
|
+
* @param opts.pool - 连接池名称(可选)
|
|
80
|
+
* @param opts.database - 数据库名称(可选)
|
|
81
|
+
* @throws NOT_CONNECTED / NO_POOL_MANAGER / POOL_NOT_FOUND
|
|
82
|
+
* @since 1.3.0
|
|
83
|
+
*/
|
|
84
|
+
scopedCollection(
|
|
85
|
+
collectionName: string,
|
|
86
|
+
opts?: { pool?: string; database?: string }
|
|
87
|
+
): ReturnType<MonSQLize['collection']>;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* 获取限定池/库的 Model 实例(不走 _modelInstances 缓存)
|
|
91
|
+
*
|
|
92
|
+
* connection 合并语义:opts 字段优先,definition.connection 作 fallback。
|
|
93
|
+
*
|
|
94
|
+
* @param key - 已注册的 Model key(或 alias)
|
|
95
|
+
* @param opts - 路由选项,字段优先于 definition.connection
|
|
96
|
+
* @throws NOT_CONNECTED / MODEL_NOT_DEFINED / NO_POOL_MANAGER / POOL_NOT_FOUND
|
|
97
|
+
* @since 1.3.0
|
|
98
|
+
*/
|
|
99
|
+
scopedModel(
|
|
100
|
+
key: string,
|
|
101
|
+
opts?: { pool?: string; database?: string }
|
|
102
|
+
): ReturnType<MonSQLize['model']>;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* 获取指定连接池的链式访问器
|
|
106
|
+
*
|
|
107
|
+
* 立即校验:NOT_CONNECTED / NO_POOL_MANAGER / POOL_NOT_FOUND。
|
|
108
|
+
*
|
|
109
|
+
* @param poolName - 连接池名称
|
|
110
|
+
* @throws NOT_CONNECTED / NO_POOL_MANAGER / POOL_NOT_FOUND
|
|
111
|
+
* @since 1.3.0
|
|
112
|
+
*/
|
|
113
|
+
pool(poolName: string): {
|
|
114
|
+
collection: (name: string) => ReturnType<MonSQLize['collection']>;
|
|
115
|
+
model: (key: string) => ReturnType<MonSQLize['model']>;
|
|
116
|
+
use: (dbName: string) => {
|
|
117
|
+
collection: (name: string) => ReturnType<MonSQLize['collection']>;
|
|
118
|
+
model: (key: string) => ReturnType<MonSQLize['model']>;
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* 获取「默认池 + 指定库」访问器
|
|
124
|
+
*
|
|
125
|
+
* 适用于单连接多库场景(无需配置多连接池)。
|
|
126
|
+
*
|
|
127
|
+
* @param dbName - 数据库名称
|
|
128
|
+
* @throws NOT_CONNECTED
|
|
129
|
+
* @since 1.3.0
|
|
130
|
+
*/
|
|
131
|
+
use(dbName: string): {
|
|
132
|
+
collection: (name: string) => ReturnType<MonSQLize['collection']>;
|
|
133
|
+
model: (key: string) => ReturnType<MonSQLize['model']>;
|
|
134
|
+
};
|
|
135
|
+
|
|
73
136
|
|
|
74
137
|
// ============================================================================
|
|
75
138
|
// 事件系统
|