odgn-rights 0.1.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +489 -0
- package/dist/adapters/base-adapter.d.ts +83 -0
- package/dist/adapters/base-adapter.js +142 -0
- package/dist/adapters/factories.d.ts +31 -0
- package/dist/adapters/factories.js +48 -0
- package/dist/adapters/index.d.ts +11 -0
- package/dist/adapters/index.js +12 -0
- package/dist/adapters/postgres-adapter.d.ts +51 -0
- package/dist/adapters/postgres-adapter.js +469 -0
- package/dist/adapters/redis-adapter.d.ts +84 -0
- package/dist/adapters/redis-adapter.js +673 -0
- package/dist/adapters/schema.d.ts +25 -0
- package/dist/adapters/schema.js +186 -0
- package/dist/adapters/sqlite-adapter.d.ts +78 -0
- package/dist/adapters/sqlite-adapter.js +655 -0
- package/dist/adapters/types.d.ts +174 -0
- package/dist/adapters/types.js +1 -0
- package/dist/cli/commands/check.d.ts +2 -0
- package/dist/cli/commands/check.js +38 -0
- package/dist/cli/commands/explain.d.ts +2 -0
- package/dist/cli/commands/explain.js +93 -0
- package/dist/cli/commands/validate.d.ts +2 -0
- package/dist/cli/commands/validate.js +177 -0
- package/dist/cli/helpers/config-loader.d.ts +3 -0
- package/dist/cli/helpers/config-loader.js +13 -0
- package/dist/cli/helpers/flag-parser.d.ts +3 -0
- package/dist/cli/helpers/flag-parser.js +40 -0
- package/dist/cli/helpers/output.d.ts +10 -0
- package/dist/cli/helpers/output.js +29 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +15 -0
- package/dist/cli/types.d.ts +10 -0
- package/dist/cli/types.js +1 -0
- package/dist/helpers.d.ts +16 -0
- package/dist/{utils.js → helpers.js} +22 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/integrations/elysia.d.ts +235 -0
- package/dist/integrations/elysia.js +375 -0
- package/dist/right.d.ts +25 -1
- package/dist/right.js +183 -19
- package/dist/rights.d.ts +31 -0
- package/dist/rights.js +162 -31
- package/dist/role-registry.d.ts +9 -0
- package/dist/role-registry.js +15 -0
- package/dist/role.d.ts +3 -1
- package/dist/role.js +11 -0
- package/dist/subject-registry.d.ts +77 -0
- package/dist/subject-registry.js +123 -0
- package/dist/subject.d.ts +21 -2
- package/dist/subject.js +51 -8
- package/package.json +63 -7
- package/dist/utils.d.ts +0 -2
package/dist/role-registry.js
CHANGED
|
@@ -23,6 +23,18 @@ export class RoleRegistry {
|
|
|
23
23
|
toJSON() {
|
|
24
24
|
return Array.from(this.roles.values()).map(r => r.toJSON());
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Load all roles and their relationships from a database adapter
|
|
28
|
+
*/
|
|
29
|
+
static async loadFrom(adapter) {
|
|
30
|
+
return adapter.loadRegistry();
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Save all roles and their relationships to a database adapter
|
|
34
|
+
*/
|
|
35
|
+
async saveTo(adapter) {
|
|
36
|
+
await adapter.saveRegistry(this);
|
|
37
|
+
}
|
|
26
38
|
static fromJSON(data) {
|
|
27
39
|
const registry = new RoleRegistry();
|
|
28
40
|
// First pass: create all roles
|
|
@@ -38,6 +50,9 @@ export class RoleRegistry {
|
|
|
38
50
|
if (parent) {
|
|
39
51
|
role.inheritsFrom(parent);
|
|
40
52
|
}
|
|
53
|
+
else {
|
|
54
|
+
throw new Error(`Role ${item.name} inherits from missing role ${parentName}`);
|
|
55
|
+
}
|
|
41
56
|
}
|
|
42
57
|
}
|
|
43
58
|
}
|
package/dist/role.d.ts
CHANGED
|
@@ -4,7 +4,8 @@ import type { RoleJSON } from './role-registry';
|
|
|
4
4
|
export declare class Role {
|
|
5
5
|
readonly name: string;
|
|
6
6
|
readonly rights: Rights;
|
|
7
|
-
|
|
7
|
+
readonly parents: Role[];
|
|
8
|
+
private children;
|
|
8
9
|
private _cachedAllRights;
|
|
9
10
|
constructor(name: string, rights?: Rights);
|
|
10
11
|
inheritsFrom(role: Role): this;
|
|
@@ -18,6 +19,7 @@ export declare class Role {
|
|
|
18
19
|
type: 'role';
|
|
19
20
|
};
|
|
20
21
|
}>;
|
|
22
|
+
findRightsByTag(tag: string): Right[];
|
|
21
23
|
invalidateCache(): void;
|
|
22
24
|
toJSON(): RoleJSON;
|
|
23
25
|
}
|
package/dist/role.js
CHANGED
|
@@ -3,9 +3,11 @@ import { Rights } from './rights';
|
|
|
3
3
|
export class Role {
|
|
4
4
|
constructor(name, rights) {
|
|
5
5
|
this.parents = [];
|
|
6
|
+
this.children = [];
|
|
6
7
|
this._cachedAllRights = null;
|
|
7
8
|
this.name = name;
|
|
8
9
|
this.rights = rights ?? new Rights();
|
|
10
|
+
this.rights.onChange = () => this.invalidateCache();
|
|
9
11
|
}
|
|
10
12
|
inheritsFrom(role) {
|
|
11
13
|
if (role === this) {
|
|
@@ -13,6 +15,7 @@ export class Role {
|
|
|
13
15
|
}
|
|
14
16
|
if (!this.parents.includes(role)) {
|
|
15
17
|
this.parents.push(role);
|
|
18
|
+
role.children.push(this);
|
|
16
19
|
this.invalidateCache();
|
|
17
20
|
}
|
|
18
21
|
return this;
|
|
@@ -34,8 +37,16 @@ export class Role {
|
|
|
34
37
|
this._cachedAllRights = list;
|
|
35
38
|
return list;
|
|
36
39
|
}
|
|
40
|
+
findRightsByTag(tag) {
|
|
41
|
+
return this.allRights()
|
|
42
|
+
.map(r => r.right)
|
|
43
|
+
.filter(r => r.hasTag(tag));
|
|
44
|
+
}
|
|
37
45
|
invalidateCache() {
|
|
38
46
|
this._cachedAllRights = null;
|
|
47
|
+
for (const child of this.children) {
|
|
48
|
+
child.invalidateCache();
|
|
49
|
+
}
|
|
39
50
|
}
|
|
40
51
|
toJSON() {
|
|
41
52
|
const out = {
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { DatabaseAdapter } from './adapters/types';
|
|
2
|
+
import { Flags } from './constants';
|
|
3
|
+
import type { ConditionContext } from './right';
|
|
4
|
+
import type { RoleRegistry } from './role-registry';
|
|
5
|
+
import { Subject, type SubjectJSON } from './subject';
|
|
6
|
+
export type SubjectRegistryJSON = {
|
|
7
|
+
[identifier: string]: SubjectJSON;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* In-memory registry for managing Subject instances.
|
|
11
|
+
* Provides an API similar to RoleRegistry for consistency.
|
|
12
|
+
*/
|
|
13
|
+
export declare class SubjectRegistry {
|
|
14
|
+
private subjects;
|
|
15
|
+
/**
|
|
16
|
+
* Register a subject with an identifier.
|
|
17
|
+
* If a subject with this identifier already exists, it will be replaced.
|
|
18
|
+
*/
|
|
19
|
+
register(identifier: string, subject: Subject): void;
|
|
20
|
+
/**
|
|
21
|
+
* Get a subject by its identifier.
|
|
22
|
+
*/
|
|
23
|
+
get(identifier: string): Subject | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Check if a subject with the given identifier exists.
|
|
26
|
+
*/
|
|
27
|
+
has(identifier: string): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Delete a subject by its identifier.
|
|
30
|
+
* @returns true if the subject was deleted, false if not found
|
|
31
|
+
*/
|
|
32
|
+
delete(identifier: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Get all registered identifiers.
|
|
35
|
+
*/
|
|
36
|
+
identifiers(): string[];
|
|
37
|
+
/**
|
|
38
|
+
* Get the number of registered subjects.
|
|
39
|
+
*/
|
|
40
|
+
get size(): number;
|
|
41
|
+
/**
|
|
42
|
+
* Clear all registered subjects.
|
|
43
|
+
*/
|
|
44
|
+
clear(): void;
|
|
45
|
+
/**
|
|
46
|
+
* Iterate over all subjects.
|
|
47
|
+
*/
|
|
48
|
+
entries(): IterableIterator<[string, Subject]>;
|
|
49
|
+
/**
|
|
50
|
+
* Find all subject identifiers that have access to a specific path with given flags.
|
|
51
|
+
* @param pathPattern The path pattern to check (supports wildcards)
|
|
52
|
+
* @param flags The flags to check for
|
|
53
|
+
* @param context Optional condition context for ABAC-style checks
|
|
54
|
+
* @returns Array of subject identifiers that have access
|
|
55
|
+
*/
|
|
56
|
+
findSubjectsWithAccess(pathPattern: string, flags: Flags, context?: ConditionContext): string[];
|
|
57
|
+
/**
|
|
58
|
+
* Serialize the registry to JSON.
|
|
59
|
+
*/
|
|
60
|
+
toJSON(): SubjectRegistryJSON;
|
|
61
|
+
/**
|
|
62
|
+
* Create a SubjectRegistry from JSON data.
|
|
63
|
+
* @param data The serialized registry data
|
|
64
|
+
* @param roleRegistry Optional RoleRegistry for resolving role references
|
|
65
|
+
*/
|
|
66
|
+
static fromJSON(data: SubjectRegistryJSON, roleRegistry?: RoleRegistry): SubjectRegistry;
|
|
67
|
+
/**
|
|
68
|
+
* Save all subjects to a database adapter.
|
|
69
|
+
*/
|
|
70
|
+
saveTo(adapter: DatabaseAdapter): Promise<void>;
|
|
71
|
+
/**
|
|
72
|
+
* Load all subjects from a database adapter.
|
|
73
|
+
* Note: This requires the adapter to support getAllSubjectIdentifiers().
|
|
74
|
+
* For adapters that don't support this, use loadFromIdentifiers() instead.
|
|
75
|
+
*/
|
|
76
|
+
static loadFrom(adapter: DatabaseAdapter, identifiers: string[]): Promise<SubjectRegistry>;
|
|
77
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { Flags } from './constants';
|
|
2
|
+
import { Subject } from './subject';
|
|
3
|
+
/**
|
|
4
|
+
* In-memory registry for managing Subject instances.
|
|
5
|
+
* Provides an API similar to RoleRegistry for consistency.
|
|
6
|
+
*/
|
|
7
|
+
export class SubjectRegistry {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.subjects = new Map();
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Register a subject with an identifier.
|
|
13
|
+
* If a subject with this identifier already exists, it will be replaced.
|
|
14
|
+
*/
|
|
15
|
+
register(identifier, subject) {
|
|
16
|
+
this.subjects.set(identifier, subject);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get a subject by its identifier.
|
|
20
|
+
*/
|
|
21
|
+
get(identifier) {
|
|
22
|
+
return this.subjects.get(identifier);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Check if a subject with the given identifier exists.
|
|
26
|
+
*/
|
|
27
|
+
has(identifier) {
|
|
28
|
+
return this.subjects.has(identifier);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Delete a subject by its identifier.
|
|
32
|
+
* @returns true if the subject was deleted, false if not found
|
|
33
|
+
*/
|
|
34
|
+
delete(identifier) {
|
|
35
|
+
return this.subjects.delete(identifier);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get all registered identifiers.
|
|
39
|
+
*/
|
|
40
|
+
identifiers() {
|
|
41
|
+
return Array.from(this.subjects.keys());
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get the number of registered subjects.
|
|
45
|
+
*/
|
|
46
|
+
get size() {
|
|
47
|
+
return this.subjects.size;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Clear all registered subjects.
|
|
51
|
+
*/
|
|
52
|
+
clear() {
|
|
53
|
+
this.subjects.clear();
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Iterate over all subjects.
|
|
57
|
+
*/
|
|
58
|
+
entries() {
|
|
59
|
+
return this.subjects.entries();
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Find all subject identifiers that have access to a specific path with given flags.
|
|
63
|
+
* @param pathPattern The path pattern to check (supports wildcards)
|
|
64
|
+
* @param flags The flags to check for
|
|
65
|
+
* @param context Optional condition context for ABAC-style checks
|
|
66
|
+
* @returns Array of subject identifiers that have access
|
|
67
|
+
*/
|
|
68
|
+
findSubjectsWithAccess(pathPattern, flags, context) {
|
|
69
|
+
const matching = [];
|
|
70
|
+
for (const [identifier, subject] of this.subjects) {
|
|
71
|
+
if (subject.has(pathPattern, flags, context)) {
|
|
72
|
+
matching.push(identifier);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return matching;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Serialize the registry to JSON.
|
|
79
|
+
*/
|
|
80
|
+
toJSON() {
|
|
81
|
+
const result = {};
|
|
82
|
+
for (const [identifier, subject] of this.subjects) {
|
|
83
|
+
result[identifier] = subject.toJSON();
|
|
84
|
+
}
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Create a SubjectRegistry from JSON data.
|
|
89
|
+
* @param data The serialized registry data
|
|
90
|
+
* @param roleRegistry Optional RoleRegistry for resolving role references
|
|
91
|
+
*/
|
|
92
|
+
static fromJSON(data, roleRegistry) {
|
|
93
|
+
const registry = new SubjectRegistry();
|
|
94
|
+
for (const [identifier, subjectData] of Object.entries(data)) {
|
|
95
|
+
const subject = Subject.fromJSON(subjectData, roleRegistry);
|
|
96
|
+
registry.register(identifier, subject);
|
|
97
|
+
}
|
|
98
|
+
return registry;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Save all subjects to a database adapter.
|
|
102
|
+
*/
|
|
103
|
+
async saveTo(adapter) {
|
|
104
|
+
for (const [identifier, subject] of this.subjects) {
|
|
105
|
+
await adapter.saveSubject(identifier, subject);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Load all subjects from a database adapter.
|
|
110
|
+
* Note: This requires the adapter to support getAllSubjectIdentifiers().
|
|
111
|
+
* For adapters that don't support this, use loadFromIdentifiers() instead.
|
|
112
|
+
*/
|
|
113
|
+
static async loadFrom(adapter, identifiers) {
|
|
114
|
+
const registry = new SubjectRegistry();
|
|
115
|
+
for (const id of identifiers) {
|
|
116
|
+
const subject = await adapter.loadSubject(id);
|
|
117
|
+
if (subject) {
|
|
118
|
+
registry.register(id, subject);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return registry;
|
|
122
|
+
}
|
|
123
|
+
}
|
package/dist/subject.d.ts
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { Flags } from './constants';
|
|
2
2
|
import { Right, type ConditionContext } from './right';
|
|
3
|
-
import { Rights } from './rights';
|
|
3
|
+
import { Rights, type RightJSON } from './rights';
|
|
4
4
|
import { Role } from './role';
|
|
5
|
+
import type { RoleRegistry } from './role-registry';
|
|
6
|
+
export type SubjectJSON = {
|
|
7
|
+
rights?: RightJSON[];
|
|
8
|
+
roles?: string[];
|
|
9
|
+
};
|
|
5
10
|
export declare class Subject {
|
|
6
|
-
|
|
11
|
+
readonly roles: Role[];
|
|
7
12
|
readonly rights: Rights;
|
|
8
13
|
private _aggregate;
|
|
9
14
|
private _aggregateMeta;
|
|
15
|
+
toJSON(): SubjectJSON;
|
|
16
|
+
static fromJSON(data: SubjectJSON, registry?: RoleRegistry): Subject;
|
|
10
17
|
memberOf(role: Role): this;
|
|
11
18
|
invalidateCache(): void;
|
|
12
19
|
has(path: string, flag: Flags, context?: ConditionContext): boolean;
|
|
@@ -22,10 +29,22 @@ export declare class Subject {
|
|
|
22
29
|
};
|
|
23
30
|
}>;
|
|
24
31
|
};
|
|
32
|
+
allRights(): Array<{
|
|
33
|
+
right: Right;
|
|
34
|
+
source?: {
|
|
35
|
+
name?: string;
|
|
36
|
+
type: 'direct' | 'role';
|
|
37
|
+
};
|
|
38
|
+
}>;
|
|
39
|
+
private ensureAggregate;
|
|
25
40
|
all(path: string, context?: ConditionContext): boolean;
|
|
26
41
|
read(path: string, context?: ConditionContext): boolean;
|
|
27
42
|
write(path: string, context?: ConditionContext): boolean;
|
|
28
43
|
delete(path: string, context?: ConditionContext): boolean;
|
|
29
44
|
create(path: string, context?: ConditionContext): boolean;
|
|
30
45
|
execute(path: string, context?: ConditionContext): boolean;
|
|
46
|
+
checkMany(requests: Array<{
|
|
47
|
+
flags: Flags;
|
|
48
|
+
path: string;
|
|
49
|
+
}>, context?: ConditionContext): boolean[];
|
|
31
50
|
}
|
package/dist/subject.js
CHANGED
|
@@ -9,6 +9,35 @@ export class Subject {
|
|
|
9
9
|
this._aggregate = null;
|
|
10
10
|
this._aggregateMeta = null;
|
|
11
11
|
}
|
|
12
|
+
toJSON() {
|
|
13
|
+
const out = {};
|
|
14
|
+
if (this.roles.length > 0) {
|
|
15
|
+
out.roles = this.roles.map(r => r.name);
|
|
16
|
+
}
|
|
17
|
+
const rights = this.rights.toJSON();
|
|
18
|
+
if (rights.length > 0) {
|
|
19
|
+
out.rights = rights;
|
|
20
|
+
}
|
|
21
|
+
return out;
|
|
22
|
+
}
|
|
23
|
+
static fromJSON(data, registry) {
|
|
24
|
+
const subject = new Subject();
|
|
25
|
+
if (data.roles && registry) {
|
|
26
|
+
for (const roleName of data.roles) {
|
|
27
|
+
const role = registry.get(roleName);
|
|
28
|
+
if (role) {
|
|
29
|
+
subject.memberOf(role);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (data.rights) {
|
|
34
|
+
const rights = Rights.fromJSON(data.rights);
|
|
35
|
+
for (const r of rights.allRights()) {
|
|
36
|
+
subject.rights.add(r);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return subject;
|
|
40
|
+
}
|
|
12
41
|
memberOf(role) {
|
|
13
42
|
if (!this.roles.includes(role)) {
|
|
14
43
|
this.roles.push(role);
|
|
@@ -24,6 +53,24 @@ export class Subject {
|
|
|
24
53
|
return this.explain(path, flag, context).allowed;
|
|
25
54
|
}
|
|
26
55
|
explain(path, flag, context) {
|
|
56
|
+
const { meta, rights } = this.ensureAggregate();
|
|
57
|
+
const res = rights.explain(path, flag, context);
|
|
58
|
+
return {
|
|
59
|
+
allowed: res.allowed,
|
|
60
|
+
details: res.details.map(d => ({
|
|
61
|
+
...d,
|
|
62
|
+
source: d.right ? meta.get(d.right) : undefined
|
|
63
|
+
}))
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
allRights() {
|
|
67
|
+
const { meta, rights } = this.ensureAggregate();
|
|
68
|
+
return rights.allRights().map(right => ({
|
|
69
|
+
right,
|
|
70
|
+
source: meta.get(right)
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
ensureAggregate() {
|
|
27
74
|
if (!this._aggregate) {
|
|
28
75
|
this._aggregate = new Rights();
|
|
29
76
|
this._aggregateMeta = new Map();
|
|
@@ -42,14 +89,7 @@ export class Subject {
|
|
|
42
89
|
this._aggregateMeta.set(r, { type: 'direct' });
|
|
43
90
|
}
|
|
44
91
|
}
|
|
45
|
-
|
|
46
|
-
return {
|
|
47
|
-
allowed: res.allowed,
|
|
48
|
-
details: res.details.map(d => ({
|
|
49
|
-
...d,
|
|
50
|
-
source: d.right ? this._aggregateMeta.get(d.right) : undefined
|
|
51
|
-
}))
|
|
52
|
-
};
|
|
92
|
+
return { meta: this._aggregateMeta, rights: this._aggregate };
|
|
53
93
|
}
|
|
54
94
|
// Convenience helpers
|
|
55
95
|
all(path, context) {
|
|
@@ -70,4 +110,7 @@ export class Subject {
|
|
|
70
110
|
execute(path, context) {
|
|
71
111
|
return this.has(path, Flags.EXECUTE, context);
|
|
72
112
|
}
|
|
113
|
+
checkMany(requests, context) {
|
|
114
|
+
return requests.map(req => this.has(req.path, req.flags, context));
|
|
115
|
+
}
|
|
73
116
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "odgn-rights",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Tiny TypeScript library for expressing and evaluating hierarchical rights with simple glob patterns.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"rights",
|
|
@@ -16,10 +16,38 @@
|
|
|
16
16
|
"license": "MIT",
|
|
17
17
|
"main": "dist/index.js",
|
|
18
18
|
"types": "dist/index.d.ts",
|
|
19
|
+
"bin": {
|
|
20
|
+
"odgn-rights": "./dist/cli/index.js",
|
|
21
|
+
"rights": "./dist/cli/index.js"
|
|
22
|
+
},
|
|
19
23
|
"exports": {
|
|
20
24
|
".": {
|
|
21
25
|
"types": "./dist/index.d.ts",
|
|
22
26
|
"import": "./dist/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./cli": {
|
|
29
|
+
"types": "./dist/cli/index.d.ts",
|
|
30
|
+
"import": "./dist/cli/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./adapters": {
|
|
33
|
+
"types": "./dist/adapters/index.d.ts",
|
|
34
|
+
"import": "./dist/adapters/index.js"
|
|
35
|
+
},
|
|
36
|
+
"./adapters/sqlite": {
|
|
37
|
+
"types": "./dist/adapters/sqlite-adapter.d.ts",
|
|
38
|
+
"import": "./dist/adapters/sqlite-adapter.js"
|
|
39
|
+
},
|
|
40
|
+
"./adapters/postgres": {
|
|
41
|
+
"types": "./dist/adapters/postgres-adapter.d.ts",
|
|
42
|
+
"import": "./dist/adapters/postgres-adapter.js"
|
|
43
|
+
},
|
|
44
|
+
"./adapters/redis": {
|
|
45
|
+
"types": "./dist/adapters/redis-adapter.d.ts",
|
|
46
|
+
"import": "./dist/adapters/redis-adapter.js"
|
|
47
|
+
},
|
|
48
|
+
"./integrations/elysia": {
|
|
49
|
+
"types": "./dist/integrations/elysia.d.ts",
|
|
50
|
+
"import": "./dist/integrations/elysia.js"
|
|
23
51
|
}
|
|
24
52
|
},
|
|
25
53
|
"files": [
|
|
@@ -32,26 +60,54 @@
|
|
|
32
60
|
"lint": "eslint --cache .",
|
|
33
61
|
"lint:fix": "eslint --fix .",
|
|
34
62
|
"outdated": "bunx npm-check-updates --interactive --format group",
|
|
35
|
-
"test": "bun test",
|
|
36
|
-
"test:coverage": "bun test --coverage",
|
|
63
|
+
"test": "bun test src",
|
|
64
|
+
"test:coverage": "bun test --coverage src",
|
|
65
|
+
"test:e2e": "playwright test",
|
|
66
|
+
"test:e2e:ui": "playwright test --ui",
|
|
37
67
|
"unused": "knip",
|
|
38
68
|
"clean": "rm -rf dist",
|
|
39
69
|
"build": "tsc -p tsconfig.build.json",
|
|
70
|
+
"playground": "bun ./playground/index.html",
|
|
71
|
+
"playground:build": "bun run ./playground/build.ts",
|
|
40
72
|
"prepublishOnly": "bun run clean && bun run build && bun run test && bun run lint:fix && bun run format:check"
|
|
41
73
|
},
|
|
42
74
|
"devDependencies": {
|
|
43
75
|
"@ianvs/prettier-plugin-sort-imports": "^4.7.0",
|
|
44
76
|
"@nkzw/eslint-config": "^3.3.0",
|
|
77
|
+
"@playwright/test": "^1.57.0",
|
|
78
|
+
"@testcontainers/postgresql": "^11.11.0",
|
|
79
|
+
"@testcontainers/valkey": "^11.11.0",
|
|
45
80
|
"@types/bun": "latest",
|
|
81
|
+
"@types/react": "^19.2.7",
|
|
82
|
+
"@types/react-dom": "^19.2.3",
|
|
83
|
+
"elysia": "^1.4.21",
|
|
46
84
|
"eslint": "^9",
|
|
47
|
-
"knip": "^5.
|
|
48
|
-
"prettier": "^3"
|
|
85
|
+
"knip": "^5.80.0",
|
|
86
|
+
"prettier": "^3",
|
|
87
|
+
"testcontainers": "^11.11.0"
|
|
49
88
|
},
|
|
50
89
|
"peerDependencies": {
|
|
51
|
-
"typescript": "^5"
|
|
90
|
+
"typescript": "^5",
|
|
91
|
+
"elysia": "^1.0.0"
|
|
92
|
+
},
|
|
93
|
+
"peerDependenciesMeta": {
|
|
94
|
+
"elysia": {
|
|
95
|
+
"optional": true
|
|
96
|
+
}
|
|
52
97
|
},
|
|
53
98
|
"publishConfig": {
|
|
54
99
|
"access": "public"
|
|
55
100
|
},
|
|
56
|
-
"sideEffects": false
|
|
101
|
+
"sideEffects": false,
|
|
102
|
+
"dependencies": {
|
|
103
|
+
"commander": "^14.0.2",
|
|
104
|
+
"ioredis": "^5.9.0",
|
|
105
|
+
"jotai": "^2.16.1",
|
|
106
|
+
"react": "^19.2.3",
|
|
107
|
+
"react-dom": "^19.2.3"
|
|
108
|
+
},
|
|
109
|
+
"trustedDependencies": [
|
|
110
|
+
"protobufjs",
|
|
111
|
+
"unrs-resolver"
|
|
112
|
+
]
|
|
57
113
|
}
|
package/dist/utils.d.ts
DELETED