@atscript/db-mongo 0.1.90 → 0.1.92
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/dist/index.cjs +75 -15
- package/dist/index.mjs +75 -15
- package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -2,8 +2,55 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
const require_mongo_filter = require("./mongo-filter-AihWWQXp.cjs");
|
|
3
3
|
let _atscript_db = require("@atscript/db");
|
|
4
4
|
let mongodb = require("mongodb");
|
|
5
|
+
//#region src/lib/projection-dedupe.ts
|
|
6
|
+
function dedupeProjection(projection) {
|
|
7
|
+
const includeKeys = Object.keys(projection).filter((k) => projection[k] === 1);
|
|
8
|
+
if (includeKeys.length < 2) return projection;
|
|
9
|
+
const toRemove = /* @__PURE__ */ new Set();
|
|
10
|
+
for (const parent of includeKeys) {
|
|
11
|
+
const prefix = parent + ".";
|
|
12
|
+
for (const other of includeKeys) if (other !== parent && other.startsWith(prefix)) toRemove.add(other);
|
|
13
|
+
}
|
|
14
|
+
if (toRemove.size === 0) return projection;
|
|
15
|
+
const result = {};
|
|
16
|
+
for (const k of Object.keys(projection)) if (!toRemove.has(k)) result[k] = projection[k];
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/lib/mongo-errors.ts
|
|
21
|
+
/**
|
|
22
|
+
* Maps MongoDB projection-validation errors (31249, 31254) to `DbError("INVALID_QUERY")`
|
|
23
|
+
* so moost-db's validation interceptor returns HTTP 400 instead of an opaque 500.
|
|
24
|
+
* These codes always indicate malformed client `$select`, not a server fault.
|
|
25
|
+
*/
|
|
26
|
+
async function wrapInvalidQuery(fn) {
|
|
27
|
+
try {
|
|
28
|
+
return await fn();
|
|
29
|
+
} catch (error) {
|
|
30
|
+
if (error instanceof mongodb.MongoServerError && (error.code === 31249 || error.code === 31254)) throw new _atscript_db.DbError("INVALID_QUERY", [{
|
|
31
|
+
path: "$select",
|
|
32
|
+
message: error.message
|
|
33
|
+
}]);
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
5
38
|
//#region src/lib/collection-patcher.ts
|
|
6
39
|
/**
|
|
40
|
+
* True when a user value contains a `$`-prefixed string or object key — the
|
|
41
|
+
* shapes aggregation `$set` would evaluate as field paths / operators instead
|
|
42
|
+
* of treating as literal data. Caller must wrap such values in `{ $literal }`.
|
|
43
|
+
*/
|
|
44
|
+
function containsAggregationExpr(v) {
|
|
45
|
+
if (typeof v === "string") return v.startsWith("$");
|
|
46
|
+
if (Array.isArray(v)) return v.some(containsAggregationExpr);
|
|
47
|
+
if (v !== null && typeof v === "object") for (const k of Object.keys(v)) {
|
|
48
|
+
if (k.startsWith("$")) return true;
|
|
49
|
+
if (containsAggregationExpr(v[k])) return true;
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
7
54
|
* CollectionPatcher is a small helper that converts a *patch payload* produced
|
|
8
55
|
* by Atscript into a shape that the official MongoDB driver understands – a
|
|
9
56
|
* triple of `(filter, update, options)` to be fed to `collection.updateOne()`.
|
|
@@ -88,6 +135,7 @@ var CollectionPatcher = class {
|
|
|
88
135
|
_setLeaf(key, value) {
|
|
89
136
|
const fieldOp = (0, _atscript_db.getDbFieldOp)(value);
|
|
90
137
|
if (fieldOp) this._set(key, this._fieldOpExpr(key, fieldOp.op, fieldOp.value));
|
|
138
|
+
else if (containsAggregationExpr(value)) this._set(key, { $literal: value });
|
|
91
139
|
else this._set(key, value);
|
|
92
140
|
}
|
|
93
141
|
/**
|
|
@@ -492,7 +540,7 @@ function buildLookupInnerPipeline(withRel, requiredFields) {
|
|
|
492
540
|
for (const f of select) projection[f] = 1;
|
|
493
541
|
for (const f of requiredFields) projection[f] = 1;
|
|
494
542
|
if (!select.includes("_id") && !requiredFields.includes("_id")) projection["_id"] = 0;
|
|
495
|
-
pipeline.push({ $project: projection });
|
|
543
|
+
pipeline.push({ $project: dedupeProjection(projection) });
|
|
496
544
|
}
|
|
497
545
|
return pipeline;
|
|
498
546
|
}
|
|
@@ -663,9 +711,12 @@ async function runSearchPipeline(host, stage, query, label, threshold) {
|
|
|
663
711
|
if (controls.$skip) pipeline.push({ $skip: controls.$skip });
|
|
664
712
|
if (controls.$limit) pipeline.push({ $limit: controls.$limit });
|
|
665
713
|
else pipeline.push({ $limit: 1e3 });
|
|
666
|
-
if (controls.$select)
|
|
714
|
+
if (controls.$select) {
|
|
715
|
+
const projection = controls.$select.asProjection;
|
|
716
|
+
if (projection) pipeline.push({ $project: dedupeProjection(projection) });
|
|
717
|
+
}
|
|
667
718
|
host._log(`aggregate (${label})`, pipeline);
|
|
668
|
-
return host.collection.aggregate(pipeline, host._getSessionOpts()).toArray();
|
|
719
|
+
return wrapInvalidQuery(() => host.collection.aggregate(pipeline, host._getSessionOpts()).toArray());
|
|
669
720
|
}
|
|
670
721
|
/** Runs a search/vector pipeline with $facet for count. Shared by searchWithCount + vectorSearchWithCount. */
|
|
671
722
|
async function runSearchWithCountPipeline(host, stage, query, label, threshold) {
|
|
@@ -680,7 +731,10 @@ async function runSearchWithCountPipeline(host, stage, query, label, threshold)
|
|
|
680
731
|
if (controls.$sort) dataStages.push({ $sort: controls.$sort });
|
|
681
732
|
if (controls.$skip) dataStages.push({ $skip: controls.$skip });
|
|
682
733
|
if (controls.$limit) dataStages.push({ $limit: controls.$limit });
|
|
683
|
-
if (controls.$select)
|
|
734
|
+
if (controls.$select) {
|
|
735
|
+
const projection = controls.$select.asProjection;
|
|
736
|
+
if (projection) dataStages.push({ $project: dedupeProjection(projection) });
|
|
737
|
+
}
|
|
684
738
|
const pipeline = [
|
|
685
739
|
stage,
|
|
686
740
|
...preStages,
|
|
@@ -691,7 +745,7 @@ async function runSearchWithCountPipeline(host, stage, query, label, threshold)
|
|
|
691
745
|
} }
|
|
692
746
|
];
|
|
693
747
|
host._log(`aggregate (${label})`, pipeline);
|
|
694
|
-
const result = await host.collection.aggregate(pipeline, host._getSessionOpts()).toArray();
|
|
748
|
+
const result = await wrapInvalidQuery(() => host.collection.aggregate(pipeline, host._getSessionOpts()).toArray());
|
|
695
749
|
return {
|
|
696
750
|
data: result[0]?.data || [],
|
|
697
751
|
count: result[0]?.meta[0]?.count || 0
|
|
@@ -1252,12 +1306,12 @@ var MongoAdapter = class MongoAdapter extends _atscript_db.BaseDbAdapter {
|
|
|
1252
1306
|
if (query.controls?.$count) {
|
|
1253
1307
|
const pipeline = buildCountPipeline(query);
|
|
1254
1308
|
this._log("aggregate (count)", pipeline);
|
|
1255
|
-
const result = await this.aggregatePipeline(pipeline).toArray();
|
|
1309
|
+
const result = await wrapInvalidQuery(() => this.aggregatePipeline(pipeline).toArray());
|
|
1256
1310
|
return result.length > 0 ? result : [{ count: 0 }];
|
|
1257
1311
|
}
|
|
1258
1312
|
const pipeline = buildAggregatePipeline(query);
|
|
1259
1313
|
this._log("aggregate", pipeline);
|
|
1260
|
-
return this.aggregatePipeline(pipeline).toArray();
|
|
1314
|
+
return wrapInvalidQuery(() => this.aggregatePipeline(pipeline).toArray());
|
|
1261
1315
|
}
|
|
1262
1316
|
get idType() {
|
|
1263
1317
|
const idProp = this._table.type.type.props.get("_id");
|
|
@@ -1497,16 +1551,19 @@ var MongoAdapter = class MongoAdapter extends _atscript_db.BaseDbAdapter {
|
|
|
1497
1551
|
if (controls.$sort) dataStages.push({ $sort: controls.$sort });
|
|
1498
1552
|
if (controls.$skip) dataStages.push({ $skip: controls.$skip });
|
|
1499
1553
|
if (controls.$limit) dataStages.push({ $limit: controls.$limit });
|
|
1500
|
-
if (controls.$select)
|
|
1554
|
+
if (controls.$select) {
|
|
1555
|
+
const projection = controls.$select.asProjection;
|
|
1556
|
+
if (projection) dataStages.push({ $project: dedupeProjection(projection) });
|
|
1557
|
+
}
|
|
1501
1558
|
const pipeline = [{ $match: filter }, { $facet: {
|
|
1502
1559
|
data: dataStages,
|
|
1503
1560
|
meta: [{ $count: "count" }]
|
|
1504
1561
|
} }];
|
|
1505
1562
|
this._log("aggregate (findManyWithCount)", pipeline);
|
|
1506
|
-
const result = await this.collection.aggregate(pipeline, {
|
|
1563
|
+
const result = await wrapInvalidQuery(() => this.collection.aggregate(pipeline, {
|
|
1507
1564
|
...this._getCollationOpts(query),
|
|
1508
1565
|
...this._getSessionOpts()
|
|
1509
|
-
}).toArray();
|
|
1566
|
+
}).toArray());
|
|
1510
1567
|
return {
|
|
1511
1568
|
data: result[0]?.data || [],
|
|
1512
1569
|
count: result[0]?.meta[0]?.count || 0
|
|
@@ -1589,21 +1646,21 @@ var MongoAdapter = class MongoAdapter extends _atscript_db.BaseDbAdapter {
|
|
|
1589
1646
|
const filter = require_mongo_filter.buildMongoFilter(query.filter);
|
|
1590
1647
|
const opts = this._buildFindOptions(query.controls);
|
|
1591
1648
|
this._log("findOne", filter, opts);
|
|
1592
|
-
return this.collection.findOne(filter, {
|
|
1649
|
+
return wrapInvalidQuery(() => this.collection.findOne(filter, {
|
|
1593
1650
|
...opts,
|
|
1594
1651
|
...this._getCollationOpts(query),
|
|
1595
1652
|
...this._getSessionOpts()
|
|
1596
|
-
});
|
|
1653
|
+
}));
|
|
1597
1654
|
}
|
|
1598
1655
|
async findMany(query) {
|
|
1599
1656
|
const filter = require_mongo_filter.buildMongoFilter(query.filter);
|
|
1600
1657
|
const opts = this._buildFindOptions(query.controls);
|
|
1601
1658
|
this._log("findMany", filter, opts);
|
|
1602
|
-
return this.collection.find(filter, {
|
|
1659
|
+
return wrapInvalidQuery(() => this.collection.find(filter, {
|
|
1603
1660
|
...opts,
|
|
1604
1661
|
...this._getCollationOpts(query),
|
|
1605
1662
|
...this._getSessionOpts()
|
|
1606
|
-
}).toArray();
|
|
1663
|
+
}).toArray());
|
|
1607
1664
|
}
|
|
1608
1665
|
async count(query) {
|
|
1609
1666
|
const filter = require_mongo_filter.buildMongoFilter(query.filter);
|
|
@@ -1790,7 +1847,10 @@ var MongoAdapter = class MongoAdapter extends _atscript_db.BaseDbAdapter {
|
|
|
1790
1847
|
if (controls.$sort) opts.sort = controls.$sort;
|
|
1791
1848
|
if (controls.$limit) opts.limit = controls.$limit;
|
|
1792
1849
|
if (controls.$skip) opts.skip = controls.$skip;
|
|
1793
|
-
if (controls.$select)
|
|
1850
|
+
if (controls.$select) {
|
|
1851
|
+
const projection = controls.$select.asProjection;
|
|
1852
|
+
if (projection) opts.projection = dedupeProjection(projection);
|
|
1853
|
+
}
|
|
1794
1854
|
return opts;
|
|
1795
1855
|
}
|
|
1796
1856
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,55 @@
|
|
|
1
1
|
import { t as buildMongoFilter } from "./mongo-filter-BsocUQG3.mjs";
|
|
2
2
|
import { AtscriptDbView, BaseDbAdapter, DbError, DbSpace, computeInsights, getDbFieldOp, getKeyProps, resolveDesignType } from "@atscript/db";
|
|
3
3
|
import { MongoClient, MongoServerError, ObjectId } from "mongodb";
|
|
4
|
+
//#region src/lib/projection-dedupe.ts
|
|
5
|
+
function dedupeProjection(projection) {
|
|
6
|
+
const includeKeys = Object.keys(projection).filter((k) => projection[k] === 1);
|
|
7
|
+
if (includeKeys.length < 2) return projection;
|
|
8
|
+
const toRemove = /* @__PURE__ */ new Set();
|
|
9
|
+
for (const parent of includeKeys) {
|
|
10
|
+
const prefix = parent + ".";
|
|
11
|
+
for (const other of includeKeys) if (other !== parent && other.startsWith(prefix)) toRemove.add(other);
|
|
12
|
+
}
|
|
13
|
+
if (toRemove.size === 0) return projection;
|
|
14
|
+
const result = {};
|
|
15
|
+
for (const k of Object.keys(projection)) if (!toRemove.has(k)) result[k] = projection[k];
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/lib/mongo-errors.ts
|
|
20
|
+
/**
|
|
21
|
+
* Maps MongoDB projection-validation errors (31249, 31254) to `DbError("INVALID_QUERY")`
|
|
22
|
+
* so moost-db's validation interceptor returns HTTP 400 instead of an opaque 500.
|
|
23
|
+
* These codes always indicate malformed client `$select`, not a server fault.
|
|
24
|
+
*/
|
|
25
|
+
async function wrapInvalidQuery(fn) {
|
|
26
|
+
try {
|
|
27
|
+
return await fn();
|
|
28
|
+
} catch (error) {
|
|
29
|
+
if (error instanceof MongoServerError && (error.code === 31249 || error.code === 31254)) throw new DbError("INVALID_QUERY", [{
|
|
30
|
+
path: "$select",
|
|
31
|
+
message: error.message
|
|
32
|
+
}]);
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
4
37
|
//#region src/lib/collection-patcher.ts
|
|
5
38
|
/**
|
|
39
|
+
* True when a user value contains a `$`-prefixed string or object key — the
|
|
40
|
+
* shapes aggregation `$set` would evaluate as field paths / operators instead
|
|
41
|
+
* of treating as literal data. Caller must wrap such values in `{ $literal }`.
|
|
42
|
+
*/
|
|
43
|
+
function containsAggregationExpr(v) {
|
|
44
|
+
if (typeof v === "string") return v.startsWith("$");
|
|
45
|
+
if (Array.isArray(v)) return v.some(containsAggregationExpr);
|
|
46
|
+
if (v !== null && typeof v === "object") for (const k of Object.keys(v)) {
|
|
47
|
+
if (k.startsWith("$")) return true;
|
|
48
|
+
if (containsAggregationExpr(v[k])) return true;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
6
53
|
* CollectionPatcher is a small helper that converts a *patch payload* produced
|
|
7
54
|
* by Atscript into a shape that the official MongoDB driver understands – a
|
|
8
55
|
* triple of `(filter, update, options)` to be fed to `collection.updateOne()`.
|
|
@@ -87,6 +134,7 @@ var CollectionPatcher = class {
|
|
|
87
134
|
_setLeaf(key, value) {
|
|
88
135
|
const fieldOp = getDbFieldOp(value);
|
|
89
136
|
if (fieldOp) this._set(key, this._fieldOpExpr(key, fieldOp.op, fieldOp.value));
|
|
137
|
+
else if (containsAggregationExpr(value)) this._set(key, { $literal: value });
|
|
90
138
|
else this._set(key, value);
|
|
91
139
|
}
|
|
92
140
|
/**
|
|
@@ -491,7 +539,7 @@ function buildLookupInnerPipeline(withRel, requiredFields) {
|
|
|
491
539
|
for (const f of select) projection[f] = 1;
|
|
492
540
|
for (const f of requiredFields) projection[f] = 1;
|
|
493
541
|
if (!select.includes("_id") && !requiredFields.includes("_id")) projection["_id"] = 0;
|
|
494
|
-
pipeline.push({ $project: projection });
|
|
542
|
+
pipeline.push({ $project: dedupeProjection(projection) });
|
|
495
543
|
}
|
|
496
544
|
return pipeline;
|
|
497
545
|
}
|
|
@@ -662,9 +710,12 @@ async function runSearchPipeline(host, stage, query, label, threshold) {
|
|
|
662
710
|
if (controls.$skip) pipeline.push({ $skip: controls.$skip });
|
|
663
711
|
if (controls.$limit) pipeline.push({ $limit: controls.$limit });
|
|
664
712
|
else pipeline.push({ $limit: 1e3 });
|
|
665
|
-
if (controls.$select)
|
|
713
|
+
if (controls.$select) {
|
|
714
|
+
const projection = controls.$select.asProjection;
|
|
715
|
+
if (projection) pipeline.push({ $project: dedupeProjection(projection) });
|
|
716
|
+
}
|
|
666
717
|
host._log(`aggregate (${label})`, pipeline);
|
|
667
|
-
return host.collection.aggregate(pipeline, host._getSessionOpts()).toArray();
|
|
718
|
+
return wrapInvalidQuery(() => host.collection.aggregate(pipeline, host._getSessionOpts()).toArray());
|
|
668
719
|
}
|
|
669
720
|
/** Runs a search/vector pipeline with $facet for count. Shared by searchWithCount + vectorSearchWithCount. */
|
|
670
721
|
async function runSearchWithCountPipeline(host, stage, query, label, threshold) {
|
|
@@ -679,7 +730,10 @@ async function runSearchWithCountPipeline(host, stage, query, label, threshold)
|
|
|
679
730
|
if (controls.$sort) dataStages.push({ $sort: controls.$sort });
|
|
680
731
|
if (controls.$skip) dataStages.push({ $skip: controls.$skip });
|
|
681
732
|
if (controls.$limit) dataStages.push({ $limit: controls.$limit });
|
|
682
|
-
if (controls.$select)
|
|
733
|
+
if (controls.$select) {
|
|
734
|
+
const projection = controls.$select.asProjection;
|
|
735
|
+
if (projection) dataStages.push({ $project: dedupeProjection(projection) });
|
|
736
|
+
}
|
|
683
737
|
const pipeline = [
|
|
684
738
|
stage,
|
|
685
739
|
...preStages,
|
|
@@ -690,7 +744,7 @@ async function runSearchWithCountPipeline(host, stage, query, label, threshold)
|
|
|
690
744
|
} }
|
|
691
745
|
];
|
|
692
746
|
host._log(`aggregate (${label})`, pipeline);
|
|
693
|
-
const result = await host.collection.aggregate(pipeline, host._getSessionOpts()).toArray();
|
|
747
|
+
const result = await wrapInvalidQuery(() => host.collection.aggregate(pipeline, host._getSessionOpts()).toArray());
|
|
694
748
|
return {
|
|
695
749
|
data: result[0]?.data || [],
|
|
696
750
|
count: result[0]?.meta[0]?.count || 0
|
|
@@ -1251,12 +1305,12 @@ var MongoAdapter = class MongoAdapter extends BaseDbAdapter {
|
|
|
1251
1305
|
if (query.controls?.$count) {
|
|
1252
1306
|
const pipeline = buildCountPipeline(query);
|
|
1253
1307
|
this._log("aggregate (count)", pipeline);
|
|
1254
|
-
const result = await this.aggregatePipeline(pipeline).toArray();
|
|
1308
|
+
const result = await wrapInvalidQuery(() => this.aggregatePipeline(pipeline).toArray());
|
|
1255
1309
|
return result.length > 0 ? result : [{ count: 0 }];
|
|
1256
1310
|
}
|
|
1257
1311
|
const pipeline = buildAggregatePipeline(query);
|
|
1258
1312
|
this._log("aggregate", pipeline);
|
|
1259
|
-
return this.aggregatePipeline(pipeline).toArray();
|
|
1313
|
+
return wrapInvalidQuery(() => this.aggregatePipeline(pipeline).toArray());
|
|
1260
1314
|
}
|
|
1261
1315
|
get idType() {
|
|
1262
1316
|
const idProp = this._table.type.type.props.get("_id");
|
|
@@ -1496,16 +1550,19 @@ var MongoAdapter = class MongoAdapter extends BaseDbAdapter {
|
|
|
1496
1550
|
if (controls.$sort) dataStages.push({ $sort: controls.$sort });
|
|
1497
1551
|
if (controls.$skip) dataStages.push({ $skip: controls.$skip });
|
|
1498
1552
|
if (controls.$limit) dataStages.push({ $limit: controls.$limit });
|
|
1499
|
-
if (controls.$select)
|
|
1553
|
+
if (controls.$select) {
|
|
1554
|
+
const projection = controls.$select.asProjection;
|
|
1555
|
+
if (projection) dataStages.push({ $project: dedupeProjection(projection) });
|
|
1556
|
+
}
|
|
1500
1557
|
const pipeline = [{ $match: filter }, { $facet: {
|
|
1501
1558
|
data: dataStages,
|
|
1502
1559
|
meta: [{ $count: "count" }]
|
|
1503
1560
|
} }];
|
|
1504
1561
|
this._log("aggregate (findManyWithCount)", pipeline);
|
|
1505
|
-
const result = await this.collection.aggregate(pipeline, {
|
|
1562
|
+
const result = await wrapInvalidQuery(() => this.collection.aggregate(pipeline, {
|
|
1506
1563
|
...this._getCollationOpts(query),
|
|
1507
1564
|
...this._getSessionOpts()
|
|
1508
|
-
}).toArray();
|
|
1565
|
+
}).toArray());
|
|
1509
1566
|
return {
|
|
1510
1567
|
data: result[0]?.data || [],
|
|
1511
1568
|
count: result[0]?.meta[0]?.count || 0
|
|
@@ -1588,21 +1645,21 @@ var MongoAdapter = class MongoAdapter extends BaseDbAdapter {
|
|
|
1588
1645
|
const filter = buildMongoFilter(query.filter);
|
|
1589
1646
|
const opts = this._buildFindOptions(query.controls);
|
|
1590
1647
|
this._log("findOne", filter, opts);
|
|
1591
|
-
return this.collection.findOne(filter, {
|
|
1648
|
+
return wrapInvalidQuery(() => this.collection.findOne(filter, {
|
|
1592
1649
|
...opts,
|
|
1593
1650
|
...this._getCollationOpts(query),
|
|
1594
1651
|
...this._getSessionOpts()
|
|
1595
|
-
});
|
|
1652
|
+
}));
|
|
1596
1653
|
}
|
|
1597
1654
|
async findMany(query) {
|
|
1598
1655
|
const filter = buildMongoFilter(query.filter);
|
|
1599
1656
|
const opts = this._buildFindOptions(query.controls);
|
|
1600
1657
|
this._log("findMany", filter, opts);
|
|
1601
|
-
return this.collection.find(filter, {
|
|
1658
|
+
return wrapInvalidQuery(() => this.collection.find(filter, {
|
|
1602
1659
|
...opts,
|
|
1603
1660
|
...this._getCollationOpts(query),
|
|
1604
1661
|
...this._getSessionOpts()
|
|
1605
|
-
}).toArray();
|
|
1662
|
+
}).toArray());
|
|
1606
1663
|
}
|
|
1607
1664
|
async count(query) {
|
|
1608
1665
|
const filter = buildMongoFilter(query.filter);
|
|
@@ -1789,7 +1846,10 @@ var MongoAdapter = class MongoAdapter extends BaseDbAdapter {
|
|
|
1789
1846
|
if (controls.$sort) opts.sort = controls.$sort;
|
|
1790
1847
|
if (controls.$limit) opts.limit = controls.$limit;
|
|
1791
1848
|
if (controls.$skip) opts.skip = controls.$skip;
|
|
1792
|
-
if (controls.$select)
|
|
1849
|
+
if (controls.$select) {
|
|
1850
|
+
const projection = controls.$select.asProjection;
|
|
1851
|
+
if (projection) opts.projection = dedupeProjection(projection);
|
|
1852
|
+
}
|
|
1793
1853
|
return opts;
|
|
1794
1854
|
}
|
|
1795
1855
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atscript/db-mongo",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.92",
|
|
4
4
|
"description": "Mongodb plugin for atscript.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"atscript",
|
|
@@ -46,17 +46,17 @@
|
|
|
46
46
|
"access": "public"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@atscript/core": "^0.1.
|
|
50
|
-
"@atscript/typescript": "^0.1.
|
|
49
|
+
"@atscript/core": "^0.1.65",
|
|
50
|
+
"@atscript/typescript": "^0.1.65",
|
|
51
51
|
"mongodb": "^6.17.0",
|
|
52
52
|
"mongodb-memory-server-core": "^10.0.0",
|
|
53
|
-
"unplugin-atscript": "^0.1.
|
|
53
|
+
"unplugin-atscript": "^0.1.65"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"@atscript/core": "^0.1.
|
|
57
|
-
"@atscript/typescript": "^0.1.
|
|
56
|
+
"@atscript/core": "^0.1.65",
|
|
57
|
+
"@atscript/typescript": "^0.1.65",
|
|
58
58
|
"mongodb": "^6.17.0",
|
|
59
|
-
"@atscript/db": "^0.1.
|
|
59
|
+
"@atscript/db": "^0.1.92"
|
|
60
60
|
},
|
|
61
61
|
"scripts": {
|
|
62
62
|
"postinstall": "asc -f dts",
|