@via-profit/ability 3.2.0 → 3.3.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/CHANGELOG.md +2 -129
- package/CONTRIBUTING.md +14 -14
- package/LICENSE +21 -21
- package/README.md +1346 -1325
- package/SECURITY.md +33 -33
- package/dist/core/AbilityPolicy.d.ts +1 -1
- package/dist/core/AbilityResolver.d.ts +1 -1
- package/dist/core/AbilityResult.d.ts +1 -1
- package/dist/core/AbilityRuleSet.d.ts +1 -1
- package/dist/core/AbilityTypeGenerator.d.ts +55 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +21 -54
- package/dist/parsers/dsl/AbilityDSLParser.d.ts +1 -1
- package/dist/parsers/json/AbilityJSONParser.d.ts +1 -1
- package/package.json +73 -73
package/SECURITY.md
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
# Security Policy
|
|
2
|
-
|
|
3
|
-
## Reporting a Vulnerability
|
|
4
|
-
|
|
5
|
-
I take the security of `@via-profit/ability` seriously. If you discover a security vulnerability, please report it responsibly.
|
|
6
|
-
|
|
7
|
-
### How to Report a Vulnerability
|
|
8
|
-
|
|
9
|
-
**Please DO NOT create a public GitHub issue for security vulnerabilities.**
|
|
10
|
-
|
|
11
|
-
Instead, send the details directly to me:
|
|
12
|
-
|
|
13
|
-
- **Email**: [delhsmail@gmail.com](mailto:delhsmail@gmail.com)
|
|
14
|
-
- **Author**: Vasily Novosad
|
|
15
|
-
- **Timezone**: UTC+5 (for coordinating response time)
|
|
16
|
-
|
|
17
|
-
### What to Include
|
|
18
|
-
|
|
19
|
-
To help me address the issue quickly, please include:
|
|
20
|
-
|
|
21
|
-
- Description of the vulnerability
|
|
22
|
-
- Steps to reproduce (if applicable)
|
|
23
|
-
- Potential impact
|
|
24
|
-
- Suggestions for fixing (if any)
|
|
25
|
-
|
|
26
|
-
### Process
|
|
27
|
-
|
|
28
|
-
1. I will acknowledge your report within 48 hours
|
|
29
|
-
2. I will assess the vulnerability
|
|
30
|
-
3. Work on a fix will begin depending on severity
|
|
31
|
-
4. After the fix is released, I will notify you and acknowledge your contribution (if you agree)
|
|
32
|
-
|
|
33
|
-
Thank you for helping keep this project secure!
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Reporting a Vulnerability
|
|
4
|
+
|
|
5
|
+
I take the security of `@via-profit/ability` seriously. If you discover a security vulnerability, please report it responsibly.
|
|
6
|
+
|
|
7
|
+
### How to Report a Vulnerability
|
|
8
|
+
|
|
9
|
+
**Please DO NOT create a public GitHub issue for security vulnerabilities.**
|
|
10
|
+
|
|
11
|
+
Instead, send the details directly to me:
|
|
12
|
+
|
|
13
|
+
- **Email**: [delhsmail@gmail.com](mailto:delhsmail@gmail.com)
|
|
14
|
+
- **Author**: Vasily Novosad
|
|
15
|
+
- **Timezone**: UTC+5 (for coordinating response time)
|
|
16
|
+
|
|
17
|
+
### What to Include
|
|
18
|
+
|
|
19
|
+
To help me address the issue quickly, please include:
|
|
20
|
+
|
|
21
|
+
- Description of the vulnerability
|
|
22
|
+
- Steps to reproduce (if applicable)
|
|
23
|
+
- Potential impact
|
|
24
|
+
- Suggestions for fixing (if any)
|
|
25
|
+
|
|
26
|
+
### Process
|
|
27
|
+
|
|
28
|
+
1. I will acknowledge your report within 48 hours
|
|
29
|
+
2. I will assess the vulnerability
|
|
30
|
+
3. Work on a fix will begin depending on severity
|
|
31
|
+
4. After the fix is released, I will notify you and acknowledge your contribution (if you agree)
|
|
32
|
+
|
|
33
|
+
Thank you for helping keep this project secure!
|
|
@@ -3,7 +3,7 @@ import AbilityMatch from './AbilityMatch';
|
|
|
3
3
|
import AbilityCompare, { AbilityCompareCodeType } from './AbilityCompare';
|
|
4
4
|
import AbilityPolicyEffect, { AbilityPolicyEffectCodeType } from './AbilityPolicyEffect';
|
|
5
5
|
import { AbilityExplain } from './AbilityExplain';
|
|
6
|
-
import { ResourceObject } from './
|
|
6
|
+
import { ResourceObject } from './AbilityTypeGenerator';
|
|
7
7
|
export type AbilityPolicyConfig = {
|
|
8
8
|
readonly permission: string;
|
|
9
9
|
readonly effect: AbilityPolicyEffectCodeType;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import AbilityPolicy from './AbilityPolicy';
|
|
2
2
|
import { AbilityResult } from './AbilityResult';
|
|
3
|
-
import { ResourcesMap } from './
|
|
3
|
+
import { ResourcesMap } from './AbilityTypeGenerator';
|
|
4
4
|
import { AbilityCacheAdapter } from '../cache/AbilityCacheAdapter';
|
|
5
5
|
export type AbilityResolverOptions = {
|
|
6
6
|
readonly cache?: AbilityCacheAdapter | null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AbilityExplain } from './AbilityExplain';
|
|
2
|
-
import { ResourceObject } from './
|
|
2
|
+
import { ResourceObject } from './AbilityTypeGenerator';
|
|
3
3
|
import AbilityPolicy from './AbilityPolicy';
|
|
4
4
|
import AbilityPolicyEffect from './AbilityPolicyEffect';
|
|
5
5
|
export declare class AbilityResult<Resource extends ResourceObject = Record<string, unknown>> {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import AbilityRule, { AbilityRuleConfig } from './AbilityRule';
|
|
2
2
|
import AbilityCompare, { AbilityCompareCodeType } from './AbilityCompare';
|
|
3
3
|
import AbilityMatch from './AbilityMatch';
|
|
4
|
-
import { ResourceObject } from './
|
|
4
|
+
import { ResourceObject } from './AbilityTypeGenerator';
|
|
5
5
|
export type AbilityRuleSetConfig = {
|
|
6
6
|
readonly id?: string | null;
|
|
7
7
|
readonly name?: string | null;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import AbilityPolicy from './AbilityPolicy';
|
|
2
|
+
export type Primitive = string | number | boolean | null | undefined;
|
|
3
|
+
export type NestedDict<T = Primitive> = {
|
|
4
|
+
[key: string]: NestedDict<T> | T;
|
|
5
|
+
};
|
|
6
|
+
export type ResourceObject = Record<string, unknown>;
|
|
7
|
+
export type ResourcesMap = Record<string, ResourceObject>;
|
|
8
|
+
export declare class AbilityTypeGenerator {
|
|
9
|
+
readonly policies: readonly AbilityPolicy[];
|
|
10
|
+
constructor(policies: readonly AbilityPolicy[]);
|
|
11
|
+
/**
|
|
12
|
+
* Generates TypeScript type definitions based on the provided policies.
|
|
13
|
+
* @returns A generated type definitions.
|
|
14
|
+
*/
|
|
15
|
+
generateTypeDefs(): string;
|
|
16
|
+
/**
|
|
17
|
+
* Determines TypeScript type based on the rule
|
|
18
|
+
* @param rule - The rule to analyze
|
|
19
|
+
* @returns TypeScript type as string
|
|
20
|
+
*/
|
|
21
|
+
private determineTypeFromRule;
|
|
22
|
+
/**
|
|
23
|
+
* Gets TypeScript type for array values
|
|
24
|
+
* @param resource - The resource value to analyze
|
|
25
|
+
* @returns TypeScript array type as string
|
|
26
|
+
*/
|
|
27
|
+
private getArrayType;
|
|
28
|
+
/**
|
|
29
|
+
* Gets primitive TypeScript type for a value
|
|
30
|
+
* @param value - The value to analyze
|
|
31
|
+
* @returns TypeScript primitive type as string
|
|
32
|
+
*/
|
|
33
|
+
private getPrimitiveType;
|
|
34
|
+
/**
|
|
35
|
+
* Builds nested structure from flat paths
|
|
36
|
+
* Example: 'user.profile.name' -> { user: { profile: { name: 'string' } } }
|
|
37
|
+
* @param flatStructure - Flat structure with dot notation paths
|
|
38
|
+
* @returns Nested object structure
|
|
39
|
+
*/
|
|
40
|
+
private buildNestedStructure;
|
|
41
|
+
/**
|
|
42
|
+
* Formats type structure into a string
|
|
43
|
+
* @param structure - Nested type structure
|
|
44
|
+
* @returns Formatted TypeScript type definition string
|
|
45
|
+
*/
|
|
46
|
+
private formatTypeDefinitions;
|
|
47
|
+
/**
|
|
48
|
+
* Recursively formats nested object
|
|
49
|
+
* @param obj - Object to format
|
|
50
|
+
* @param indent - Current indentation level
|
|
51
|
+
* @returns Formatted string
|
|
52
|
+
*/
|
|
53
|
+
private formatNestedObject;
|
|
54
|
+
}
|
|
55
|
+
export default AbilityTypeGenerator;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export * from './core/AbilityCompare';
|
|
|
3
3
|
export * from './core/AbilityCondition';
|
|
4
4
|
export * from './core/AbilityError';
|
|
5
5
|
export * from './core/AbilityMatch';
|
|
6
|
-
export * from './core/
|
|
6
|
+
export * from './core/AbilityTypeGenerator';
|
|
7
7
|
export * from './core/AbilityPolicy';
|
|
8
8
|
export * from './core/AbilityPolicyEffect';
|
|
9
9
|
export * from './core/AbilityResolver';
|
package/dist/index.js
CHANGED
|
@@ -94,56 +94,20 @@ class AbilityMatch extends AbilityCode {
|
|
|
94
94
|
static mismatch = new AbilityMatch('mismatch');
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
class
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
* @param path - The path to the property in dot/bracket notation.
|
|
102
|
-
* @param value - The value to set at the specified path.
|
|
103
|
-
*/
|
|
104
|
-
static setValueDotValue(object, path, value) {
|
|
105
|
-
if (!path || path.trim().length === 0) {
|
|
106
|
-
throw new AbilityParserError(`Invalid path provided on a [${path}]`);
|
|
107
|
-
}
|
|
108
|
-
const way = path.replace(/\[/g, '.').replace(/]/g, '').split('.');
|
|
109
|
-
const last = way.pop();
|
|
110
|
-
if (!last) {
|
|
111
|
-
throw new AbilityParserError(`Invalid path provided on a [${path}]`);
|
|
112
|
-
}
|
|
113
|
-
const lastObj = way.reduce((acc, key, index, array) => {
|
|
114
|
-
const currentValue = acc[key];
|
|
115
|
-
const nextKey = array[index + 1];
|
|
116
|
-
const shouldBeArray = nextKey !== undefined && isFinite(Number(nextKey));
|
|
117
|
-
if (currentValue === undefined || currentValue === null) {
|
|
118
|
-
// Create missing property
|
|
119
|
-
const newValue = shouldBeArray ? [] : {};
|
|
120
|
-
acc[key] = newValue;
|
|
121
|
-
return newValue;
|
|
122
|
-
}
|
|
123
|
-
if (typeof currentValue !== 'object') {
|
|
124
|
-
throw new AbilityParserError(`Cannot set property '${key}' on non-object value at path: ${path}`);
|
|
125
|
-
}
|
|
126
|
-
return currentValue;
|
|
127
|
-
}, object);
|
|
128
|
-
const existingValue = lastObj[last];
|
|
129
|
-
if (existingValue !== undefined &&
|
|
130
|
-
typeof existingValue === 'object' &&
|
|
131
|
-
existingValue !== null &&
|
|
132
|
-
!Array.isArray(existingValue)) {
|
|
133
|
-
throw new AbilityParserError(`Cannot set primitive value on existing object at path: ${path}`);
|
|
134
|
-
}
|
|
135
|
-
lastObj[last] = value;
|
|
97
|
+
class AbilityTypeGenerator {
|
|
98
|
+
policies;
|
|
99
|
+
constructor(policies) {
|
|
100
|
+
this.policies = policies;
|
|
136
101
|
}
|
|
137
102
|
/**
|
|
138
103
|
* Generates TypeScript type definitions based on the provided policies.
|
|
139
|
-
* @param policies - An array of AbilityPolicy instances.
|
|
140
104
|
* @returns A generated type definitions.
|
|
141
105
|
*/
|
|
142
|
-
|
|
106
|
+
generateTypeDefs() {
|
|
143
107
|
// Structure to store types: { [action]: { [subjectPath]: type } }
|
|
144
108
|
const typeStructure = {};
|
|
145
109
|
// Iterate through all policies
|
|
146
|
-
policies.forEach(policy => {
|
|
110
|
+
this.policies.forEach(policy => {
|
|
147
111
|
const action = policy.permission;
|
|
148
112
|
// Initialize object for action if it doesn't exist
|
|
149
113
|
if (!typeStructure[action]) {
|
|
@@ -175,7 +139,7 @@ class AbilityParser {
|
|
|
175
139
|
* @param rule - The rule to analyze
|
|
176
140
|
* @returns TypeScript type as string
|
|
177
141
|
*/
|
|
178
|
-
|
|
142
|
+
determineTypeFromRule(rule) {
|
|
179
143
|
// Numeric comparisons - always number
|
|
180
144
|
if (rule.condition.isEqual(AbilityCondition.greater_than) ||
|
|
181
145
|
rule.condition.isEqual(AbilityCondition.less_than) ||
|
|
@@ -200,7 +164,7 @@ class AbilityParser {
|
|
|
200
164
|
* @param resource - The resource value to analyze
|
|
201
165
|
* @returns TypeScript array type as string
|
|
202
166
|
*/
|
|
203
|
-
|
|
167
|
+
getArrayType(resource) {
|
|
204
168
|
if (Array.isArray(resource)) {
|
|
205
169
|
if (resource.length === 0)
|
|
206
170
|
return 'any[]';
|
|
@@ -209,18 +173,18 @@ class AbilityParser {
|
|
|
209
173
|
const elementType = elementTypes.size === 1
|
|
210
174
|
? Array.from(elementTypes)[0]
|
|
211
175
|
: `(${Array.from(elementTypes).join(' | ')})`;
|
|
212
|
-
return
|
|
176
|
+
return `readonly ${elementType}[]`;
|
|
213
177
|
}
|
|
214
178
|
// If resource is not an array but condition is in/not_in,
|
|
215
179
|
// it expects an array of such elements
|
|
216
|
-
return
|
|
180
|
+
return `readonly ${this.getPrimitiveType(resource)}[]`;
|
|
217
181
|
}
|
|
218
182
|
/**
|
|
219
183
|
* Gets primitive TypeScript type for a value
|
|
220
184
|
* @param value - The value to analyze
|
|
221
185
|
* @returns TypeScript primitive type as string
|
|
222
186
|
*/
|
|
223
|
-
|
|
187
|
+
getPrimitiveType(value) {
|
|
224
188
|
if (value === null)
|
|
225
189
|
return 'null';
|
|
226
190
|
if (value === undefined)
|
|
@@ -247,7 +211,7 @@ class AbilityParser {
|
|
|
247
211
|
* @param flatStructure - Flat structure with dot notation paths
|
|
248
212
|
* @returns Nested object structure
|
|
249
213
|
*/
|
|
250
|
-
|
|
214
|
+
buildNestedStructure(flatStructure) {
|
|
251
215
|
const result = {};
|
|
252
216
|
Object.entries(flatStructure).forEach(([action, paths]) => {
|
|
253
217
|
result[action] = {};
|
|
@@ -279,10 +243,9 @@ class AbilityParser {
|
|
|
279
243
|
* @param structure - Nested type structure
|
|
280
244
|
* @returns Formatted TypeScript type definition string
|
|
281
245
|
*/
|
|
282
|
-
|
|
246
|
+
formatTypeDefinitions(structure) {
|
|
283
247
|
let output = '// Automatically generated by via-profit/ability\n';
|
|
284
248
|
output += '// Do not edit manually\n';
|
|
285
|
-
output += '\n/* eslint-disable */\n\n';
|
|
286
249
|
output += 'export type Resources = {\n';
|
|
287
250
|
// Sort actions for stable output
|
|
288
251
|
const sortedActions = Object.keys(structure).sort();
|
|
@@ -300,7 +263,7 @@ class AbilityParser {
|
|
|
300
263
|
* @param indent - Current indentation level
|
|
301
264
|
* @returns Formatted string
|
|
302
265
|
*/
|
|
303
|
-
|
|
266
|
+
formatNestedObject(obj, indent) {
|
|
304
267
|
const spaces = ' '.repeat(indent);
|
|
305
268
|
let output = '';
|
|
306
269
|
// Sort keys for stable output
|
|
@@ -587,8 +550,12 @@ class AbilityResolver {
|
|
|
587
550
|
async enforce(permission, resource, environment) {
|
|
588
551
|
const result = await this.resolve(permission, resource, environment);
|
|
589
552
|
if (result.isDenied()) {
|
|
590
|
-
const
|
|
591
|
-
|
|
553
|
+
const lastPolicy = result.getLastMatchedPolicy();
|
|
554
|
+
if (lastPolicy) {
|
|
555
|
+
throw new AbilityError(`Permission denied by policy "${lastPolicy.name.toString()}"`);
|
|
556
|
+
}
|
|
557
|
+
// No policy matched → implicit deny
|
|
558
|
+
throw new AbilityError(`Permission denied: no matching policy found (implicit deny)`);
|
|
592
559
|
}
|
|
593
560
|
}
|
|
594
561
|
/**
|
|
@@ -2235,7 +2202,6 @@ exports.AbilityExplainRuleSet = AbilityExplainRuleSet;
|
|
|
2235
2202
|
exports.AbilityInMemoryCache = AbilityInMemoryCache;
|
|
2236
2203
|
exports.AbilityJSONParser = AbilityJSONParser;
|
|
2237
2204
|
exports.AbilityMatch = AbilityMatch;
|
|
2238
|
-
exports.AbilityParser = AbilityParser;
|
|
2239
2205
|
exports.AbilityParserError = AbilityParserError;
|
|
2240
2206
|
exports.AbilityPolicy = AbilityPolicy;
|
|
2241
2207
|
exports.AbilityPolicyEffect = AbilityPolicyEffect;
|
|
@@ -2243,3 +2209,4 @@ exports.AbilityResolver = AbilityResolver;
|
|
|
2243
2209
|
exports.AbilityResult = AbilityResult;
|
|
2244
2210
|
exports.AbilityRule = AbilityRule;
|
|
2245
2211
|
exports.AbilityRuleSet = AbilityRuleSet;
|
|
2212
|
+
exports.AbilityTypeGenerator = AbilityTypeGenerator;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AbilityRule, AbilityRuleConfig } from '../../core/AbilityRule';
|
|
2
2
|
import { AbilityRuleSet, AbilityRuleSetConfig } from '../../core/AbilityRuleSet';
|
|
3
|
-
import { ResourceObject } from '../../core/
|
|
3
|
+
import { ResourceObject } from '../../core/AbilityTypeGenerator';
|
|
4
4
|
import { AbilityPolicy, AbilityPolicyConfig } from '../../core/AbilityPolicy';
|
|
5
5
|
export declare class AbilityJSONParser {
|
|
6
6
|
/**
|
package/package.json
CHANGED
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@via-profit/ability",
|
|
3
|
-
"support": "https://via-profit.ru",
|
|
4
|
-
"version": "3.
|
|
5
|
-
"description": "Via-Profit Ability service",
|
|
6
|
-
"keywords": [
|
|
7
|
-
"ability",
|
|
8
|
-
"access",
|
|
9
|
-
"via-profit"
|
|
10
|
-
],
|
|
11
|
-
"main": "./dist/index.js",
|
|
12
|
-
"engines": {
|
|
13
|
-
"node": ">= 17.0.0",
|
|
14
|
-
"npm": ">= 8.19.3"
|
|
15
|
-
},
|
|
16
|
-
"files": [
|
|
17
|
-
"dist",
|
|
18
|
-
"README.md",
|
|
19
|
-
"LICENSE",
|
|
20
|
-
"CHANGELOG.md",
|
|
21
|
-
"CONTRIBUTING.md",
|
|
22
|
-
"SECURITY.md"
|
|
23
|
-
],
|
|
24
|
-
"scripts": {
|
|
25
|
-
"build": "rollup -c",
|
|
26
|
-
"build:dev": "cross-env NODE_ENV=development rollup -c -w",
|
|
27
|
-
"bench": "npm run build && node ./bench/benchmark.js",
|
|
28
|
-
"test": "jest",
|
|
29
|
-
"lint": "tsc --noEmit && eslint --fix .",
|
|
30
|
-
"pretty": "prettier --write ./src"
|
|
31
|
-
},
|
|
32
|
-
"repository": {
|
|
33
|
-
"type": "git",
|
|
34
|
-
"url": "https://github.com/via-profit/ability.git"
|
|
35
|
-
},
|
|
36
|
-
"author": {
|
|
37
|
-
"name": "Via Profit",
|
|
38
|
-
"url": "https://dev.via-profit.ru"
|
|
39
|
-
},
|
|
40
|
-
"contributors": [
|
|
41
|
-
"Vasily Novosad <delhsmail@gmail.com>",
|
|
42
|
-
"Pavel Natalin <trubonru@gmail.com>"
|
|
43
|
-
],
|
|
44
|
-
"license": "MIT",
|
|
45
|
-
"devDependencies": {
|
|
46
|
-
"@eslint/js": "^9.13.0",
|
|
47
|
-
"@jagi/jest-transform-graphql": "^1.0.2",
|
|
48
|
-
"@jest/types": "^29.6.3",
|
|
49
|
-
"@rollup/plugin-alias": "^6.0.0",
|
|
50
|
-
"@rollup/plugin-commonjs": "^29.0.2",
|
|
51
|
-
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
52
|
-
"@rollup/plugin-typescript": "^12.3.0",
|
|
53
|
-
"@types/jest": "^29.5.13",
|
|
54
|
-
"@types/node": "^22.7.7",
|
|
55
|
-
"@types/nodemon": "^1.19.6",
|
|
56
|
-
"concurrently": "^9.0.1",
|
|
57
|
-
"cross-env": "^7.0.3",
|
|
58
|
-
"eslint": "^9.13.0",
|
|
59
|
-
"globals": "^15.11.0",
|
|
60
|
-
"jest": "^29.7.0",
|
|
61
|
-
"jest-transform-graphql": "^2.1.0",
|
|
62
|
-
"nodemon": "^3.1.7",
|
|
63
|
-
"prettier": "^3.3.3",
|
|
64
|
-
"rollup": "^4.60.0",
|
|
65
|
-
"rollup-plugin-copy": "^3.5.0",
|
|
66
|
-
"tinybench": "^6.0.0",
|
|
67
|
-
"ts-jest": "^29.2.5",
|
|
68
|
-
"ts-loader": "^9.5.1",
|
|
69
|
-
"ts-node": "^10.9.2",
|
|
70
|
-
"typescript": "^5.6.3",
|
|
71
|
-
"typescript-eslint": "^8.10.0"
|
|
72
|
-
}
|
|
73
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@via-profit/ability",
|
|
3
|
+
"support": "https://via-profit.ru",
|
|
4
|
+
"version": "3.3.0",
|
|
5
|
+
"description": "Via-Profit Ability service",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"ability",
|
|
8
|
+
"access",
|
|
9
|
+
"via-profit"
|
|
10
|
+
],
|
|
11
|
+
"main": "./dist/index.js",
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">= 17.0.0",
|
|
14
|
+
"npm": ">= 8.19.3"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE",
|
|
20
|
+
"CHANGELOG.md",
|
|
21
|
+
"CONTRIBUTING.md",
|
|
22
|
+
"SECURITY.md"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "rollup -c",
|
|
26
|
+
"build:dev": "cross-env NODE_ENV=development rollup -c -w",
|
|
27
|
+
"bench": "npm run build && node ./bench/benchmark.js",
|
|
28
|
+
"test": "jest",
|
|
29
|
+
"lint": "tsc --noEmit && eslint --fix .",
|
|
30
|
+
"pretty": "prettier --write ./src"
|
|
31
|
+
},
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://github.com/via-profit/ability.git"
|
|
35
|
+
},
|
|
36
|
+
"author": {
|
|
37
|
+
"name": "Via Profit",
|
|
38
|
+
"url": "https://dev.via-profit.ru"
|
|
39
|
+
},
|
|
40
|
+
"contributors": [
|
|
41
|
+
"Vasily Novosad <delhsmail@gmail.com>",
|
|
42
|
+
"Pavel Natalin <trubonru@gmail.com>"
|
|
43
|
+
],
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@eslint/js": "^9.13.0",
|
|
47
|
+
"@jagi/jest-transform-graphql": "^1.0.2",
|
|
48
|
+
"@jest/types": "^29.6.3",
|
|
49
|
+
"@rollup/plugin-alias": "^6.0.0",
|
|
50
|
+
"@rollup/plugin-commonjs": "^29.0.2",
|
|
51
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
52
|
+
"@rollup/plugin-typescript": "^12.3.0",
|
|
53
|
+
"@types/jest": "^29.5.13",
|
|
54
|
+
"@types/node": "^22.7.7",
|
|
55
|
+
"@types/nodemon": "^1.19.6",
|
|
56
|
+
"concurrently": "^9.0.1",
|
|
57
|
+
"cross-env": "^7.0.3",
|
|
58
|
+
"eslint": "^9.13.0",
|
|
59
|
+
"globals": "^15.11.0",
|
|
60
|
+
"jest": "^29.7.0",
|
|
61
|
+
"jest-transform-graphql": "^2.1.0",
|
|
62
|
+
"nodemon": "^3.1.7",
|
|
63
|
+
"prettier": "^3.3.3",
|
|
64
|
+
"rollup": "^4.60.0",
|
|
65
|
+
"rollup-plugin-copy": "^3.5.0",
|
|
66
|
+
"tinybench": "^6.0.0",
|
|
67
|
+
"ts-jest": "^29.2.5",
|
|
68
|
+
"ts-loader": "^9.5.1",
|
|
69
|
+
"ts-node": "^10.9.2",
|
|
70
|
+
"typescript": "^5.6.3",
|
|
71
|
+
"typescript-eslint": "^8.10.0"
|
|
72
|
+
}
|
|
73
|
+
}
|