@drawbridge/mongodb 0.0.5 → 0.0.6

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.d.mts CHANGED
@@ -42,8 +42,8 @@ const formats = {
42
42
  const date = new Date();
43
43
 
44
44
  // Split `rest` into MongoDB operators ($-prefixed) and plain fields.
45
- // Plain fields are merged into $set so callers can pass `{ telemetry, $set: {...} }`
46
- // without MongoDB rejecting `telemetry` as an unknown modifier.
45
+ // Plain fields are merged into $set so callers can pass `{ field, $set: {...} }`
46
+ // without MongoDB rejecting `field` as an unknown modifier.
47
47
  const operators = {};
48
48
  const fields = {};
49
49
 
@@ -396,6 +396,72 @@ module.exports = ({
396
396
 
397
397
  }
398
398
 
399
+ // Per-document totals. Each spec counts (or $sums) related docs for a
400
+ // single page row and writes the result under `totals.<key>`. These
401
+ // stages run AFTER $skip/$limit, so the lookups touch ONLY the
402
+ // paginated page — never the full result set. Display-only by design:
403
+ // because they run post-pagination they are invisible to search/sort/
404
+ // refine (those operate on the full set, pre-pagination). Spec shapes:
405
+ // { key, from, foreignField, localField = 'id', match } -> count
406
+ // { key, from, foreignField, localField = 'id', match, sum } -> $sum field
407
+ // { key, from, localField = 'id', pipeline } -> custom
408
+ // sub-pipeline (e.g. 2-hop); receives the owner id as `$$local`
409
+ // and must yield a single doc shaped `{ value: <number> }`.
410
+ if( ( rest?.totals || [] ).length > 0 ){
411
+
412
+ const temps = [];
413
+ const additions = {};
414
+
415
+ for( const spec of rest.totals ){
416
+
417
+ const temp = '__total_' + spec.key;
418
+ const localField = spec.localField || 'id';
419
+
420
+ temps.push( temp );
421
+
422
+ const pipeline = spec.pipeline || [
423
+ {
424
+ $match : {
425
+ $expr : spec.array
426
+ ? { $in : [ '$$local', { $ifNull : [ '$' + spec.foreignField, [] ] } ] }
427
+ : { $eq : [ '$' + spec.foreignField, '$$local' ] },
428
+ ...( spec.match || {} )
429
+ }
430
+ },
431
+ spec.sum
432
+ ? { $group : { _id : null, value : { $sum : '$' + spec.sum } } }
433
+ : { $count : 'value' }
434
+ ];
435
+
436
+ dataStages.push({
437
+ $lookup : {
438
+ from : spec.from,
439
+ let : { local : '$' + localField },
440
+ pipeline,
441
+ as : temp
442
+ }
443
+ });
444
+
445
+ additions[ 'totals.' + spec.key ] = {
446
+ $ifNull : [ { $arrayElemAt : [ '$' + temp + '.value', 0 ] }, 0 ]
447
+ };
448
+
449
+ }
450
+
451
+ dataStages.push({ $addFields : additions });
452
+
453
+ dataStages.push({
454
+ $project : temps.reduce( ( accumulator, temp ) => {
455
+
456
+ accumulator[ temp ] = 0;
457
+
458
+ return accumulator;
459
+
460
+ }, {} )
461
+ });
462
+
463
+ }
464
+
399
465
  if( rest?.project ){
400
466
 
401
467
  dataStages.push({
package/dist/index.d.ts CHANGED
@@ -42,8 +42,8 @@ const formats = {
42
42
  const date = new Date();
43
43
 
44
44
  // Split `rest` into MongoDB operators ($-prefixed) and plain fields.
45
- // Plain fields are merged into $set so callers can pass `{ telemetry, $set: {...} }`
46
- // without MongoDB rejecting `telemetry` as an unknown modifier.
45
+ // Plain fields are merged into $set so callers can pass `{ field, $set: {...} }`
46
+ // without MongoDB rejecting `field` as an unknown modifier.
47
47
  const operators = {};
48
48
  const fields = {};
49
49
 
@@ -396,6 +396,72 @@ module.exports = ({
396
396
 
397
397
  }
398
398
 
399
+ // Per-document totals. Each spec counts (or $sums) related docs for a
400
+ // single page row and writes the result under `totals.<key>`. These
401
+ // stages run AFTER $skip/$limit, so the lookups touch ONLY the
402
+ // paginated page — never the full result set. Display-only by design:
403
+ // because they run post-pagination they are invisible to search/sort/
404
+ // refine (those operate on the full set, pre-pagination). Spec shapes:
405
+ // { key, from, foreignField, localField = 'id', match } -> count
406
+ // { key, from, foreignField, localField = 'id', match, sum } -> $sum field
407
+ // { key, from, localField = 'id', pipeline } -> custom
408
+ // sub-pipeline (e.g. 2-hop); receives the owner id as `$$local`
409
+ // and must yield a single doc shaped `{ value: <number> }`.
410
+ if( ( rest?.totals || [] ).length > 0 ){
411
+
412
+ const temps = [];
413
+ const additions = {};
414
+
415
+ for( const spec of rest.totals ){
416
+
417
+ const temp = '__total_' + spec.key;
418
+ const localField = spec.localField || 'id';
419
+
420
+ temps.push( temp );
421
+
422
+ const pipeline = spec.pipeline || [
423
+ {
424
+ $match : {
425
+ $expr : spec.array
426
+ ? { $in : [ '$$local', { $ifNull : [ '$' + spec.foreignField, [] ] } ] }
427
+ : { $eq : [ '$' + spec.foreignField, '$$local' ] },
428
+ ...( spec.match || {} )
429
+ }
430
+ },
431
+ spec.sum
432
+ ? { $group : { _id : null, value : { $sum : '$' + spec.sum } } }
433
+ : { $count : 'value' }
434
+ ];
435
+
436
+ dataStages.push({
437
+ $lookup : {
438
+ from : spec.from,
439
+ let : { local : '$' + localField },
440
+ pipeline,
441
+ as : temp
442
+ }
443
+ });
444
+
445
+ additions[ 'totals.' + spec.key ] = {
446
+ $ifNull : [ { $arrayElemAt : [ '$' + temp + '.value', 0 ] }, 0 ]
447
+ };
448
+
449
+ }
450
+
451
+ dataStages.push({ $addFields : additions });
452
+
453
+ dataStages.push({
454
+ $project : temps.reduce( ( accumulator, temp ) => {
455
+
456
+ accumulator[ temp ] = 0;
457
+
458
+ return accumulator;
459
+
460
+ }, {} )
461
+ });
462
+
463
+ }
464
+
399
465
  if( rest?.project ){
400
466
 
401
467
  dataStages.push({
package/dist/index.js CHANGED
@@ -274,6 +274,42 @@ module.exports = ({
274
274
  $limit: Number(limit)
275
275
  });
276
276
  }
277
+ if (((rest == null ? void 0 : rest.totals) || []).length > 0) {
278
+ const temps = [];
279
+ const additions = {};
280
+ for (const spec of rest.totals) {
281
+ const temp = "__total_" + spec.key;
282
+ const localField = spec.localField || "id";
283
+ temps.push(temp);
284
+ const pipeline = spec.pipeline || [
285
+ {
286
+ $match: {
287
+ $expr: spec.array ? { $in: ["$$local", { $ifNull: ["$" + spec.foreignField, []] }] } : { $eq: ["$" + spec.foreignField, "$$local"] },
288
+ ...spec.match || {}
289
+ }
290
+ },
291
+ spec.sum ? { $group: { _id: null, value: { $sum: "$" + spec.sum } } } : { $count: "value" }
292
+ ];
293
+ dataStages.push({
294
+ $lookup: {
295
+ from: spec.from,
296
+ let: { local: "$" + localField },
297
+ pipeline,
298
+ as: temp
299
+ }
300
+ });
301
+ additions["totals." + spec.key] = {
302
+ $ifNull: [{ $arrayElemAt: ["$" + temp + ".value", 0] }, 0]
303
+ };
304
+ }
305
+ dataStages.push({ $addFields: additions });
306
+ dataStages.push({
307
+ $project: temps.reduce((accumulator, temp) => {
308
+ accumulator[temp] = 0;
309
+ return accumulator;
310
+ }, {})
311
+ });
312
+ }
277
313
  if (rest == null ? void 0 : rest.project) {
278
314
  dataStages.push({
279
315
  $project: rest == null ? void 0 : rest.project
package/dist/index.mjs CHANGED
@@ -287,6 +287,42 @@ var require_index = __commonJS({
287
287
  $limit: Number(limit)
288
288
  });
289
289
  }
290
+ if (((rest == null ? void 0 : rest.totals) || []).length > 0) {
291
+ const temps = [];
292
+ const additions = {};
293
+ for (const spec of rest.totals) {
294
+ const temp = "__total_" + spec.key;
295
+ const localField = spec.localField || "id";
296
+ temps.push(temp);
297
+ const pipeline = spec.pipeline || [
298
+ {
299
+ $match: {
300
+ $expr: spec.array ? { $in: ["$$local", { $ifNull: ["$" + spec.foreignField, []] }] } : { $eq: ["$" + spec.foreignField, "$$local"] },
301
+ ...spec.match || {}
302
+ }
303
+ },
304
+ spec.sum ? { $group: { _id: null, value: { $sum: "$" + spec.sum } } } : { $count: "value" }
305
+ ];
306
+ dataStages.push({
307
+ $lookup: {
308
+ from: spec.from,
309
+ let: { local: "$" + localField },
310
+ pipeline,
311
+ as: temp
312
+ }
313
+ });
314
+ additions["totals." + spec.key] = {
315
+ $ifNull: [{ $arrayElemAt: ["$" + temp + ".value", 0] }, 0]
316
+ };
317
+ }
318
+ dataStages.push({ $addFields: additions });
319
+ dataStages.push({
320
+ $project: temps.reduce((accumulator, temp) => {
321
+ accumulator[temp] = 0;
322
+ return accumulator;
323
+ }, {})
324
+ });
325
+ }
290
326
  if (rest == null ? void 0 : rest.project) {
291
327
  dataStages.push({
292
328
  $project: rest == null ? void 0 : rest.project
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drawbridge/mongodb",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "exports": {
@@ -23,14 +23,11 @@
23
23
  "build": "tsup ./index.js && npm publish"
24
24
  },
25
25
  "dependencies": {
26
- "@drawbridge/drawbridge-agents": "0.0.6",
26
+ "@drawbridge/drawbridge-agents": "0.0.10",
27
27
  "mongodb": "5.9.2"
28
28
  },
29
29
  "devDependencies": {
30
30
  "tsup": "8.5.1",
31
31
  "typescript": "5.9.3"
32
- },
33
- "overrides": {
34
- "ip-address": "10.2.0"
35
32
  }
36
33
  }