@via-profit/ability 3.1.1 → 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 CHANGED
@@ -1,129 +1,2 @@
1
1
  # Changelog
2
2
 
3
- ## [3.2.0] - 2026-x3-xx
4
-
5
- ### Изменено
6
-
7
- - Метод `AbilityPolicy.parseAll()` переименован в `AbilityPolicy.fromJSONAll()`
8
- - Метод `AbilityPolicy.parse()` переименован в `AbilityPolicy.toJSON()`
9
- - Метод `AbilityRule.parse()` переименован в `AbilityRule.toJSON()`
10
- - Метод `AbilityRuleSet.parse()` переименован в `.toJSON()`
11
-
12
- ## [3.1.0] - 2026-03-20
13
-
14
- ### Добавлено
15
-
16
- - Реализован кэш
17
- - Добавлен кэш-провайдер `AbilityCacheProvider` для реализации кастомного кэша
18
- - Реализован и включён по умолчанию `AbilityInMemoryCache` (кэш в памяти)
19
- - Добавлена полноценная поддержка `environment` как третьего аргумента в:
20
- - `resolver.resolve(action, resource, environment)`
21
- - `resolver.enforce(action, resource, environment)`
22
- - Введена возможность использовать пути вида `env.*` в правилах политик.
23
- - Пример: `"subject": "env.time.hour"`
24
- - Добавлена поддержка смешанных сравнений:
25
- - `resource.*` ↔ `env.*`
26
- - литерал ↔ `env.*`
27
- - `env.*` ↔ литерал
28
-
29
- ### Breaking changes
30
-
31
- Асинхронизация механизма проверки политик.
32
- Все методы, участвующие в цепочке вычисления разрешений, теперь возвращают `Promise`.
33
-
34
- #### Изменено
35
-
36
- - `AbilityRule.check(resource): Promise<AbilityMatch>`
37
- Ранее возвращал `AbilityMatch` синхронно.
38
-
39
- - `AbilityRuleSet.check(resource): Promise<AbilityMatch>`
40
- Теперь выполняет правила последовательно и асинхронно.
41
-
42
- - `AbilityPolicy.check(resource): Promise<AbilityMatch>`
43
- Асинхронно проверяет ruleSet в строгом порядке.
44
-
45
- - `AbilityResolver.resolve(action, resource): Promise<AbilityResult>`
46
- Теперь асинхронный метод, который дожидается выполнения всех политик.
47
-
48
- - `AbilityResolver.enforce(action, resource): Promise<void | never>`
49
- Теперь работает асинхронно.
50
-
51
- ### Миграция
52
-
53
- 1. Все вызовы `check()` должны быть обновлены:
54
-
55
- ```ts
56
- await rule.check(resource);
57
- await ruleSet.check(resource);
58
- await policy.check(resource);
59
- ```
60
-
61
- 2. Все вызовы `resolver.resolve()` и `resolver.enforce()` теперь требуют `await`:
62
-
63
- ```ts
64
- await resolver.resolve('order.update', resource);
65
- await resolver.enforce('order.update', resource);
66
- ```
67
-
68
- ## [3.0.1] - 2026-03-19
69
-
70
- ## Добавлено
71
-
72
- ### 1. **Лицензия MIT** (`LICENSE`)
73
-
74
- - Добавлен официальный файл лицензии MIT от Via Profit
75
-
76
- ### 2. **Класс `AbilityExplain.ts`**
77
-
78
- - Новый класс для получения человекочитаемых объяснений результатов проверки
79
- - Классы-наследники:
80
- - `AbilityExplainRule` - объяснение для правила
81
- - `AbilityExplainRuleSet` - объяснение для группы правил
82
- - `AbilityExplainPolicy` - объяснение для политики
83
- - Метод `toString()` форматирует вывод с отступами и символами ✓/✗
84
-
85
- ---
86
-
87
- ## Обновлено
88
-
89
- ### **AbilityParser.ts** (полная переработка)
90
-
91
- - **Было**: Базовая генерация типов
92
- - **Стало**: Расширенная система генерации TypeScript типов
93
- - Новые методы:
94
- - `determineTypeFromRule()` - определение типа на основе правила
95
- - `getArrayType()` - обработка массивов
96
- - `getPrimitiveType()` - определение примитивных типов
97
- - `buildNestedStructure()` - трансформация плоской структуры во вложенную
98
- - `formatTypeDefinitions()` - форматирование финального вывода
99
- - `formatNestedObject()` - рекурсивное форматирование объектов
100
-
101
- ### **AbilityRule.ts**
102
-
103
- - `id` и `name` теперь опциональные (`?`)
104
- - Автогенерация `id` и `name` если не предоставлены
105
- - **Новые статические методы** (фабричные методы):
106
- - `equal()`, `notEqual()`, `in()`, `notIn()`
107
- - `lessThan()`, `lessOrEqual()`, `moreThan()`, `moreOrEqual()`
108
-
109
- ### **AbilityRuleSet.ts**
110
-
111
- - `id` и `name` теперь опциональные
112
- - Добавлены статические методы:
113
- - `and()` - создание группы с логическим И
114
- - `or()` - создание группы с логическим ИЛИ
115
-
116
- ### **AbilityPolicy.ts**
117
-
118
- - Новый метод `explain()` - получение объяснения проверки
119
- - Новый статический метод `parseAll()` - парсинг массива конфигураций
120
- - Улучшены комментарии к полю `action`
121
-
122
- ### **AbilityResolver.ts**
123
-
124
- - Новый метод `resolveWithExplain()` - проверка с детальным объяснением
125
- - Возвращает массив `AbilityExplain[]` для анализа результатов
126
-
127
- ---
128
-
129
- ## Обновлена документация и примеры
package/README.md CHANGED
@@ -3,6 +3,15 @@
3
3
  > A set of services that partially implement the [Attribute Based Access Control](https://en.wikipedia.org/wiki/Attribute-based_access_control) principle.
4
4
  > The package allows you to describe rules, combine them into groups, form policies, and apply them to data to determine permissions.
5
5
 
6
+ ![npm version](https://img.shields.io/npm/v/%40via-profit/ability)
7
+ ![npm downloads](https://img.shields.io/npm/dm/%40via-profit/ability)
8
+ ![license](https://img.shields.io/github/license/via-profit/ability)
9
+ ![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue)
10
+ ![status](https://img.shields.io/badge/status-active-success)
11
+ ![issues](https://img.shields.io/github/issues/via-profit/ability)
12
+ ![stars](https://img.shields.io/github/stars/via-profit/ability?style=social)
13
+
14
+
6
15
  ## Language / Язык
7
16
 
8
17
  - [🇬🇧 English](/docs/en/README.md)
@@ -113,6 +122,191 @@ Let’s briefly list the key points you need to know before starting to use the
113
122
  7. Generally, rely on the principle: if permission is not explicitly granted → access is denied.
114
123
  8. Use the built-in cache only if your policies are incredibly complex and contain a large number of rules.
115
124
 
125
+ ### Interaction Model
126
+
127
+ First, you define "raw" policies (using DSL, JSON, or classes). Then, you transform the raw data into ready-to-use policies (an array of policies). This is done once and provides a single source of truth. After that, you can perform permission checks in any part of your code using the prepared policies and the resolver.
128
+
129
+ Policies, rule sets, and rules can be created using:
130
+
131
+ - DSL (Domain-Specific Language)
132
+ - Classes (classic approach)
133
+ - JSON
134
+
135
+ **Creating policies with DSL**
136
+
137
+ ```ts
138
+ import { AbilityDSLParser } from '@via-profit/ability';
139
+
140
+ // Describe policies using Ability-DSL
141
+ const dsl = `
142
+ # @name Order creation is only available to persons over 18 years old
143
+ permit permission.order.action.create if all:
144
+ all of:
145
+ user.age gte 18
146
+
147
+ # @name Price editing is only available to administrators
148
+ permit permission.order.data.price if all:
149
+ all of:
150
+ user.roles contains 'administrator'
151
+ `;
152
+
153
+ // Define resource types for TypeScript
154
+ // Types can be generated automatically (more on this later) or defined manually
155
+ // In this example, for simplicity, types are defined manually
156
+ type Resources = {
157
+ ['order.action.create']: {
158
+ user: {
159
+ age: number;
160
+ }
161
+ }
162
+ ['order.data.price']: {
163
+ user: {
164
+ roles: string[];
165
+ }
166
+ }
167
+ }
168
+
169
+ // Use the parser to create policies
170
+ // Pass the resource type as a generic parameter
171
+ const policies = new AbilityDSLParser<Resources>(dsl).parse(); // AbilityPolicy[]
172
+
173
+ // The parser returns an array of policies even
174
+ // if only one policy is described in the DSL
175
+ console.log(policies); // [AbilityPolicy, AbilityPolicy, ...]
176
+
177
+ // Export the ready-to-use policies
178
+ export default policies;
179
+ ```
180
+
181
+ For more details about DSL, see the [DSL](#dsl) section.
182
+
183
+ **Creating policies using classes (classic approach)**
184
+
185
+ This approach is quite verbose but gives you full control over the policies.
186
+
187
+ ```ts
188
+ import { AbilityPolicy, AbilityRuleSet, AbilityRule, AbilityCompare, AbilityPolicyEffect } from '@via-profit/ability';
189
+
190
+ // Define resource types for TypeScript
191
+ // Types can be generated automatically (more on this later) or defined manually
192
+ // In this example, for simplicity, types are defined manually
193
+ type Resources = {
194
+ ['order.action.create']: {
195
+ user: {
196
+ age: number;
197
+ }
198
+ }
199
+ ['order.data.price']: {
200
+ user: {
201
+ roles: string[];
202
+ }
203
+ }
204
+ }
205
+
206
+ const policies = [
207
+ // first policy
208
+ new AbilityPolicy<Resources>({
209
+ id: '1',
210
+ name: 'Order creation is only available to persons over 18 years old',
211
+ compareMethod: AbilityCompare.and,
212
+ effect: AbilityPolicyEffect.permit,
213
+ permission: 'order.action.create',
214
+ }).addRuleSet(
215
+ AbilityRuleSet.and([
216
+ // rule
217
+ AbilityRule.moreOrEqual('user.age', 18),
218
+ ]),
219
+ ),
220
+
221
+ // second policy
222
+ new AbilityPolicy<Resources>({
223
+ id: '2',
224
+ name: 'Price editing is only available to administrators',
225
+ compareMethod: AbilityCompare.and,
226
+ effect: AbilityPolicyEffect.permit,
227
+ permission: 'order.data.price',
228
+ }).addRuleSet(
229
+ AbilityRuleSet.and([
230
+ // rule
231
+ AbilityRule.contains('user.roles', 'administrator'),
232
+ ])
233
+ ),
234
+ ];
235
+
236
+ // Export the ready-to-use policies
237
+ export default policies;
238
+ ```
239
+
240
+ **Creating policies with JSON**
241
+
242
+ JSON allows you to store policies in a file or database, for example, in PostgreSQL, which supports working with JSON data.
243
+
244
+ Policy, rule set, and rule classes have JSON export methods, so you can create policies in any way and export them to JSON whenever needed.
245
+
246
+ ```ts
247
+ import { AbilityJSONParser } from '@via-profit/ability';
248
+
249
+ // Define resource types for TypeScript
250
+ // Types can be generated automatically (more on this later) or defined manually
251
+ // In this example, for simplicity, types are defined manually
252
+ type Resources = {
253
+ ['order.action.create']: {
254
+ user: {
255
+ age: number;
256
+ }
257
+ }
258
+ ['order.data.price']: {
259
+ user: {
260
+ roles: string[];
261
+ }
262
+ }
263
+ }
264
+
265
+ // Parse JSON using AbilityJSONParser
266
+ // Pass the resource types as a generic parameter
267
+ const policies = AbilityJSONParser.parse<Resources>([
268
+ {
269
+ id: '1',
270
+ name: 'Order creation is only available to persons over 18 years old',
271
+ effect: 'permit',
272
+ permission: 'order.action.create',
273
+ compareMethod: 'and',
274
+ ruleSet: [
275
+ {
276
+ compareMethod: 'and',
277
+ rules: [
278
+ {
279
+ subject: 'user.age',
280
+ resource: 18,
281
+ condition: '>',
282
+ }
283
+ ]
284
+ }
285
+ ],
286
+ },
287
+ {
288
+ id: '2',
289
+ name: 'Price editing is only available to administrators',
290
+ effect: 'permit',
291
+ permission: 'order.data.price',
292
+ compareMethod: 'and',
293
+ ruleSet: [
294
+ {
295
+ compareMethod: 'and',
296
+ rules: [
297
+ {
298
+ subject: 'user.roles',
299
+ resource: 'administrator',
300
+ condition: 'contains',
301
+ }
302
+ ]
303
+ }
304
+ ]
305
+ }
306
+ ]);
307
+
308
+ export default policies;
309
+ ```
116
310
  ---
117
311
 
118
312
  ## DSL
@@ -447,24 +641,17 @@ The content of the object is defined by the developer and can be any object cons
447
641
  - session context,
448
642
  - any other external conditions.
449
643
 
450
- **Examples:**
451
-
452
- ```ts
453
- type Environment = {
454
- time: {
455
- hour: number;
456
- };
457
- ip: string;
458
- geo: {
459
- country: string;
460
- };
461
- };
462
- ```
463
644
 
464
645
  Environment is passed to `resolve()` and `enforce()` as the third argument:
465
646
 
466
647
  ```ts
467
- await resolver.resolve('order.update', resource, environment);
648
+ const environment = {
649
+ time: {
650
+ hour: new Date().getHours(),
651
+ },
652
+ ip: req.ip,
653
+ }
654
+
468
655
  await resolver.enforce('order.update', resource, environment);
469
656
  ```
470
657
 
@@ -515,18 +702,14 @@ This allows:
515
702
 
516
703
  ## TypeScript Type Generator
517
704
 
518
- `AbilityParser.generateTypeDefs()` generates TypeScript types based on policies, allowing you to avoid discrepancies between types and data in policies.
519
-
520
- **Usage Example**
705
+ `AbilityTypeGenerator.generateTypeDefs(policies)` generates TypeScript types based on policies, allowing you to avoid inconsistencies between types and the data in the policies.
521
706
 
522
- First, you need to prepare an array of policies. Policies can be stored in DSL or JSON and parsed into an array of ready-made policies. In this example, for clarity, policies are stored in DSL.
707
+ **Example usage**
523
708
 
524
- ```ts
525
- // scripts/policies.ts
526
-
527
- import { AbilityDSLParser } from './AbilityDSLParser';
709
+ Policies can be stored in DSL or JSON. This example uses a DSL file.
528
710
 
529
- const dsl = `
711
+ _policies/policies.dsl_
712
+ ```
530
713
  # @name Update order
531
714
  permit permission.order.update if all:
532
715
 
@@ -534,25 +717,46 @@ permit permission.order.update if all:
534
717
  all of:
535
718
  # @name User is owner
536
719
  user.id = order.ownerId
537
- `;
720
+ ```
721
+
722
+ _scripts/policies.js_
723
+ ```js
724
+ const fs = require('node:fs');
725
+ const path = require('node:path');
726
+ const { AbilityTypeGenerator, AbilityDSLParser } = require('@via-profit/ability');
727
+
728
+ // Prepare paths
729
+ const dslPath = path.resolve(__dirname, '../src/policies/policies.dsl');
730
+ const typeDefsPath = path.join(path.dirname(dslPath), 'policies.types.ts');
538
731
 
732
+ // Read DSL as a string
733
+ const dsl = fs.readFileSync(dslPath, {encoding: 'utf-8'});
734
+
735
+ // Create policies
539
736
  const policies = new AbilityDSLParser(dsl).parse();
540
737
 
541
- export default policies;
738
+ // Generate TypeScript types
739
+ const typeDefs = new AbilityTypeGenerator(policies).generateTypeDefs();
740
+
741
+ // Save TypeScript types to file
742
+ fs.writeFileSync(typeDefsPath, typeDefs, {encoding: 'utf-8'});
542
743
  ```
543
744
 
745
+ _policies/index.ts_
544
746
  ```ts
545
- // scripts/generate-types.ts
546
- import { writeFileSync } from 'node:fs';
547
- import { AbilityParser } from '@via-profit/ability';
548
- import policies from './policies.json';
747
+ import { AbilityDSLParser, AbilityResolver } from '@via-profit/ability';
748
+ import type { Resources } from './policies.types';
749
+ import dsl from './policies.dsl';
750
+
751
+ const policies = new AbilityDSLParser<Resources>(dsl).parse();
549
752
 
550
- const typedefs = AbilityParser.generateTypeDefs(policies);
753
+ export const policyResolver = new AbilityResolver(new AbilityDSLParser<Resources>(dsl).parse());
754
+
755
+ export default policyResolver;
551
756
 
552
- writeFileSync('./src/ability/types.generated.ts', typedefs, 'utf8');
553
757
  ```
554
758
 
555
- **Generated File (example)**
759
+ **Generated file (example)**
556
760
 
557
761
  ```ts
558
762
  // src/ability/types.generated.ts
@@ -574,12 +778,7 @@ export type Resources = {
574
778
  **Usage in code**
575
779
 
576
780
  ```ts
577
- import { AbilityResolver, AbilityPolicy } from '@via-profit/ability';
578
- import type { Resources } from './ability/types.generated';
579
-
580
- const resolver = new AbilityResolver<Resources>(
581
- AbilityPolicy.parseAll(policies),
582
- );
781
+ import { policyResolver } from './policies';
583
782
 
584
783
  await resolver.enforce('order.update', {
585
784
  user: { id: 'u1' },
@@ -1144,4 +1343,4 @@ Throughput (ops/s)
1144
1343
 
1145
1344
  ## License
1146
1345
 
1147
- This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
1346
+ This project is licensed under the MIT License. See the [LICENSE](/LICENSE) file for details.
@@ -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 './AbilityParser';
6
+ import { ResourceObject } from './AbilityTypeGenerator';
7
7
  export type AbilityPolicyConfig = {
8
8
  readonly permission: string;
9
9
  readonly effect: AbilityPolicyEffectCodeType;
@@ -67,18 +67,13 @@ export declare class AbilityPolicy<Resource extends ResourceObject = Record<stri
67
67
  */
68
68
  check(resource: Resource, environment?: Environment): Promise<AbilityMatch>;
69
69
  explain(): AbilityExplain;
70
- /**
71
- * Parses an array of policy configurations into an array of AbilityPolicy instances.
72
- * @param configs - Array of policy configurations
73
- * @returns Array of AbilityPolicy instances
74
- */
75
- static fromJSONAll<Resource extends ResourceObject, Environment = unknown>(configs: readonly AbilityPolicyConfig[]): AbilityPolicy<Resource, Environment>[];
76
- /**
77
- * Parse the config JSON format to Policy class instance
78
- */
79
- static fromJSON<Resource extends ResourceObject = Record<string, unknown>, Environment = unknown>(config: AbilityPolicyConfig): AbilityPolicy<Resource, Environment>;
80
- static fromDSL<Resource extends ResourceObject = Record<string, unknown>, Environment = unknown>(dsl: string): AbilityPolicy<Resource, Environment>;
81
- toJSON(): AbilityPolicyConfig;
82
- toString(): string;
70
+ copyWith(props: Partial<{
71
+ id: string;
72
+ name: string;
73
+ permission: string;
74
+ effect: AbilityPolicyEffect;
75
+ compareMethod: AbilityCompare;
76
+ ruleSet: AbilityRuleSet<Resource, Environment>[];
77
+ }>): AbilityPolicy<Resource, Environment>;
83
78
  }
84
79
  export default AbilityPolicy;
@@ -1,6 +1,6 @@
1
1
  import AbilityPolicy from './AbilityPolicy';
2
2
  import { AbilityResult } from './AbilityResult';
3
- import { ResourcesMap } from './AbilityParser';
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 './AbilityParser';
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>> {
@@ -61,7 +61,13 @@ export declare class AbilityRule<Resources extends object = object, Environment
61
61
  */
62
62
  getDotNotationValue<T = unknown>(resource: unknown, desc: string): T | undefined;
63
63
  toString(): string;
64
- static fromJSON<Resources extends object, Environment = unknown>(config: AbilityRuleConfig): AbilityRule<Resources, Environment>;
64
+ copyWith(props: Partial<{
65
+ id: string | null;
66
+ name: string | null;
67
+ subject: string;
68
+ resource: AbilityRuleConfig['resource'];
69
+ condition: AbilityCondition;
70
+ }>): AbilityRule<Resources, Environment>;
65
71
  static equals<Resources extends object = object, Environment = unknown>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources, Environment>;
66
72
  static notEquals<Resources extends object = object, Environment = unknown>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources, Environment>;
67
73
  static contains<Resources extends object = object, Environment = unknown>(subject: string, resource: AbilityRuleConfig['resource']): AbilityRule<Resources, Environment>;
@@ -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 './AbilityParser';
4
+ import { ResourceObject } from './AbilityTypeGenerator';
5
5
  export type AbilityRuleSetConfig = {
6
6
  readonly id?: string | null;
7
7
  readonly name?: string | null;
@@ -39,10 +39,12 @@ export declare class AbilityRuleSet<Resources extends ResourceObject = Record<st
39
39
  addRules(rules: AbilityRule<Resources, Environment>[]): this;
40
40
  check(resources: Resources | null, environment?: Environment): Promise<AbilityMatch>;
41
41
  toString(): string;
42
- /**
43
- * Parse the config JSON format to Group class instance
44
- */
45
- static fromJSON<Resource extends ResourceObject = Record<string, unknown>, Environment = unknown>(config: AbilityRuleSetConfig): AbilityRuleSet<Resource, Environment>;
42
+ copyWith(props: Partial<{
43
+ id: string | null;
44
+ name: string | null;
45
+ compareMethod: AbilityCompare;
46
+ rules: AbilityRule<Resources, Environment>[];
47
+ }>): AbilityRuleSet<Resources, Environment>;
46
48
  static and(rules: AbilityRule[]): AbilityRuleSet<Record<string, unknown>, unknown>;
47
49
  static or(rules: AbilityRule[]): AbilityRuleSet<Record<string, unknown>, unknown>;
48
50
  }
@@ -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/AbilityParser';
6
+ export * from './core/AbilityTypeGenerator';
7
7
  export * from './core/AbilityPolicy';
8
8
  export * from './core/AbilityPolicyEffect';
9
9
  export * from './core/AbilityResolver';