@furystack/core 15.0.30 → 15.0.32
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 +9 -66
- package/README.md +19 -2
- package/esm/identity-context.d.ts +32 -0
- package/esm/identity-context.d.ts.map +1 -1
- package/esm/identity-context.js +32 -0
- package/esm/identity-context.js.map +1 -1
- package/esm/in-memory-store.d.ts.map +1 -1
- package/esm/in-memory-store.js +75 -69
- package/esm/in-memory-store.js.map +1 -1
- package/esm/models/physical-store.d.ts +1 -1
- package/esm/models/physical-store.d.ts.map +1 -1
- package/esm/models/physical-store.js.map +1 -1
- package/esm/port-generator.d.ts +2 -2
- package/esm/port-generator.d.ts.map +1 -1
- package/esm/port-generator.js +4 -3
- package/esm/port-generator.js.map +1 -1
- package/package.json +5 -5
- package/src/identity-context.ts +32 -0
- package/src/in-memory-store.ts +93 -70
- package/src/models/physical-store.ts +3 -1
- package/src/port-generator.ts +5 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,76 +1,19 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
3
|
+
## [15.0.32] - 2026-01-22
|
|
5
4
|
|
|
6
|
-
###
|
|
5
|
+
### ⬆️ Dependencies
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
- Dependency updates
|
|
9
8
|
|
|
10
|
-
###
|
|
9
|
+
### 📚 Documentation
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
### [10.4.4](https://github.com/furystack/furystack/compare/@furystack/core@10.4.2...@furystack/core@10.4.4) (2022-01-10)
|
|
15
|
-
|
|
16
|
-
**Note:** Version bump only for package @furystack/core
|
|
17
|
-
|
|
18
|
-
### [10.4.3](https://github.com/furystack/furystack/compare/@furystack/core@10.4.2...@furystack/core@10.4.3) (2022-01-10)
|
|
19
|
-
|
|
20
|
-
**Note:** Version bump only for package @furystack/core
|
|
21
|
-
|
|
22
|
-
### [10.4.2](https://github.com/furystack/furystack/compare/@furystack/core@10.4.1...@furystack/core@10.4.2) (2021-12-20)
|
|
23
|
-
|
|
24
|
-
**Note:** Version bump only for package @furystack/core
|
|
25
|
-
|
|
26
|
-
### [10.4.1](https://github.com/furystack/furystack/compare/@furystack/core@10.4.0...@furystack/core@10.4.1) (2021-12-08)
|
|
11
|
+
- Improved README with clearer examples and better structure
|
|
27
12
|
|
|
28
13
|
### 🐛 Bug Fixes
|
|
29
14
|
|
|
30
|
-
-
|
|
31
|
-
|
|
32
|
-
## [10.4.0](https://github.com/furystack/furystack/compare/@furystack/core@10.3.8...@furystack/core@10.4.0) (2021-11-30)
|
|
33
|
-
|
|
34
|
-
### 🚀 What's new
|
|
35
|
-
|
|
36
|
-
- **@furystack/core:** Advanced filters for InMemory store ([bc89ecc](https://github.com/furystack/furystack/commit/bc89ecc49781d9f6ec1b772662e00d3467b15227))
|
|
37
|
-
|
|
38
|
-
### [10.3.8](https://github.com/furystack/furystack/compare/@furystack/core@10.3.7...@furystack/core@10.3.8) (2021-11-29)
|
|
39
|
-
|
|
40
|
-
**Note:** Version bump only for package @furystack/core
|
|
41
|
-
|
|
42
|
-
### [10.3.7](https://github.com/furystack/furystack/compare/@furystack/core@10.3.6...@furystack/core@10.3.7) (2021-11-19)
|
|
43
|
-
|
|
44
|
-
**Note:** Version bump only for package @furystack/core
|
|
45
|
-
|
|
46
|
-
### [10.3.6](https://github.com/furystack/furystack/compare/@furystack/core@10.3.5...@furystack/core@10.3.6) (2021-11-09)
|
|
47
|
-
|
|
48
|
-
**Note:** Version bump only for package @furystack/core
|
|
49
|
-
|
|
50
|
-
### [10.3.5](https://github.com/furystack/furystack/compare/@furystack/core@10.3.4...@furystack/core@10.3.5) (2021-10-15)
|
|
51
|
-
|
|
52
|
-
**Note:** Version bump only for package @furystack/core
|
|
53
|
-
|
|
54
|
-
### [10.3.4](https://github.com/furystack/furystack/compare/@furystack/core@10.3.3...@furystack/core@10.3.4) (2021-10-05)
|
|
55
|
-
|
|
56
|
-
**Note:** Version bump only for package @furystack/core
|
|
57
|
-
|
|
58
|
-
### [10.3.3](https://github.com/furystack/furystack/compare/@furystack/core@10.3.2...@furystack/core@10.3.3) (2021-09-16)
|
|
59
|
-
|
|
60
|
-
**Note:** Version bump only for package @furystack/core
|
|
61
|
-
|
|
62
|
-
### [10.3.2](https://github.com/furystack/furystack/compare/@furystack/core@10.3.1...@furystack/core@10.3.2) (2021-08-27)
|
|
63
|
-
|
|
64
|
-
**Note:** Version bump only for package @furystack/core
|
|
65
|
-
|
|
66
|
-
### [10.3.1](https://github.com/furystack/furystack/compare/@furystack/core@10.3.0...@furystack/core@10.3.1) (2021-08-19)
|
|
67
|
-
|
|
68
|
-
**Note:** Version bump only for package @furystack/core
|
|
69
|
-
|
|
70
|
-
## [10.3.0](https://github.com/furystack/furystack/compare/@furystack/core@9.1.16...@furystack/core@10.3.0) (2021-08-19)
|
|
71
|
-
|
|
72
|
-
**Note:** Version bump only for package @furystack/core
|
|
15
|
+
- Fixed `getPort()` returning duplicate ports by reusing a shared generator instance instead of creating a new one on each call
|
|
73
16
|
|
|
74
|
-
|
|
17
|
+
### 🔧 Chores
|
|
75
18
|
|
|
76
|
-
|
|
19
|
+
- Migrated to centralized changelog management system
|
package/README.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Core package for FuryStack with generic type and interface definitions and concepts.
|
|
4
4
|
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @furystack/core
|
|
9
|
+
# or
|
|
10
|
+
yarn add @furystack/core
|
|
11
|
+
```
|
|
12
|
+
|
|
5
13
|
## Concepts
|
|
6
14
|
|
|
7
15
|
### Physical Store
|
|
@@ -14,7 +22,16 @@ The generic way to implement authentication and authorization logic is with an I
|
|
|
14
22
|
|
|
15
23
|
### User
|
|
16
24
|
|
|
17
|
-
|
|
25
|
+
The `User` model is a simple class that represents an application user with a `username` and a list of `roles`. You can extend this class to add custom properties for your application.
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { User } from '@furystack/core'
|
|
29
|
+
|
|
30
|
+
class MyUser extends User {
|
|
31
|
+
declare email: string
|
|
32
|
+
declare createdAt: Date
|
|
33
|
+
}
|
|
34
|
+
```
|
|
18
35
|
|
|
19
36
|
## Other Utilities
|
|
20
37
|
|
|
@@ -23,7 +40,7 @@ The generic way to implement authentication and authorization logic is with an I
|
|
|
23
40
|
Global Disposables is a list you can fill with disposables that will be disposed on app exit – this helps with graceful app shutdowns.
|
|
24
41
|
|
|
25
42
|
```ts
|
|
26
|
-
import { globalDisposables } from '@furystack/core
|
|
43
|
+
import { globalDisposables } from '@furystack/core'
|
|
27
44
|
|
|
28
45
|
globalDisposables.add(myRootInjector)
|
|
29
46
|
```
|
|
@@ -1,7 +1,39 @@
|
|
|
1
1
|
import type { User } from './models/user.js';
|
|
2
|
+
/**
|
|
3
|
+
* Provides authentication and authorization context for the current request/session.
|
|
4
|
+
* This is a base implementation that should be extended or replaced with a concrete
|
|
5
|
+
* implementation that connects to your authentication system.
|
|
6
|
+
*
|
|
7
|
+
* The IdentityContext is scoped to the request, meaning each request gets its own instance.
|
|
8
|
+
* Override this class or set an explicit instance to provide actual authentication logic.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* // Use the helper functions instead of accessing IdentityContext directly
|
|
13
|
+
* import { isAuthenticated, isAuthorized, getCurrentUser } from '@furystack/core'
|
|
14
|
+
*
|
|
15
|
+
* const authenticated = await isAuthenticated(injector)
|
|
16
|
+
* const authorized = await isAuthorized(injector, 'admin')
|
|
17
|
+
* const user = await getCurrentUser(injector)
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
2
20
|
export declare class IdentityContext {
|
|
21
|
+
/**
|
|
22
|
+
* Checks if the current user is authenticated.
|
|
23
|
+
* @returns Promise resolving to true if authenticated, false otherwise
|
|
24
|
+
*/
|
|
3
25
|
isAuthenticated(): Promise<boolean>;
|
|
26
|
+
/**
|
|
27
|
+
* Checks if the current user has the specified roles.
|
|
28
|
+
* @param _roles - The roles to check
|
|
29
|
+
* @returns Promise resolving to true if authorized, false otherwise
|
|
30
|
+
*/
|
|
4
31
|
isAuthorized(..._roles: string[]): Promise<boolean>;
|
|
32
|
+
/**
|
|
33
|
+
* Gets the current authenticated user.
|
|
34
|
+
* @returns Promise resolving to the current user
|
|
35
|
+
* @throws Error if no user is authenticated
|
|
36
|
+
*/
|
|
5
37
|
getCurrentUser<TUser extends User>(): Promise<TUser>;
|
|
6
38
|
}
|
|
7
39
|
//# sourceMappingURL=identity-context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity-context.d.ts","sourceRoot":"","sources":["../src/identity-context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAE5C,qBACa,eAAe;
|
|
1
|
+
{"version":3,"file":"identity-context.d.ts","sourceRoot":"","sources":["../src/identity-context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAE5C;;;;;;;;;;;;;;;;;GAiBG;AACH,qBACa,eAAe;IAC1B;;;OAGG;IACI,eAAe;IAItB;;;;OAIG;IACI,YAAY,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE;IAIvC;;;;OAIG;IACI,cAAc,CAAC,KAAK,SAAS,IAAI,KAAK,OAAO,CAAC,KAAK,CAAC;CAG5D"}
|
package/esm/identity-context.js
CHANGED
|
@@ -5,13 +5,45 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
import { Injectable } from '@furystack/inject';
|
|
8
|
+
/**
|
|
9
|
+
* Provides authentication and authorization context for the current request/session.
|
|
10
|
+
* This is a base implementation that should be extended or replaced with a concrete
|
|
11
|
+
* implementation that connects to your authentication system.
|
|
12
|
+
*
|
|
13
|
+
* The IdentityContext is scoped to the request, meaning each request gets its own instance.
|
|
14
|
+
* Override this class or set an explicit instance to provide actual authentication logic.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* // Use the helper functions instead of accessing IdentityContext directly
|
|
19
|
+
* import { isAuthenticated, isAuthorized, getCurrentUser } from '@furystack/core'
|
|
20
|
+
*
|
|
21
|
+
* const authenticated = await isAuthenticated(injector)
|
|
22
|
+
* const authorized = await isAuthorized(injector, 'admin')
|
|
23
|
+
* const user = await getCurrentUser(injector)
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
8
26
|
let IdentityContext = class IdentityContext {
|
|
27
|
+
/**
|
|
28
|
+
* Checks if the current user is authenticated.
|
|
29
|
+
* @returns Promise resolving to true if authenticated, false otherwise
|
|
30
|
+
*/
|
|
9
31
|
isAuthenticated() {
|
|
10
32
|
return Promise.resolve(false);
|
|
11
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Checks if the current user has the specified roles.
|
|
36
|
+
* @param _roles - The roles to check
|
|
37
|
+
* @returns Promise resolving to true if authorized, false otherwise
|
|
38
|
+
*/
|
|
12
39
|
isAuthorized(..._roles) {
|
|
13
40
|
return Promise.resolve(false);
|
|
14
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Gets the current authenticated user.
|
|
44
|
+
* @returns Promise resolving to the current user
|
|
45
|
+
* @throws Error if no user is authenticated
|
|
46
|
+
*/
|
|
15
47
|
getCurrentUser() {
|
|
16
48
|
throw new Error('No IdentityContext');
|
|
17
49
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity-context.js","sourceRoot":"","sources":["../src/identity-context.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"identity-context.js","sourceRoot":"","sources":["../src/identity-context.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAG9C;;;;;;;;;;;;;;;;;GAiBG;AAEI,IAAM,eAAe,GAArB,MAAM,eAAe;IAC1B;;;OAGG;IACI,eAAe;QACpB,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC/B,CAAC;IAED;;;;OAIG;IACI,YAAY,CAAC,GAAG,MAAgB;QACrC,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC/B,CAAC;IAED;;;;OAIG;IACI,cAAc;QACnB,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAA;IACvC,CAAC;CACF,CAAA;AA1BY,eAAe;IAD3B,UAAU,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;GACtB,eAAe,CA0B3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"in-memory-store.d.ts","sourceRoot":"","sources":["../src/in-memory-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"in-memory-store.d.ts","sourceRoot":"","sources":["../src/in-memory-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAqBrH,qBAAa,aAAa,CAAC,CAAC,EAAE,WAAW,SAAS,MAAM,CAAC,CACvD,SAAQ,QAAQ,CAAC;IACf,aAAa,EAAE;QAAE,MAAM,EAAE,CAAC,CAAA;KAAE,CAAA;IAC5B,eAAe,EAAE;QAAE,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;KAAE,CAAA;IAC3D,eAAe,EAAE;QAAE,GAAG,EAAE,CAAC,CAAC,WAAW,CAAC,CAAA;KAAE,CAAA;CACzC,CACD,YAAW,aAAa,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC;IAE3C;;;OAGG;IACU,MAAM,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAOrD,GAAG,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAapD,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAY;IACzC,GAAG,GAAI,KAAK,CAAC,CAAC,WAAW,CAAC,EAAE,SAAS,KAAK,CAAC,MAAM,CAAC,CAAC,qCAGzD;IAED,OAAO,CAAC,YAAY,CAGnB;IAED,OAAO,CAAC,cAAc;IA8GT,IAAI,CAAC,OAAO,SAAS,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC,EAAE,OAAO,CAAC;IA4B3E,KAAK,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC;IAI5B,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,CAAC;IAWxC,CAAC,MAAM,CAAC,OAAO,CAAC;IAKvB,SAAgB,UAAU,EAAE,WAAW,CAAA;IACvC,SAAgB,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAA;IAEvC;;;;;OAKG;gBACS,OAAO,EAAE;QACnB;;WAEG;QACH,UAAU,EAAE,WAAW,CAAA;QACvB;;WAEG;QACH,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAA;KACxB;CAKF"}
|
package/esm/in-memory-store.js
CHANGED
|
@@ -37,9 +37,11 @@ export class InMemoryStore extends EventHub {
|
|
|
37
37
|
return values;
|
|
38
38
|
}
|
|
39
39
|
return values.filter((item) => {
|
|
40
|
-
|
|
40
|
+
const filterRecord = filter;
|
|
41
|
+
const itemRecord = item;
|
|
42
|
+
for (const key in filterRecord) {
|
|
41
43
|
if (isLogicalOperator(key)) {
|
|
42
|
-
const filterValue =
|
|
44
|
+
const filterValue = filterRecord[key];
|
|
43
45
|
switch (key) {
|
|
44
46
|
case '$and':
|
|
45
47
|
if (filterValue.some((v) => !this.filterInternal([item], v).length)) {
|
|
@@ -55,83 +57,86 @@ export class InMemoryStore extends EventHub {
|
|
|
55
57
|
throw new Error(`The logical operation '${key}' is not a valid operation`);
|
|
56
58
|
}
|
|
57
59
|
}
|
|
58
|
-
else
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (filterValue === itemValue) {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
break;
|
|
74
|
-
case '$in':
|
|
75
|
-
if (!filterValue.includes(itemValue)) {
|
|
76
|
-
return false;
|
|
77
|
-
}
|
|
78
|
-
break;
|
|
79
|
-
case '$nin':
|
|
80
|
-
if (filterValue.includes(itemValue)) {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
break;
|
|
84
|
-
case '$lt':
|
|
85
|
-
if (itemValue < filterValue) {
|
|
60
|
+
else {
|
|
61
|
+
const fieldFilter = filterRecord[key];
|
|
62
|
+
if (typeof fieldFilter === 'object' && fieldFilter !== null) {
|
|
63
|
+
for (const filterKey in fieldFilter) {
|
|
64
|
+
if (isOperator(filterKey)) {
|
|
65
|
+
const itemValue = itemRecord[key];
|
|
66
|
+
const filterValue = fieldFilter[filterKey];
|
|
67
|
+
switch (filterKey) {
|
|
68
|
+
case '$eq':
|
|
69
|
+
if (filterValue !== itemValue) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
86
72
|
break;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
73
|
+
case '$ne':
|
|
74
|
+
if (filterValue === itemValue) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
91
77
|
break;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
78
|
+
case '$in':
|
|
79
|
+
if (!filterValue.includes(itemValue)) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
96
82
|
break;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
83
|
+
case '$nin':
|
|
84
|
+
if (filterValue.includes(itemValue)) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
101
87
|
break;
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
88
|
+
case '$lt':
|
|
89
|
+
if (itemValue < filterValue) {
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
106
92
|
return false;
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
93
|
+
case '$lte':
|
|
94
|
+
if (itemValue <= filterValue) {
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
111
97
|
return false;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
98
|
+
case '$gt':
|
|
99
|
+
if (itemValue > filterValue) {
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
116
102
|
return false;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
103
|
+
case '$gte':
|
|
104
|
+
if (itemValue >= filterValue) {
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
121
107
|
return false;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
108
|
+
case '$regex':
|
|
109
|
+
if (!new RegExp(filterValue).test(String(itemValue))) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
break;
|
|
113
|
+
case '$startsWith':
|
|
114
|
+
if (!itemValue.startsWith(filterValue)) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
break;
|
|
118
|
+
case '$endsWith':
|
|
119
|
+
if (!itemValue.endsWith(filterValue)) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
break;
|
|
123
|
+
case '$like':
|
|
124
|
+
if (!this.evaluateLike(itemValue, filterValue)) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
break;
|
|
128
|
+
default:
|
|
129
|
+
throw new Error(`The expression (${filterKey}) is not supported by '${this.constructor.name}'!`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
throw new Error(`The filter key '${filterKey}' is not a valid operation`);
|
|
126
134
|
}
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
throw new Error(`The filter key '${filterKey}' is not a valid operation`);
|
|
130
135
|
}
|
|
131
136
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
137
|
+
else {
|
|
138
|
+
throw new Error(`The filter has to be an object, got ${typeof fieldFilter} for field '${key}'`);
|
|
139
|
+
}
|
|
135
140
|
}
|
|
136
141
|
}
|
|
137
142
|
return true;
|
|
@@ -140,9 +145,10 @@ export class InMemoryStore extends EventHub {
|
|
|
140
145
|
async find(searchOptions) {
|
|
141
146
|
let value = this.filterInternal([...this.cache.values()], searchOptions.filter);
|
|
142
147
|
if (searchOptions.order) {
|
|
148
|
+
const orderRecord = searchOptions.order;
|
|
143
149
|
for (const fieldName of Object.keys(searchOptions.order)) {
|
|
144
150
|
value = value.sort((a, b) => {
|
|
145
|
-
const order =
|
|
151
|
+
const order = orderRecord[fieldName];
|
|
146
152
|
if (a[fieldName] < b[fieldName])
|
|
147
153
|
return order === 'ASC' ? -1 : 1;
|
|
148
154
|
if (a[fieldName] > b[fieldName])
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"in-memory-store.js","sourceRoot":"","sources":["../src/in-memory-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"in-memory-store.js","sourceRoot":"","sources":["../src/in-memory-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,7 +19,7 @@ export type FilterType<T> = {
|
|
|
19
19
|
} & {
|
|
20
20
|
[LO in (typeof LogicalOperators)[number]]?: Array<FilterType<T>>;
|
|
21
21
|
};
|
|
22
|
-
export declare const isLogicalOperator: (propertyString: string) => propertyString is (typeof LogicalOperators)[number];
|
|
22
|
+
export declare const isLogicalOperator: (propertyString: string | number | symbol) => propertyString is (typeof LogicalOperators)[number];
|
|
23
23
|
export declare const isOperator: (propertyString: string) => propertyString is (typeof allOperators)[number];
|
|
24
24
|
export declare const t: FilterType<{
|
|
25
25
|
a: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"physical-store.d.ts","sourceRoot":"","sources":["../../src/models/physical-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAEhD,eAAO,MAAM,yBAAyB,yCAA0C,CAAA;AAEhF,eAAO,MAAM,yBAAyB,0DAA2D,CAAA;AACjG,eAAO,MAAM,yBAAyB,yBAA0B,CAAA;AAEhE,eAAO,MAAM,wBAAwB,0BAA2B,CAAA;AAChE,eAAO,MAAM,gBAAgB,0CAA2C,CAAA;AAExE,eAAO,MAAM,YAAY,oJAMf,CAAA;AAEV,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI;KACzB,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EACX,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GAAG;SAAG,GAAG,IAAI,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;KAAE,GAAG,KAAK,CAAC,GAC9F,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GAAG;SAAG,GAAG,IAAI,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;KAAE,GAAG,KAAK,CAAC,GAC9F;SAAG,GAAG,IAAI,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;KAAE,GAC9D;SAAG,GAAG,IAAI,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KAAE;CACzE,GAAG;KAAG,EAAE,IAAI,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;CAAE,CAAA;AAExE,eAAO,MAAM,iBAAiB,
|
|
1
|
+
{"version":3,"file":"physical-store.d.ts","sourceRoot":"","sources":["../../src/models/physical-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"physical-store.js","sourceRoot":"","sources":["../../src/models/physical-store.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAU,CAAA;AAEhF,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,aAAa,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAU,CAAA;AACjG,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,KAAK,CAAU,CAAA;AAEhE,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,KAAK,EAAE,MAAM,CAAU,CAAA;AAChE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAU,CAAA;AAExE,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,GAAG,yBAAyB;IAC5B,GAAG,yBAAyB;IAC5B,GAAG,wBAAwB;IAC3B,GAAG,gBAAgB;IACnB,GAAG,yBAAyB;CACpB,CAAA;AAUV,MAAM,CAAC,MAAM,iBAAiB,GAAG,
|
|
1
|
+
{"version":3,"file":"physical-store.js","sourceRoot":"","sources":["../../src/models/physical-store.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAU,CAAA;AAEhF,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,aAAa,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAU,CAAA;AACjG,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,KAAK,CAAU,CAAA;AAEhE,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,KAAK,EAAE,MAAM,CAAU,CAAA;AAChE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAU,CAAA;AAExE,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,GAAG,yBAAyB;IAC5B,GAAG,yBAAyB;IAC5B,GAAG,wBAAwB;IAC3B,GAAG,gBAAgB;IACnB,GAAG,yBAAyB;CACpB,CAAA;AAUV,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,cAAwC,EACa,EAAE,CACvD,gBAAgB,CAAC,QAAQ,CAAC,cAAmD,CAAC,CAAA;AAEhF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,cAAsB,EAAmD,EAAE,CACpG,YAAY,CAAC,QAAQ,CAAC,cAA+C,CAAC,CAAA;AAExE,MAAM,CAAC,MAAM,CAAC,GAAqD;IACjE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE;IACb,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE;IAC3B,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;CAC1B,CAAA;AAuCD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAkD,KAAQ,EAAE,GAAG,MAAc,EAAE,EAAE;IAC3G,MAAM,WAAW,GAAG,EAA8B,CAAA;IAClD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAmB,GAAqB,CAAA;QACnD,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,WAAW,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;QACnC,CAAC;IACH,CAAC,CAAC,CAAA;IACF,OAAO,WAAW,CAAA;AACpB,CAAC,CAAA"}
|
package/esm/port-generator.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Generates a
|
|
3
|
-
* @returns the next port number starting from 14000
|
|
2
|
+
* Generates a unique port number for testing purposes
|
|
3
|
+
* @returns the next sequential port number starting from a random base between 14000 and 16000
|
|
4
4
|
*/
|
|
5
5
|
export declare const getPort: () => number;
|
|
6
6
|
//# sourceMappingURL=port-generator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"port-generator.d.ts","sourceRoot":"","sources":["../src/port-generator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"port-generator.d.ts","sourceRoot":"","sources":["../src/port-generator.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,eAAO,MAAM,OAAO,QAAO,MAAgC,CAAA"}
|
package/esm/port-generator.js
CHANGED
|
@@ -5,9 +5,10 @@ const portGenerator = function* () {
|
|
|
5
5
|
yield port++;
|
|
6
6
|
}
|
|
7
7
|
};
|
|
8
|
+
const generator = portGenerator();
|
|
8
9
|
/**
|
|
9
|
-
* Generates a
|
|
10
|
-
* @returns the next port number starting from 14000
|
|
10
|
+
* Generates a unique port number for testing purposes
|
|
11
|
+
* @returns the next sequential port number starting from a random base between 14000 and 16000
|
|
11
12
|
*/
|
|
12
|
-
export const getPort = () =>
|
|
13
|
+
export const getPort = () => generator.next().value;
|
|
13
14
|
//# sourceMappingURL=port-generator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"port-generator.js","sourceRoot":"","sources":["../src/port-generator.ts"],"names":[],"mappings":"AAAA,MAAM,aAAa,GAAG,QAAQ,CAAC;IAC7B,MAAM,WAAW,GAAG,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAA;IAC5D,IAAI,IAAI,GAAG,WAAW,CAAA;IACtB,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,IAAI,EAAE,CAAA;IACd,CAAC;AACH,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,
|
|
1
|
+
{"version":3,"file":"port-generator.js","sourceRoot":"","sources":["../src/port-generator.ts"],"names":[],"mappings":"AAAA,MAAM,aAAa,GAAG,QAAQ,CAAC;IAC7B,MAAM,WAAW,GAAG,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAA;IAC5D,IAAI,IAAI,GAAG,WAAW,CAAA;IACtB,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,IAAI,EAAE,CAAA;IACd,CAAC;AACH,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,aAAa,EAAE,CAAA;AAEjC;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,GAAW,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,KAAK,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@furystack/core",
|
|
3
|
-
"version": "15.0.
|
|
3
|
+
"version": "15.0.32",
|
|
4
4
|
"description": "Core FuryStack package",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
},
|
|
41
41
|
"homepage": "https://github.com/furystack/furystack",
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@types/node": "^25.0.
|
|
43
|
+
"@types/node": "^25.0.10",
|
|
44
44
|
"typescript": "^5.9.3",
|
|
45
|
-
"vitest": "^4.0.
|
|
45
|
+
"vitest": "^4.0.17"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@furystack/inject": "^12.0.
|
|
49
|
-
"@furystack/utils": "^8.1.
|
|
48
|
+
"@furystack/inject": "^12.0.26",
|
|
49
|
+
"@furystack/utils": "^8.1.8"
|
|
50
50
|
},
|
|
51
51
|
"gitHead": "1045d854bfd8c475b7035471d130d401417a2321"
|
|
52
52
|
}
|
package/src/identity-context.ts
CHANGED
|
@@ -1,16 +1,48 @@
|
|
|
1
1
|
import { Injectable } from '@furystack/inject'
|
|
2
2
|
import type { User } from './models/user.js'
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Provides authentication and authorization context for the current request/session.
|
|
6
|
+
* This is a base implementation that should be extended or replaced with a concrete
|
|
7
|
+
* implementation that connects to your authentication system.
|
|
8
|
+
*
|
|
9
|
+
* The IdentityContext is scoped to the request, meaning each request gets its own instance.
|
|
10
|
+
* Override this class or set an explicit instance to provide actual authentication logic.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* // Use the helper functions instead of accessing IdentityContext directly
|
|
15
|
+
* import { isAuthenticated, isAuthorized, getCurrentUser } from '@furystack/core'
|
|
16
|
+
*
|
|
17
|
+
* const authenticated = await isAuthenticated(injector)
|
|
18
|
+
* const authorized = await isAuthorized(injector, 'admin')
|
|
19
|
+
* const user = await getCurrentUser(injector)
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
4
22
|
@Injectable({ lifetime: 'scoped' })
|
|
5
23
|
export class IdentityContext {
|
|
24
|
+
/**
|
|
25
|
+
* Checks if the current user is authenticated.
|
|
26
|
+
* @returns Promise resolving to true if authenticated, false otherwise
|
|
27
|
+
*/
|
|
6
28
|
public isAuthenticated() {
|
|
7
29
|
return Promise.resolve(false)
|
|
8
30
|
}
|
|
9
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Checks if the current user has the specified roles.
|
|
34
|
+
* @param _roles - The roles to check
|
|
35
|
+
* @returns Promise resolving to true if authorized, false otherwise
|
|
36
|
+
*/
|
|
10
37
|
public isAuthorized(..._roles: string[]) {
|
|
11
38
|
return Promise.resolve(false)
|
|
12
39
|
}
|
|
13
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Gets the current authenticated user.
|
|
43
|
+
* @returns Promise resolving to the current user
|
|
44
|
+
* @throws Error if no user is authenticated
|
|
45
|
+
*/
|
|
14
46
|
public getCurrentUser<TUser extends User>(): Promise<TUser> {
|
|
15
47
|
throw new Error('No IdentityContext')
|
|
16
48
|
}
|
package/src/in-memory-store.ts
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
2
|
-
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
3
1
|
import type { Constructable } from '@furystack/inject'
|
|
4
2
|
import { EventHub } from '@furystack/utils'
|
|
5
3
|
import type { CreateResult, FilterType, FindOptions, PartialResult, PhysicalStore } from './models/physical-store.js'
|
|
6
4
|
import { isLogicalOperator, isOperator, selectFields } from './models/physical-store.js'
|
|
7
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Helper type representing all possible field filter operations
|
|
8
|
+
*/
|
|
9
|
+
type FieldOperatorFilter = {
|
|
10
|
+
$eq?: unknown
|
|
11
|
+
$ne?: unknown
|
|
12
|
+
$in?: unknown[]
|
|
13
|
+
$nin?: unknown[]
|
|
14
|
+
$gt?: unknown
|
|
15
|
+
$gte?: unknown
|
|
16
|
+
$lt?: unknown
|
|
17
|
+
$lte?: unknown
|
|
18
|
+
$startsWith?: string
|
|
19
|
+
$endsWith?: string
|
|
20
|
+
$like?: string
|
|
21
|
+
$regex?: string
|
|
22
|
+
}
|
|
23
|
+
|
|
8
24
|
export class InMemoryStore<T, TPrimaryKey extends keyof T>
|
|
9
25
|
extends EventHub<{
|
|
10
26
|
onEntityAdded: { entity: T }
|
|
@@ -53,9 +69,12 @@ export class InMemoryStore<T, TPrimaryKey extends keyof T>
|
|
|
53
69
|
return values
|
|
54
70
|
}
|
|
55
71
|
return values.filter((item) => {
|
|
56
|
-
|
|
72
|
+
const filterRecord = filter as Record<string, Array<FilterType<T>> | FieldOperatorFilter | undefined>
|
|
73
|
+
const itemRecord = item as Record<string, unknown>
|
|
74
|
+
|
|
75
|
+
for (const key in filterRecord) {
|
|
57
76
|
if (isLogicalOperator(key)) {
|
|
58
|
-
const filterValue =
|
|
77
|
+
const filterValue = filterRecord[key] as Array<FilterType<T>>
|
|
59
78
|
switch (key) {
|
|
60
79
|
case '$and':
|
|
61
80
|
if (filterValue.some((v: FilterType<T>) => !this.filterInternal([item], v).length)) {
|
|
@@ -70,82 +89,85 @@ export class InMemoryStore<T, TPrimaryKey extends keyof T>
|
|
|
70
89
|
default:
|
|
71
90
|
throw new Error(`The logical operation '${key}' is not a valid operation`)
|
|
72
91
|
}
|
|
73
|
-
} else
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (filterValue === itemValue) {
|
|
86
|
-
return false
|
|
87
|
-
}
|
|
88
|
-
break
|
|
89
|
-
case '$in':
|
|
90
|
-
if (!filterValue.includes(itemValue)) {
|
|
91
|
-
return false
|
|
92
|
-
}
|
|
93
|
-
break
|
|
94
|
-
|
|
95
|
-
case '$nin':
|
|
96
|
-
if (filterValue.includes(itemValue)) {
|
|
97
|
-
return false
|
|
98
|
-
}
|
|
99
|
-
break
|
|
100
|
-
case '$lt':
|
|
101
|
-
if (itemValue < filterValue) {
|
|
92
|
+
} else {
|
|
93
|
+
const fieldFilter = filterRecord[key] as FieldOperatorFilter | undefined
|
|
94
|
+
if (typeof fieldFilter === 'object' && fieldFilter !== null) {
|
|
95
|
+
for (const filterKey in fieldFilter) {
|
|
96
|
+
if (isOperator(filterKey)) {
|
|
97
|
+
const itemValue = itemRecord[key]
|
|
98
|
+
const filterValue = fieldFilter[filterKey as keyof FieldOperatorFilter]
|
|
99
|
+
switch (filterKey) {
|
|
100
|
+
case '$eq':
|
|
101
|
+
if (filterValue !== itemValue) {
|
|
102
|
+
return false
|
|
103
|
+
}
|
|
102
104
|
break
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
case '$ne':
|
|
106
|
+
if (filterValue === itemValue) {
|
|
107
|
+
return false
|
|
108
|
+
}
|
|
107
109
|
break
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
case '$in':
|
|
111
|
+
if (!(filterValue as unknown[]).includes(itemValue)) {
|
|
112
|
+
return false
|
|
113
|
+
}
|
|
112
114
|
break
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
115
|
+
|
|
116
|
+
case '$nin':
|
|
117
|
+
if ((filterValue as unknown[]).includes(itemValue)) {
|
|
118
|
+
return false
|
|
119
|
+
}
|
|
117
120
|
break
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
121
|
+
case '$lt':
|
|
122
|
+
if ((itemValue as number) < (filterValue as number)) {
|
|
123
|
+
break
|
|
124
|
+
}
|
|
122
125
|
return false
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
126
|
+
case '$lte':
|
|
127
|
+
if ((itemValue as number) <= (filterValue as number)) {
|
|
128
|
+
break
|
|
129
|
+
}
|
|
127
130
|
return false
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
131
|
+
case '$gt':
|
|
132
|
+
if ((itemValue as number) > (filterValue as number)) {
|
|
133
|
+
break
|
|
134
|
+
}
|
|
132
135
|
return false
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
136
|
+
case '$gte':
|
|
137
|
+
if ((itemValue as number) >= (filterValue as number)) {
|
|
138
|
+
break
|
|
139
|
+
}
|
|
137
140
|
return false
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
141
|
+
case '$regex':
|
|
142
|
+
if (!new RegExp(filterValue as string).test(String(itemValue))) {
|
|
143
|
+
return false
|
|
144
|
+
}
|
|
145
|
+
break
|
|
146
|
+
case '$startsWith':
|
|
147
|
+
if (!(itemValue as string).startsWith(filterValue as string)) {
|
|
148
|
+
return false
|
|
149
|
+
}
|
|
150
|
+
break
|
|
151
|
+
case '$endsWith':
|
|
152
|
+
if (!(itemValue as string).endsWith(filterValue as string)) {
|
|
153
|
+
return false
|
|
154
|
+
}
|
|
155
|
+
break
|
|
156
|
+
case '$like':
|
|
157
|
+
if (!this.evaluateLike(itemValue as string, filterValue as string)) {
|
|
158
|
+
return false
|
|
159
|
+
}
|
|
160
|
+
break
|
|
161
|
+
default:
|
|
162
|
+
throw new Error(`The expression (${filterKey}) is not supported by '${this.constructor.name}'!`)
|
|
163
|
+
}
|
|
164
|
+
} else {
|
|
165
|
+
throw new Error(`The filter key '${filterKey}' is not a valid operation`)
|
|
142
166
|
}
|
|
143
|
-
} else {
|
|
144
|
-
throw new Error(`The filter key '${filterKey}' is not a valid operation`)
|
|
145
167
|
}
|
|
168
|
+
} else {
|
|
169
|
+
throw new Error(`The filter has to be an object, got ${typeof fieldFilter} for field '${key}'`)
|
|
146
170
|
}
|
|
147
|
-
} else {
|
|
148
|
-
throw new Error(`The filter has to be an object, got ${typeof (filter as any)[key]} for field '${key}'`)
|
|
149
171
|
}
|
|
150
172
|
}
|
|
151
173
|
return true
|
|
@@ -156,9 +178,10 @@ export class InMemoryStore<T, TPrimaryKey extends keyof T>
|
|
|
156
178
|
let value: Array<PartialResult<T, TFields>> = this.filterInternal([...this.cache.values()], searchOptions.filter)
|
|
157
179
|
|
|
158
180
|
if (searchOptions.order) {
|
|
181
|
+
const orderRecord = searchOptions.order as Record<string, 'ASC' | 'DESC'>
|
|
159
182
|
for (const fieldName of Object.keys(searchOptions.order) as Array<keyof T>) {
|
|
160
183
|
value = value.sort((a, b) => {
|
|
161
|
-
const order =
|
|
184
|
+
const order = orderRecord[fieldName as string]
|
|
162
185
|
if (a[fieldName] < b[fieldName]) return order === 'ASC' ? -1 : 1
|
|
163
186
|
if (a[fieldName] > b[fieldName]) return order === 'ASC' ? 1 : -1
|
|
164
187
|
return 0
|
|
@@ -25,7 +25,9 @@ export type FilterType<T> = {
|
|
|
25
25
|
| { [ACO in (typeof ArrayComparisonOperators)[number]]?: Array<T[K]> }
|
|
26
26
|
} & { [LO in (typeof LogicalOperators)[number]]?: Array<FilterType<T>> }
|
|
27
27
|
|
|
28
|
-
export const isLogicalOperator = (
|
|
28
|
+
export const isLogicalOperator = (
|
|
29
|
+
propertyString: string | number | symbol,
|
|
30
|
+
): propertyString is (typeof LogicalOperators)[number] =>
|
|
29
31
|
LogicalOperators.includes(propertyString as (typeof LogicalOperators)[number])
|
|
30
32
|
|
|
31
33
|
export const isOperator = (propertyString: string): propertyString is (typeof allOperators)[number] =>
|
package/src/port-generator.ts
CHANGED
|
@@ -6,8 +6,10 @@ const portGenerator = function* () {
|
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
const generator = portGenerator()
|
|
10
|
+
|
|
9
11
|
/**
|
|
10
|
-
* Generates a
|
|
11
|
-
* @returns the next port number starting from 14000
|
|
12
|
+
* Generates a unique port number for testing purposes
|
|
13
|
+
* @returns the next sequential port number starting from a random base between 14000 and 16000
|
|
12
14
|
*/
|
|
13
|
-
export const getPort = () =>
|
|
15
|
+
export const getPort = (): number => generator.next().value
|