@casl/mongoose 4.0.0 → 6.0.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/README.md CHANGED
@@ -22,7 +22,7 @@ pnpm add @casl/mongoose @casl/ability
22
22
 
23
23
  ### Accessible Records plugin
24
24
 
25
- `accessibleRecordsPlugin` is a plugin which adds `accessibleBy` method to query and static methods of your models. You can add this plugin globally:
25
+ `accessibleRecordsPlugin` is a plugin which adds `accessibleBy` method to query and static methods of mongoose models. We can add this plugin globally:
26
26
 
27
27
  ```js
28
28
  const { accessibleRecordsPlugin } = require('@casl/mongoose');
@@ -31,7 +31,7 @@ const mongoose = require('mongoose');
31
31
  mongoose.plugin(accessibleRecordsPlugin);
32
32
  ```
33
33
 
34
- > Make sure you add the plugin before calling `mongoose.model(...)` method. Mongoose won't add global plugins to models that where created before calling `mongoose.plugin()`.
34
+ > Make sure to add the plugin before calling `mongoose.model(...)` method. Mongoose won't add global plugins to models that where created before calling `mongoose.plugin()`.
35
35
 
36
36
  or to a particular model:
37
37
 
@@ -49,7 +49,7 @@ Post.plugin(accessibleRecordsPlugin)
49
49
  module.exports = mongoose.model('Post', Post)
50
50
  ```
51
51
 
52
- Afterwards you can fetch accessible records by calling `accessibleBy` method on `Post`:
52
+ Afterwards, we can fetch accessible records using `accessibleBy` method on `Post`:
53
53
 
54
54
  ```js
55
55
  const Post = require('./Post')
@@ -77,7 +77,7 @@ async function main() {
77
77
  }
78
78
  ```
79
79
 
80
- `accessibleBy` returns an instance of `mongoose.Query` and that means you can chain it with any `mongoose.Query`'s method (e.g., `select`, `limit`, `sort`). By default, `accessibleBy` constructs query based on the list of rules for `read` action but you can change this by providing the 2nd optional argument:
80
+ `accessibleBy` returns an instance of `mongoose.Query` and that means you can chain it with any `mongoose.Query`'s method (e.g., `select`, `limit`, `sort`). By default, `accessibleBy` constructs a query based on the list of rules for `read` action but we can change this by providing the 2nd optional argument:
81
81
 
82
82
  ```js
83
83
  const Post = require('./Post');
@@ -91,7 +91,7 @@ async function main() {
91
91
 
92
92
  > `accessibleBy` is built on top of `rulesToQuery` function from `@casl/ability/extra`. Read [Ability to database query](https://casl.js.org/v5/en/advanced/ability-to-database-query) to get insights of how it works.
93
93
 
94
- In case when user doesn’t have permission to do a particular action, CASL will not even send request to MongoDB and instead will force Query to return empty result set. CASL patches native mongodb collection's methods in such case to return predefine value (empty array for `find`, `null` for `findOne` and `0` for `count`). It also adds `__forbiddenByCasl__: 1` condition which will enforce mongodb to return empty set in case if you use one of methods that are not patched, so users who is not allowed to get particular records won't get them!
94
+ In case user doesn’t have permission to do a particular action, CASL will throw `ForbiddenError` and will not send request to MongoDB. It also adds `__forbiddenByCasl__: 1` condition for additional safety.
95
95
 
96
96
  For example, lets find all posts which user can delete (we haven’t defined abilities for delete):
97
97
 
@@ -105,12 +105,15 @@ mongoose.set('debug', true);
105
105
  const ability = defineAbility(can => can('read', 'Post', { private: false }));
106
106
 
107
107
  async function main() {
108
- const posts = await Post.accessibleBy(ability, 'delete');
109
- console.log(posts) // [];
108
+ try {
109
+ const posts = await Post.accessibleBy(ability, 'delete');
110
+ } catch (error) {
111
+ console.log(error) // ForbiddenError;
112
+ }
110
113
  }
111
114
  ```
112
115
 
113
- You can also use the resulting conditions in [aggregation pipeline](https://mongoosejs.com/docs/api.html#aggregate_Aggregate):
116
+ We can also use the resulting conditions in [aggregation pipeline](https://mongoosejs.com/docs/api.html#aggregate_Aggregate):
114
117
 
115
118
  ```js
116
119
  const Post = require('./Post');
@@ -161,7 +164,7 @@ async function main() {
161
164
 
162
165
  ### Accessible Fields plugin
163
166
 
164
- `accessibleFieldsPlugin` is a plugin that adds `accessibleFieldsBy` method to instance and static methods of a model and allows to retrieve all accessible fields. This is useful when you need send only accessible part of a model in response:
167
+ `accessibleFieldsPlugin` is a plugin that adds `accessibleFieldsBy` method to instance and static methods of a model and allows to retrieve all accessible fields. This is useful when we need to send only accessible part of a model in response:
165
168
 
166
169
  ```js
167
170
  const { accessibleFieldsPlugin } = require('@casl/mongoose');
@@ -198,7 +201,7 @@ post.accessibleFieldsBy(ability); // ['title']
198
201
 
199
202
  As you can see, a static method returns all fields that can be read for all posts. At the same time, an instance method returns fields that can be read from this particular `post` instance. That's why there is no much sense (except you want to reduce traffic between app and database) to pass the result of static method into `mongoose.Query`'s `select` method because eventually you will need to call `accessibleFieldsBy` on every instance.
200
203
 
201
- ## Integration with any MongoDB library
204
+ ## Integration with other MongoDB libraries
202
205
 
203
206
  In case you don't use mongoose, this package provides `toMongoQuery` function which can convert CASL rules into [MongoDB] query. Lets see an example of how to fetch accessible records using raw [MongoDB adapter][mongo-adapter]
204
207
 
@@ -229,14 +232,14 @@ async function main() {
229
232
 
230
233
  ## TypeScript support
231
234
 
232
- The package is written in TypeScript, this makes it easier to work with plugins and `toMongoQuery` helper because IDE will hint you about you can pass inside arguments and TypeScript will warn you about wrong usage. Let's see it in action!
235
+ The package is written in TypeScript, this makes it easier to work with plugins and `toMongoQuery` helper because IDE provides useful hints. Let's see it in action!
233
236
 
234
237
  Suppose we have `Post` entity which can be described as:
235
238
 
236
239
  ```ts
237
- import * as mongoose from 'mongoose';
240
+ import mongoose from 'mongoose';
238
241
 
239
- export interface Post {
242
+ export interface Post extends mongoose.Document {
240
243
  title: string
241
244
  content: string
242
245
  published: boolean
@@ -295,7 +298,7 @@ const post = new Post();
295
298
  post.accessibleFieldsBy(/* parameters */);
296
299
  ```
297
300
 
298
- And we want to include both plugins, we can use `AccessibleModel` type that includes methods from both plugins:
301
+ And if we want to include both plugins, we can use `AccessibleModel` type that provides methods from both plugins:
299
302
 
300
303
  ```ts
301
304
  import {
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});var t=require("@casl/ability");var n=require("mongoose");var e=require("@casl/ability/extra");function r(t){const n=t.conditions;return t.inverted?{$nor:[n]}:n}function o(t,n,o){return e.rulesToQuery(t,o||"read",n,r)}function i(n,e,r,o){const i=t.ForbiddenError.from(n);i.action=e;i.subjectType=r;i.setMessage(t.getDefaultErrorMessage(i));o.where({__forbiddenByCasl__:1});o.exec=function t(...n){const e="function"===typeof n[0]?n[0]:n[1];if("function"===typeof e){process.nextTick((()=>e(i)));return}return Promise.reject(i)};return o}function s(t,e){let r=this.modelName;if(!r)r="model"in this?this.model.modelName:null;if(!r)throw new TypeError("Cannot detect model name to return accessible records");const s=o(t,r,e);if(null===s)return i(t,e||"read",r,this.where());return this instanceof n.Query?this.and([s]):this.where({$and:[s]})}function c(t){t.query.accessibleBy=s;t.statics.accessibleBy=s}const u=t=>Object.keys(t.paths);function f(n,e){const r=e.getFields(n);if(!e||!("except"in e))return r;const o=t.wrapArray(e.except);return r.filter((t=>-1===o.indexOf(t)))}function l(){let n;return(e,r)=>{if(!n){const o=r&&"only"in r?t.wrapArray(r.only):f(e,r);n=t=>t.fields||o}return n}}function a(t,n){const r=Object.assign({getFields:u},n);const o=l();function i(n,i){const s="function"===typeof this?this.modelName:this;return e.permittedFieldsOf(n,i||"read",s,{fieldsFrom:o(t,r)})}t.statics.accessibleFieldsBy=i;t.method("accessibleFieldsBy",i)}exports.accessibleFieldsPlugin=a;exports.accessibleRecordsPlugin=c;exports.getSchemaPaths=u;exports.toMongoQuery=o;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});var t=require("@casl/ability");var e=require("mongoose");var n=require("@casl/ability/extra");function r(t){return t&&"object"===typeof t&&"default"in t?t:{default:t}}var o=r(e);function i(t){const e=t.conditions;return t.inverted?{$nor:[e]}:e}function s(t,e,r="read"){return n.rulesToQuery(t,r,e,i)}function c(e,n,r,o){o.where({__forbiddenByCasl__:1});const i=o;if("function"===typeof i.pre)i.pre((o=>{const i=t.ForbiddenError.from(e);i.action=n;i.subjectType=r;i.setMessage(t.getDefaultErrorMessage(i));o(i)}));return o}function u(t,e){let n=this.modelName;if(!n)n="model"in this?this.model.modelName:null;if(!n)throw new TypeError("Cannot detect model name to return accessible records");const r=s(t,n,e);if(null===r)return c(t,e||"read",n,this.where());return this instanceof o["default"].Query?this.and([r]):this.where({$and:[r]})}function f(t){t.query.accessibleBy=u;t.statics.accessibleBy=u}const l=t=>Object.keys(t.paths);function a(e,n){const r=n.getFields(e);if(!n||!("except"in n))return r;const o=t.wrapArray(n.except);return r.filter((t=>-1===o.indexOf(t)))}function d(){let e;return(n,r)=>{if(!e){const o=r&&"only"in r?t.wrapArray(r.only):a(n,r);e=t=>t.fields||o}return e}}function h(t,e){const r=Object.assign({getFields:l},e);const o=d();function i(e,i){const s="function"===typeof this?this.modelName:this;return n.permittedFieldsOf(e,i||"read",s,{fieldsFrom:o(t,r)})}t.statics.accessibleFieldsBy=i;t.method("accessibleFieldsBy",i)}exports.accessibleFieldsPlugin=h;exports.accessibleRecordsPlugin=f;exports.getSchemaPaths=l;exports.toMongoQuery=s;
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/mongo.ts","../../src/accessible_records.ts","../../src/accessible_fields.ts"],"sourcesContent":["import { AnyMongoAbility } from '@casl/ability';\nimport { rulesToQuery } from '@casl/ability/extra';\n\nfunction convertToMongoQuery(rule: AnyMongoAbility['rules'][number]) {\n const conditions = rule.conditions!;\n return rule.inverted ? { $nor: [conditions] } : conditions;\n}\n\nexport function toMongoQuery<T extends AnyMongoAbility>(\n ability: T,\n subjectType: Parameters<T['rulesFor']>[1],\n action: Parameters<T['rulesFor']>[0]\n) {\n return rulesToQuery(ability, action || 'read', subjectType, convertToMongoQuery);\n}\n","import { Normalize, AnyMongoAbility, Generics, ForbiddenError, getDefaultErrorMessage } from '@casl/ability';\nimport { Schema, DocumentQuery, Query, Model, Document } from 'mongoose';\nimport { toMongoQuery } from './mongo';\n\nfunction failedQuery(\n ability: AnyMongoAbility,\n action: string,\n modelName: string,\n query: DocumentQuery<Document, Document>\n) {\n const error = ForbiddenError.from(ability);\n error.action = action;\n error.subjectType = modelName;\n error.setMessage(getDefaultErrorMessage(error));\n\n query.where({ __forbiddenByCasl__: 1 }); // eslint-disable-line\n query.exec = function patchedExecByCasl(...args: any[]) {\n const cb = typeof args[0] === 'function' ? args[0] : args[1];\n if (typeof cb === 'function') {\n process.nextTick(() => cb(error));\n return;\n }\n // eslint-disable-next-line consistent-return\n return Promise.reject(error);\n } as typeof query['exec'];\n\n return query;\n}\n\ntype GetAccessibleRecords<T extends Document> = <U extends AnyMongoAbility>(\n ability: U,\n action?: Normalize<Generics<U>['abilities']>[0]\n) => DocumentQuery<T, T>;\n\nfunction accessibleBy<T extends AnyMongoAbility>(\n this: any,\n ability: T,\n action?: Normalize<Generics<T>['abilities']>[0]\n): DocumentQuery<Document, Document> {\n let modelName: string | undefined = this.modelName;\n\n if (!modelName) {\n modelName = 'model' in this ? this.model.modelName : null;\n }\n\n if (!modelName) {\n throw new TypeError('Cannot detect model name to return accessible records');\n }\n\n const query = toMongoQuery(ability, modelName, action);\n\n if (query === null) {\n return failedQuery(ability, action || 'read', modelName, this.where());\n }\n\n return this instanceof Query ? this.and([query]) : this.where({ $and: [query] });\n}\n\nexport interface AccessibleRecordModel<T extends Document, K = {}> extends Model<T, K & {\n accessibleBy: GetAccessibleRecords<T>\n}> {\n accessibleBy: GetAccessibleRecords<T>\n}\n\nexport function accessibleRecordsPlugin(schema: Schema<Document>) {\n schema.query.accessibleBy = accessibleBy;\n schema.statics.accessibleBy = accessibleBy;\n}\n","import { wrapArray, Normalize, AnyMongoAbility, Generics } from '@casl/ability';\nimport { permittedFieldsOf, PermittedFieldsOptions } from '@casl/ability/extra';\nimport { Schema, Model, Document } from 'mongoose';\n\nexport type AccessibleFieldsOptions =\n {\n getFields(schema: Schema<Document>): string[]\n } &\n ({ only: string | string[] } | { except: string | string[] });\n\nexport const getSchemaPaths: AccessibleFieldsOptions['getFields'] = schema => Object.keys((schema as { paths: object }).paths);\n\nfunction fieldsOf(schema: Schema<Document>, options: Partial<AccessibleFieldsOptions>) {\n const fields = options.getFields!(schema);\n\n if (!options || !('except' in options)) {\n return fields;\n }\n\n const excludedFields = wrapArray(options.except);\n return fields.filter(field => excludedFields.indexOf(field) === -1);\n}\n\ntype GetAccessibleFields<T extends AccessibleFieldsDocument> = <U extends AnyMongoAbility>(\n this: Model<T> | T,\n ability: U,\n action?: Normalize<Generics<U>['abilities']>[0]\n) => string[];\n\nexport interface AccessibleFieldsModel<T extends AccessibleFieldsDocument> extends Model<T> {\n accessibleFieldsBy: GetAccessibleFields<T>\n}\n\nexport interface AccessibleFieldsDocument extends Document {\n accessibleFieldsBy: GetAccessibleFields<AccessibleFieldsDocument>\n}\n\nfunction modelFieldsGetter() {\n let fieldsFrom: PermittedFieldsOptions<AnyMongoAbility>['fieldsFrom'];\n return (schema: Schema<Document>, options: Partial<AccessibleFieldsOptions>) => {\n if (!fieldsFrom) {\n const ALL_FIELDS = options && 'only' in options\n ? wrapArray(options.only as string[])\n : fieldsOf(schema, options);\n fieldsFrom = rule => rule.fields || ALL_FIELDS;\n }\n\n return fieldsFrom;\n };\n}\n\nexport function accessibleFieldsPlugin(\n schema: Schema<AccessibleFieldsDocument>,\n rawOptions?: Partial<AccessibleFieldsOptions>\n) {\n const options = { getFields: getSchemaPaths, ...rawOptions };\n const fieldsFrom = modelFieldsGetter();\n type ModelOrDoc = Model<AccessibleFieldsDocument> | AccessibleFieldsDocument;\n\n function accessibleFieldsBy(this: ModelOrDoc, ability: AnyMongoAbility, action?: string) {\n const subject = typeof this === 'function' ? this.modelName : this;\n return permittedFieldsOf(ability, action || 'read', subject, {\n fieldsFrom: fieldsFrom(schema, options)\n });\n }\n\n schema.statics.accessibleFieldsBy = accessibleFieldsBy;\n schema.method('accessibleFieldsBy', accessibleFieldsBy);\n}\n"],"names":["convertToMongoQuery","rule","conditions","inverted","$nor","toMongoQuery","ability","subjectType","action","rulesToQuery","failedQuery","modelName","query","error","ForbiddenError","from","setMessage","getDefaultErrorMessage","where","__forbiddenByCasl__","exec","patchedExecByCasl","args","cb","process","nextTick","Promise","reject","accessibleBy","this","model","TypeError","Query","and","$and","accessibleRecordsPlugin","schema","statics","getSchemaPaths","Object","keys","paths","fieldsOf","options","fields","getFields","excludedFields","wrapArray","except","filter","field","indexOf","modelFieldsGetter","fieldsFrom","ALL_FIELDS","only","accessibleFieldsPlugin","rawOptions","accessibleFieldsBy","subject","permittedFieldsOf","method"],"mappings":"oKAGA,SAASA,EAAoBC,SACrBC,EAAaD,EAAKC,kBACjBD,EAAKE,SAAW,CAAEC,KAAM,CAACF,IAAgBA,EAG3C,SAASG,EACdC,EACAC,EACAC,UAEOC,eAAaH,EAASE,GAAU,OAAQD,EAAaP,GCT9D,SAASU,EACPJ,EACAE,EACAG,EACAC,SAEMC,EAAQC,iBAAeC,KAAKT,GAClCO,EAAML,OAASA,EACfK,EAAMN,YAAcI,EACpBE,EAAMG,WAAWC,yBAAuBJ,IAExCD,EAAMM,MAAM,CAAEC,oBAAqB,IACnCP,EAAMQ,KAAO,SAASC,KAAqBC,SACnCC,EAAwB,oBAAZD,EAAK,GAAoBA,EAAK,GAAKA,EAAK,MACxC,oBAAPC,EAAmB,CAC5BC,QAAQC,UAAS,IAAMF,EAAGV,mBAIrBa,QAAQC,OAAOd,WAGjBD,EAQT,SAASgB,EAEPtB,EACAE,OAEIG,EAAgCkB,KAAKlB,cAEpCA,EACHA,EAAY,UAAWkB,KAAOA,KAAKC,MAAMnB,UAAY,SAGlDA,QACG,IAAIoB,UAAU,+DAGhBnB,EAAQP,EAAaC,EAASK,EAAWH,MAEjC,OAAVI,SACKF,EAAYJ,EAASE,GAAU,OAAQG,EAAWkB,KAAKX,gBAGzDW,gBAAgBG,QAAQH,KAAKI,IAAI,CAACrB,IAAUiB,KAAKX,MAAM,CAAEgB,KAAM,CAACtB,KASlE,SAASuB,EAAwBC,GACtCA,EAAOxB,MAAMgB,aAAeA,EAC5BQ,EAAOC,QAAQT,aAAeA,QCxDnBU,EAAuDF,GAAUG,OAAOC,KAAMJ,EAA6BK,OAExH,SAASC,EAASN,EAA0BO,SACpCC,EAASD,EAAQE,UAAWT,OAE7BO,KAAa,WAAYA,UACrBC,QAGHE,EAAiBC,YAAUJ,EAAQK,eAClCJ,EAAOK,QAAOC,IAA4C,IAAnCJ,EAAeK,QAAQD,KAiBvD,SAASE,QACHC,QACG,CAACjB,EAA0BO,SAC3BU,EAAY,OACTC,EAAaX,GAAW,SAAUA,EACpCI,YAAUJ,EAAQY,MAClBb,EAASN,EAAQO,GACrBU,EAAapD,GAAQA,EAAK2C,QAAUU,SAG/BD,GAIJ,SAASG,EACdpB,EACAqB,SAEMd,iBAAYE,UAAWP,GAAmBmB,SAC1CJ,EAAaD,aAGVM,EAAqCpD,EAA0BE,SAChEmD,EAA0B,oBAAT9B,KAAsBA,KAAKlB,UAAYkB,YACvD+B,oBAAkBtD,EAASE,GAAU,OAAQmD,EAAS,CAC3DN,WAAYA,EAAWjB,EAAQO,KAInCP,EAAOC,QAAQqB,mBAAqBA,EACpCtB,EAAOyB,OAAO,qBAAsBH"}
1
+ {"version":3,"file":"index.js","sources":["../../src/mongo.ts","../../src/accessible_records.ts","../../src/accessible_fields.ts"],"sourcesContent":["import { AnyMongoAbility } from '@casl/ability';\nimport { rulesToQuery } from '@casl/ability/extra';\n\nfunction convertToMongoQuery(rule: AnyMongoAbility['rules'][number]) {\n const conditions = rule.conditions!;\n return rule.inverted ? { $nor: [conditions] } : conditions;\n}\n\nexport function toMongoQuery<T extends AnyMongoAbility>(\n ability: T,\n subjectType: Parameters<T['rulesFor']>[1],\n action: Parameters<T['rulesFor']>[0] = 'read'\n) {\n return rulesToQuery(ability, action, subjectType, convertToMongoQuery);\n}\n","import { Normalize, AnyMongoAbility, Generics, ForbiddenError, getDefaultErrorMessage } from '@casl/ability';\nimport type { Schema, QueryWithHelpers, Model, Document } from 'mongoose';\nimport mongoose from 'mongoose';\nimport { toMongoQuery } from './mongo';\n\nfunction failedQuery(\n ability: AnyMongoAbility,\n action: string,\n modelName: string,\n query: QueryWithHelpers<Document, Document>\n) {\n query.where({ __forbiddenByCasl__: 1 }); // eslint-disable-line\n const anyQuery: any = query;\n\n if (typeof anyQuery.pre === 'function') {\n anyQuery.pre((cb: (error?: Error) => void) => {\n const error = ForbiddenError.from(ability);\n error.action = action;\n error.subjectType = modelName;\n error.setMessage(getDefaultErrorMessage(error));\n cb(error);\n });\n }\n\n return query;\n}\n\nfunction accessibleBy<T extends AnyMongoAbility>(\n this: any,\n ability: T,\n action?: Normalize<Generics<T>['abilities']>[0]\n): QueryWithHelpers<Document, Document> {\n let modelName: string | undefined = this.modelName;\n\n if (!modelName) {\n modelName = 'model' in this ? this.model.modelName : null;\n }\n\n if (!modelName) {\n throw new TypeError('Cannot detect model name to return accessible records');\n }\n\n const query = toMongoQuery(ability, modelName, action);\n\n if (query === null) {\n return failedQuery(ability, action || 'read', modelName, this.where());\n }\n\n return this instanceof mongoose.Query ? this.and([query]) : this.where({ $and: [query] });\n}\n\ntype GetAccessibleRecords<T extends Document> = <U extends AnyMongoAbility>(\n ability: U,\n action?: Normalize<Generics<U>['abilities']>[0]\n) => QueryWithHelpers<T, T, QueryHelpers<T>>;\n\ntype QueryHelpers<T extends Document> = {\n accessibleBy: GetAccessibleRecords<T>\n};\nexport interface AccessibleRecordModel<\n T extends Document, K = unknown\n> extends Model<T, K & QueryHelpers<T>> {\n accessibleBy: GetAccessibleRecords<T>\n}\n\nexport function accessibleRecordsPlugin(schema: Schema<any>) {\n schema.query.accessibleBy = accessibleBy;\n schema.statics.accessibleBy = accessibleBy;\n}\n","import { wrapArray, Normalize, AnyMongoAbility, Generics } from '@casl/ability';\nimport { permittedFieldsOf, PermittedFieldsOptions } from '@casl/ability/extra';\nimport type { Schema, Model, Document } from 'mongoose';\n\nexport type AccessibleFieldsOptions =\n {\n getFields(schema: Schema<Document>): string[]\n } &\n ({ only: string | string[] } | { except: string | string[] });\n\nexport const getSchemaPaths: AccessibleFieldsOptions['getFields'] = schema => Object.keys((schema as { paths: object }).paths);\n\nfunction fieldsOf(schema: Schema<Document>, options: Partial<AccessibleFieldsOptions>) {\n const fields = options.getFields!(schema);\n\n if (!options || !('except' in options)) {\n return fields;\n }\n\n const excludedFields = wrapArray(options.except);\n return fields.filter(field => excludedFields.indexOf(field) === -1);\n}\n\ntype GetAccessibleFields<T extends AccessibleFieldsDocument> = <U extends AnyMongoAbility>(\n this: Model<T> | T,\n ability: U,\n action?: Normalize<Generics<U>['abilities']>[0]\n) => string[];\n\nexport interface AccessibleFieldsModel<T extends AccessibleFieldsDocument> extends Model<T> {\n accessibleFieldsBy: GetAccessibleFields<T>\n}\n\nexport interface AccessibleFieldsDocument extends Document {\n accessibleFieldsBy: GetAccessibleFields<AccessibleFieldsDocument>\n}\n\nfunction modelFieldsGetter() {\n let fieldsFrom: PermittedFieldsOptions<AnyMongoAbility>['fieldsFrom'];\n return (schema: Schema<any>, options: Partial<AccessibleFieldsOptions>) => {\n if (!fieldsFrom) {\n const ALL_FIELDS = options && 'only' in options\n ? wrapArray(options.only as string[])\n : fieldsOf(schema, options);\n fieldsFrom = rule => rule.fields || ALL_FIELDS;\n }\n\n return fieldsFrom;\n };\n}\n\nexport function accessibleFieldsPlugin(\n schema: Schema<any>,\n rawOptions?: Partial<AccessibleFieldsOptions>\n) {\n const options = { getFields: getSchemaPaths, ...rawOptions };\n const fieldsFrom = modelFieldsGetter();\n type ModelOrDoc = Model<AccessibleFieldsDocument> | AccessibleFieldsDocument;\n\n function accessibleFieldsBy(this: ModelOrDoc, ability: AnyMongoAbility, action?: string) {\n const subject = typeof this === 'function' ? this.modelName : this;\n return permittedFieldsOf(ability, action || 'read', subject, {\n fieldsFrom: fieldsFrom(schema, options)\n });\n }\n\n schema.statics.accessibleFieldsBy = accessibleFieldsBy;\n schema.method('accessibleFieldsBy', accessibleFieldsBy);\n}\n"],"names":["convertToMongoQuery","rule","conditions","inverted","$nor","toMongoQuery","ability","subjectType","action","rulesToQuery","failedQuery","modelName","query","where","__forbiddenByCasl__","anyQuery","pre","cb","error","ForbiddenError","from","setMessage","getDefaultErrorMessage","accessibleBy","this","model","TypeError","mongoose","Query","and","$and","accessibleRecordsPlugin","schema","statics","getSchemaPaths","Object","keys","paths","fieldsOf","options","fields","getFields","excludedFields","wrapArray","except","filter","field","indexOf","modelFieldsGetter","fieldsFrom","ALL_FIELDS","only","accessibleFieldsPlugin","rawOptions","accessibleFieldsBy","subject","permittedFieldsOf","method"],"mappings":"wPAGA,SAASA,EAAoBC,SACrBC,EAAaD,EAAKC,kBACjBD,EAAKE,SAAW,CAAEC,KAAM,CAACF,IAAgBA,EAG3C,SAASG,EACdC,EACAC,EACAC,EAAuC,eAEhCC,eAAaH,EAASE,EAAQD,EAAaP,GCRpD,SAASU,EACPJ,EACAE,EACAG,EACAC,GAEAA,EAAMC,MAAM,CAAEC,oBAAqB,UAC7BC,EAAgBH,KAEM,oBAAjBG,EAASC,IAClBD,EAASC,KAAKC,UACNC,EAAQC,iBAAeC,KAAKd,GAClCY,EAAMV,OAASA,EACfU,EAAMX,YAAcI,EACpBO,EAAMG,WAAWC,yBAAuBJ,IACxCD,EAAGC,aAIAN,EAGT,SAASW,EAEPjB,EACAE,OAEIG,EAAgCa,KAAKb,cAEpCA,EACHA,EAAY,UAAWa,KAAOA,KAAKC,MAAMd,UAAY,SAGlDA,QACG,IAAIe,UAAU,+DAGhBd,EAAQP,EAAaC,EAASK,EAAWH,MAEjC,OAAVI,SACKF,EAAYJ,EAASE,GAAU,OAAQG,EAAWa,KAAKX,gBAGzDW,gBAAgBG,aAASC,MAAQJ,KAAKK,IAAI,CAACjB,IAAUY,KAAKX,MAAM,CAAEiB,KAAM,CAAClB,KAiB3E,SAASmB,EAAwBC,GACtCA,EAAOpB,MAAMW,aAAeA,EAC5BS,EAAOC,QAAQV,aAAeA,QCzDnBW,EAAuDF,GAAUG,OAAOC,KAAMJ,EAA6BK,OAExH,SAASC,EAASN,EAA0BO,SACpCC,EAASD,EAAQE,UAAWT,OAE7BO,KAAa,WAAYA,UACrBC,QAGHE,EAAiBC,YAAUJ,EAAQK,eAClCJ,EAAOK,QAAOC,IAA4C,IAAnCJ,EAAeK,QAAQD,KAiBvD,SAASE,QACHC,QACG,CAACjB,EAAqBO,SACtBU,EAAY,OACTC,EAAaX,GAAW,SAAUA,EACpCI,YAAUJ,EAAQY,MAClBb,EAASN,EAAQO,GACrBU,EAAahD,GAAQA,EAAKuC,QAAUU,SAG/BD,GAIJ,SAASG,EACdpB,EACAqB,SAEMd,iBAAYE,UAAWP,GAAmBmB,SAC1CJ,EAAaD,aAGVM,EAAqChD,EAA0BE,SAChE+C,EAA0B,oBAAT/B,KAAsBA,KAAKb,UAAYa,YACvDgC,oBAAkBlD,EAASE,GAAU,OAAQ+C,EAAS,CAC3DN,WAAYA,EAAWjB,EAAQO,KAInCP,EAAOC,QAAQqB,mBAAqBA,EACpCtB,EAAOyB,OAAO,qBAAsBH"}
@@ -1,2 +1,2 @@
1
- import{ForbiddenError as t,getDefaultErrorMessage as n,wrapArray as o}from"@casl/ability";import{Query as e}from"mongoose";import{rulesToQuery as r,permittedFieldsOf as i}from"@casl/ability/extra";function c(t){const n=t.conditions;return t.inverted?{$nor:[n]}:n}function s(t,n,o){return r(t,o||"read",n,c)}function f(o,e,r,i){const c=t.from(o);c.action=e;c.subjectType=r;c.setMessage(n(c));i.where({__forbiddenByCasl__:1});i.exec=function t(...n){const o="function"===typeof n[0]?n[0]:n[1];if("function"===typeof o){process.nextTick((()=>o(c)));return}return Promise.reject(c)};return i}function u(t,n){let o=this.modelName;if(!o)o="model"in this?this.model.modelName:null;if(!o)throw new TypeError("Cannot detect model name to return accessible records");const r=s(t,o,n);if(null===r)return f(t,n||"read",o,this.where());return this instanceof e?this.and([r]):this.where({$and:[r]})}function l(t){t.query.accessibleBy=u;t.statics.accessibleBy=u}const a=t=>Object.keys(t.paths);function d(t,n){const e=n.getFields(t);if(!n||!("except"in n))return e;const r=o(n.except);return e.filter((t=>-1===r.indexOf(t)))}function m(){let t;return(n,e)=>{if(!t){const r=e&&"only"in e?o(e.only):d(n,e);t=t=>t.fields||r}return t}}function h(t,n){const o=Object.assign({getFields:a},n);const e=m();function r(n,r){const c="function"===typeof this?this.modelName:this;return i(n,r||"read",c,{fieldsFrom:e(t,o)})}t.statics.accessibleFieldsBy=r;t.method("accessibleFieldsBy",r)}export{h as accessibleFieldsPlugin,l as accessibleRecordsPlugin,a as getSchemaPaths,s as toMongoQuery};
1
+ import{ForbiddenError as t,getDefaultErrorMessage as n,wrapArray as o}from"@casl/ability";import i from"mongoose";import{rulesToQuery as e,permittedFieldsOf as r}from"@casl/ability/extra";function c(t){const n=t.conditions;return t.inverted?{$nor:[n]}:n}function s(t,n,o="read"){return e(t,o,n,c)}function f(o,i,e,r){r.where({__forbiddenByCasl__:1});const c=r;if("function"===typeof c.pre)c.pre((r=>{const c=t.from(o);c.action=i;c.subjectType=e;c.setMessage(n(c));r(c)}));return r}function u(t,n){let o=this.modelName;if(!o)o="model"in this?this.model.modelName:null;if(!o)throw new TypeError("Cannot detect model name to return accessible records");const e=s(t,o,n);if(null===e)return f(t,n||"read",o,this.where());return this instanceof i.Query?this.and([e]):this.where({$and:[e]})}function l(t){t.query.accessibleBy=u;t.statics.accessibleBy=u}const a=t=>Object.keys(t.paths);function d(t,n){const i=n.getFields(t);if(!n||!("except"in n))return i;const e=o(n.except);return i.filter((t=>-1===e.indexOf(t)))}function h(){let t;return(n,i)=>{if(!t){const e=i&&"only"in i?o(i.only):d(n,i);t=t=>t.fields||e}return t}}function m(t,n){const o=Object.assign({getFields:a},n);const i=h();function e(n,e){const c="function"===typeof this?this.modelName:this;return r(n,e||"read",c,{fieldsFrom:i(t,o)})}t.statics.accessibleFieldsBy=e;t.method("accessibleFieldsBy",e)}export{m as accessibleFieldsPlugin,l as accessibleRecordsPlugin,a as getSchemaPaths,s as toMongoQuery};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../src/mongo.ts","../../src/accessible_records.ts","../../src/accessible_fields.ts"],"sourcesContent":["import { AnyMongoAbility } from '@casl/ability';\nimport { rulesToQuery } from '@casl/ability/extra';\n\nfunction convertToMongoQuery(rule: AnyMongoAbility['rules'][number]) {\n const conditions = rule.conditions!;\n return rule.inverted ? { $nor: [conditions] } : conditions;\n}\n\nexport function toMongoQuery<T extends AnyMongoAbility>(\n ability: T,\n subjectType: Parameters<T['rulesFor']>[1],\n action: Parameters<T['rulesFor']>[0]\n) {\n return rulesToQuery(ability, action || 'read', subjectType, convertToMongoQuery);\n}\n","import { Normalize, AnyMongoAbility, Generics, ForbiddenError, getDefaultErrorMessage } from '@casl/ability';\nimport { Schema, DocumentQuery, Query, Model, Document } from 'mongoose';\nimport { toMongoQuery } from './mongo';\n\nfunction failedQuery(\n ability: AnyMongoAbility,\n action: string,\n modelName: string,\n query: DocumentQuery<Document, Document>\n) {\n const error = ForbiddenError.from(ability);\n error.action = action;\n error.subjectType = modelName;\n error.setMessage(getDefaultErrorMessage(error));\n\n query.where({ __forbiddenByCasl__: 1 }); // eslint-disable-line\n query.exec = function patchedExecByCasl(...args: any[]) {\n const cb = typeof args[0] === 'function' ? args[0] : args[1];\n if (typeof cb === 'function') {\n process.nextTick(() => cb(error));\n return;\n }\n // eslint-disable-next-line consistent-return\n return Promise.reject(error);\n } as typeof query['exec'];\n\n return query;\n}\n\ntype GetAccessibleRecords<T extends Document> = <U extends AnyMongoAbility>(\n ability: U,\n action?: Normalize<Generics<U>['abilities']>[0]\n) => DocumentQuery<T, T>;\n\nfunction accessibleBy<T extends AnyMongoAbility>(\n this: any,\n ability: T,\n action?: Normalize<Generics<T>['abilities']>[0]\n): DocumentQuery<Document, Document> {\n let modelName: string | undefined = this.modelName;\n\n if (!modelName) {\n modelName = 'model' in this ? this.model.modelName : null;\n }\n\n if (!modelName) {\n throw new TypeError('Cannot detect model name to return accessible records');\n }\n\n const query = toMongoQuery(ability, modelName, action);\n\n if (query === null) {\n return failedQuery(ability, action || 'read', modelName, this.where());\n }\n\n return this instanceof Query ? this.and([query]) : this.where({ $and: [query] });\n}\n\nexport interface AccessibleRecordModel<T extends Document, K = {}> extends Model<T, K & {\n accessibleBy: GetAccessibleRecords<T>\n}> {\n accessibleBy: GetAccessibleRecords<T>\n}\n\nexport function accessibleRecordsPlugin(schema: Schema<Document>) {\n schema.query.accessibleBy = accessibleBy;\n schema.statics.accessibleBy = accessibleBy;\n}\n","import { wrapArray, Normalize, AnyMongoAbility, Generics } from '@casl/ability';\nimport { permittedFieldsOf, PermittedFieldsOptions } from '@casl/ability/extra';\nimport { Schema, Model, Document } from 'mongoose';\n\nexport type AccessibleFieldsOptions =\n {\n getFields(schema: Schema<Document>): string[]\n } &\n ({ only: string | string[] } | { except: string | string[] });\n\nexport const getSchemaPaths: AccessibleFieldsOptions['getFields'] = schema => Object.keys((schema as { paths: object }).paths);\n\nfunction fieldsOf(schema: Schema<Document>, options: Partial<AccessibleFieldsOptions>) {\n const fields = options.getFields!(schema);\n\n if (!options || !('except' in options)) {\n return fields;\n }\n\n const excludedFields = wrapArray(options.except);\n return fields.filter(field => excludedFields.indexOf(field) === -1);\n}\n\ntype GetAccessibleFields<T extends AccessibleFieldsDocument> = <U extends AnyMongoAbility>(\n this: Model<T> | T,\n ability: U,\n action?: Normalize<Generics<U>['abilities']>[0]\n) => string[];\n\nexport interface AccessibleFieldsModel<T extends AccessibleFieldsDocument> extends Model<T> {\n accessibleFieldsBy: GetAccessibleFields<T>\n}\n\nexport interface AccessibleFieldsDocument extends Document {\n accessibleFieldsBy: GetAccessibleFields<AccessibleFieldsDocument>\n}\n\nfunction modelFieldsGetter() {\n let fieldsFrom: PermittedFieldsOptions<AnyMongoAbility>['fieldsFrom'];\n return (schema: Schema<Document>, options: Partial<AccessibleFieldsOptions>) => {\n if (!fieldsFrom) {\n const ALL_FIELDS = options && 'only' in options\n ? wrapArray(options.only as string[])\n : fieldsOf(schema, options);\n fieldsFrom = rule => rule.fields || ALL_FIELDS;\n }\n\n return fieldsFrom;\n };\n}\n\nexport function accessibleFieldsPlugin(\n schema: Schema<AccessibleFieldsDocument>,\n rawOptions?: Partial<AccessibleFieldsOptions>\n) {\n const options = { getFields: getSchemaPaths, ...rawOptions };\n const fieldsFrom = modelFieldsGetter();\n type ModelOrDoc = Model<AccessibleFieldsDocument> | AccessibleFieldsDocument;\n\n function accessibleFieldsBy(this: ModelOrDoc, ability: AnyMongoAbility, action?: string) {\n const subject = typeof this === 'function' ? this.modelName : this;\n return permittedFieldsOf(ability, action || 'read', subject, {\n fieldsFrom: fieldsFrom(schema, options)\n });\n }\n\n schema.statics.accessibleFieldsBy = accessibleFieldsBy;\n schema.method('accessibleFieldsBy', accessibleFieldsBy);\n}\n"],"names":["convertToMongoQuery","rule","conditions","inverted","$nor","toMongoQuery","ability","subjectType","action","rulesToQuery","failedQuery","modelName","query","error","ForbiddenError","from","setMessage","getDefaultErrorMessage","where","__forbiddenByCasl__","exec","patchedExecByCasl","args","cb","process","nextTick","Promise","reject","accessibleBy","this","model","TypeError","Query","and","$and","accessibleRecordsPlugin","schema","statics","getSchemaPaths","Object","keys","paths","fieldsOf","options","fields","getFields","excludedFields","wrapArray","except","filter","field","indexOf","modelFieldsGetter","fieldsFrom","ALL_FIELDS","only","accessibleFieldsPlugin","rawOptions","accessibleFieldsBy","subject","permittedFieldsOf","method"],"mappings":"qMAGA,SAASA,EAAoBC,SACrBC,EAAaD,EAAKC,kBACjBD,EAAKE,SAAW,CAAEC,KAAM,CAACF,IAAgBA,EAG3C,SAASG,EACdC,EACAC,EACAC,UAEOC,EAAaH,EAASE,GAAU,OAAQD,EAAaP,GCT9D,SAASU,EACPJ,EACAE,EACAG,EACAC,SAEMC,EAAQC,EAAeC,KAAKT,GAClCO,EAAML,OAASA,EACfK,EAAMN,YAAcI,EACpBE,EAAMG,WAAWC,EAAuBJ,IAExCD,EAAMM,MAAM,CAAEC,oBAAqB,IACnCP,EAAMQ,KAAO,SAASC,KAAqBC,SACnCC,EAAwB,oBAAZD,EAAK,GAAoBA,EAAK,GAAKA,EAAK,MACxC,oBAAPC,EAAmB,CAC5BC,QAAQC,UAAS,IAAMF,EAAGV,mBAIrBa,QAAQC,OAAOd,WAGjBD,EAQT,SAASgB,EAEPtB,EACAE,OAEIG,EAAgCkB,KAAKlB,cAEpCA,EACHA,EAAY,UAAWkB,KAAOA,KAAKC,MAAMnB,UAAY,SAGlDA,QACG,IAAIoB,UAAU,+DAGhBnB,EAAQP,EAAaC,EAASK,EAAWH,MAEjC,OAAVI,SACKF,EAAYJ,EAASE,GAAU,OAAQG,EAAWkB,KAAKX,gBAGzDW,gBAAgBG,EAAQH,KAAKI,IAAI,CAACrB,IAAUiB,KAAKX,MAAM,CAAEgB,KAAM,CAACtB,KASlE,SAASuB,EAAwBC,GACtCA,EAAOxB,MAAMgB,aAAeA,EAC5BQ,EAAOC,QAAQT,aAAeA,QCxDnBU,EAAuDF,GAAUG,OAAOC,KAAMJ,EAA6BK,OAExH,SAASC,EAASN,EAA0BO,SACpCC,EAASD,EAAQE,UAAWT,OAE7BO,KAAa,WAAYA,UACrBC,QAGHE,EAAiBC,EAAUJ,EAAQK,eAClCJ,EAAOK,QAAOC,IAA4C,IAAnCJ,EAAeK,QAAQD,KAiBvD,SAASE,QACHC,QACG,CAACjB,EAA0BO,SAC3BU,EAAY,OACTC,EAAaX,GAAW,SAAUA,EACpCI,EAAUJ,EAAQY,MAClBb,EAASN,EAAQO,GACrBU,EAAapD,GAAQA,EAAK2C,QAAUU,SAG/BD,GAIJ,SAASG,EACdpB,EACAqB,SAEMd,iBAAYE,UAAWP,GAAmBmB,SAC1CJ,EAAaD,aAGVM,EAAqCpD,EAA0BE,SAChEmD,EAA0B,oBAAT9B,KAAsBA,KAAKlB,UAAYkB,YACvD+B,EAAkBtD,EAASE,GAAU,OAAQmD,EAAS,CAC3DN,WAAYA,EAAWjB,EAAQO,KAInCP,EAAOC,QAAQqB,mBAAqBA,EACpCtB,EAAOyB,OAAO,qBAAsBH"}
1
+ {"version":3,"file":"index.mjs","sources":["../../src/mongo.ts","../../src/accessible_records.ts","../../src/accessible_fields.ts"],"sourcesContent":["import { AnyMongoAbility } from '@casl/ability';\nimport { rulesToQuery } from '@casl/ability/extra';\n\nfunction convertToMongoQuery(rule: AnyMongoAbility['rules'][number]) {\n const conditions = rule.conditions!;\n return rule.inverted ? { $nor: [conditions] } : conditions;\n}\n\nexport function toMongoQuery<T extends AnyMongoAbility>(\n ability: T,\n subjectType: Parameters<T['rulesFor']>[1],\n action: Parameters<T['rulesFor']>[0] = 'read'\n) {\n return rulesToQuery(ability, action, subjectType, convertToMongoQuery);\n}\n","import { Normalize, AnyMongoAbility, Generics, ForbiddenError, getDefaultErrorMessage } from '@casl/ability';\nimport type { Schema, QueryWithHelpers, Model, Document } from 'mongoose';\nimport mongoose from 'mongoose';\nimport { toMongoQuery } from './mongo';\n\nfunction failedQuery(\n ability: AnyMongoAbility,\n action: string,\n modelName: string,\n query: QueryWithHelpers<Document, Document>\n) {\n query.where({ __forbiddenByCasl__: 1 }); // eslint-disable-line\n const anyQuery: any = query;\n\n if (typeof anyQuery.pre === 'function') {\n anyQuery.pre((cb: (error?: Error) => void) => {\n const error = ForbiddenError.from(ability);\n error.action = action;\n error.subjectType = modelName;\n error.setMessage(getDefaultErrorMessage(error));\n cb(error);\n });\n }\n\n return query;\n}\n\nfunction accessibleBy<T extends AnyMongoAbility>(\n this: any,\n ability: T,\n action?: Normalize<Generics<T>['abilities']>[0]\n): QueryWithHelpers<Document, Document> {\n let modelName: string | undefined = this.modelName;\n\n if (!modelName) {\n modelName = 'model' in this ? this.model.modelName : null;\n }\n\n if (!modelName) {\n throw new TypeError('Cannot detect model name to return accessible records');\n }\n\n const query = toMongoQuery(ability, modelName, action);\n\n if (query === null) {\n return failedQuery(ability, action || 'read', modelName, this.where());\n }\n\n return this instanceof mongoose.Query ? this.and([query]) : this.where({ $and: [query] });\n}\n\ntype GetAccessibleRecords<T extends Document> = <U extends AnyMongoAbility>(\n ability: U,\n action?: Normalize<Generics<U>['abilities']>[0]\n) => QueryWithHelpers<T, T, QueryHelpers<T>>;\n\ntype QueryHelpers<T extends Document> = {\n accessibleBy: GetAccessibleRecords<T>\n};\nexport interface AccessibleRecordModel<\n T extends Document, K = unknown\n> extends Model<T, K & QueryHelpers<T>> {\n accessibleBy: GetAccessibleRecords<T>\n}\n\nexport function accessibleRecordsPlugin(schema: Schema<any>) {\n schema.query.accessibleBy = accessibleBy;\n schema.statics.accessibleBy = accessibleBy;\n}\n","import { wrapArray, Normalize, AnyMongoAbility, Generics } from '@casl/ability';\nimport { permittedFieldsOf, PermittedFieldsOptions } from '@casl/ability/extra';\nimport type { Schema, Model, Document } from 'mongoose';\n\nexport type AccessibleFieldsOptions =\n {\n getFields(schema: Schema<Document>): string[]\n } &\n ({ only: string | string[] } | { except: string | string[] });\n\nexport const getSchemaPaths: AccessibleFieldsOptions['getFields'] = schema => Object.keys((schema as { paths: object }).paths);\n\nfunction fieldsOf(schema: Schema<Document>, options: Partial<AccessibleFieldsOptions>) {\n const fields = options.getFields!(schema);\n\n if (!options || !('except' in options)) {\n return fields;\n }\n\n const excludedFields = wrapArray(options.except);\n return fields.filter(field => excludedFields.indexOf(field) === -1);\n}\n\ntype GetAccessibleFields<T extends AccessibleFieldsDocument> = <U extends AnyMongoAbility>(\n this: Model<T> | T,\n ability: U,\n action?: Normalize<Generics<U>['abilities']>[0]\n) => string[];\n\nexport interface AccessibleFieldsModel<T extends AccessibleFieldsDocument> extends Model<T> {\n accessibleFieldsBy: GetAccessibleFields<T>\n}\n\nexport interface AccessibleFieldsDocument extends Document {\n accessibleFieldsBy: GetAccessibleFields<AccessibleFieldsDocument>\n}\n\nfunction modelFieldsGetter() {\n let fieldsFrom: PermittedFieldsOptions<AnyMongoAbility>['fieldsFrom'];\n return (schema: Schema<any>, options: Partial<AccessibleFieldsOptions>) => {\n if (!fieldsFrom) {\n const ALL_FIELDS = options && 'only' in options\n ? wrapArray(options.only as string[])\n : fieldsOf(schema, options);\n fieldsFrom = rule => rule.fields || ALL_FIELDS;\n }\n\n return fieldsFrom;\n };\n}\n\nexport function accessibleFieldsPlugin(\n schema: Schema<any>,\n rawOptions?: Partial<AccessibleFieldsOptions>\n) {\n const options = { getFields: getSchemaPaths, ...rawOptions };\n const fieldsFrom = modelFieldsGetter();\n type ModelOrDoc = Model<AccessibleFieldsDocument> | AccessibleFieldsDocument;\n\n function accessibleFieldsBy(this: ModelOrDoc, ability: AnyMongoAbility, action?: string) {\n const subject = typeof this === 'function' ? this.modelName : this;\n return permittedFieldsOf(ability, action || 'read', subject, {\n fieldsFrom: fieldsFrom(schema, options)\n });\n }\n\n schema.statics.accessibleFieldsBy = accessibleFieldsBy;\n schema.method('accessibleFieldsBy', accessibleFieldsBy);\n}\n"],"names":["convertToMongoQuery","rule","conditions","inverted","$nor","toMongoQuery","ability","subjectType","action","rulesToQuery","failedQuery","modelName","query","where","__forbiddenByCasl__","anyQuery","pre","cb","error","ForbiddenError","from","setMessage","getDefaultErrorMessage","accessibleBy","this","model","TypeError","mongoose","Query","and","$and","accessibleRecordsPlugin","schema","statics","getSchemaPaths","Object","keys","paths","fieldsOf","options","fields","getFields","excludedFields","wrapArray","except","filter","field","indexOf","modelFieldsGetter","fieldsFrom","ALL_FIELDS","only","accessibleFieldsPlugin","rawOptions","accessibleFieldsBy","subject","permittedFieldsOf","method"],"mappings":"4LAGA,SAASA,EAAoBC,SACrBC,EAAaD,EAAKC,kBACjBD,EAAKE,SAAW,CAAEC,KAAM,CAACF,IAAgBA,EAG3C,SAASG,EACdC,EACAC,EACAC,EAAuC,eAEhCC,EAAaH,EAASE,EAAQD,EAAaP,GCRpD,SAASU,EACPJ,EACAE,EACAG,EACAC,GAEAA,EAAMC,MAAM,CAAEC,oBAAqB,UAC7BC,EAAgBH,KAEM,oBAAjBG,EAASC,IAClBD,EAASC,KAAKC,UACNC,EAAQC,EAAeC,KAAKd,GAClCY,EAAMV,OAASA,EACfU,EAAMX,YAAcI,EACpBO,EAAMG,WAAWC,EAAuBJ,IACxCD,EAAGC,aAIAN,EAGT,SAASW,EAEPjB,EACAE,OAEIG,EAAgCa,KAAKb,cAEpCA,EACHA,EAAY,UAAWa,KAAOA,KAAKC,MAAMd,UAAY,SAGlDA,QACG,IAAIe,UAAU,+DAGhBd,EAAQP,EAAaC,EAASK,EAAWH,MAEjC,OAAVI,SACKF,EAAYJ,EAASE,GAAU,OAAQG,EAAWa,KAAKX,gBAGzDW,gBAAgBG,EAASC,MAAQJ,KAAKK,IAAI,CAACjB,IAAUY,KAAKX,MAAM,CAAEiB,KAAM,CAAClB,KAiB3E,SAASmB,EAAwBC,GACtCA,EAAOpB,MAAMW,aAAeA,EAC5BS,EAAOC,QAAQV,aAAeA,QCzDnBW,EAAuDF,GAAUG,OAAOC,KAAMJ,EAA6BK,OAExH,SAASC,EAASN,EAA0BO,SACpCC,EAASD,EAAQE,UAAWT,OAE7BO,KAAa,WAAYA,UACrBC,QAGHE,EAAiBC,EAAUJ,EAAQK,eAClCJ,EAAOK,QAAOC,IAA4C,IAAnCJ,EAAeK,QAAQD,KAiBvD,SAASE,QACHC,QACG,CAACjB,EAAqBO,SACtBU,EAAY,OACTC,EAAaX,GAAW,SAAUA,EACpCI,EAAUJ,EAAQY,MAClBb,EAASN,EAAQO,GACrBU,EAAahD,GAAQA,EAAKuC,QAAUU,SAG/BD,GAIJ,SAASG,EACdpB,EACAqB,SAEMd,iBAAYE,UAAWP,GAAmBmB,SAC1CJ,EAAaD,aAGVM,EAAqChD,EAA0BE,SAChE+C,EAA0B,oBAAT/B,KAAsBA,KAAKb,UAAYa,YACvDgC,EAAkBlD,EAASE,GAAU,OAAQ+C,EAAS,CAC3DN,WAAYA,EAAWjB,EAAQO,KAInCP,EAAOC,QAAQqB,mBAAqBA,EACpCtB,EAAOyB,OAAO,qBAAsBH"}
@@ -1,5 +1,5 @@
1
1
  import { Normalize, AnyMongoAbility, Generics } from '@casl/ability';
2
- import { Schema, Model, Document } from 'mongoose';
2
+ import type { Schema, Model, Document } from 'mongoose';
3
3
  export declare type AccessibleFieldsOptions = {
4
4
  getFields(schema: Schema<Document>): string[];
5
5
  } & ({
@@ -15,5 +15,5 @@ export interface AccessibleFieldsModel<T extends AccessibleFieldsDocument> exten
15
15
  export interface AccessibleFieldsDocument extends Document {
16
16
  accessibleFieldsBy: GetAccessibleFields<AccessibleFieldsDocument>;
17
17
  }
18
- export declare function accessibleFieldsPlugin(schema: Schema<AccessibleFieldsDocument>, rawOptions?: Partial<AccessibleFieldsOptions>): void;
18
+ export declare function accessibleFieldsPlugin(schema: Schema<any>, rawOptions?: Partial<AccessibleFieldsOptions>): void;
19
19
  export {};
@@ -1,10 +1,11 @@
1
1
  import { Normalize, AnyMongoAbility, Generics } from '@casl/ability';
2
- import { Schema, DocumentQuery, Model, Document } from 'mongoose';
3
- declare type GetAccessibleRecords<T extends Document> = <U extends AnyMongoAbility>(ability: U, action?: Normalize<Generics<U>['abilities']>[0]) => DocumentQuery<T, T>;
4
- export interface AccessibleRecordModel<T extends Document, K = {}> extends Model<T, K & {
2
+ import type { Schema, QueryWithHelpers, Model, Document } from 'mongoose';
3
+ declare type GetAccessibleRecords<T extends Document> = <U extends AnyMongoAbility>(ability: U, action?: Normalize<Generics<U>['abilities']>[0]) => QueryWithHelpers<T, T, QueryHelpers<T>>;
4
+ declare type QueryHelpers<T extends Document> = {
5
5
  accessibleBy: GetAccessibleRecords<T>;
6
- }> {
6
+ };
7
+ export interface AccessibleRecordModel<T extends Document, K = unknown> extends Model<T, K & QueryHelpers<T>> {
7
8
  accessibleBy: GetAccessibleRecords<T>;
8
9
  }
9
- export declare function accessibleRecordsPlugin(schema: Schema<Document>): void;
10
+ export declare function accessibleRecordsPlugin(schema: Schema<any>): void;
10
11
  export {};
@@ -1,2 +1,2 @@
1
1
  import { AnyMongoAbility } from '@casl/ability';
2
- export declare function toMongoQuery<T extends AnyMongoAbility>(ability: T, subjectType: Parameters<T['rulesFor']>[1], action: Parameters<T['rulesFor']>[0]): import("@casl/ability/extra").AbilityQuery<object> | null;
2
+ export declare function toMongoQuery<T extends AnyMongoAbility>(ability: T, subjectType: Parameters<T['rulesFor']>[1], action?: Parameters<T['rulesFor']>[0]): import("@casl/ability/extra").AbilityQuery<object> | null;
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@casl/mongoose",
3
- "version": "4.0.0",
3
+ "version": "6.0.0",
4
4
  "description": "Allows to query accessible records from MongoDB based on CASL rules",
5
5
  "main": "dist/es6c/index.js",
6
6
  "es2015": "dist/es6m/index.mjs",
7
- "typings": "index.d.ts",
7
+ "typings": "dist/types/index.d.ts",
8
8
  "exports": {
9
9
  ".": {
10
10
  "import": "./dist/es6m/index.mjs",
@@ -13,7 +13,8 @@
13
13
  },
14
14
  "repository": {
15
15
  "type": "git",
16
- "url": "https://github.com/stalniy/casl.git"
16
+ "url": "https://github.com/stalniy/casl.git",
17
+ "directory": "packages/casl-mongoose"
17
18
  },
18
19
  "publishConfig": {
19
20
  "access": "public"
@@ -21,54 +22,32 @@
21
22
  "homepage": "https://casl.js.org",
22
23
  "scripts": {
23
24
  "prebuild": "rm -rf dist/* && npm run build.types",
24
- "build": "BUILD_TYPES=es6m,es6c rollup -c ../../rollup.config.js -e @casl/ability/extra,@casl/ability,mongoose",
25
- "build.types": "tsc -p tsconfig.build.json",
26
- "lint": "eslint --ext .ts,.js src/ spec/",
27
- "test": "NODE_ENV=test jest --config ../../tools/jest.config.js --env node --runInBand",
25
+ "build": "BUILD_TYPES=es6m,es6c dx rollup -e @casl/ability/extra,@casl/ability,mongoose",
26
+ "build.types": "dx tsc",
27
+ "lint": "dx eslint src/ spec/",
28
+ "test": "dx jest",
28
29
  "prerelease": "npm run lint && npm test && NODE_ENV=production npm run build",
29
- "release": "semantic-release -e ../../tools/semantic-release"
30
+ "release": "dx semantic-release"
30
31
  },
31
32
  "keywords": [
33
+ "casl",
32
34
  "mongo",
33
- "access control",
34
35
  "authorization",
35
36
  "acl",
36
- "security",
37
37
  "permissions"
38
38
  ],
39
39
  "author": "Sergii Stotskyi <sergiy.stotskiy@gmail.com>",
40
40
  "license": "MIT",
41
41
  "peerDependencies": {
42
42
  "@casl/ability": "^3.0.0 || ^4.0.0 || ^5.1.0",
43
- "mongoose": "^4.0.0 || <= 5.10.0"
43
+ "mongoose": "^6.0.0"
44
44
  },
45
45
  "devDependencies": {
46
- "@babel/core": "^7.8.4",
47
- "@babel/plugin-proposal-class-properties": "^7.8.3",
48
- "@babel/plugin-proposal-object-rest-spread": "^7.10.0",
49
- "@babel/plugin-transform-typescript": "^7.10.0",
50
- "@babel/preset-env": "^7.8.4",
51
46
  "@casl/ability": "^5.1.0",
52
- "@rollup/plugin-babel": "^5.0.2",
53
- "@rollup/plugin-node-resolve": "^11.0.0",
54
- "@semantic-release/changelog": "^5.0.1",
55
- "@semantic-release/git": "^9.0.0",
56
- "@types/mongoose": "^5.7.0",
57
- "@typescript-eslint/eslint-plugin": "4.15.0",
47
+ "@casl/dx": "workspace:^1.0.0",
58
48
  "chai": "^4.1.0",
59
49
  "chai-spies": "^1.0.0",
60
- "eslint": "^7.1.0",
61
- "eslint-config-airbnb-base": "^14.1.0",
62
- "eslint-config-airbnb-typescript": "^12.0.0",
63
- "eslint-plugin-import": "^2.20.2",
64
- "jest": "^26.0.0",
65
- "mongoose": "~5.10.0",
66
- "rollup": "^2.10.9",
67
- "rollup-plugin-sourcemaps": "^0.6.2",
68
- "rollup-plugin-terser": "^7.0.0",
69
- "semantic-release": "17.3.2",
70
- "ts-jest": "^26.4.4",
71
- "typescript": "~4.0.0"
50
+ "mongoose": "^6.0.0"
72
51
  },
73
52
  "files": [
74
53
  "dist",
package/CHANGELOG.md DELETED
@@ -1,342 +0,0 @@
1
- # Change Log
2
-
3
- All notable changes to this project will be documented in this file.
4
-
5
- # [4.0.0](https://github.com/stalniy/casl/compare/@casl/mongoose@3.2.2...@casl/mongoose@4.0.0) (2021-02-12)
6
-
7
-
8
- ### Code Refactoring
9
-
10
- * **vue:** adds support for vue 3 ([#444](https://github.com/stalniy/casl/issues/444)) ([e742bcf](https://github.com/stalniy/casl/commit/e742bcf0d187f8283ff171ec9760431759b55910)), closes [#396](https://github.com/stalniy/casl/issues/396)
11
-
12
-
13
- ### Features
14
-
15
- * **angular:** updates angular to v11 ([#421](https://github.com/stalniy/casl/issues/421)) ([ec16bf9](https://github.com/stalniy/casl/commit/ec16bf9e93536c4ec249d2520cf336c1497615a9))
16
- * **mongoose:** throws `ForbiddenError` instead of returning a hard-coded value when user has not permissions to do some action ([917dd01](https://github.com/stalniy/casl/commit/917dd017bd95627f2550fc8f34b4ccf03fea94c5)), closes [#404](https://github.com/stalniy/casl/issues/404)
17
-
18
-
19
- ### BREAKING CHANGES
20
-
21
- * **vue:** refactor to use Vue 3 what introduces a bunch of breaking changes:
22
-
23
- * `Ability` instance is not a required plugin parameter. Previously, we could decide whether to pass ability as plugin parameter or as root component option. Now, the only way is to pass it in plugin:
24
-
25
- **Before**
26
-
27
- ```js
28
- import { abilitiesPlugin } from '@casl/vue';
29
- import Vue from 'vue';
30
- import { ability } from './services/AppAbility';
31
-
32
- Vue.use(abilitiesPlugin);
33
- new Vue({
34
- ability
35
- }).$mount('#app')
36
- ```
37
-
38
- **After**
39
-
40
- ```js
41
- import { abilitiesPlugin } from '@casl/vue';
42
- import { createApp } from 'vue';
43
- import { ability } from './services/AppAbility';
44
-
45
- createApp()
46
- .use(abilitiesPlugin, ability)
47
- .mount('#app');
48
- ```
49
-
50
- * `abilitiesPlugin` no more define global `$ability` and `$can` properties, instead a recommended way to get `AppAbility` instance is by injecting it through [provide/inject API](https://v3.vuejs.org/guide/component-provide-inject.html). To get previous behavior, pass `useGlobalProperties: true` option:
51
-
52
- **Before**
53
-
54
- ```js
55
- import { abilitiesPlugin } from '@casl/vue';
56
- import Vue from 'vue';
57
- import { ability } from './services/AppAbility';
58
-
59
- Vue.use(abilitiesPlugin);
60
- const root = new Vue({
61
- ability
62
- }).$mount('#app')
63
-
64
- console.log(root.$ability)
65
- ```
66
-
67
- **After**
68
-
69
- Recommended way:
70
-
71
- ```js
72
- import { abilitiesPlugin, ABILITY_TOKEN } from '@casl/vue';
73
- import { createApp } from 'vue';
74
- import { ability } from './services/AppAbility';
75
-
76
- const App = {
77
- name: 'App',
78
- inject: {
79
- $ability: { from: ABILITY_TOKEN }
80
- }
81
- };
82
-
83
- const root = createApp(App)
84
- .use(abilitiesPlugin, ability, {
85
- useGlobalProperties: true
86
- })
87
- .mount('#app');
88
-
89
- console.log(root.$ability)
90
- ```
91
-
92
- Backward compatible way:
93
-
94
- ```js
95
- import { abilitiesPlugin } from '@casl/vue';
96
- import { createApp } from 'vue';
97
- import { ability } from './services/AppAbility';
98
-
99
- const root = createApp()
100
- .use(abilitiesPlugin, ability, {
101
- useGlobalProperties: true
102
- })
103
- .mount('#app');
104
-
105
- console.log(root.$ability)
106
- ```
107
-
108
- * `AllCanProps<TAbility>` type was renamed to `CanProps<TAbility>`
109
-
110
- * `@casl/vue` no more augment vue types, so if you decide to use global properties, you will need to augment types by yourself
111
-
112
- **Before**
113
-
114
- @casl/vue augments type of `$ability` to `AnyAbility` and `$can` to `typeof $ability['can']`
115
-
116
- **After**
117
-
118
- create a separate file `src/ability-shim.d.ts` with the next content:
119
-
120
- ```ts
121
- import { AppAbility } from './AppAbility'
122
-
123
- declare module 'vue' {
124
- interface ComponentCustomProperties {
125
- $ability: AppAbility;
126
- $can(this: this, ...args: Parameters<this['$ability']['can']>): boolean;
127
- }
128
- }
129
- ```
130
- * **mongoose:** `accessibleBy` eventually throws `ForbiddenError` instead of returning a hard-coded value
131
-
132
- **Before**:
133
-
134
- ```ts
135
- // ability doesn't allow to read Post
136
- const ability = defineAbility(can => can('manage', 'Comment'));
137
-
138
- try {
139
- const items = await Post.accessibleBy(ability, 'read');
140
- console.log(items); // []
141
- } catch (error) {
142
- console.error(error); // no error thrown
143
- }
144
- ```
145
-
146
- **After**:
147
-
148
- ```ts
149
- // ability doesn't allow to read Post
150
- const ability = defineAbility(can => can('manage', 'Comment'));
151
-
152
- try {
153
- const items = await Post.accessibleBy(ability, 'read');
154
- console.log(items); // not reached, because query fails with error
155
- } catch (error) {
156
- console.error(error); // ForbiddenError thrown
157
- }
158
- ```
159
-
160
- ## [3.2.2](https://github.com/stalniy/casl/compare/@casl/mongoose@3.2.1...@casl/mongoose@3.2.2) (2021-01-05)
161
-
162
-
163
- ### Bug Fixes
164
-
165
- * **mongoose:** simplifies types for `toMongoQuery` helper ([1615f4b](https://github.com/stalniy/casl/commit/1615f4b9ba870cddc190bdf4a504822760a21add))
166
-
167
- ## [3.2.1](https://github.com/stalniy/casl/compare/@casl/mongoose@3.2.0...@casl/mongoose@3.2.1) (2020-12-28)
168
-
169
-
170
- ### Bug Fixes
171
-
172
- * **dist:** adds separate `tsconfig.build.json` to every completementary project ([87742ce](https://github.com/stalniy/casl/commit/87742cec518a8a68d5fc29be2bbc9561cbc7da6c)), closes [#419](https://github.com/stalniy/casl/issues/419)
173
-
174
- # [3.2.0](https://github.com/stalniy/casl/compare/@casl/mongoose@3.1.0...@casl/mongoose@3.2.0) (2020-12-26)
175
-
176
-
177
- ### Bug Fixes
178
-
179
- * **angular:** fixes sourcemap generation for the code built by ngc ([7715263](https://github.com/stalniy/casl/commit/771526379ff8203170a433d71b68644a48ff44eb)), closes [#387](https://github.com/stalniy/casl/issues/387) [#382](https://github.com/stalniy/casl/issues/382)
180
- * **package:** removes `engine` section that points to npm@6 ([eecd12a](https://github.com/stalniy/casl/commit/eecd12ac49f56d6a0f57d1a57fb37487335b5f03)), closes [#417](https://github.com/stalniy/casl/issues/417)
181
-
182
-
183
- ### Features
184
-
185
- * **esm:** adds ESM support for latest Node.js through `exports` prop in package.json ([cac2506](https://github.com/stalniy/casl/commit/cac2506a80c18f194210c2d89108d1d094751fa4)), closes [#331](https://github.com/stalniy/casl/issues/331)
186
-
187
- # [3.1.0](https://github.com/stalniy/casl/compare/@casl/mongoose@3.0.3...@casl/mongoose@3.1.0) (2020-08-20)
188
-
189
-
190
- ### Features
191
-
192
- * **mongoose:** adds `getFields` option to `accessibleFieldsPlugin` ([a93037c](https://github.com/stalniy/casl/commit/a93037cc423649b6ea45347166adc8ea7eeffe9e))
193
-
194
- ## [3.0.3](https://github.com/stalniy/casl/compare/@casl/mongoose@3.0.2...@casl/mongoose@3.0.3) (2020-06-09)
195
-
196
-
197
- ### Bug Fixes
198
-
199
- * **docs:** ensure README and docs for all packages are in sync ([8df3684](https://github.com/stalniy/casl/commit/8df3684b139de0af60c9c37f284a5028ffbf2224)), closes [#338](https://github.com/stalniy/casl/issues/338)
200
-
201
- ## [3.0.2](https://github.com/stalniy/casl/compare/@casl/mongoose@3.0.1...@casl/mongoose@3.0.2) (2020-04-10)
202
-
203
-
204
- ### Bug Fixes
205
-
206
- * **mongoose:** ensure that terser doesn't mangle reserved required props ([83f1d32](https://github.com/stalniy/casl/commit/83f1d32d47cb99335c26fb2ba4aa4e6920cb761c))
207
-
208
- ## [3.0.1](https://github.com/stalniy/casl/compare/@casl/mongoose@3.0.0...@casl/mongoose@3.0.1) (2020-04-09)
209
-
210
-
211
- ### Bug Fixes
212
-
213
- * **mongoose:** adds support for casl/ability@4 in package.json ([ffb887c](https://github.com/stalniy/casl/commit/ffb887c57b7839e0239d59bbcb859b4469782fbd))
214
-
215
- # [3.0.0](https://github.com/stalniy/casl/compare/@casl/mongoose@2.3.3...@casl/mongoose@3.0.0) (2020-04-09)
216
-
217
-
218
- ### Bug Fixes
219
-
220
- * **mongoose:** ensures mongoose works with MongoQuery conditions ([f92b7df](https://github.com/stalniy/casl/commit/f92b7df532ecca24ee05d02cf9388b21f8d242fa)), closes [#249](https://github.com/stalniy/casl/issues/249)
221
- * **mongoose:** fixes mongoose typings ([d320eba](https://github.com/stalniy/casl/commit/d320eba70c14c7fc6700aba3e38fee062fdd9c3a)), closes [#248](https://github.com/stalniy/casl/issues/248)
222
-
223
-
224
- ### Features
225
-
226
- * **mongoose:** adds generics to mongoose types ([6cdf82e](https://github.com/stalniy/casl/commit/6cdf82ee2f547fdb6c5dcd9cb51cef1c4b4c542d)), closes [#256](https://github.com/stalniy/casl/issues/256)
227
- * **mongoose:** simplifies generics for mongoose ([7ff65f7](https://github.com/stalniy/casl/commit/7ff65f75cf715ca9428dda2fe6e0c91715646979)), closes [#107](https://github.com/stalniy/casl/issues/107)
228
-
229
-
230
- ### BREAKING CHANGES
231
-
232
- * **mongoose:** removes deprecated `permittedFieldsPlugin` use `accessibleFieldsPlugin` instead
233
- * **typescript:** weak hand written declaration files are removed as `@casl/mongoose` has been completely rewritten to TypeScript.
234
-
235
- ## [2.3.3](https://github.com/stalniy/casl/compare/@casl/mongoose@2.3.2...@casl/mongoose@2.3.3) (2020-03-13)
236
-
237
-
238
- ### Bug Fixes
239
-
240
- * **mongoose:** adds missing `index.js` file ([804c0dd](https://github.com/stalniy/casl/commit/804c0dd9aeaa5a0a2753cba0677c8150c362d671))
241
- * **mongoose:** makes sure abilityConditions does not override existing `$and` conditions ([#273](https://github.com/stalniy/casl/issues/273)) ([c13300f](https://github.com/stalniy/casl/commit/c13300f37d218d2c0754133557e3795887c6ef3b)), closes [#272](https://github.com/stalniy/casl/issues/272)
242
-
243
- # [@casl/mongoose-v2.3.2](https://github.com/stalniy/casl/compare/@casl/mongoose@2.3.1...@casl/mongoose@2.3.2) (2019-09-14)
244
-
245
-
246
- ### Bug Fixes
247
-
248
- * **mongoose:** mock query result on collection level ([1e8c241](https://github.com/stalniy/casl/commit/1e8c241)), closes [#218](https://github.com/stalniy/casl/issues/218)
249
-
250
- # [@casl/mongoose-v2.3.1](https://github.com/stalniy/casl/compare/@casl/mongoose@2.3.0...@casl/mongoose@2.3.1) (2019-02-10)
251
-
252
-
253
- ### Bug Fixes
254
-
255
- * **packages:** increases peerDependency of [@casl](https://github.com/casl)/ability ([9f6a7b8](https://github.com/stalniy/casl/commit/9f6a7b8)), closes [#119](https://github.com/stalniy/casl/issues/119)
256
-
257
- # [@casl/mongoose-v2.3.0](https://github.com/stalniy/casl/compare/@casl/mongoose@2.2.2...@casl/mongoose@2.3.0) (2018-12-28)
258
-
259
-
260
- ### Features
261
-
262
- * **mongoose:** wraps resulting query into additional `$and` ([1af1c54](https://github.com/stalniy/casl/commit/1af1c54)), closes [#140](https://github.com/stalniy/casl/issues/140)
263
-
264
- # [@casl/mongoose-v2.2.2](https://github.com/stalniy/casl/compare/@casl/mongoose@2.2.1...@casl/mongoose@2.2.2) (2018-11-07)
265
-
266
-
267
- ### Bug Fixes
268
-
269
- * **mongoose:** adds optional options as null type ([#127](https://github.com/stalniy/casl/issues/127)) ([ac3c262](https://github.com/stalniy/casl/commit/ac3c262))
270
-
271
- # [@casl/mongoose-v2.2.1](https://github.com/stalniy/casl/compare/@casl/mongoose@2.2.0...@casl/mongoose@2.2.1) (2018-10-14)
272
-
273
-
274
- ### Bug Fixes
275
-
276
- * **mongoose:** sets the correct `this` for deprecated methods ([488a227](https://github.com/stalniy/casl/commit/488a227)), closes [#116](https://github.com/stalniy/casl/issues/116)
277
-
278
- # [@casl/mongoose-v2.2.0](https://github.com/stalniy/casl/compare/@casl/mongoose@2.1.2...@casl/mongoose@2.2.0) (2018-10-10)
279
-
280
-
281
- ### Bug Fixes
282
-
283
- * **angular:** adding type definitions for accessibleFields ([#117](https://github.com/stalniy/casl/issues/117)) ([a00c02b](https://github.com/stalniy/casl/commit/a00c02b))
284
- * **README:** changes links to [@casl](https://github.com/casl)/ability to point to npm package instead to git root [skip ci] ([a74086b](https://github.com/stalniy/casl/commit/a74086b)), closes [#102](https://github.com/stalniy/casl/issues/102)
285
-
286
-
287
- ### Features
288
-
289
- * **react:can:** updates typescript declarations ([213dcde](https://github.com/stalniy/casl/commit/213dcde))
290
-
291
- <a name="@casl/mongoose-v2.1.2"></a>
292
- # [@casl/mongoose-v2.1.2](https://github.com/stalniy/casl/compare/@casl/mongoose@2.1.1...@casl/mongoose@2.1.2) (2018-07-02)
293
-
294
-
295
- ### Bug Fixes
296
-
297
- * **mongoose:** `accessibleBy` now doesn't change query type ([da7ed74](https://github.com/stalniy/casl/commit/da7ed74)), closes [#87](https://github.com/stalniy/casl/issues/87)
298
-
299
- <a name="2.1.1"></a>
300
- ## [2.1.1](https://github.com/stalniy/casl/compare/@casl/mongoose@2.1.0...@casl/mongoose@2.1.1) (2018-05-06)
301
-
302
-
303
- ### Bug Fixes
304
-
305
- * **mongoose:** fixes d.ts ([9be9989](https://github.com/stalniy/casl/commit/9be9989)), closes [#57](https://github.com/stalniy/casl/issues/57)
306
-
307
-
308
-
309
-
310
- <a name="2.1.0"></a>
311
- # 2.1.0 (2018-04-17)
312
-
313
-
314
- ### Bug Fixes
315
-
316
- * **mongoose:** returns empty result set for Query#count ([f89dfb9](https://github.com/stalniy/casl/commit/f89dfb9)), closes [#52](https://github.com/stalniy/casl/issues/52)
317
- * **typescript:** fixes typings ([d5fc51c](https://github.com/stalniy/casl/commit/d5fc51c)), relates to [#18](https://github.com/stalniy/casl/issues/18)
318
-
319
-
320
- ### Features
321
-
322
- * **mongoose:** adds `permittedFieldsBy` to [@casl](https://github.com/casl)/mongoose ([17bcf9e](https://github.com/stalniy/casl/commit/17bcf9e)), closes [#49](https://github.com/stalniy/casl/issues/49)
323
-
324
-
325
- <a name="2.0.2"></a>
326
- ## 2.0.2 (2018-04-16)
327
-
328
-
329
- ### Bug Fixes
330
-
331
- * **mongoose:** returns empty result set for Query#count ([f89dfb9](https://github.com/stalniy/casl/commit/f89dfb9)), closes [#52](https://github.com/stalniy/casl/issues/52)
332
- * **typescript:** updates d.ts files ([d5fc51c](https://github.com/stalniy/casl/commit/d5fc51c)), closes [#18](https://github.com/stalniy/casl/issues/18)
333
-
334
-
335
- <a name="2.0.1"></a>
336
- # 2.0.1 (2018-03-23)
337
-
338
-
339
- ### Features
340
-
341
- * **package:** adds mongoose plugin
342
- * **package:** adds MongoDB query builder
package/index.d.ts DELETED
@@ -1 +0,0 @@
1
- export * from './dist/types';
package/index.js DELETED
@@ -1 +0,0 @@
1
- module.exports = require('./dist/umd');