@casl/mongoose 4.0.2 → 6.0.1
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 +17 -14
- package/dist/es6c/index.js +1 -1
- package/dist/es6c/index.js.map +1 -1
- package/dist/es6m/index.mjs +1 -1
- package/dist/es6m/index.mjs.map +1 -1
- package/dist/types/accessible_fields.d.ts +1 -1
- package/dist/types/accessible_records.d.ts +6 -5
- package/dist/types/mongo.d.ts +1 -1
- package/package.json +16 -36
- package/CHANGELOG.md +0 -240
- package/index.d.ts +0 -1
- package/index.js +0 -1
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
109
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 {
|
package/dist/es6c/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});var t=require("@casl/ability");var
|
|
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
|
package/dist/es6c/index.js.map
CHANGED
|
@@ -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
|
|
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"}
|
package/dist/es6m/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{ForbiddenError as t,getDefaultErrorMessage as n,wrapArray as o}from"@casl/ability";import
|
|
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
|
package/dist/es6m/index.mjs.map
CHANGED
|
@@ -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
|
|
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"}
|
|
@@ -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<
|
|
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 type { Schema,
|
|
3
|
-
declare type GetAccessibleRecords<T extends Document> = <U extends AnyMongoAbility>(ability: U, action?: Normalize<Generics<U>['abilities']>[0]) =>
|
|
4
|
-
|
|
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<
|
|
10
|
+
export declare function accessibleRecordsPlugin(schema: Schema<any>): void;
|
|
10
11
|
export {};
|
package/dist/types/mongo.d.ts
CHANGED
|
@@ -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
|
|
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": "
|
|
3
|
+
"version": "6.0.1",
|
|
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,33 @@
|
|
|
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
|
|
25
|
-
"build.types": "tsc
|
|
26
|
-
"lint": "eslint
|
|
27
|
-
"test": "
|
|
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": "
|
|
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
|
-
"@casl/ability": "^3.0.0 || ^4.0.0 || ^5.1.0",
|
|
43
|
-
"mongoose": "^
|
|
42
|
+
"@casl/ability": "^3.0.0 || ^4.0.0 || ^5.1.0 || ^6.0.0",
|
|
43
|
+
"mongoose": "^6.0.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@
|
|
47
|
-
"@
|
|
48
|
-
"@
|
|
49
|
-
"@babel/plugin-transform-typescript": "^7.10.0",
|
|
50
|
-
"@babel/preset-env": "^7.8.4",
|
|
51
|
-
"@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.21.0",
|
|
46
|
+
"@casl/ability": "^6.0.0",
|
|
47
|
+
"@casl/dx": "workspace:^1.0.0",
|
|
48
|
+
"@types/jest": "^26.0.22",
|
|
58
49
|
"chai": "^4.1.0",
|
|
59
50
|
"chai-spies": "^1.0.0",
|
|
60
|
-
"
|
|
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"
|
|
51
|
+
"mongoose": "^6.0.0"
|
|
72
52
|
},
|
|
73
53
|
"files": [
|
|
74
54
|
"dist",
|
package/CHANGELOG.md
DELETED
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
# Change Log
|
|
2
|
-
|
|
3
|
-
All notable changes to this project will be documented in this file.
|
|
4
|
-
|
|
5
|
-
## [4.0.2](https://github.com/stalniy/casl/compare/@casl/mongoose@4.0.1...@casl/mongoose@4.0.2) (2021-04-12)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
### Bug Fixes
|
|
9
|
-
|
|
10
|
-
* **mongoose:** uses `mongoose` as commonjs module ([c98506b](https://github.com/stalniy/casl/commit/c98506b77ebd6b3068040f512012e12891749b87))
|
|
11
|
-
|
|
12
|
-
## [4.0.1](https://github.com/stalniy/casl/compare/@casl/mongoose@4.0.0...@casl/mongoose@4.0.1) (2021-02-12)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
### Bug Fixes
|
|
16
|
-
|
|
17
|
-
* **changelog:** removes unrelated entries from changelog ([5437622](https://github.com/stalniy/casl/commit/543762224e329cda02f786c585998217581c2f3b))
|
|
18
|
-
|
|
19
|
-
# [4.0.0](https://github.com/stalniy/casl/compare/@casl/mongoose@3.2.2...@casl/mongoose@4.0.0) (2021-02-12)
|
|
20
|
-
|
|
21
|
-
### Features
|
|
22
|
-
|
|
23
|
-
* **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)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
### BREAKING CHANGES
|
|
27
|
-
|
|
28
|
-
* **mongoose:** `accessibleBy` eventually throws `ForbiddenError` instead of returning a hard-coded value
|
|
29
|
-
|
|
30
|
-
**Before**:
|
|
31
|
-
|
|
32
|
-
```ts
|
|
33
|
-
// ability doesn't allow to read Post
|
|
34
|
-
const ability = defineAbility(can => can('manage', 'Comment'));
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
const items = await Post.accessibleBy(ability, 'read');
|
|
38
|
-
console.log(items); // []
|
|
39
|
-
} catch (error) {
|
|
40
|
-
console.error(error); // no error thrown
|
|
41
|
-
}
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
**After**:
|
|
45
|
-
|
|
46
|
-
```ts
|
|
47
|
-
// ability doesn't allow to read Post
|
|
48
|
-
const ability = defineAbility(can => can('manage', 'Comment'));
|
|
49
|
-
|
|
50
|
-
try {
|
|
51
|
-
const items = await Post.accessibleBy(ability, 'read');
|
|
52
|
-
console.log(items); // not reached, because query fails with error
|
|
53
|
-
} catch (error) {
|
|
54
|
-
console.error(error); // ForbiddenError thrown
|
|
55
|
-
}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
## [3.2.2](https://github.com/stalniy/casl/compare/@casl/mongoose@3.2.1...@casl/mongoose@3.2.2) (2021-01-05)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
### Bug Fixes
|
|
62
|
-
|
|
63
|
-
* **mongoose:** simplifies types for `toMongoQuery` helper ([1615f4b](https://github.com/stalniy/casl/commit/1615f4b9ba870cddc190bdf4a504822760a21add))
|
|
64
|
-
|
|
65
|
-
## [3.2.1](https://github.com/stalniy/casl/compare/@casl/mongoose@3.2.0...@casl/mongoose@3.2.1) (2020-12-28)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
### Bug Fixes
|
|
69
|
-
|
|
70
|
-
* **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)
|
|
71
|
-
|
|
72
|
-
# [3.2.0](https://github.com/stalniy/casl/compare/@casl/mongoose@3.1.0...@casl/mongoose@3.2.0) (2020-12-26)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
### Bug Fixes
|
|
76
|
-
|
|
77
|
-
* **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)
|
|
78
|
-
* **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)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
### Features
|
|
82
|
-
|
|
83
|
-
* **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)
|
|
84
|
-
|
|
85
|
-
# [3.1.0](https://github.com/stalniy/casl/compare/@casl/mongoose@3.0.3...@casl/mongoose@3.1.0) (2020-08-20)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
### Features
|
|
89
|
-
|
|
90
|
-
* **mongoose:** adds `getFields` option to `accessibleFieldsPlugin` ([a93037c](https://github.com/stalniy/casl/commit/a93037cc423649b6ea45347166adc8ea7eeffe9e))
|
|
91
|
-
|
|
92
|
-
## [3.0.3](https://github.com/stalniy/casl/compare/@casl/mongoose@3.0.2...@casl/mongoose@3.0.3) (2020-06-09)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
### Bug Fixes
|
|
96
|
-
|
|
97
|
-
* **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)
|
|
98
|
-
|
|
99
|
-
## [3.0.2](https://github.com/stalniy/casl/compare/@casl/mongoose@3.0.1...@casl/mongoose@3.0.2) (2020-04-10)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
### Bug Fixes
|
|
103
|
-
|
|
104
|
-
* **mongoose:** ensure that terser doesn't mangle reserved required props ([83f1d32](https://github.com/stalniy/casl/commit/83f1d32d47cb99335c26fb2ba4aa4e6920cb761c))
|
|
105
|
-
|
|
106
|
-
## [3.0.1](https://github.com/stalniy/casl/compare/@casl/mongoose@3.0.0...@casl/mongoose@3.0.1) (2020-04-09)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
### Bug Fixes
|
|
110
|
-
|
|
111
|
-
* **mongoose:** adds support for casl/ability@4 in package.json ([ffb887c](https://github.com/stalniy/casl/commit/ffb887c57b7839e0239d59bbcb859b4469782fbd))
|
|
112
|
-
|
|
113
|
-
# [3.0.0](https://github.com/stalniy/casl/compare/@casl/mongoose@2.3.3...@casl/mongoose@3.0.0) (2020-04-09)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
### Bug Fixes
|
|
117
|
-
|
|
118
|
-
* **mongoose:** ensures mongoose works with MongoQuery conditions ([f92b7df](https://github.com/stalniy/casl/commit/f92b7df532ecca24ee05d02cf9388b21f8d242fa)), closes [#249](https://github.com/stalniy/casl/issues/249)
|
|
119
|
-
* **mongoose:** fixes mongoose typings ([d320eba](https://github.com/stalniy/casl/commit/d320eba70c14c7fc6700aba3e38fee062fdd9c3a)), closes [#248](https://github.com/stalniy/casl/issues/248)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
### Features
|
|
123
|
-
|
|
124
|
-
* **mongoose:** adds generics to mongoose types ([6cdf82e](https://github.com/stalniy/casl/commit/6cdf82ee2f547fdb6c5dcd9cb51cef1c4b4c542d)), closes [#256](https://github.com/stalniy/casl/issues/256)
|
|
125
|
-
* **mongoose:** simplifies generics for mongoose ([7ff65f7](https://github.com/stalniy/casl/commit/7ff65f75cf715ca9428dda2fe6e0c91715646979)), closes [#107](https://github.com/stalniy/casl/issues/107)
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
### BREAKING CHANGES
|
|
129
|
-
|
|
130
|
-
* **mongoose:** removes deprecated `permittedFieldsPlugin` use `accessibleFieldsPlugin` instead
|
|
131
|
-
* **typescript:** weak hand written declaration files are removed as `@casl/mongoose` has been completely rewritten to TypeScript.
|
|
132
|
-
|
|
133
|
-
## [2.3.3](https://github.com/stalniy/casl/compare/@casl/mongoose@2.3.2...@casl/mongoose@2.3.3) (2020-03-13)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
### Bug Fixes
|
|
137
|
-
|
|
138
|
-
* **mongoose:** adds missing `index.js` file ([804c0dd](https://github.com/stalniy/casl/commit/804c0dd9aeaa5a0a2753cba0677c8150c362d671))
|
|
139
|
-
* **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)
|
|
140
|
-
|
|
141
|
-
# [@casl/mongoose-v2.3.2](https://github.com/stalniy/casl/compare/@casl/mongoose@2.3.1...@casl/mongoose@2.3.2) (2019-09-14)
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
### Bug Fixes
|
|
145
|
-
|
|
146
|
-
* **mongoose:** mock query result on collection level ([1e8c241](https://github.com/stalniy/casl/commit/1e8c241)), closes [#218](https://github.com/stalniy/casl/issues/218)
|
|
147
|
-
|
|
148
|
-
# [@casl/mongoose-v2.3.1](https://github.com/stalniy/casl/compare/@casl/mongoose@2.3.0...@casl/mongoose@2.3.1) (2019-02-10)
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
### Bug Fixes
|
|
152
|
-
|
|
153
|
-
* **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)
|
|
154
|
-
|
|
155
|
-
# [@casl/mongoose-v2.3.0](https://github.com/stalniy/casl/compare/@casl/mongoose@2.2.2...@casl/mongoose@2.3.0) (2018-12-28)
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
### Features
|
|
159
|
-
|
|
160
|
-
* **mongoose:** wraps resulting query into additional `$and` ([1af1c54](https://github.com/stalniy/casl/commit/1af1c54)), closes [#140](https://github.com/stalniy/casl/issues/140)
|
|
161
|
-
|
|
162
|
-
# [@casl/mongoose-v2.2.2](https://github.com/stalniy/casl/compare/@casl/mongoose@2.2.1...@casl/mongoose@2.2.2) (2018-11-07)
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
### Bug Fixes
|
|
166
|
-
|
|
167
|
-
* **mongoose:** adds optional options as null type ([#127](https://github.com/stalniy/casl/issues/127)) ([ac3c262](https://github.com/stalniy/casl/commit/ac3c262))
|
|
168
|
-
|
|
169
|
-
# [@casl/mongoose-v2.2.1](https://github.com/stalniy/casl/compare/@casl/mongoose@2.2.0...@casl/mongoose@2.2.1) (2018-10-14)
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
### Bug Fixes
|
|
173
|
-
|
|
174
|
-
* **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)
|
|
175
|
-
|
|
176
|
-
# [@casl/mongoose-v2.2.0](https://github.com/stalniy/casl/compare/@casl/mongoose@2.1.2...@casl/mongoose@2.2.0) (2018-10-10)
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
### Bug Fixes
|
|
180
|
-
|
|
181
|
-
* **angular:** adding type definitions for accessibleFields ([#117](https://github.com/stalniy/casl/issues/117)) ([a00c02b](https://github.com/stalniy/casl/commit/a00c02b))
|
|
182
|
-
* **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)
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
### Features
|
|
186
|
-
|
|
187
|
-
* **react:can:** updates typescript declarations ([213dcde](https://github.com/stalniy/casl/commit/213dcde))
|
|
188
|
-
|
|
189
|
-
<a name="@casl/mongoose-v2.1.2"></a>
|
|
190
|
-
# [@casl/mongoose-v2.1.2](https://github.com/stalniy/casl/compare/@casl/mongoose@2.1.1...@casl/mongoose@2.1.2) (2018-07-02)
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
### Bug Fixes
|
|
194
|
-
|
|
195
|
-
* **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)
|
|
196
|
-
|
|
197
|
-
<a name="2.1.1"></a>
|
|
198
|
-
## [2.1.1](https://github.com/stalniy/casl/compare/@casl/mongoose@2.1.0...@casl/mongoose@2.1.1) (2018-05-06)
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
### Bug Fixes
|
|
202
|
-
|
|
203
|
-
* **mongoose:** fixes d.ts ([9be9989](https://github.com/stalniy/casl/commit/9be9989)), closes [#57](https://github.com/stalniy/casl/issues/57)
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
<a name="2.1.0"></a>
|
|
209
|
-
# 2.1.0 (2018-04-17)
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
### Bug Fixes
|
|
213
|
-
|
|
214
|
-
* **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)
|
|
215
|
-
* **typescript:** fixes typings ([d5fc51c](https://github.com/stalniy/casl/commit/d5fc51c)), relates to [#18](https://github.com/stalniy/casl/issues/18)
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
### Features
|
|
219
|
-
|
|
220
|
-
* **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)
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
<a name="2.0.2"></a>
|
|
224
|
-
## 2.0.2 (2018-04-16)
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
### Bug Fixes
|
|
228
|
-
|
|
229
|
-
* **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)
|
|
230
|
-
* **typescript:** updates d.ts files ([d5fc51c](https://github.com/stalniy/casl/commit/d5fc51c)), closes [#18](https://github.com/stalniy/casl/issues/18)
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
<a name="2.0.1"></a>
|
|
234
|
-
# 2.0.1 (2018-03-23)
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
### Features
|
|
238
|
-
|
|
239
|
-
* **package:** adds mongoose plugin
|
|
240
|
-
* **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');
|