Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance typing #112

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 41 additions & 15 deletions lib/AccessControl.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Access, IAccessInfo, Query, IQueryInfo, Permission } from './core';
import { Access, IAccessInfo, Query, IQueryInfo, Permission, AccessControlError } from './core';
import { Action, Possession } from './enums';
import { Grants } from './utils';
/**
* @classdesc
* AccessControl class that implements RBAC (Role-Based Access Control) basics
Expand Down Expand Up @@ -68,7 +70,7 @@ import { Access, IAccessInfo, Query, IQueryInfo, Permission } from './core';
* // since these permissions have common resources, there is an alternative way:
* ac.grant('admin')
* .resource('profile').createAny().readAny(null, ["*", "!password"])
* .resource('video').readAny()..deleteAny();
* .resource('video').readAny().deleteAny();
*
* ac.grant('user')
* .readOwn('profile', ["uid", "email", "address.*", "account.*", "!account.roles"])
Expand Down Expand Up @@ -111,7 +113,7 @@ declare class AccessControl {
* @param {Object|Array} [grants] - A list containing the access grant
* definitions. See the structure of this object in the examples.
*/
constructor(grants?: any);
constructor(grants?: Grants);
/**
* Specifies whether the underlying grants object is frozen and all
* functionality for modifying it is disabled.
Expand Down Expand Up @@ -163,7 +165,7 @@ declare class AccessControl {
* }
* }
*/
getGrants(): any;
getGrants(): Grants;
/**
* Sets all access grants at once, from an object or array. Note that this
* will reset the object and remove all previous grants.
Expand All @@ -177,7 +179,7 @@ declare class AccessControl {
* @throws {AccessControlError} - If called after `.lock()` is called or if
* passed grants object fails inspection.
*/
setGrants(grantsObject: any): AccessControl;
setGrants(grantsObject: Grants): AccessControl;
/**
* Resets the internal grants object and removes all previous grants.
* @chainable
Expand Down Expand Up @@ -504,33 +506,32 @@ declare class AccessControl {
/**
* @private
*/
_removePermission(resources: string | string[], roles?: string | string[], actionPossession?: string): void;
_removePermission(resources: string | string[], roles?: string | string[], actionPossession?: Action): void;
/**
* Documented separately in enums/Action
* @private
*/
static readonly Action: any;
static readonly Action: typeof Action;
/**
* Documented separately in enums/Possession
* @private
*/
static readonly Possession: any;
static readonly Possession: typeof Possession;
/**
* Documented separately in AccessControlError
* @private
*/
static readonly Error: any;
static readonly Error: typeof AccessControlError;
/**
* A utility method for deep cloning the given data object(s) while
* A utility method for deep cloning the given data object while
* filtering its properties by the given attribute (glob) notations.
* Includes all matched properties and removes the rest.
*
* Note that this should be used to manipulate data / arbitrary objects
* with enumerable properties. It will not deal with preserving the
* prototype-chain of the given object.
*
* @param {Object|Array} data - A single or array of data objects
* to be filtered.
* @param {Object} data - A single data objects to be filtered.
* @param {Array|String} attributes - The attribute glob notation(s)
* to be processed. You can use wildcard stars (*) and negate
* the notation by prepending a bang (!). A negated notation
Expand All @@ -543,8 +544,7 @@ declare class AccessControl {
* Passing no parameters or passing an empty string (`""` or `[""]`)
* will empty the source object.
*
* @returns {Object|Array} - Returns the filtered data object or array
* of data objects.
* @returns {Object} - Returns the filtered data object.
*
* @example
* var assets = { notebook: "Mac", car: { brand: "Ford", model: "Mustang", year: 1970, color: "red" } };
Expand All @@ -558,7 +558,33 @@ declare class AccessControl {
* filtered = AccessControl.filter(assets); // or AccessControl.filter(assets, "");
* console.log(assets); // {}
*/
static filter(data: any, attributes: string[]): any;
static filter<T>(data: T, attributes: string[]): Partial<T>;
/**
* A utility method for deep cloning the given data objects while
* filtering its properties by the given attribute (glob) notations.
* Includes all matched properties and removes the rest.
*
* Note that this should be used to manipulate data / arbitrary objects
* with enumerable properties. It will not deal with preserving the
* prototype-chain of the given object.
*
* @param {Array} data - An array of data objects
* to be filtered.
* @param {Array|String} attributes - The attribute glob notation(s)
* to be processed. You can use wildcard stars (*) and negate
* the notation by prepending a bang (!). A negated notation
* will be excluded. Order of the globs do not matter, they will
* be logically sorted. Loose globs will be processed first and
* verbose globs or normal notations will be processed last.
* e.g. `[ "car.model", "*", "!car.*" ]`
* will be sorted as:
* `[ "*", "!car.*", "car.model" ]`.
* Passing no parameters or passing an empty string (`""` or `[""]`)
* will empty the source object.
*
* @returns {Array} - Returns the filtered array of data objects.
*/
static filter<T>(data: T[], attributes: string[]): Partial<T>[];
/**
* Checks whether the given object is an instance of `AccessControl.Error`.
* @name AccessControl.isACError
Expand Down
16 changes: 13 additions & 3 deletions lib/AccessControl.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ var utils_1 = require("./utils");
* // since these permissions have common resources, there is an alternative way:
* ac.grant('admin')
* .resource('profile').createAny().readAny(null, ["*", "!password"])
* .resource('video').readAny()..deleteAny();
* .resource('video').readAny().deleteAny();
*
* ac.grant('user')
* .readOwn('profile', ["uid", "email", "address.*", "account.*", "!account.roles"])
Expand Down Expand Up @@ -246,7 +246,17 @@ var AccessControl = /** @class */ (function () {
* // underlying grants model is not changed
*/
AccessControl.prototype.lock = function () {
utils_1.utils.lockAC(this);
if (!this._grants || Object.keys(this._grants).length === 0) {
throw new core_1.AccessControlError('Cannot lock empty or invalid grants model.');
}
var locked = this.isLocked && Object.isFrozen(this._grants);
if (!locked)
locked = Boolean(utils_1.utils.deepFreeze(this._grants));
/* istanbul ignore next */
if (!locked) {
throw new core_1.AccessControlError("Could not lock grants: " + typeof this._grants);
}
this._isLocked = locked;
return this;
};
/**
Expand Down Expand Up @@ -643,7 +653,7 @@ var AccessControl = /** @class */ (function () {
throw new core_1.AccessControlError("Invalid role(s): " + JSON.stringify(roles));
}
}
utils_1.utils.eachRoleResource(this._grants, function (role, resource, permissions) {
utils_1.utils.eachRoleResource(this._grants, function (role, resource) {
if (resources.indexOf(resource) >= 0
// roles is optional. so remove if role is not defined.
// if defined, check if the current role is in the list.
Expand Down
3 changes: 2 additions & 1 deletion lib/core/Access.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AccessControl } from '../';
import { IAccessInfo } from '../core';
import { Grants } from '../utils';
/**
* Represents the inner `Access` class that helps build an access information
* to be granted or denied; and finally commits it to the underlying grants
Expand Down Expand Up @@ -27,7 +28,7 @@ declare class Access {
* @protected
* @type {Any}
*/
protected _grants: any;
protected _grants: Grants;
/**
* Initializes a new instance of `Access`.
* @private
Expand Down
4 changes: 2 additions & 2 deletions lib/core/Access.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ var Access = /** @class */ (function () {
*/
this._ = {};
this._ac = ac;
this._grants = ac._grants;
this._grants = ac.getGrants();
this._.denied = denied;
if (typeof roleOrInfo === 'string' || Array.isArray(roleOrInfo)) {
this.role(roleOrInfo);
Expand Down Expand Up @@ -187,7 +187,7 @@ var Access = /** @class */ (function () {
* @returns {Access}
*/
Access.prototype.lock = function () {
utils_1.utils.lockAC(this._ac);
this._ac.lock();
return this;
};
/**
Expand Down
7 changes: 4 additions & 3 deletions lib/core/IAccessInfo.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Action, Possession } from "../enums";
/**
* An interface that defines an access information to be granted or denied.
* When you start a method chain with `AccessControl#grant` or `AccessControl#deny`
Expand Down Expand Up @@ -30,16 +31,16 @@ interface IAccessInfo {
* for possible values.
* @type {String}
*/
action?: string;
action?: Action;
/**
* Defines the possession of the resource(s) for the specified action.
* See {@link ?api=ac#AccessControl.Possession|`AccessControl.Possession` enumeration}
* for possible values.
* @type {String}
*/
possession?: string;
possession?: Possession;
/**
* Single or multiple roles for this access information.
* Flag for denied access.
* @private
* @type {String|Array<String>}
*/
Expand Down
5 changes: 3 additions & 2 deletions lib/core/IQueryInfo.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Action, Possession } from "../enums";
/**
* An interface that defines an access information to be queried.
* When you start a method chain with `AccessControl#can` method, you're
Expand All @@ -23,13 +24,13 @@ interface IQueryInfo {
* for possible values.
* @type {String}
*/
action?: string;
action?: Action;
/**
* Defines the possession of the resource for the specified action.
* See {@link ?api=ac#AccessControl.Possession|`AccessControl.Possession` enumeration}
* for possible values.
* @type {String}
*/
possession?: string;
possession?: Possession;
}
export { IQueryInfo };
22 changes: 13 additions & 9 deletions lib/core/Permission.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ declare class Permission {
* @type {Array<String>}
* @readonly
*/
readonly roles: string[];
readonly roles: string | string[];
/**
* Specifies the target resource for which the permission is queried for.
*
Expand Down Expand Up @@ -92,16 +92,20 @@ declare class Permission {
*/
readonly granted: boolean;
/**
* Filters the given data object (or array of objects) by the permission
* attributes and returns this data with allowed attributes.
* Filters the given data object by the permission attributes and returns
* this data with allowed attributes.
*
* @param {Object|Array} data
* Data object to be filtered. Either a single object or array
* of objects.
* @param {Object} data Data object to be filtered.
* @returns {Object} The filtered data object.
*/
filter<T>(data: T): Partial<T>;
/**
* Filters the given array of objects by the permission attributes and
* returns this data with allowed attributes.
*
* @returns {Object|Array}
* The filtered data object.
* @param {Array} data Data objects to be filtered.
* @returns {Array} The filtered data objects.
*/
filter(data: any): any;
filter<T>(data: T[]): Partial<T>[];
}
export { Permission };
5 changes: 3 additions & 2 deletions lib/core/Query.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { IQueryInfo, Permission } from '../core';
import { Grants } from '../utils';
/**
* Represents the inner `Query` class that helps build an access information
* for querying and checking permissions, from the underlying grants model.
Expand All @@ -20,7 +21,7 @@ declare class Query {
* @protected
* @type {Any}
*/
protected _grants: any;
protected _grants: Grants;
/**
* Initializes a new instance of `Query`.
* @private
Expand All @@ -32,7 +33,7 @@ declare class Query {
* Either a single or array of roles or an
* {@link ?api=ac#AccessControl~IQueryInfo|`IQueryInfo` arbitrary object}.
*/
constructor(grants: any, roleOrInfo?: string | string[] | IQueryInfo);
constructor(grants: Grants, roleOrInfo?: string | string[] | IQueryInfo);
/**
* A chainer method that sets the role(s) for this `Query` instance.
* @param {String|Array<String>} roles
Expand Down
Loading