@r5v/mongoose-paginate 1.0.14 → 1.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -139,7 +139,7 @@ GET /api/books?$lean=true
139
139
  | staticPostFilter | Mongo Filter Object | create a filter on the pipeline that is added after all the pipeline stages. this cannot be overwritten by params | AggregationPagingQuery | | {} |
140
140
  | staticFilter | Mongo Filter Object | create a filter on the pipeline that is added before all the pipeline stages. on find requests, this is added to the filter object. this cannot be overwritten by params | AggregationPagingQuery | | {} |
141
141
  | pipeline | MongoPipelineStage[] | pipeline request object. if the first item in pipeline stage is a $match or another required first stage operator. it will be placed before all other modifiers | AggregationPagingQuery | true | [] |
142
- | removeProtected \(REMOVED\) | boolean | auto remove protected (select: false) for root Model | AggregationPagingQuery | | false |
142
+ | removeProtected | boolean | **EXPERIMENTAL** - auto remove protected fields (those with `select: false` in schema) from aggregation results. Use with caution and test thoroughly in your environment | AggregationPagingQuery | | false |
143
143
 
144
144
  ## Utilities
145
145
 
@@ -307,8 +307,9 @@ $ yarn run start
307
307
  9. Apply pagination (`$skip`, `$limit`) and options
308
308
 
309
309
 
310
- ## NOTES
311
- 1. removeProtected removed from aggregation query due to inconsistent results after publication
310
+ ### 1.0.15
311
+ - **Re-enabled `removeProtected` option** for `AggregationPagingQuery` (EXPERIMENTAL) - Automatically excludes fields marked with `select: false` in your schema (e.g., passwords, secret keys) from aggregation results. Use with caution and test thoroughly in your environment.
312
+ - Uses refactored `findProtectedPaths` utility which safely traverses schemas without JSON serialization
312
313
 
313
314
  ### 1.0.14
314
315
  - Added proper TypeScript package exports with subpaths (`/utils`, `/types`)
@@ -1 +1 @@
1
- {"version":3,"file":"aggregationPagingQuery.d.ts","sourceRoot":"","sources":["../src/aggregationPagingQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,EACL,SAAS,EAKZ,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAC,qBAAqB,EAAE,iCAAiC,EAAE,WAAW,EAAC,MAAM,SAAS,CAAA;AAQlG,qBAAa,sBAAsB;IAC/B,MAAM,EAAG,iCAAiC,CAYzC;IACD,OAAO,EAAE,qBAAqB,CAK7B;IACD,KAAK,EAAE,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,SAAS,CAAA;IACvC,cAAc,EAAE,MAAM,EAAE,CAAK;IAC7B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;gBACL,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,qBAAqB;IAiB/E,kBAAkB,kCAAqB;IACvC,WAAW,sPAAc;IACzB,iBAAiB,6BAAoB;IACrC,YAAY,2BAAe;IAC3B,eAAe,mEAAkB;IACjC,wBAAwB;;MAA2B;IACnD,YAAY,aAOX;IACD,SAAS,sBAkDR;IACD,cAAc,GAAI,CAAC,EAAE,UAAU,CAAC,KAAG,CAAC,CAmCnC;IAED,OAAO,CAAC,qBAAqB,CAS5B;IACD,IAAI,yBAgCH;CAEJ"}
1
+ {"version":3,"file":"aggregationPagingQuery.d.ts","sourceRoot":"","sources":["../src/aggregationPagingQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,EACL,SAAS,EAKZ,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAC,qBAAqB,EAAE,iCAAiC,EAAE,WAAW,EAAC,MAAM,SAAS,CAAA;AAQlG,qBAAa,sBAAsB;IAC/B,MAAM,EAAG,iCAAiC,CAYzC;IACD,OAAO,EAAE,qBAAqB,CAM7B;IACD,KAAK,EAAE,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,SAAS,CAAA;IACvC,cAAc,EAAE,MAAM,EAAE,CAAK;IAC7B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;gBACL,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,qBAAqB;IAoB/E,kBAAkB,kCAAqB;IACvC,WAAW,sPAAc;IACzB,iBAAiB,6BAAoB;IACrC,YAAY,2BAAe;IAC3B,eAAe,mEAAkB;IACjC,wBAAwB;;MAA2B;IACnD,YAAY,aAOX;IACD,SAAS,sBAsDR;IACD,cAAc,GAAI,CAAC,EAAE,UAAU,CAAC,KAAG,CAAC,CAmCnC;IAED,OAAO,CAAC,qBAAqB,CAS5B;IACD,IAAI,yBAgCH;CAEJ"}
@@ -45,6 +45,7 @@ class AggregationPagingQuery {
45
45
  enableFilter: false,
46
46
  enablePostFilter: false,
47
47
  enablePreSort: true,
48
+ removeProtected: false,
48
49
  pipeline: []
49
50
  };
50
51
  this.protectedPaths = [];
@@ -65,7 +66,7 @@ class AggregationPagingQuery {
65
66
  };
66
67
  this.initQuery = () => __awaiter(this, void 0, void 0, function* () {
67
68
  const { $filter, $sort, $preSort, $select, $count, $postFilter } = this.params;
68
- const _a = this.options, { enableFilter, enablePreSort, enablePostFilter, staticFilter, staticPostFilter, pipeline } = _a, options = __rest(_a, ["enableFilter", "enablePreSort", "enablePostFilter", "staticFilter", "staticPostFilter", "pipeline"]);
69
+ const _a = this.options, { enableFilter, enablePreSort, enablePostFilter, staticFilter, staticPostFilter, removeProtected, pipeline } = _a, options = __rest(_a, ["enableFilter", "enablePreSort", "enablePostFilter", "staticFilter", "staticPostFilter", "removeProtected", "pipeline"]);
69
70
  this.query = this.model.aggregate();
70
71
  const [p1, ...pipes] = pipeline;
71
72
  const filterObj = { $and: [Object.assign({}, staticFilter)] };
@@ -100,6 +101,9 @@ class AggregationPagingQuery {
100
101
  if ($select) {
101
102
  this.query.project($select);
102
103
  }
104
+ if (removeProtected) {
105
+ this.removeProtectedFields();
106
+ }
103
107
  if ($count.length) {
104
108
  this.createCounts();
105
109
  }
@@ -191,6 +195,9 @@ class AggregationPagingQuery {
191
195
  this.options = Object.assign(Object.assign({}, this.options), options);
192
196
  this.model = model;
193
197
  this.params = this.parseParams(this.params, req.query, true);
198
+ if (this.options.removeProtected) {
199
+ this.protectedPaths = this.findProtectedPaths(model);
200
+ }
194
201
  this.initQuery();
195
202
  }
196
203
  }
@@ -56,6 +56,18 @@ const AggTestSchema = new mongoose_1.Schema({
56
56
  category: { type: mongoose_1.Schema.Types.ObjectId, ref: 'Category' }
57
57
  });
58
58
  const AggTestModel = mongoose_1.default.model('AggTestModel', AggTestSchema);
59
+ // Create a test schema with protected fields
60
+ const ProtectedSchema = new mongoose_1.Schema({
61
+ username: { type: String, required: true },
62
+ email: { type: String },
63
+ password: { type: String, select: false },
64
+ secretKey: { type: String, select: false },
65
+ profile: {
66
+ name: { type: String },
67
+ ssn: { type: String, select: false }
68
+ }
69
+ });
70
+ const ProtectedModel = mongoose_1.default.model('ProtectedModel', ProtectedSchema);
59
71
  // Default pipeline with at least one stage to avoid undefined error
60
72
  const defaultPipeline = [{ $match: {} }];
61
73
  describe('AggregationPagingQuery', () => {
@@ -362,4 +374,46 @@ describe('AggregationPagingQuery', () => {
362
374
  }).toThrow('Invalid JSON in $postFilter parameter');
363
375
  });
364
376
  });
377
+ describe('removeProtected', () => {
378
+ test('should find protected paths when removeProtected is enabled', () => {
379
+ const req = (0, node_mocks_http_1.createRequest)({ query: {} });
380
+ const apq = new aggregationPagingQuery_1.AggregationPagingQuery(req, ProtectedModel, {
381
+ pipeline: defaultPipeline,
382
+ removeProtected: true
383
+ });
384
+ expect(apq.protectedPaths).toContain('password');
385
+ expect(apq.protectedPaths).toContain('secretKey');
386
+ });
387
+ test('should not find protected paths when removeProtected is disabled', () => {
388
+ const req = (0, node_mocks_http_1.createRequest)({ query: {} });
389
+ const apq = new aggregationPagingQuery_1.AggregationPagingQuery(req, ProtectedModel, {
390
+ pipeline: defaultPipeline,
391
+ removeProtected: false
392
+ });
393
+ expect(apq.protectedPaths).toEqual([]);
394
+ });
395
+ test('should not find protected paths by default', () => {
396
+ const req = (0, node_mocks_http_1.createRequest)({ query: {} });
397
+ const apq = new aggregationPagingQuery_1.AggregationPagingQuery(req, ProtectedModel, {
398
+ pipeline: defaultPipeline
399
+ });
400
+ expect(apq.protectedPaths).toEqual([]);
401
+ });
402
+ test('should set removeProtected option correctly', () => {
403
+ const req = (0, node_mocks_http_1.createRequest)({ query: {} });
404
+ const apq = new aggregationPagingQuery_1.AggregationPagingQuery(req, ProtectedModel, {
405
+ pipeline: defaultPipeline,
406
+ removeProtected: true
407
+ });
408
+ expect(apq.options.removeProtected).toBe(true);
409
+ });
410
+ test('should have empty protected paths for model without protected fields', () => {
411
+ const req = (0, node_mocks_http_1.createRequest)({ query: {} });
412
+ const apq = new aggregationPagingQuery_1.AggregationPagingQuery(req, AggTestModel, {
413
+ pipeline: defaultPipeline,
414
+ removeProtected: true
415
+ });
416
+ expect(apq.protectedPaths).toEqual([]);
417
+ });
418
+ });
365
419
  });
@@ -59,9 +59,15 @@ export interface AggregateQueryOptions extends Omit<AggregateOptions, 'comment'>
59
59
  disablePaging?: boolean;
60
60
  disablePostFilter?: boolean;
61
61
  disablePreSort?: boolean;
62
+ enablePostFilter?: boolean;
63
+ enablePreSort?: boolean;
64
+ staticFilter?: {
65
+ [key: string]: any;
66
+ };
62
67
  staticPostFilter?: {
63
68
  [key: string]: any;
64
69
  };
70
+ removeProtected?: boolean;
65
71
  pipeline: mongoose.PipelineStage[];
66
72
  }
67
73
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AACA,OAAO,QAAQ,EAAE,EAAC,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAC,MAAM,UAAU,CAAC;AAC7E,OAAO,EAAC,QAAQ,EAAC,MAAM,IAAI,CAAC;AAE5B;;;;GAIG;AACH,MAAM,WAAW,WAAW;IACxB,KAAK,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,eAAgB,SAAQ,QAAQ;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,KAAK,GAAG,IAAI,GAAG,GAAG,GAAG,OAAO,CAAA;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,2BAA2B;IACxC,OAAO,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAA;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,8BAA+B,SAAQ,2BAA2B;IAC/E,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAAA;CAEhC;AACD,MAAM,WAAW,iCAAkC,SAAQ,2BAA2B;IAClF,QAAQ,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAA;IACtC,KAAK,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAA;IACnC,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,WAAW,EAAE;QAAC,CAAC,GAAG,EAAC,MAAM,GAAE,GAAG,CAAA;KAAC,CAAA;CAClC;AACD,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACtD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,kBAAmB,SAAQ,oBAAoB;IAC5D,YAAY,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAA;IACrC,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,gBAAgB,EAAC,SAAS,CAAC;IAC3E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE;QAAE,CAAC,GAAG,EAAC,MAAM,GAAG,GAAG,CAAA;KAAE,CAAA;IACxC,QAAQ,EAAE,QAAQ,CAAC,aAAa,EAAE,CAAA;CACrC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AACA,OAAO,QAAQ,EAAE,EAAC,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAC,MAAM,UAAU,CAAC;AAC7E,OAAO,EAAC,QAAQ,EAAC,MAAM,IAAI,CAAC;AAE5B;;;;GAIG;AACH,MAAM,WAAW,WAAW;IACxB,KAAK,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,eAAgB,SAAQ,QAAQ;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,KAAK,GAAG,IAAI,GAAG,GAAG,GAAG,OAAO,CAAA;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,2BAA2B;IACxC,OAAO,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAA;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,8BAA+B,SAAQ,2BAA2B;IAC/E,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAAA;CAEhC;AACD,MAAM,WAAW,iCAAkC,SAAQ,2BAA2B;IAClF,QAAQ,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAA;IACtC,KAAK,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAA;IACnC,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,WAAW,EAAE;QAAC,CAAC,GAAG,EAAC,MAAM,GAAE,GAAG,CAAA;KAAC,CAAA;CAClC;AACD,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACtD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,kBAAmB,SAAQ,oBAAoB;IAC5D,YAAY,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAA;IACrC,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,gBAAgB,EAAC,SAAS,CAAC;IAC3E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAA;IACrC,gBAAgB,CAAC,EAAE;QAAE,CAAC,GAAG,EAAC,MAAM,GAAG,GAAG,CAAA;KAAE,CAAA;IACxC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,QAAQ,CAAC,aAAa,EAAE,CAAA;CACrC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@r5v/mongoose-paginate",
3
- "version": "1.0.14",
3
+ "version": "1.0.15",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",